[英]Why do I get the following error? Invalid variance modifier. Only interface and delegate type parameters can be specified as variant
[英]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.