Search code examples
.netreflectionannotations

.NET Reflection - how to get implemented interface method on class?


I'm trying to write custom attributes for .net that mimic the jpa converter in Java that allows me to decorate a class like so:

@Entity(name = "PersonTable")
public class Person {

    @Convert(converter = PersonNameConverter.class)
    private PersonName personName;
}

I want to restrict the type of converter the user can pass into the Converter attribute to be a particular interface that I defined.

public interface ICustomConverter<T1, T2>
{
    T1 ConvertToType1(T2 source);
    T2 ConvertToType2(T1 source);
}

I could not find a way to do this during compile time, so I'm testing out this during runtime with this code:

class BooleanConverter : ICustomConverter<bool, string>
{
    bool ICustomConverter<bool, string>.ConvertToType1(string source)
    {
        if ("y".Equals(source.ToLower()))
            return true;
        else
            return false;
    }

    string ICustomConverter<bool, string>.ConvertToType2(bool source)
    {
        if (source)
            return "Y";
        else
            return "N";
    }
}

[XmlMapper(ParentNodeName = "Loan")]
class Loan
{
    [CustomConverterAttribute(typeof(BooleanConverter))]
    public bool IsJointAccount { get; set; }
}

public CustomConverterAttribute(Type converter)
    {
        _converter = converter;

        _convertToType1 = converter
            .GetMethod("ConvertToType1", BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy);

        _convertToType2 = converter
            .GetMethod("ConvertToType2", BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy);

        _type1 = _convertToType1.ReturnType;
        _type2 = _convertToType2.ReturnType;

        _converterInstance = ReflectionUtils.CreateInstance(_converter);
    }

But both .GetMethods() and .GetMethod() do not return the implemented methods. I have tried various different BindingFlags such as (BindingFlags.DeclaredOnly) but none of the binding options actually return these methods.


Solution

  • The issue is that BooleanConverter explicitly implements the interface methods, therefore in order to find the method you must explicitly specify the full method name (see this answer How can I access an explicitly implemented method using reflection?).

    In short, "ConvertToType1" is not explicit enough to get the method. Either implement the interface non explicitly, or get the method from the interface instead (in above answer)