Ответ 1
Если вы KNOW, что каждый T имеет VALUE, вы можете использовать dynamic
вместо var
foreach(dynamic item in items) //items is List<T>
{
item.VALUE
}
У меня есть переменная List<T>
, где T не известно во время компиляции. Мне нужно получить доступ к свойству value
по типу T
, как этот
foreach(var item in items) // items is List<T>
{
item.value // this won't compile because T is unknown
}
Я знаю, что <T>
в моем случае будет иметь свойство value
. Как я могу получить к нему доступ?
Если вы KNOW, что каждый T имеет VALUE, вы можете использовать dynamic
вместо var
foreach(dynamic item in items) //items is List<T>
{
item.VALUE
}
Как уже было сказано, правильным способом является создание интерфейса, реализующего Value prop.
Однако вы прокомментировали, что у вас нет контроля над классами, вам нужно будет сделать это по-другому.
Одним из способов было бы отражение, я предполагаю, что ваше имя свойства VALUE (с учетом регистра)
PropertyInfo pi = typeof(T).GetProperty("VALUE");
object value = pi == null ? null pi.GetValue(item,null);
Вы можете кэшировать вызов отражения в статический универсальный класс, который создает статическое поле при первом использовании.
В качестве альтернативы вы можете использовать статический общий вспомогательный класс с полем и вспомогательный метод.
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);
}
}
}
Затем где-то в вашем коде, где вы знаете T, например, вы хотите настроить MyClass
ValueHelper<MyClass>.ValueFunction = x => x.Value;
Затем ваш код списка станет
foreach(var item in items)
{
value = ValueHelper<T>.GetValue(item);
}
Если у вас есть контроль над классами T, вы можете ввести интерфейс со значением Value и сделать каждый T-класс реализацией этого интерфейса. В этом случае вы можете перечислить такие значения:
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. Он работает, даже если ваши классы T имеют разные свойства:
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;}
}
Если типы T известны заранее, вы можете сделать это (не лучший подход, но они уже объяснены в других ответах):
foreach(var item in List<T>)
{
if (item.GetType().Equals(typeof(fooClassA)))
{
ret = (item as fooClassA).VALUE_A;
}
if (item.GetType().Equals(typeof(fooClassB)))
{
ret = (item as fooClassB).VALUE_B;
}
....
}