简体   繁体   中英

How to refactor when reflection is used to get methods by name?

Suppose I get a MethodInfo in the following way:

Assembly assembly = Assembly.Load(assemblyName);
Type type = assembly.GetType(nameSpaceName+"."+className);
MethodInfo mi = type.GetMethod("myMethod", bf); // bf are the binding flags.

But later I decide to change the case/name of myMethod .

Is there a way to either:

  1. Refactor so that it changes the name in the string.
  2. Change the reflection call so it gets the method without using the method's name as a string?

The reason for this is so I can test my code which requires the use of reflection, but I'd rather not require that nobody ever change the name of the methods in the code.

If you use Visual Studio to do the refactoring, there is an option to search literal strings and comments for the name and change those too. I highly recommend using the preview when using that option, though, to verify that you're only changing the parts you expect.

Of course, you could use a constant like internal const string methodName = "methodName"; so that you only have the literal string once. You could manually change the one string literal when you refactor the method name. You'd also be able to rename the methodName more easily.

You could use a custom attribute, and decorate your methods with this attribute. Then instead of getting the method by its name, you could get it by the ID defined in the attribute. That way the method name could change as often as it needs to...just a thought.

[AttributeUsage(AttributeTargets.Method)]
public class CustomMethodAttribute : Attribute
{
    public string ID { get; set; }
}

Usage:

[CustomMethodAttribute(ID = "UniqueIDHere")]
public void Test()
{

}

Do you have a concrete reference to the type in question?

Even if you don't have it explicitly, you can make the method generic.

public void TestMethod<TargetType>(object o)
{
    if (typeof(TargetType).IsAssignableFrom(o.GetType())) {
        TargetType strongType = o as TargetType;
        strongType.myMethod();
    }
}

In fact, you could do this without reflection at all:

public void TestMethod<TargetType>(object o)
{
    if (o is TargetType) {
        TargetType strongType = o as TargetType;
        strongType.myMethod();
    }
}

For methods and properties try using expression trees. You can get reflection-related information from them, saving compile-time checking and enabling automatic refactoring. I believe you can get assembly-related information and namespace names as well. Just write several helper functions which can retrieve such information from expression trees.

You can find several helper functions here They allow write such code:

FirePropertyChanged(() => PropertyName);

which is the same as

FirePropertyChanged("PropertyName");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM