Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to make a generic type's limitation to "interface" #3390

Closed
ghost opened this issue Jun 9, 2015 · 8 comments
Closed

Allow to make a generic type's limitation to "interface" #3390

ghost opened this issue Jun 9, 2015 · 8 comments

Comments

@ghost
Copy link

ghost commented Jun 9, 2015

We can force a generic type inherted from a class:

 public class XXX<T> where T:class

However we cannot force a generic type implemented by an interface, just like this:

public class YYY<T>where T:interface

Why need this? Some special design mode needs it.—— A typical example is SignalR's latest Hub, here "T" in fact must be an interface for us instead of a fully-filled class or a class implemented from an interface.
Notice it that SignalR is ONLY AN EXAMPLE, and this isn't the core issue from SignalR.

@tmat
Copy link
Member

tmat commented Jun 9, 2015

What operations do you perform on T that require the distinction between a class and an interface?

@ghost
Copy link
Author

ghost commented Jun 9, 2015

@tmat :Just like what I said above——In SignalR, Any class will be a hub class if it inherits from Hub, however A signalR's Hub class can recall the client's js codes as its event by definations of interfaces, A sample is something like this:

  public interface ICall
  {
     void Say(string word);
  }
  public class MyHub: Hub<ICall>
  {
         public void CallSay(string say)
         {
                Context.Caller.Say("Hello"+say);
         }
   }

At the client side, your declaration is:
var myHub = $.connection.hub.myHub;
myHub.server.callSay("Yes"); //This will call SignalR's server-side thing.
myHub.client.say=function(words){alert(words);} //This is an event called by "CallSay" at "MyHub".

From the given example you can see that here interfaces used for the declarations of client's js anoymous event functions. So this must be an interface instead of a class. And If I pass a class inside it, this means the SignalR will execute this at the server-side, and it won't return to activate the client's anoymous js function.

@HaloFour
Copy link

HaloFour commented Jun 9, 2015

Seems to be a pretty limited use case for a language feature. Do you know of any others?

@whoisj
Copy link

whoisj commented Jun 9, 2015

Interface gives no contract. At least class is used to indicate by-reference. You even need to use new() to enable allocation. I'm very confused as to what this brings, but it sounds interesting so I'd like to understand.

@ghost
Copy link
Author

ghost commented Jun 10, 2015

Haha……Yes. To a general thought an interface cannot be used directly. However I only give you an example of SignalR, which means, since net 4.0 starts dynamic object. I mean that if dynamic object begins more and more popular (You see that dynamic objects don't have any intellisenses at all).

However, just like SignalR and if you take some time to see SignalR's core codes, you will find Hub will change dynamic object to something like "interface proxy". This means we define an interface about its declarations of its inner properties, functions……In fact this is a dynamic object type, but it can be used through intellisense. This is my thought from SignalR —— Here "interface" takes the ability of "declarations" (something like WebService's proxy or TypeScript's interface, in fact the real thing doesn't implement it). It just gives Visual Studio and customers intellisenses.

All in all, From SignalR's thought I can see that "interface" can have another very important usage:Interface Declarations For Dynamic Object Type.

@HaloFour
Copy link

That was proposed as #3012 , the ability to specify an interface to use with a dynamic object so that you can get some Intellisense support.

@yume-chan
Copy link

Recently I'm working on a P/Invoke project and I found another usage.

In COM, lots of classes will uses methods like HRESULT GetService (REFIID riid, void** ppObject) to return some services (Most common is QueryInterface).

So I wrapped it to a generic method:

public T GetService<T>()
{
    Guid iid = type(T).GUID;
    return (T)WrappedObject.GetService(ref iid);
}

Now I want T must be an interface, maybe user will call my method with a wrong interface, but it's better than nothing.

@gafter
Copy link
Member

gafter commented Mar 20, 2017

We are now taking language feature discussion on https://github.com/dotnet/csharplang for C# specific issues, https://github.com/dotnet/vblang for VB-specific features, and https://github.com/dotnet/csharplang for features that affect both languages.

@gafter gafter closed this as completed Mar 20, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants