Как переопределить метод базового класса, который не переопределен в подписи

Сегодня обнаружил интересную вещь. Я попытался определить тип динамически, используя TypeBuilder, и попытался «переопределить» (т.е. заменить) метод, определенный в базовом классе:

public class Test
{
    public void Method()
    {
        Console.WriteLine("Test from Test");
    }
}

public void Bind(string methodToReplace, Action expr)
{
    @object = Activator.CreateInstance<T>();
    Type objectType = @object.GetType();
    AssemblyBuilder asmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("Mock"), AssemblyBuilderAccess.Run);
    ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule("Mock");
    TypeBuilder tB = modBuilder.DefineType(objectType.Name, TypeAttributes.Public | TypeAttributes.Class, objectType);
    var mB = tB.DefineMethod(methodToReplace, MethodAttributes.Public);
    ILGenerator ilGen = mB.GetILGenerator();
    ilGen.EmitCall(OpCodes.Call, expr.GetType().GetMethod("Invoke"), null);
    ilGen.Emit(OpCodes.Ret);
    @object = (T)Activator.CreateInstance(tB.CreateType());
}

Но, к сожалению, в определяемом типе есть два метода с одинаковым именем «Метод» («t» — экземпляр динамически определяемого типа):

t.GetType().GetMethods()
{System.Reflection.MethodInfo[6]}
    [0]: {Void Method()}
    [1]: {Void Method()}
    [2]: {System.String ToString()}
    [3]: {Boolean Equals(System.Object)}
    [4]: {Int32 GetHashCode()}
    [5]: {System.Type GetType()}

Итак, мой вопрос: как добавить новый метод, который скрывает реализацию базового класса, что эквивалентно использованию ключевого слова С# «новый» при определении нового метода, например:

public class Test2 : Test
{
    new public void Method()
    {
    }
}

person vchyzhevskyi    schedule 18.08.2014    source источник
comment
Вы можете переопределить только virtual методы.   -  person Henk Holterman    schedule 18.08.2014
comment
@HenkHolterman coirius, вероятно, означает скрытие метода С#.   -  person Eugene Podskal    schedule 18.08.2014
comment
Похоже, здесь может повлиять MethodAttributes.HideBySig?   -  person Corey    schedule 18.08.2014
comment
@EugenePodskal - может быть, не все так ясно. coinus: небрежное использование слова override .   -  person Henk Holterman    schedule 18.08.2014
comment
@Corey Я пробовал MethodAttributes.HideBySign, но у меня это не работает. У меня все еще есть два метода с одинаковым именем в типе, и я не могу вызвать ни один из них.   -  person vchyzhevskyi    schedule 21.08.2014
comment
Попробуйте использовать NewSlot как MethodAttribute. Этот вопрос кажется мне полезным для вас. stackoverflow.com/ вопросы/26335597/   -  person danish    schedule 05.01.2015


Ответы (1)


Вы видите два метода, поскольку использовали type.GetMethods() без флагов привязки. Попробуйте использовать bindflags.declaredonly.

Вы видите только один метод. Это именно то, что вы хотите.

новое ключевое слово - это С#, чтобы избежать ошибочного скрытия базового метода.

это заставит вас использовать переопределение или новое, чтобы избежать предупреждения.

если вы хотите переопределить базовый метод, используйте метод DefineMethodOverride для TypeBuilder.

person Teter28    schedule 16.01.2015