C#中使用反射继承
Inheritance in c# using reflection
我处于必须继承 class 并访问其受保护方法以获取值的情况。
由于一些奇怪的情况,我的大部分代码都在反射中,我希望我是否有机会使用反射来实现它。
为了让事情更清楚,
下面是class
public class Converter: BaseConverter
{
public Converter();
protected override object StringToValue();
}
我需要执行以下操作才能使功能正常运行。
public class myclass:Converter
{
public StringToValue()
{
base.StringToVaue();
}
}
但是我不能在我的项目中直接引用 Converter dll。所以我在这里无法使用继承和 myclass : 转换器。那么我如何使用反射来解决这个问题,这基本上是让我的 class 在运行时继承转换器 class。我不确定它是否有意义,但在我看来,它是我试图前往获得答案的地方
您可以使用 TypeBuilder to create a whole new type at runtime via reflection. Of course ultimately you need a reference to the assembly which contains Converter
to inherent from it. Make sure to check out the MSDN example of TypeBuidler
. You need to call ModuleBuilder.DefineType() 来指定父类型。
但是如果你这样做,你必须用反射做所有事情,包括发出方法。我不完全理解您的限制,所以这是我能想到的最佳答案,但我不太喜欢它 ;)
当我们谈论黑客时:你真的需要从 Converter 继承还是你只需要访问它的方法?如果您只需要这些方法,您可以简单地将 Converter 的实例作为类型对象的属性,并通过 public StringToValue
方法中的反射调用受保护的方法。
编辑:
当你要求示例代码时。通过反射,您可以绕过 C# 的 class 安全机制,这意味着您可以在任何对象上调用非 public 方法。首先,您需要 Type. Because you can't write it out in C# you need to get it some other way. Then you can create an instance of that type with 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 才能实际调用该方法。
我还没有测试该代码,因为我现在没有机器可以这样做。
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);
}
}
这应该在没有继承的情况下做你想做的事:
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();
}
}
}
出于多种原因,这是一个坏主意,但如果您确定这是您需要的...
我处于必须继承 class 并访问其受保护方法以获取值的情况。
由于一些奇怪的情况,我的大部分代码都在反射中,我希望我是否有机会使用反射来实现它。
为了让事情更清楚,
下面是class
public class Converter: BaseConverter
{
public Converter();
protected override object StringToValue();
}
我需要执行以下操作才能使功能正常运行。
public class myclass:Converter
{
public StringToValue()
{
base.StringToVaue();
}
}
但是我不能在我的项目中直接引用 Converter dll。所以我在这里无法使用继承和 myclass : 转换器。那么我如何使用反射来解决这个问题,这基本上是让我的 class 在运行时继承转换器 class。我不确定它是否有意义,但在我看来,它是我试图前往获得答案的地方
您可以使用 TypeBuilder to create a whole new type at runtime via reflection. Of course ultimately you need a reference to the assembly which contains Converter
to inherent from it. Make sure to check out the MSDN example of TypeBuidler
. You need to call ModuleBuilder.DefineType() 来指定父类型。
但是如果你这样做,你必须用反射做所有事情,包括发出方法。我不完全理解您的限制,所以这是我能想到的最佳答案,但我不太喜欢它 ;)
当我们谈论黑客时:你真的需要从 Converter 继承还是你只需要访问它的方法?如果您只需要这些方法,您可以简单地将 Converter 的实例作为类型对象的属性,并通过 public StringToValue
方法中的反射调用受保护的方法。
编辑:
当你要求示例代码时。通过反射,您可以绕过 C# 的 class 安全机制,这意味着您可以在任何对象上调用非 public 方法。首先,您需要 Type. Because you can't write it out in C# you need to get it some other way. Then you can create an instance of that type with 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 才能实际调用该方法。
我还没有测试该代码,因为我现在没有机器可以这样做。
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);
}
}
这应该在没有继承的情况下做你想做的事:
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();
}
}
}
出于多种原因,这是一个坏主意,但如果您确定这是您需要的...