【问题标题】:Can I set the type of a field within a class at runtime to a newly created type in c#?我可以在运行时将类中的字段类型设置为 c# 中新创建的类型吗?
【发布时间】:2016-02-08 01:06:11
【问题描述】:

我正在使用Reflection.EmitTypeBuilder 在运行时创建一个新类型。我的设置是这样的:

public class MyClass {
    public object MyField = CreateInstanceOfNewType();
    public MyClass() {}
}

问题在于MyClass.MyField 是用object 类型声明的,因此当可转换类型分配给MyClass.MyField 时,不会调用新类型存在的隐式转换运算符。有没有办法将字段的类型设置为新创建的类型,使其行为类似于典型情况下的行为?

【问题讨论】:

  • 该类型会实现已知接口吗?如果是这样,只需将 object 分配给类型为该接口的变量。
  • 隐式转换运算符不能在接口中定义。这确实绕过了赋值时的类型更改,但不允许使用隐式强制转换。
  • 请描述您的实际业务问题,而不是针对未知问题的这种不可行的解决方案。你是对的 - C# des 不允许这个解决方案工作。这并不意味着您的问题无法解决。

标签: c# reflection casting reflection.emit typebuilder


【解决方案1】:

这取决于具体的用例,一个可能的解决方案是让你的类泛型,然后使用反射创建一个静态泛型方法来创建类的实例。这允许您在声明属性时使用变量动态类型:

public class MyClass<T> { 
public T MyField = CreateInstanceOfNewType<T≥(); 
public MyClass() {} 
}

public static MyClass<T> createClass<T>() {
return new MyClass<T>:
}

dynamic instanceOfMyClass = typeof(SomeClass).GetMethod("createClass").MakeGeneric(dynamicType).Invoke()

另一种选择是使用动态关键字。

【讨论】:

  • 当我使用dynamic 时,它的行为与我使用object 相同。当我尝试分配另一种类型时,它只是采用新类型而不是强制隐式转换。
  • 你的 createinstanceofclass 返回什么类型?
【解决方案2】:

如果我理解正确的话,你想初始化一个你的新类型的对象,用一个你已经为其构建隐式转换运算符的可转换类型的对象。我建议您考虑使用构造函数而不是隐式运算符:使用Reflection.Emit 创建构造函数,该构造函数采用可转换类型的一个参数并使用该参数值来初始化新类型的对象。您希望获得与这段代码相同的结果:

public class MyNewType
{
    public MyNewType(CastableType value)
    {
        /* implement initialization with value */
    }

    /* other stuff */
}

然后您可以使用Activator.CreateInstance(Type type, params object[] arguments) 来使用该构造函数。这是一个例子:

var newType = GetNewType();
var castableObject = CreateInstanceOfCastableType();
this.MyField = Activator.CreateInstance(newType, castableObject);

【讨论】:

    猜你喜欢
    • 2020-05-31
    • 2010-10-13
    • 1970-01-01
    • 1970-01-01
    • 2011-05-01
    • 1970-01-01
    • 2022-06-22
    相关资源
    最近更新 更多