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