c# - 从 Dictionary<int, Fleas> 中高效获取 IReadOnlyDictionary<int, Animals>

标签 c# generics casting covariance contravariance

public class Flea : Animals {...}

var fleas = new Dictionary<int, Flea>();

public IReadOnlyDictionary<string, Animal> Animals => fleas.ToDictionary(pair => pair.Key, pair => (Animal)pair.Value);

是否有更有效的方法从跳蚤获取动物

最佳答案

.NET 支持接口(interface)、委托(delegate)、泛型类型和数组中的协变。尽管使用 out 接口(interface)或类型必须指定它是协变的关键词。

你可以写

IEnumerable<Animal> animals=new List<Flea>();

var dict=new Dictionary<int,Flea>{
    [1]=new Flea()
};
IEnumerable<Animal> animals=dict.Values;

这是有效的,因为 Dictionary.Values返回 IEnumerable<Flea>IEnumerable是协变的——它的定义是IEnumerable<out T> .

KeyValuePair虽然不是协变的,这意味着使用它的类像 IDictionary<TKey,TValue>IReadOnlyDictionary<TKey,TValue>也不是。这是故意的。

由于您只需要从该字典中读取,您可以使用委托(delegate)或在 C# 7 及更高版本中使用本地函数来创建访问器方法。您可以将该函数传递给需要 Func<TKey,TValue> 的方法并使用它从字典中读取值。

如果您有一个方法需要基于 key 的访问,比方说:

void Process(Func<int,Animal> reader)
{
    var value=reader(1);
}

在 C# 7 中你可以这样写:

var dict =...

Animal get(int key)=>dict[key];

Process(get);

这有点作弊,通过使用变量捕获来访问字典。

在 C# 7 之前,您将使用委托(delegate):

Func<int,Animal> get= key=>dict[key];
Process(get);

这可能看起来很奇怪,但这就是 LINQ 本身的工作方式,通过使用谓词和委托(delegate)而不是接口(interface)和包装器。

关于c# - 从 Dictionary<int, Fleas> 中高效获取 IReadOnlyDictionary<int, Animals>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56593508/

相关文章:

c# - .NET 中的货币格式

C# 9 记录有 ToString() 的 { propertyName=value } 输出,如何从中返回记录类型?

java - 通用列表打印方法

java - 返回泛型类型 <String,Double>

c++ - 我应该在 C 风格的转换中使用 C++ reinterpret_cast 吗?

c# - 从 ASP.NET Core 1 迁移到 ASP.NET Core 2 后, token 身份验证停止工作

c# - 您将如何对两个矩阵的位置进行插值?

c# - 如何触发通用类方法以递归方式更改 T 的类型?

c++ - 需要澄清 C 风格、重新解释和 const 转换

C 在宏中强制转换