C# LINQ中AsEnumerable()的内部实现
我有两个问题: 问题1背景: 当我看到Microsoft在LINQ中实现“AsEnumerable()”方法时,我注意到:C# LINQ中AsEnumerable()的内部实现,c#,linq,compiler-construction,covariance,contravariance,C#,Linq,Compiler Construction,Covariance,Contravariance,我有两个问题: 问题1背景: 当我看到Microsoft在LINQ中实现“AsEnumerable()”方法时,我注意到: public static IEnumerable<TSource> AsEnumerable<TSource>(this IEnumerable<TSource> source) { return source; } 公共静态IEnumerable AsEnumerable(此IEnumerable源) { 返回源; }
public static IEnumerable<TSource> AsEnumerable<TSource>(this IEnumerable<TSource> source)
{
return source;
}
公共静态IEnumerable AsEnumerable(此IEnumerable源)
{
返回源;
}
问题1:
我在这里期待某种类型的强制转换或其他东西,但它只是返回传递的值。这是怎么回事
问题2/3背景:
我一直在努力理解协方差、逆变换和不变量。我想,我对“in”和“out”关键字在将子类型指定给父类型时决定多态行为有一个模糊的理解
问题2:
我从阅读中了解到IEnumerable是协变的,List是不变的,那么为什么这不可能:
List<char> content = "testString".AsEnumerable();
IEnumerable<char> content1 = "testString";
IList<char> content2 = content1;
List content=“testString”.AsEnumerable();
问题3:如果IList实现IEnumerable,那么为什么不可能:
List<char> content = "testString".AsEnumerable();
IEnumerable<char> content1 = "testString";
IList<char> content2 = content1;
IEnumerable content1=“testString”;
IList content2=content1;
请帮我理解,提前谢谢
IEnumerable
。为什么它需要投下任何东西?将对象强制转换为类型TSource
不会有任何效果,因为它们已经被保证为该类型(或更派生的类型)IEnumerable
类型的值分配给List
类型的变量。我想你的想法是相反的<代码>列表源自IEnumerable
,而不是反过来。这与List
不变无关IEnumerable
是协变的(更准确地说,类型参数T
是协变的),这给了我们以下情况:
IEnumerable enumerable = Enumerable.Empty<string>(); // Allowed
IEnumerable<string> genericEnumerable = enumerable; // Not allowed
IEnumerable enumerable=enumerable.Empty();//允许
IEnumerable genericEnumerable=可枚举;//不准
IList
继承自IEnumerable
,而不是相反。您可以这样做:
IList<char> content1 = "testString".ToList();
IEnumerable<char> content2 = content1;
IList content1=“testString”.ToList();
IEnumerable content2=content1;
恐怕你所要求的毫无意义,而且与协方差无关。IEnumerable
是协变的,这意味着您可以这样做:
IEnumerable<object> asObject = new List<string>() { "test" };
IEnumerable asObject=new List(){“test”};
但是List
是不变的,所以您不能这样做:
List<object> asObject = new List<string>() { "test" };
List asObject=new List(){“test”};
AsEnumerable()强制查询在其他LINQ提供程序(如LINQ to SQL或实体框架)中立即执行。它可能是为了完整性而添加到LINQ对象中的。我需要一些时间来消化它!作为对第一个答案的回应,我明白了,所以如果我可以直接将派生对象的值分配给父类型的实例,“AsEnumerable()”解决了什么问题?作为对第二个答案的回应,好的,那么为什么IEnumerable enumerable=(IEnumerable)enumerable.Empty();不可能?IEnumerable实现了IEnumerable,那么为什么编译器会抱怨呢?@RaM你又反过来想了
IEnumerable
实现了IEnumerable
,这意味着您可以将IEnumerable
的实例分配给IEnumerable
类型的变量,而不是相反。在您引用的示例中,编译器不知道该变量实际上是IEnumerable
的实例。我对示例进行了编辑,希望能更清楚一点。至于AsEnumerable(),老实说,我也不太确定它的意义是什么。的备注部分指出,它可以用于“隐藏”其他LINQ方法的特殊实现,如Where
和Select
,但这对我来说似乎是一个奇怪的原理。也许我从来就不需要它。