簡體   English   中英

使用通用接口進行C#轉換

[英]C# casting with generic interfaces

我試圖理解為什么在這種情況下鑄造不起作用。

假設以下接口:

public interface IDomainEvent { }

public interface IHandler<T> where T: IDomainEvent
{
    void Handle(T args);
}

這些簡單的實現:

public class SomeEvent : IDomainEvent
{
    public string Value { get; set; }
}

public class SomeEventHandler : IHandler<SomeEvent>
{
    public void Handle(SomeEvent args) { }
}

我不明白為什么我不能做這個演員:

var handler = new SomeEventHandler() as IHandler<IDomainEvent>;

我正在使用Autofac來解析基於事件的處理程序列表,它做得很好,但它創建它們當然是完全具體的,在運行時我需要通過接口處理它們。 我可以使用反射很容易調用handle方法,但似乎這應該工作:/

您不能在概念IHandler<SomeEvent>視為IHandler<IDomainEvent> IHandler<IDomainEvent>需要能夠接受AThirdEvent (實現IDomainEvent )的實例作為Handle的參數,但是SomeEventHandler類型不能接受AThirdEvent實例,只能接受SomeEvent實例。

編譯器正確地通知您,從概念的角度來看,此類型轉換無效。

從概念上講,您的界面實際上是逆變的 如果您有一個IHandler<IDomainEvent>您可以隱式將其轉換為IHandler<SomeEvent> (如果您調整了接口的定義以通知編譯器它實際上是逆變的),因為如果您的Handle方法可以接受任何類型的IDomainEvent那么顯然它可以接受每一個SomeEvent

這要求您的界面是協變的

public interface IHandler<out T> : where T : IDomainEvent

但是,您的界面本身不支持這一點,因為它有效地逆轉。 允許此工作不是類型安全的,並且沒有直接的解決方法。 協變接口只允許返回T ,不接受T作為方法的參數。

有關詳細信息,請參閱通用接口中的差異

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM