Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

var keyword not always working?

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?

like image 280
l33t Avatar asked Feb 14 '13 11:02

l33t


People also ask

What is the problem with VAR in JavaScript?

“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.

Why you should not use VAR?

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.

Is var keyword deprecated?

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.

Should I always use var in C#?

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.


2 Answers

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;
}
like image 55
Daniel Hilgarth Avatar answered Oct 21 '22 03:10

Daniel Hilgarth


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>();
like image 45
Lee Avatar answered Oct 21 '22 04:10

Lee