开发者

Working around missing MI in C#

开发者 https://www.devze.com 2023-01-08 23:17 出处:网络
I have a some code that gets passed a class derived from a certain class. Let\'s call this a parameter class.

I have a some code that gets passed a class derived from a certain class. Let's call this a parameter class.

The code uses reflection to walk the class' members and analyze certain custom attributes given to them. Basically, it's a configurable parser which will analyze input according to the attributes and put what it found into the data members.

This is used in several places in our code. You specify the parameter class, putting in attributed data members, and pass this to the parser. Something like this:

public class MyFancyParameters : ParametersBase
{
  [SomeAttribute(Name="blah", AnotherParam=true)]
  public string Blah { get; set; }

  // .. .more such stuff
}

var parameters = new My开发者_如何学GoFancyParameters();
Parser.Parse(input, parameters);

In many places there are similar groups of attributed data members that need to get parsed. So the parameter classes are, in some places, similar. That's redundant and that, of course, hurts. Whenever I need a change in such an area, I need to make that change in half a dozen places, all clones. It's just a matter of time when these parts will start drift apart.

However, the similarities cannot be grouped in acyclic graphs, so I can't use single inheritance to group them.

What I would do in C++ is to put these chunks of similar stuff into their own classes, just inherit a bunch of them that contain whatever I need, and be done. (I think that's referred to as mix-in inheritance.)

C#, however, doesn't have multiple inheritance. So I was thinking of putting these chunks into data members and change the parser to recurse into data members. But that would considerably complicate the parser.

What else is there?


Can you have your parser accept a collection of parameter classes instead of a single parameter class? Alternately, you could allow the parser to recurse into your parameter class and have it supply additional parameter classes as properties. Basically, every property of a ParametersBase derived class that inherits from type ParametersBase is recursed into and flattened into a single list of parameters.

Actually, I just saw that you already mentioned the recursive solution. I think this is probably your best bet and it's not too complex to support. You should be able to create a helper function for enumerating the parameter properties that makes a hierarchy look like a flat class.


Here's some code that would provided a 'flattened' view of your properties, if I understand your requirement correctly. You'll probably want to augment the production code with additional safeguards (such as keeping a stack of types to detect circular references.)

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

精彩评论

暂无评论...
验证码 换一张
取 消