C#, VS 2010. Somebody, please explain why I can't use var in my code below!
var props = TypeDescriptor.GetProperties(adapter);
// error CS1061: 'object' does not contain a definition for 'DisplayName'
foreach (var prop in props)
{
string name = prop.DisplayName;
}
// No error
foreach (PropertyDescriptor prop in props)
{
string name = prop.DisplayName;
}
TypeDescriptor.GetProperties returns a PropertyDescriptorCollection with instances of PropertyDescriptor. Why can't the compiler see this?
“var” has no block scope They are visible through blocks. As var ignores code blocks, we've got a global variable test . As we can see, var pierces through if , for or other code blocks. That's because a long time ago in JavaScript, blocks had no Lexical Environments, and var is a remnant of that.
The Var Keyword This means that if a variable is defined in a loop or in an if statement it can be accessed outside the block and accidentally redefined leading to a buggy program. As a general rule, you should avoid using the var keyword.
The var keyword is same as public when declaring variables or property of a class. Note: The var keyword was deprecated from version 5.0.
Using var is lazy. While var is certainly easier to type than Dictionary<int,IList> , if the variable isn't named well, you'd never know what it refers to. Using var makes it hard to know what type the underlying variable actually is.
TypeDescriptor.GetProperties returns a class that only has a GetEnumerator implementation that returns the non-generic IEnumerator. The type of its Current property is object - and that's the only type the compiler can infer, so that's the type your prop variable will be.
The second foreach that uses PropertyDescriptor instead of var as the type of prop actually performs a conversion from object to PropertyDescriptor.
Assume this code:
PropertyDescriptor x = // get from somewhere;
object o = x;
PropertyDescriptor y = (PropertyDescriptor)o;
The same is happening in the second foreach loop for each item.
You could add a Cast<PropertyDescriptor>() to get a generic IEnumerable<T> with an implementation of GetEnumerator that returns IEnumerator<T>. If you do this, you can use var in the foreach loop:
var props = TypeDescriptor.GetProperties(adapter).Cast<PropertyDescriptor>();
// No error
foreach (var prop in props)
{
string name = prop.DisplayName;
}
PropertyDescriptorCollection only implements IEnumerable, so the compiler only knows that elements contained in it are of type object. When you specify the type in your foreach loop, the compiler will insert a cast to the type you specify.
You can use the Cast<T> extension method on IEnumerable to cast each item to a given type:
using System.Linq;
...
IEnumerable<PropertyDescriptor> descriptors = props.Cast<PropertyDescriptor>();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With