下面是我想按静态区域属性按降序存储和排序的简化类
abstract class Top { }
abstract class Top<T> : Top
{
public static int Area { get; protected set; }
}
abstract class Middle1 : Top<Middle1>
{
static Middle1()
{
Area = 1;
}
}
//sealed classes inherited from Middle1
abstract class Middle2 : Top<Middle2>
{
static Middle2()
{
Area = 2;
}
}
//sealed classes inherited from Middle2和LINQ查询我用了什么。
var array = from type in Assembly.GetExecutingAssembly().DefinedTypes
where
type.IsSealed &&
type.BaseType != typeof(Object) &&
type.BaseType != typeof(Enum)
orderby type.Name
group type by type.BaseType;
foreach (var item in array)
item.Key.TypeInitializer.Invoke(null, null);
array = array.OrderByDescending(x => x.Key.GetProperty("Area",
BindingFlags.Public |
BindingFlags.Static |
BindingFlags.FlattenHierarchy)
.GetValue(null, null));我想把这三步变成一项声明。
发布于 2017-09-28 12:08:54
这是不可能的在这里,foreach循环是您的问题-它对数组中的所有条目做了一些事情(即调用类型初始化程序),但是它不会返回您可能在LINQ语句中继续使用的任何内容。您可以为IEnumerable编写自定义扩展方法,如下所示
public static IEnumerable<T> MyForEach<T>(this IEnumerable<T> enumeration, Action<T> action)
{
foreach(T item in enumeration)
{
action(item);
}
return enumeration;
}然而,这并不符合LINQ的精神-我不建议使用这样的代码(LINQ应该是无副作用的!)然后你可以写你的声明
var array = Assembly.GetExecutingAssembly().DefinedTypes.Where(type => type.IsSealed &&
type.BaseType != typeof (Object) &&
type.BaseType != typeof (Enum))
.OrderBy(type => type.Name)
.GroupBy(type => type.BaseType)
.MyForEach(x => x.Key.TypeInitializer.Invoke(null, null))
.OrderByDescending(x => x.Key.GetProperty("Area",
BindingFlags.Public |
BindingFlags.Static |
BindingFlags.FlattenHierarchy)
.GetValue(null, null));..。但我不明白这是什么意思。它不能提高代码的可读性。
发布于 2017-09-28 13:03:31
下面是一个使用自定义Attribute建议的例子,我在对您的问题(LINQPad文件)的评论中提出了这个建议。代码注释中有一些注释。
void Main()
{
var array = Assembly.GetExecutingAssembly().DefinedTypes
.Where(t => t.IsSealed &&
t.BaseType != typeof(object) &&
t.BaseType != typeof(Enum))
.OrderBy(t => t.Name)
.GroupBy(t => t.BaseType)
.OrderByDescending(a => a.Key.GetCustomAttribute<AreaAttribute>().Value);
array.Dump();
}
abstract class Top { }
abstract class Top<T> : Top
{
//If you want to have the Area property available on sub-class instances, uncomment this line.
//public int Area=> this.GetType().GetCustomAttribute<AreaAttribute>().Value;
}
[Area(1)]
abstract class Middle1 : Top<Middle1>
{
}
sealed class M1Sub1 : Middle1 { }
sealed class M1Sub2 : Middle1 { }
sealed class M1Sub3 : Middle1 { }
[Area(2)]
abstract class Middle2 : Top<Middle2>
{
}
sealed class M2Sub1 : Middle2 { }
sealed class M2Sub2 : Middle2 { }
sealed class M2Sub3 : Middle2 { }
[AttributeUsage(AttributeTargets.Class)]
public class AreaAttribute : Attribute
{
public AreaAttribute(int value)
{
Value = value;
}
public int Value { get; }
}它产生以下输出:

https://stackoverflow.com/questions/46468507
复制相似问题