[英]Why IntelliSense doesn't work as expected in a foreach loop?
While typing the following code snippet, I noticed that Intellisense didn't work as expected: 在输入以下代码片段时,我注意到Intellisense不能按预期工作:
StringBuilder sb = new StringBuilder();
foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(sb))
{
var name = prop.DisplayName;
Console.WriteLine("{0}", name);
}
In the foreach statement, if I start typing prop.Di, Intellisense completes as expexcted with prop.DisplayName. 在foreach语句中,如果我开始键入prop.Di,则Intellisense将按照prop.DisplayName的要求完成。 However, I use the var keyword instead of PropertyDescriptor
, then I see only the method inherited from object. 但是,我使用var关键字而不是PropertyDescriptor
,然后仅看到从object继承的方法。
As TypeDescriptor.GetProperties()
returns a collection of TypeDescriptor, I thought that Visual Studio would be able to infer the correct type for prop
. 由于TypeDescriptor.GetProperties()
返回TypeDescriptor.GetProperties()
的集合,我认为Visual Studio将能够为prop
推断正确的类型。
Why is it not working? 为什么不起作用?
GetProperties
returns a PropertyDescriptorCollection
which only implements IEnumerable
, not IEnumerable<PropertyDescriptor>
. GetProperties
返回一个PropertyDescriptorCollection
,它仅实现IEnumerable
,而不实现IEnumerable<PropertyDescriptor>
。 If you use var
, the type of prop
is inferred to be object
not PropertyDescriptor
. 如果使用var
,则将prop
的类型推断为object
而不是PropertyDescriptor
。
It returns PropertyDescriptorCollection
, and the return type of GetEnumerator
method of PropertyDescriptorCollection
is IEnumerator
(non-generic). 它返回PropertyDescriptorCollection
,和的返回类型GetEnumerator
的方法PropertyDescriptorCollection
是IEnumerator
(非通用)。 So even you can write 所以即使你可以写
foreach (int prop in TypeDescriptor.GetProperties(sb))
And you won't get any exception in compile time,but at runtime you will get an InvalidCastException
. 而且您不会在编译时获得任何异常,但是在运行时,您将获得InvalidCastException
。
Here is an example that demonstrates the difference: 这是一个说明差异的示例:
Normally, this is invalid: 通常,这是无效的:
foreach(string x in new List<int>())
Because List<T>
implements IEnumerable<T>
.But if you wrap it with a class and implement non-generic IEnumerable
interface: 因为List<T>
实现IEnumerable<T>
。但是如果用类包装它并实现非泛型IEnumerable
接口:
class NonGenericCollection : IEnumerable
{
public List<int> List { get; set; }
public NonGenericCollection()
{
List = new List<int>();
}
public IEnumerator GetEnumerator()
{
return List.GetEnumerator();
}
}
You can write any type you want and don't get any exceptions in compile time: 您可以编写所需的任何类型,并且在编译时不会出现任何异常:
foreach(string x in new NonGenericCollection())
Because the return type is inferred as object and the actual type is not known until the run-time. 因为将返回类型推断为对象,并且直到运行时才知道实际类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.