如何将简单的类成员重构为更复杂的类型

本文关键字:复杂 类型 重构 简单 成员 | 更新日期: 2023-09-27 18:28:33

我有一个小类

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"); }
    }
}

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

出于这个原因,我想把我的课改成这样。

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"); }
    }
}

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

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文档和教程。