C# LINQ to dictionary具有针对单个值的多个键
考虑以下代码:C# LINQ to dictionary具有针对单个值的多个键,c#,linq,dictionary,C#,Linq,Dictionary,考虑以下代码: 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
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
,其中键是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());
但是正如您所看到的,上面的代码没有处理具有多个属性的情况。
所以我做了以下几点,但这显然是错误的,我不知道如何纠正它
return AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(t => typeof(IClass).IsAssignableFrom(t))
.ToDictionary(t =>
{
return t.GetCustomAttributes(typeof(KeyAttribute), true).Select(a => ((KeyAttribute)a).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;
var types=AppDomain.CurrentDomain.getAssemblys()
.SelectMany(s=>s.GetTypes())
其中(t=>typeof(IClass).IsAssignableFrom(t));
var dict=新字典();
foreach(类型中的变量类型)
{
var keys=type.GetCustomAttributes(typeof(KeyAttribute),true).Cast().Select(a=>a.Value);
var ctorInfo=type.GetConstructors(BindingFlags.Public).First();
foreach(var键入键)
{
dict.Add(键、信息);
}
}
返回命令;
但如果可能的话,我宁愿选择林克
很抱歉,关于属性和所有这些有点误导性的细节,虽然这是一个关于LINQ的问题,但我想不出任何其他生动的例子。这应该可以:
return AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(t => typeof(IClass).IsAssignableFrom(t))
.SelectMany(t => t.GetCustomAttributes(typeof(KeyAttribute), true)
.Select(a => new
{
constInfo = t.GetConstructors(BindingFlags.Public).First(),
attrVal = ((KeyAttribute)a).Value
}))
.ToDictionary(entry => entry.attrVal, entry => entry.constInfo);
这应该起作用:
return AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(t => typeof(IClass).IsAssignableFrom(t))
.SelectMany(t => t.GetCustomAttributes(typeof(KeyAttribute), true)
.Select(a => new
{
constInfo = t.GetConstructors(BindingFlags.Public).First(),
attrVal = ((KeyAttribute)a).Value
}))
.ToDictionary(entry => entry.attrVal, entry => entry.constInfo);
对关键属性使用
SelectMany
return AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(t => typeof(IClass).IsAssignableFrom(t))
.SelectMany(t =>
{
return t.GetCustomAttributes<KeyAttribute>()
.Select(ka => new
{
Key = ka,
Ctor = t.GetConstructors(BindingFlags.Public).First()
});
})
.ToDictionary(t => t.Key, t.Ctor);
返回AppDomain.CurrentDomain.getAssemblys()
.SelectMany(s=>s.GetTypes())
.Where(t=>typeof(IClass).IsAssignableFrom(t))
.SelectMany(t=>
{
返回t.GetCustomAttributes()
.选择(ka=>new
{
Key=ka,
Ctor=t.GetConstructors(BindingFlags.Public).First()
});
})
.ToDictionary(t=>t.Key,t.Ctor);
使用选择多个
作为关键属性
return AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(t => typeof(IClass).IsAssignableFrom(t))
.SelectMany(t =>
{
return t.GetCustomAttributes<KeyAttribute>()
.Select(ka => new
{
Key = ka,
Ctor = t.GetConstructors(BindingFlags.Public).First()
});
})
.ToDictionary(t => t.Key, t.Ctor);
返回AppDomain.CurrentDomain.getAssemblys()
.SelectMany(s=>s.GetTypes())
.Where(t=>typeof(IClass).IsAssignableFrom(t))
.SelectMany(t=>
{
返回t.GetCustomAttributes()
.选择(ka=>new
{
Key=ka,
Ctor=t.GetConstructors(BindingFlags.Public).First()
});
})
.ToDictionary(t=>t.Key,t.Ctor);
嘿,谢谢你的回答!答案有点问题-第一个Select
实际上应该是SelectMany
。否则,我们必须处理IEnumerable
而不是IEnumerable
。嘿,谢谢你的回答!答案有点问题-第一个Select
实际上应该是SelectMany
。否则,我们必须处理IEnumerable
,而不是IEnumerable
。