【问题标题】:C# private T CreateObject<T>()C# 私有 T CreateObject<T>()
【发布时间】:2012-11-02 10:27:46
【问题描述】:

我想创建一个带有动态参数的对象实例

private Type ClassType { get; set; }
model = (CreateObject<typeof(this.ClassType)>)ser.Deserialize(sr);


private T CreateObject<T>()
{
    return (T)Activator.CreateInstance(this.ClassType);
}

我想在没有“startconfig”之类的修复类型的情况下尝试它。 但是还是不行,你能帮帮我吗?

        var mi = GetType().GetMethod("CreateObject");
        var miConstructed = mi.MakeGenericMethod(this.ClassType);
        var instance = miConstructed.Invoke(this, null);
        var model = (instance)ser.Deserialize(sr);
    }

    private T CreateObject<T>()
    {
        return (T)Activator.CreateInstance(this.ClassType);
    }

这无论如何都不起作用,原因:找不到他的类型或命名空间名称“类型/命名空间”(您是否缺少 using 指令或程序集引用?)

发生在转换 ser.Deserialize(sr);

【问题讨论】:

标签: c# object activator createinstance


【解决方案1】:

你想创建一个 T 的实例吗?然后:

var model = CreateObject<StartConfig>();    

private T CreateObject<T>()
{
    return (T)Activator.CreateInstance(typeof(T));
}

使用您的第二个代码示例,您可能会执行类似的操作。

private Type ClassType { get; set; }
var mi = GetType().GetMethod("CreateObject");
var miConstructed = mi.MakeGenericMethod(ClassType);
var instance = miConstructed.Invoke(this, null);
model = (instance)ser.Deserialize(sr);

private T CreateObject<T>()
{
    return (T)Activator.CreateInstance(typeof(T));
}

【讨论】:

  • 那你为什么要使用泛型?这就是使用 Activator.CreateInstance...
  • @user1793913 可能会看到编辑...但是您应该显示更多代码,因为您的架构似乎存在一些问题...
  • 仅作记录:我的评论是关于 OP 之后评论和删除的内容。
【解决方案2】:

试试……

public class Factory<T>
{
    public static T getInstance()
    {
        return getInstance(typeof(T), null);
    }

    public static T getInstance(object[] initializationParameters)
    {
        return (T)Activator.CreateInstance(typeof(T), initializationParameters);
    }
{

【讨论】:

    【解决方案3】:

    你想用你的model做什么?我的意思是接口方面。您必须定义一个所有类型都遵循您反序列化的接口。

    public interface IModel
    {
         int ComputeFavoriteNumber(); // or a property
    }
    
    ...
    
    // class is practically unknown to deserializing module
    internal class ErnieModel : IModel
    {
        public int ComputeFavoriteNumber()
        {
            return 8243721;
        }
    }
    
    ...
    
    // deserializing module
    var bf = new BinaryFormatter();
    using (var ms = new MemoryStream())
    {
        bf.Serialize(ms, new ErnieModel()); // In reality ErnieModel should be unknown to the deserializing code, this is just to fill the Stream with data
        ms.Position = 0;
        var model = (IModel)bf.Deserialize(sr);
        Console.WriteLine("Favorite number: {0}", model.ComputeFavoriteNumber());
    }
    

    在这种情况下,您甚至不需要 Activator.CreateInstance。但是,如果您只是保存了要创建的类型的完全限定名称或类型本身(不确定是否有效),则确实需要它。

    // interfaces/classes the same as above
    Type deserializedType = typeof(ErnieModel); // or get it from wherever, maybe through (Type)bf.Deserialize(stream); ? In reality ErnieModel should be unknown to the deserializing code
    var model = (IModel)Activator.CreateInstance(deserializedType);
    Console.WriteLine("Favorite number: {0}", model.ComputeFavoriteNumber());
    

    在这种情况下使用泛型没有意义(尽管一开始感觉它是一个应用的好地方),您必须使用 oldschool object 并转换为已知的接口类型以启用真正的插件式扩展.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-10
      • 1970-01-01
      • 2018-07-15
      • 2019-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多