简体   繁体   English

为什么IntelliSense在foreach循环中无法按预期工作?

[英]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的方法PropertyDescriptorCollectionIEnumerator (非通用)。 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM