我有一堂课

public class ExcitingResults
{
    public int A { get; set; }
    public string B { get; set; }
    public DateTime C { get; set; }

    public string ComplexD
    {
        get { return SomeMethod("A", "B"); }
    }
}


目前,我对结果List<ExcitingResults>进行一些处理,该结果创建JSON或Excel文件。
此处理强烈依赖于每个属性的名称,事物在输出中出现的顺序由它们在类中出现的顺序定义。尽管实际上这是未定义的行为,所以如果编译器决定以不同的顺序来处理,则可能会更改。

因此,我想将我的课改成这样。

public class ExcitingResults
{
    public column<int> A { get; set; }
    public column<string> B { get; set; }
    public column<DateTime> C { get; set; }

    public column<string> ComplexD
    {
        get { return SomeMethod(A.Name, B.Name); }
    }
}

public class column<T>
{
    public T Value { get; set; }
    public string Name { get; set; }
}


显然,这并不是替代品的减少……我可以采取一些明智的策略来使此更改尽可能地轻松。然后,将来会增加Column类的复杂性,例如顺序,易记名称以及我遇到的其他属性。

还是这是一种疯狂的前进方式,我应该考虑另一种能够将这些额外信息添加到专栏中的策略?

最佳答案

您可以添加属性属性,其优点是无需触摸类的API。例如,添加类:

[AttributeUsage(AttributeTargets.Property)]
public class ColumnAttribute : System.Attribute {
    public string FriendlyName { get; set; }
    public int Rank { get; set; }
}


您现在可以像这样注释您的ExcitingResults类:

public class ExcitingResults {
    [Column(FriendlyName = "A", Rank = 1)]
    public int A { get; set; }

    [Column(FriendlyName = "B", Rank = 4)]
    public string B { get; set; }

    [Column(FriendlyName = "C", Rank = 3)]
    public DateTime C { get; set; }


    [Column(FriendlyName = "D", Rank = 2)]
    public string ComplexD {
        get { return SomeMethod("A", "B"); }
    }
}


然后,您的处理器类可以使用反射来访问属性属性。例如,按照ExcitingResult的顺序打印Rank的属性:

public static void Process(ExcitingResults result) {
    var propertiesByRank = typeof(ExcitingResults)
        .GetProperties()
        .OrderBy(x => x.GetCustomAttribute<ColumnAttribute>().Rank);

    foreach (var propertyInfo in propertiesByRank) {
        var property = result.GetType().GetProperty(propertyInfo.Name);
        var propertysFriendlyName = property.GetCustomAttribute<ColumnAttribute>().FriendlyName;
        var propertysValue = property.GetValue(result, null);
        Console.WriteLine($"{propertysFriendlyName} = {propertysValue}");
    }
}


您将需要在处理类中进行更多的错误检查,但是您知道了。有关更多信息,请参见MSDN documentationtutorial

07-28 01:55
查看更多