Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#:泛型——推断泛型类型的泛型类型_C#_Generics - Fatal编程技术网

C#:泛型——推断泛型类型的泛型类型

C#:泛型——推断泛型类型的泛型类型,c#,generics,C#,Generics,我甚至不知道如何问这个问题,所以我只给出代码示例 以下是域名: public interface ISubscriptionProvider<T> { void Subscribe(Action<T> callback); } public class Notification {} public class CurrentUserNotifications : ISubscriptionProvider<Notification> { p

我甚至不知道如何问这个问题,所以我只给出代码示例

以下是域名:

public interface ISubscriptionProvider<T>
{
    void Subscribe(Action<T> callback);
}

public class Notification {}

public class CurrentUserNotifications : ISubscriptionProvider<Notification>
{
    public void Subscribe(Action<Notification> callback) { }
}
公共接口ISubscriptionProvider
{
无效订阅(动作回调);
}
公共类通知{}
公共类CurrentUserNotifications:ISubscriptionProvider
{
公共无效订阅(操作回调){}
}
以下是我想让它变得神奇的方法:

public void Subscribe<P, T>(Action<T> callback) where P : ISubscriptionProvider<T>
{
    // body left out -- code uses P
}
public void Subscribe(操作回调),其中P:ISubscriptionProvider
{
//body省略了--代码使用P
}
这是可行的,你可以这样称呼它:

Subscribe<CurrentUserNotifications, Notification>((n) => Console.WriteLine(n));
Subscribe((n)=>Console.WriteLine(n));
所以问题是:有没有办法让它像这样可调用

Subscribe<CurrentUserNotifications>((n) => Console.WriteLine(n));
Subscribe((n)=>Console.WriteLine(n));
基本上,它可以推断动作类型应该仅来自
ISubscriptionProvider

这个subscribe方法存在于一个静态类上(这是一个静态方法,我省略了这一部分)。其思想是,它将负责构造
ISubscriptionProvider
,并将其保持为一个单例(可能使用structuremap)。因此,在使用中:

Messages.Subscribe<CurrentUserNotifications>((n) => Console.WriteLine(n));
Messages.Subscribe((n)=>Console.WriteLine(n));
谢谢

更新:

这有点离题,但如果有scala人读到这篇文章

。。。这是一个更高级类型的例子吗?比如:

public void Subscribe<P<T>>(Action<T> callback) { }
publicsvoidsubscribe(操作回调){}
其中
p
是更高级的类型吗?

为什么不能直接使用

public void Subscribe<T>(Action<T> callback)
{
}
public void Subscribe(操作回调)
{
}

类型p参数在您的场景中是不相关的,因为它从未被使用过。

C#要么推断出所有类型参数,要么一个都没有。澄清了问题——不是,不是,它在一个静态类上。在哪个类中定义Subscribe方法?@CodesInChaos我知道,但我不确定它是否可以检查ISubscriptionProvider并从它的泛型类型推断。从技术上讲,所有信息都存在于单一类型(CurrentUserNotifications)中,但我不确定是否可以让c#使用它。@CodeInChaos它变得越来越清楚,答案是否定的:)你能回答这个问题,这样我就可以给你光荣、光荣的业力吗?对不起,为了避免混乱,我省略了正文,但它确实使用了P--更新的问题。