考虑下面的代码:LINQ与多个密钥字典的单个值
public KeyAttribute : Attribute{
public string Value;
public KeyAttribute(string value){
Value = value;
}
}
[Key("A")]
[Key("AB")]
public class A : IClass
{
public string FieldA {get;set;}
}
[Key("B")]
public class B : IClass
{
public string FieldB {get;set;}
}
所以我要通过IClass
接口的所有的实现,我一定要建立一个字典Dictionary<string, ConstructorInfo>
其中键是KeyAttribute
的Value
属性,并且值是相应的ConstructorInfo
。
请注意,单个类上可能有几个KeyAttribute
,因此在这种情况下,字典中应该有相应数量的条目。
对于当前的例子,理想的结果是:
key | value
--------+-------------------
"A" | ConstructorInfo A
"AB" | ConstructorInfo A
"B" | ConstructorInfo B
起初,我写了这个:
return AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(t => typeof(IClass).IsAssignableFrom(t))
.ToDictionary(t =>
{
var key = (KeyAttribute) t.GetCustomAttributes(typeof(KeyAttribute), true).First();
return key.Value;
}, t => t.GetConstructors(BindingFlags.Public).First());
但正如你所看到的,上面的代码不处理与几个情况属性。 所以我做了以下,但它显然是错误的,我不知道如何纠正它。
我知道我可以做,没有LINQ这样的:
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(t => typeof(IClass).IsAssignableFrom(t));
var dict = new Dictionary<string, ConstructorInfo>();
foreach (var type in types)
{
var keys = type.GetCustomAttributes(typeof(KeyAttribute), true).Cast<KeyAttribute>().Select(a => a.Value);
var ctorInfo = type.GetConstructors(BindingFlags.Public).First();
foreach (var key in keys)
{
dict.Add(key, ctorInfo);
}
}
return dict;
但我宁愿坚持LINQ,如果可能的话。
对于所有这些有关属性和所有这些有点误导性的细节,抱歉,虽然这是一个关于LINQ的问题,但我想不出任何其他生动的例子。
嘿,感谢的答案!答案有点小问题 - 第一个“Select”实际上应该是“SelectMany”。否则,我们必须处理'IEnumerable'而不是'IEnumerable '。 –
@DmitryVolkov好点 –