Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reflection or Dynamic Dispatching

I'm writing a abstract file parser (C#) which is extended by two concrete parsers. Both need to perform several checks. Currently there is a validate method in the abstract parser, which uses reflection to call all methods with a name starting with 'test'. That way adding checks is as easy as adding a method with a name that starts with 'test'.

Now recently I've had some comments about the use of reflection and it being better to use dynamic dispatching. My question to you is, why not use reflection and how would you implement this? Also how should I use dynamic dispatch to solve this problem?

    public bool Validate()
    {
        bool combinedResult = true;
        Type t = this.GetType();
        MethodInfo[] mInfos = t.GetMethods();

        foreach (MethodInfo m in mInfos)
        {
            if (m.Name.StartsWith("Check") && m.IsPublic)
            {
                combinedResult &= (bool)m.Invoke(this, null);
            }
        }
        return combinedResult;
    }

2 Answers

You should use regular OOP and not reflection for this. Have you abstract class expose an abstract method like Validate. Each parser will have to implement it. In the Validate, each parser will call the revelent Check methods to do the work.

like image 152
Fabian Vilers Avatar answered Nov 18 '25 19:11

Fabian Vilers


There's nothing wrong with code that works... until someone comes to maintain it. In particular, this kind of convention would need to be documented quite carefully as it's not immediately obvious how your class will do what it does.

(As an aside, however, using Reflection for this will be rather slow.)

The most obvious way might be to have an abstract base method bool Validate() that is implemented by the subclasses. The subclasses then have e.g.

public override bool Validate()
{
    return TestFirst() && 
        TestSecond() &&  
        TestThird();
 }

While this looks bulky it's immediately obvious what's going on. It also makes unit testing of Validate() a breeze.

It might also be possible to have the Testxxx() methods register themselves with the superclass in the constructor so they are called automatically - but that's more work and probably less maintainable.

If you really want to do this with reflection, consider marking the Testxxx() methods with attributes and reflecting on those instead. Then your code remains readable.

like image 41
Jeremy McGee Avatar answered Nov 18 '25 20:11

Jeremy McGee



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!