Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get List<T> values with late binding

Tags:

c#

.net

list

I have a List<T> variable where T is not known at compile time. I need to access the value property on type T like this

foreach(var item in items) // items is List<T>
{
    item.value // this won't compile because T is unknown 
}

I know that <T> in my case will have the value property. How can I access it?

like image 584
user3721728 Avatar asked Jun 09 '14 09:06

user3721728


3 Answers

If you KNOW that every T has VALUE you can use dynamic instead of var

foreach(dynamic item in items) //items is List<T>
{
    item.VALUE
}
like image 130
Tzah Mama Avatar answered Nov 10 '22 18:11

Tzah Mama


As already answered the correct way is to create an interface that implements the Value prop.

However you have commented that you have no control over classes you will need to do this another way.

One way would be reflection, I'm assuming your property name is VALUE, (case sensitive)

PropertyInfo pi = typeof(T).GetProperty("VALUE");
object value = pi == null ? null pi.GetValue(item,null);

You could cache the reflection call into a static generic class that creates a static field the first time it is used.

Alternatively you could use a static generic helper class with field and a helper method.

 public static class ValueHelper<T> {
     public static Func<T,object> ValueFunction;

     public static object GetValue(T item) {
        var function = ValueFunction;
        return function == null ? null : function(item);
     }

     }
 }

Then somewhere in your code, where you know T, eg you want to setup for MyClass

  ValueHelper<MyClass>.ValueFunction = x => x.Value;

Then your list code becomes

foreach(var item in items)
{
    value = ValueHelper<T>.GetValue(item);
}
like image 26
Bob Vale Avatar answered Nov 10 '22 16:11

Bob Vale


If you have a control over T classes, you can introduce an interface with Value property and make every T class implement this interface. In that case you can enumerate list values like this:

    foreach(IMyInterface item in items)
    {
        var someVar = item.VALUE; 
//you know that item does have VALUE property and the type of that property as declared in interface
    }

UPD. It works even if your T classes have different properties:

interface IMyInterface
{
    string VALUE{get;set;}
}

class A : IMyInterface
{
   public int Aprop{get;set;}
   public string VALUE{get;set;}
}

class B : IMyInterface
{
   public int Bprop{get;set;}
   public string VALUE{get;set;}
}
like image 1
Andrei Zubov Avatar answered Nov 10 '22 17:11

Andrei Zubov