在输入以下代码段时,我注意到Intellisense没有按预期工作:
StringBuilder sb = new StringBuilder();
foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(sb))
{
var name = prop.DisplayName;
Console.WriteLine("{0}", name);
}
在foreach语句中,如果我开始输入prop.Di,则Intellisense将以prop.DisplayName完成。但是,我使用var关键字而不是PropertyDescriptor
,然后我只看到从object继承的方法。
当TypeDescriptor.GetProperties()
返回TypeDescriptor的集合时,我认为Visual Studio能够推断出prop
的正确类型。
为什么不起作用?
答案 0 :(得分:8)
GetProperties
会返回PropertyDescriptorCollection
,只会IEnumerable
,而不是IEnumerable<PropertyDescriptor>
。如果您使用var
,则prop
的类型推断为object
而不是PropertyDescriptor
。
答案 1 :(得分:4)
返回PropertyDescriptorCollection
,GetEnumerator
PropertyDescriptorCollection
方法的返回类型为IEnumerator
(非通用)。所以即使你可以写
foreach (int prop in TypeDescriptor.GetProperties(sb))
你在编译时没有得到任何异常,但在运行时你会得到一个InvalidCastException
。
这是一个展示差异的例子:
通常,这是无效的:
foreach(string x in new List<int>())
因为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();
}
}
您可以编写任何您想要的类型,并且在编译时不会出现任何异常:
foreach(string x in new NonGenericCollection())
因为返回类型被推断为 object ,并且直到运行时才知道实际类型。