代码之家  ›  专栏  ›  技术社区  ›  sbi

解决C中的Mi缺失问题#

c#
  •  3
  • sbi  · 技术社区  · 14 年前

    我有一些代码可以传递一个从某个类派生的类。让我们称之为参数类。
    代码使用反射来遍历类成员并分析给定给他们的某些自定义属性。基本上,它是一个可配置的解析器,它将根据属性分析输入,并将找到的内容放入数据成员中。

    这在我们的代码中有几个地方使用。您可以指定参数类,放入属性化的数据成员,并将其传递给解析器。像这样:

    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没有多重继承。所以我考虑将这些块放入数据成员中,并更改解析器以递归到数据成员中。但这会使解析器非常复杂。

    还有什么?

    1 回复  |  直到 14 年前
        1
  •  1
  •   Dan Bryant    14 年前

    您的解析器是否可以接受参数类的集合而不是单个参数类?或者,您可以允许解析器递归到参数类中,并让它提供额外的参数类作为属性。基本上,从类型ParameterBase继承的ParameterBase派生类的每个属性都递归到一个参数列表中,并展平为一个参数列表。

    实际上,我刚刚看到您已经提到了递归解决方案。我认为这可能是你的最佳选择,而且不太复杂,无法支持。您应该能够创建一个助手函数来枚举参数属性,使层次结构看起来像一个平面类。


    如果我正确理解您的需求,下面的一些代码将提供您的属性的“扁平”视图。您可能希望使用附加的保护措施来增强生产代码(例如保留一组类型以检测循环引用)。

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