簡體   English   中英

接口方法中的委托無效方差

[英]Invalid variance with delegate in interface method

為什么以下接口聲明會產生無效的方差錯誤?

public interface ICache<in TKey, TValue>
{
  TValue GetOrAdd(TKey key, Func<TKey, TValue> valueFactory);
}

編譯器說:

錯誤CS1961無效方差:類型參數'TKey'必須在'ICache <TKey,TValue> .GetOrAdd(TKey,Func <TKey,TValue>)'上協變有效。 “ TKey”是互變的。

問題在於在Func參數中使用TKey 但是,根據Func要求,將TKey用作輸入。 為什么必須是協變的?

TL; DR:C#編譯器可確保您安全。

實際上,涉及一般差異時,“在輸入位置的嵌套輸入將產生輸出”。 您的方法有一個參數,該參數本身接受TKey ,它可以逆轉方差。

通過想象是否允許,最容易了解為什么禁止使用它。 然后,您可以編寫:

public class ObjectKeyedCache : ICache<object, object>
{
    public object GetOrAdd(object key, Func<object, object> valueFactory)
    {
        // Let's ignore the specified key, and just pass in an object!
        return valueFactory(new object());
    }
}

然后,您可以編寫:

ICache<object, object> objectKeyedCache = new ObjectKeyedCache();
// Ah, due to contravariance, this should be okay...
ICache<string, object> stringKeyedCache = objectKeyedCache;

// Okay, this is a weird cache function, but bear with me
stringKeyedCache("key", text => text.Length);

然后,它將嘗試將object引用傳遞到從lambda表達式text => text.Length創建的Func<string, object> 砰!

有關更多詳細信息,請閱讀Eric Lippert的variance博客系列的第5部分 這是該帖子最重要的部分:

這樣做會使我的大腦受傷,但這也可以建立性格,所以我們開始吧!

任何會使埃里克的大腦受傷的東西都應該被視為對其余人的主要健康危害。 你被警告了。

暫無
暫無

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

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