例如,如果我有这个课程
public class User{
int Id;
string Name;
short Age;
}
以及User
:
public class UserCollection: List<User>{...}
我可以从List<KeyValue>
创建一个KeyValue
(UserCollection
是我的班级),选择哪个属性为Key
(或Value
)?
我尝试使用此代码:
private List<KeyValue> ReadCollection(dynamic collection, string keyName, string valueName)
{
List<KeyValue> list = new List<KeyValue>();
for(int i = 0; i < collection.Count; i++)
{
dynamic elem = collection[i];
// I can't use this notation, but only elem.Id
int key = elem[keyName];
// I can't use this notation, but only elem.Name
string value = elem[valueName];
list.Add(new KeyValue(key, value));
}
return list;
}
List<KeyValue> list = ReadCollection(userCollection, "Id", "Name");
但它不起作用。可以选择放在KeyValue
类中的属性吗?
答案 0 :(得分:1)
好吧,由于源集合不是键值集合,因此您无法使用[]
表示法来访问属性。这就是为什么符号不起作用的原因。您可以尝试使用GetProperty
之类的反射方法来动态访问该值:
var key = elem.GetType().GetProperty(keyName).GetValue(elem, null);
var value = elem.GetType().GetProperty(valueName).GetValue(elem, null);
答案 1 :(得分:1)
我至少会使方法变得通用,而不是采用动态对象。
然后,您可以生成简单的LINQ表达式来访问所需的属性,并使用它们来获取每个条目的键和值:
private static List<KeyValue> ReadCollection<T>(IList<T> collection, string keyName, string valueName)
{
List<KeyValue> list = new List<KeyValue>();
Func<T, int> keyFunction = GenerateLambda<T, int>(keyName);
Func<T, string> valueFunction = GenerateLambda<T, string>(valueName);
for (int i = 0; i < collection.Count; i++)
{
T elem = collection[i];
int key = keyFunction(elem);
string value = valueFunction(elem);
list.Add(new KeyValue(key, value));
}
return list;
// or simpler
//return collection.Select(elem => new KeyValue(keyFunction(elem), valueFunction(elem))).ToList();
}
private static Func<T, TProp> GenerateLambda<T, TProp>(string propertyName)
{
var p = Expression.Parameter(typeof(T));
var expr = Expression.Lambda<Func<T, TProp>>(Expression.PropertyOrField(p, propertyName), p);
return expr.Compile();
}
List<KeyValue> list = ReadCollection(userCollection, "Id", "Name");
答案 2 :(得分:0)
我会使用Func
而不是所有动态内容重写此内容。
private List<KeyValue> ReadCollection<T>(IEnumerable<T> collection, Func<T, int> keyFunc, Func<T, string> valueFunc)
{
List<KeyValue> list = new List<KeyValue>();
foreach (T elem in collection)
{
int key = keyFunc(elem);
string value = valueFunc(elem);
list.Add(new KeyValue(key, value));
}
return list;
}
您可以这样称呼它:
List<KeyValue> list = ReadCollection<User>(userCollection, u => u.Id, u => u.Name);
优点:
答案 3 :(得分:0)
只需使用Select即可轻松解决此问题。
List<KeyValue> list = userCollection
.Select(x => new KeyValue(x.ID, x.Name))
.ToList();