考慮下面的代碼: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好點 –