首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何通过静态属性调用LINQ中的静态构造函数和排序元素?

如何通过静态属性调用LINQ中的静态构造函数和排序元素?
EN

Stack Overflow用户
提问于 2017-09-28 11:54:56
回答 2查看 72关注 0票数 1

下面是我想按静态区域属性按降序存储和排序的简化类

代码语言:javascript
复制
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查询我用了什么。

代码语言:javascript
复制
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));

我想把这三步变成一项声明。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-09-28 12:08:54

这是不可能的在这里,foreach循环是您的问题-它对数组中的所有条目做了一些事情(即调用类型初始化程序),但是它不会返回您可能在LINQ语句中继续使用的任何内容。您可以为IEnumerable编写自定义扩展方法,如下所示

代码语言:javascript
复制
public static IEnumerable<T> MyForEach<T>(this IEnumerable<T> enumeration, Action<T> action)
{
    foreach(T item in enumeration)
    {
        action(item);
    }
    return enumeration;
}

然而,这并不符合LINQ的精神-我不建议使用这样的代码(LINQ应该是无副作用的!)然后你可以写你的声明

代码语言:javascript
复制
    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));

..。但我不明白这是什么意思。它不能提高代码的可读性。

票数 1
EN

Stack Overflow用户

发布于 2017-09-28 13:03:31

下面是一个使用自定义Attribute建议的例子,我在对您的问题(LINQPad文件)的评论中提出了这个建议。代码注释中有一些注释。

代码语言:javascript
复制
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; }
}

它产生以下输出:

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46468507

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档