2013-04-23 67 views
1

我有两个列表,一个是字符串列表,另外一个是一个类的列表,该类包含像soid,itemname,qty等一些属性,其值也是..字符串列表和类列表有一些共同的属性。所以我想用类列表检查字符串列表并将常用值添加到一个字典中。在c#中比较不同类型的列表

public class Input 
    { 
     public string soid { get; set; } 

     public string itemname { get; set; } 

     public int qty { get; set; } 
    } 
list<Input> inputclass=new list<Input>();//inputclass list 

List<string> metadata=new List<string>();//string list 
metadata.Add("itemname"); 
     metadata.Add("soid"); 
     metadata.Add("qty"); 

,所以我想比较字符串列表名称

+1

你想如何看字典?即什么将是关键,什么价值? – 2013-04-23 11:59:23

+0

而且?你的问题是什么 ?你尝试了什么,你得到了哪些错误? – 2013-04-23 11:59:34

+0

这里有什么'inputclass'的用法? – 2013-04-23 12:04:18

回答

1

类成员的名字。如果我的理解是正确的,你要比较的类型本身,不在名单内的情况。

你可以这样做:

List<string> metadata = new List<string>();//string list 
metadata.Add("itemname"); 
metadata.Add("soid"); 
metadata.Add("qty"); 
metadata.Add("yada"); 

var result = from str in metadata 
      join prop in typeof(Input).GetProperties() on str equals prop.Name 
      select str; 

foreach (string prop in result) 
{ 
    Console.WriteLine(prop); 
} 

现在,如果你有T未知对象的名单,并希望与元数据相互匹配,告诉我,我会帮你的。

编辑根据您的评论:when we get the common name between list<input> and string how will get the value of corresponding member of the class.now you return only common names r8..?

你可以不喜欢这样。假设你有这两个类:

public class Input 
{ 
    public string soid { get; set; } 

    public string itemname { get; set; } 

    public int qty { get; set; } 
} 

public class Yada : Input 
{ 
    public string yada { get; set; } 
} 

所以Input有4个属性的3,和Yada类有所有4

然后假设我们有对象的列表:

List<Input> inputclass = new List<Input>();//inputclass list 

inputclass.Add(new Input() { itemname = "test",soid="myId",qty=10 }); 
inputclass.Add(new Yada() { itemname = "test2",soid="myId2", yada = "woo",qty=20 }); 

您可以使用此代码获取对象的所有匹配属性,包括其当前值:

var result = inputclass.Select(
       input => (from str in metadata 
          join prop in input.GetType().GetProperties() 
          on str equals prop.Name 
          select new { Obj = input, Prop = str, Value = prop.GetValue(input, null) })) 
          .SelectMany(i => i) 
          .GroupBy(obj => obj.Obj); 

foreach (var obj in result) 
{ 
    Console.WriteLine(obj.Key); 
    foreach (var prop in obj) 
    { 
     Console.WriteLine(prop.Prop + ":" + prop.Value); 
    } 
    Console.WriteLine(); 
} 

Console.ReadKey(); 

这是我输入:

enter image description here

刚上一记,使用GetValue时要小心:你必须做的细微变化为它用在索引工作,例如。

+0

当我们得到列表和字符串之间的通用名称将如何获得类的相应成员的值。现在只返回常用名称r8 ..? – nichu09 2013-04-23 13:06:19

+0

@ nixen09编辑,以符合您的要求。 – 2013-04-23 13:52:01

0

使用此ReflectionExt.GetAttr你可以做这样的事情:

var dict = new Dictionary<string, List<string>>(); 

foreach(var listItem in inputclass) 
{ 
    foreach(var metaItem in metadata) 
    { 
     try 
     { 
      var value = ReflectionExt.GetAttr(listItem, metaItem); 

      if (dict[metaItem] == null) 
       dict[metaItem] = new List<string>(); 

      if (!dict[metaItem].Contains(value)) // Add only if not exists 
       dict[metaItem].Add(value); 
     } 
     catch 
     { 
      ; 
     } 

    } 

} 
3

不知道我是否100%正确地理解你,但鉴于以下输入:

var inputclass= new List<Input>() { 
    new Input(){ soid="123", itemname="Bar", qty=123 }, 
    new Input(){ soid="777", itemname="Foo", qty=999 } 
}; 
List<string> metadata=new List<string>() { "itemname", "soid", "qty" }; 

可以使用.ToDictionary().GetProperty()这样的方法

Type t = typeof(Input); 
var result = metadata.ToDictionary(i => i, i => inputclass.Select(c => t.GetProperty(i).GetValue(c))); 

创建一个字典,像

enter image description here

编辑:

如果metadata可以包含不是的Input属性的值,以下将被保存:

var result = metadata.Select(i => t.GetProperty(i)) 
        .Where(i => i != null) 
        .ToDictionary(i => i.Name, i => inputclass.Select(c => i.GetValue(c))); 
+0

+1很好的答案。但不要忘记过滤阶段。我的意思是如果'我'不是t的财产? – 2013-04-23 12:24:27

+0

@domanic我得到一个错误无法将lambda表达式转换为类型'System.Collections.Generic.IEqualityComparer ',因为它不是委托类型。 – nichu09 2013-04-23 12:39:03

+0

@HseseinNarimaniRad好点!编辑我的答案。 – sloth 2013-04-23 12:45:58