简体   繁体   English

在C#中使用反射继承

[英]Inheritance in c# using reflection

I am in a situation where i have to inherit a class and access its protected method to get a value. 我处于必须继承一个类并访问其受保护的方法以获得值的情况。

Due to some weird situations i have most of my code in reflection and im hoping if i have any chance to get this working using reflection. 由于某些奇怪的情况,我的大部分代码都处于反射状态,希望我是否有机会使用反射进行此工作。

To make things more clear, 为了使事情更清楚

Below is the class 下面是课程

public class Converter: BaseConverter
{
    public Converter();
    protected override object StringToValue();
}

I need to do below to get the functionality working. 我需要执行以下操作才能使功能正常运行。

public class myclass:Converter
{
 public StringToValue()
  {
    base.StringToVaue();
  }
}

However I cannot use direct reference of Converter dll in my project . 但是,我不能在项目中使用Converter dll的直接引用。 So i am handicapped here to use inheritance and myclass : converter. 所以我在这里无法使用继承和myclass:converter。 So how can i approach this using reflection which would be to basically make myclass inherit the converter class at runtime. 因此,我该如何使用反射来解决这个问题,即使myclass在运行时基本上继承转换器类。 I am not sure if it makes sense or not however it seems to me that its where i am trying to head towards to get an answer 我不确定这是否有意义,但是在我看来,这是我试图获得答案的地方

You can use TypeBuilder to create a whole new type at runtime via reflection. 您可以使用TypeBuilder在运行时通过反射创建一个全新的类型。 Of course ultimately you need a reference to the assembly which contains Converter to inherent from it. 当然,最终您需要引用其中包含Converter的程序集。 Make sure to check out the MSDN example of TypeBuidler . 确保检查出TypeBuidler的MSDN示例。 You need to call ModuleBuilder.DefineType() which has an overload to specify the parent type. 您需要调用具有重载的ModuleBuilder.DefineType()来指定父类型。

But if you go that way you have to do everything with reflection including emitting the methods. 但是,如果采用这种方式,则必须使用反射进行所有操作,包括发出方法。 I don't fully understand your restrictions so that's the best answer I could think of but I don't really like it ;) 我不完全了解您的限制,因此这是我能想到的最佳答案,但我不太喜欢;)

While we're talking about hacking: Do you really need to inherit from Converter or do you only need to access its methods? 当我们谈论黑客时:您确实需要从Converter继承还是只需要访问其方法? In case you only need the methods you could simply hold an instance of Converter as an attribute of type object and call the protected method via refletion inside your public StringToValue method. 如果只需要这些方法,则只需将Converter的实例作为类型object的属性保存,然后通过公共StringToValue方法内的refletion调用受保护的方法。

EDIT: 编辑:

As you ask for sample code. 当您要求提供示例代码时。 With reflection you can bypass the class security mechanism of C#, which means you're able to call non-public methods on any object. 通过反射,您可以绕过C#的类安全性机制,这意味着您可以在任何对象上调用非公共方法。 First you need the Type . 首先,您需要Type Because you can't write it out in C# you need to get it some other way. 因为您不能用C#编写它,所以需要以其他方式获得它。 Then you can create an instance of that type with Activator. 然后,您可以使用Activator创建该类型的实例。 You also need to obtain information about the method you want to call. 您还需要获取有关要调用的方法的信息。 It makes sense to cache this information because the processes of reading that information with reflection is kinda slow. 缓存此信息是有道理的,因为通过反射读取该信息的过程有点慢。 Finally you can use the MethodInfo to actually call the method. 最后,您可以使用MethodInfo实际调用该方法。

I haven't tested that code because I don't have a machine to do so right now. 我没有测试该代码,因为我现在没有机器可以测试。

class myclass
{
    object internalConverter;
    MethodInfo converterStringToValueMethod;

    public myclass()
    {
        // Here you need a reference to the assembly which contains the Converter type
        Assembly asm = Assembly.Load("xxx.dll"); // Name of the assembly which contains Converter
        Type converterType = asm.GetType("Converter");
        this.internalConverter = Activator.CreateInstance(converterType);

        this.converterStringToValueMethod = converterType.GetMethod("StringToValue", BindingFlags.NonPublic | BindingFlags.Instance);
    }

    public object StringToValue()
    {
        return converterStringToValueMethod.Invoke(internalConverter, null);
    }
}

This should do what you want without inheritance: 这应该在没有继承的情况下完成您想做的事情:

using System;
using System.Reflection;

namespace Test
{
    class Converter
    {
        string Value;

        public Converter(string test)
        {
            Value = test;
        }
        protected object StringToValue()
        {
            return Value;
        }
    }

    class myclass
    {
        object Unknown;

        public myclass(object other)
        {
            Unknown = other;
        }

        MethodInfo originalFunction;
        public object StringToValue()
        {
            if (originalFunction == null)
            {
                originalFunction = Unknown.GetType().GetMethod("StringToValue", BindingFlags.NonPublic | BindingFlags.Instance);
            }
            return originalFunction.Invoke(Unknown, null);
        }
    }

    class Test
    {
        [System.STAThread]
        public static void Main(string[] args)
        {
            Converter unknown = new Converter("TEST");
            myclass mine = new myclass(unknown);
            Console.WriteLine(mine.StringToValue());
            Console.ReadLine();
        }
    }
}

This is a bad idea for a number of reasons, but if you are sure it is what you need... 由于许多原因,这是个坏主意,但是如果您确定这是您所需要的...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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