Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/315.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#5.0泛型:参数类型推断_C#_Generics_Type Inference - Fatal编程技术网

C#5.0泛型:参数类型推断

C#5.0泛型:参数类型推断,c#,generics,type-inference,C#,Generics,Type Inference,我一直认为C#编译器能够在以下情况下推断类型参数: class Program { static void Main(string[] args) { IMessageBus messageBus = null; //Here the compiler nags "type params for Publish cannot be inferred from the usage.. .." messageBus.Publish(ne

我一直认为C#编译器能够在以下情况下推断类型参数:

class Program
{
    static void Main(string[] args)
    {
        IMessageBus messageBus = null;

       //Here the compiler nags "type params for Publish cannot be inferred from the usage.. .."
        messageBus.Publish(new CorrectorAdded(10));
    }
}

public interface IEvent<out TPayload>
{
    TPayload Payload { get; }
}

public abstract class EventBase<TPayload> : IEvent<TPayload>
{
    public TPayload Payload { get; private set; }

    protected EventBase(TPayload payload)
    {
        Payload = payload;
    }
}

public interface IMessageBus
{
    void Publish<TEvent, TPayload>(TEvent @event) where TEvent : IEvent<TPayload>;

    IDisposable Subscribe<TEvent, TPayload>(Action<TPayload> listener) where TEvent : IEvent<TPayload>;
}

public class CorrectorAdded : EventBase<CorrectorAddedArgs>
{
    public CorrectorAdded(CorrectorAddedArgs payload) : base(payload)
    {
    }

    public CorrectorAdded(int correctorId) : this(new CorrectorAddedArgs(correctorId))
    {
    }
}

public class CorrectorAddedArgs
{
    public int CorrectorId { get; private set; }

    public CorrectorAddedArgs(int correctorId)
    {
        CorrectorId = correctorId;
    }
}
类程序
{
静态void Main(字符串[]参数)
{
IMessageBus messageBus=null;
//这里,编译器nags“发布的类型参数无法从用法中推断…”
messageBus.Publish(新校正器添加(10));
}
}
公共接口事件
{
TPayload有效负载{get;}
}
公共抽象类EventBase:IEvent
{
公共TPayload有效负载{get;private set;}
受保护的事件库(TPayload负载)
{
有效载荷=有效载荷;
}
}
公共接口IMessageBus
{
作废发布(TEvent@event),其中TEvent:IEvent;
IDisposable订阅(操作侦听器),其中TEvent:IEvent;
}
添加的公共类校正器:EventBase
{
公共校正器添加(校正器添加有效载荷):基础(有效载荷)
{
}
公共校正器添加(int correctorId):此(新校正器添加(correctorId))
{
}
}
公共类校正器标准
{
public int CorrectorId{get;private set;}
公共校正器标准(int校正器ID)
{
CorrectorId=CorrectorId;
}
}
关于为什么会发生这种情况,以及如何在这种情况下使类型推断工作,有什么想法吗


谢谢。

发布的接口签名定义了两个约束:

void Publish<TEvent, TPayload>(TEvent @event) where TEvent : IEvent<TPayload>;
messageBus.Publish( new CorrectorAdded( 10 ), new FooThatImplementsTPayload() );
这样,就可以在没有类型约束的情况下使用方法调用,即

messageBus.Publish( new CorrectorAdded( 10 ) );
// would be the same as
messageBus.Publish<CorrectorAdded>( new CorrectorAdded( 10 ) );
void Publish<TEvent, TPayload>(TEvent @event, TPayload payload) where TEvent : IEvent<TPayload>;
然后,可以在没有类型约束的情况下调用方法:

void Publish<TEvent, TPayload>(TEvent @event) where TEvent : IEvent<TPayload>;
messageBus.Publish( new CorrectorAdded( 10 ), new FooThatImplementsTPayload() );

对于那些仍然对替代API的外观感到好奇的人,以下是我的想法:

class Program
{
    static void Main(string[] args)
    {
        IMessageBus messageBus = null;

        messageBus
            .Event<CorrectorAdded>()
            .Subscribe(eventArgs => { /*skipped*/ });

        //skipped

        messageBus
            .Event<CorrectorAdded>()
            .Publish(new CorrectorAddedArgs(1));
    }
}

public abstract class EventBase
{
    //skipped
}

public abstract class EventBase<TPayload> : EventBase
{
    public IDisposable Subscribe(Action<TPayload> listener)
    {
        //skipped
    }

    public void Publish(TPayload payload)
    {
        //skipped
    }
}

public class CorrectorAdded : EventBase<CorrectorAddedArgs>
{
}

public class CorrectorAddedArgs
{
    public int CorrectorId { get; private set; }

    public CorrectorAddedArgs(int correctorId)
    {
        CorrectorId = correctorId;
    }
}

public interface IMessageBus
{
    TEvent Event<TEvent>() where TEvent : EventBase, new();
}
类程序
{
静态void Main(字符串[]参数)
{
IMessageBus messageBus=null;
消息总线
.Event()
.Subscribe(eventArgs=>{/*跳过*/});
//跳过
消息总线
.Event()
.出版(新校正器增补(1));
}
}
公共抽象类事件库
{
//跳过
}
公共抽象类EventBase:EventBase
{
公共IDisposable订阅(操作侦听器)
{
//跳过
}
公共无效发布(TPayload有效负载)
{
//跳过
}
}
添加的公共类校正器:EventBase
{
}
公共类校正器标准
{
public int CorrectorId{get;private set;}
公共校正器标准(int校正器ID)
{
CorrectorId=CorrectorId;
}
}
公共接口IMessageBus
{
TEvent事件(),其中TEvent:EventBase,new();
}

!一切都清楚了。这并没有让我的生活更轻松,尽管API看起来确实有点模棱两可(this way=)。可能需要把smth扭转过来。。