如何将简单的 class 成员重构为更复杂的类型?
How can I refactor a simple class member to a more complex type?
我有点class
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 文件。
此处理强烈依赖于每个 属性 的名称,并且事物在输出中出现的顺序由它们在 class 中出现的顺序定义。尽管实际上这是未定义的行为,因此如果编译器决定它想要以不同的顺序进行操作,则可能会发生变化。
因此,我想将我的 class 改成这样。
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
class 的复杂性,例如我想到的顺序、友好名称和其他属性。
或者这是一个疯狂的前进方式,我应该寻找另一种策略来将这些额外信息添加到列中吗?
您可以添加 属性 属性,优点是您不会触及 class 的 API。例如,添加 class:
[AttributeUsage(AttributeTargets.Property)]
public class ColumnAttribute : System.Attribute {
public string FriendlyName { get; set; }
public int Rank { get; set; }
}
您现在可以像这样注释您的 ExcitingResults
class:
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"); }
}
}
您的处理器 class 然后可以使用反射访问 属性 属性。例如,要按 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}");
}
}
您会希望在处理过程中进行更多错误检查 class,但您明白了。有关详细信息,请参阅 MSDN documentation and tutorial。
我有点class
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 文件。
此处理强烈依赖于每个 属性 的名称,并且事物在输出中出现的顺序由它们在 class 中出现的顺序定义。尽管实际上这是未定义的行为,因此如果编译器决定它想要以不同的顺序进行操作,则可能会发生变化。
因此,我想将我的 class 改成这样。
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
class 的复杂性,例如我想到的顺序、友好名称和其他属性。
或者这是一个疯狂的前进方式,我应该寻找另一种策略来将这些额外信息添加到列中吗?
您可以添加 属性 属性,优点是您不会触及 class 的 API。例如,添加 class:
[AttributeUsage(AttributeTargets.Property)]
public class ColumnAttribute : System.Attribute {
public string FriendlyName { get; set; }
public int Rank { get; set; }
}
您现在可以像这样注释您的 ExcitingResults
class:
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"); }
}
}
您的处理器 class 然后可以使用反射访问 属性 属性。例如,要按 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}");
}
}
您会希望在处理过程中进行更多错误检查 class,但您明白了。有关详细信息,请参阅 MSDN documentation and tutorial。