我有一些代码可以传递一个派生自某个类的类。我们称之为参数类 代码使用反射来遍历类的成员并分析给予它们的某些自定义属性。基本上,它是一个可配置的解析器,它将根据属性分析输入并将它找到的内容放入数据成员。
这在我们的代码中的几个地方使用。您指定参数类,放入属性数据成员,并将其传递给解析器。像这样:
public class MyFancyParameters : ParametersBase
{
[SomeAttribute(Name="blah", AnotherParam=true)]
public string Blah { get; set; }
// .. .more such stuff
}
var parameters = new MyFancyParameters();
Parser.Parse(input, parameters);
在许多地方,都有类似的需要解析的属性数据成员组。所以参数类在某些地方是相似的。这是多余的,当然,伤害。每当我需要改变这样的区域时,我需要在六个地方进行改变,所有克隆。这些部件开始分开只是时间问题。
但是,相似之处不能在非循环图中分组,因此我不能使用单一继承对它们进行分组。
我在C ++中要做的是将这些类似的东西放入他们自己的类中,只需继承一堆包含我需要的东西,然后完成。 (我认为这被称为混合继承。)
但是,C#没有多重继承。所以我想把这些块放到数据成员中并更改解析器以递归到数据成员中。但这会使解析器复杂化。
还有什么?
答案 0 :(得分:1)
你能让解析器接受一组参数类而不是一个参数类吗?或者,您可以允许解析器递归到您的参数类中,并让它提供其他参数类作为属性。基本上,从ParameterBase类型继承的ParametersBase派生类的每个属性都被递归并展平为单个参数列表。
实际上,我刚看到你已经提到了递归解决方案。我认为这可能是你最好的选择,并不是太复杂而无法支持。您应该能够创建一个辅助函数来枚举参数属性,使层次结构看起来像一个扁平类。
如果我正确理解您的要求,这里有一些代码会提供您的属性的“扁平化”视图。您可能希望使用额外的安全措施来扩充生产代码(例如保留一堆类型来检测循环引用。)
public class ParametersParser
{
public static IEnumerable<PropertyInfo> GetAllParameterProperties(Type parameterType)
{
foreach (var property in parameterType.GetProperties())
{
if (Attribute.IsDefined(property, typeof(SomeAttribute)))
yield return property;
if (typeof(ParametersBase).IsAssignableFrom(property.PropertyType))
{
foreach (var subProperty in GetAllParameterProperties(property.PropertyType))
yield return subProperty;
}
}
}
}