【问题标题】:How to cast object to generic type?如何将对象转换为泛型类型?
【发布时间】:2011-06-25 00:29:31
【问题描述】:

我有很多实现 IBuilder 接口的类,如下所示

更新: 每个 Model1、Model2... 都继承自 IModel

public class A : IBuilder<Model1>
{
     public Model1 Create(string param)
     {
         return new Model1();
     }
}
public class B : IBuilder<Model2>
{
     public Model2 Create(string param)
     {
          return new Model2();
     }
}

我正在使用 StructureMap 注册所有继承 IBuilder

的类
Scan(x =>
{
       x.TheCallingAssembly();
       x.AddAllTypesOf(typeof(IViewModelBuilder<>));                
});

更新

现在,每次我需要获取某个模块的模型时,我都会调用 Do 函数

public IModel Do(Module module)
{
        //ModelSettings is taken from web.config  
        var builderType = Type.GetType(string.Format("{0}.{1}ModelBuilder,{2}", ModelSettings.Namespace, module.CodeName, ModelSettings.Assembly));
        var builder = ObjectFactory.GetInstance(t) as IViewModelBuilder<>;

        return builder.Create("");            
}

我在ObjectFactory.GetInstance(t) as IViewModelBuilder&lt;&gt; 行中遇到编译错误。 许多帖子建议创建 NOT 通用接口(IViewModelBuilder)并让通用接口继承它。然后我可以让演员像

ObjectFactory.GetInstance(t) as IViewModelBuilder

这是唯一的方法吗?

谢谢

【问题讨论】:

  • 你有一个非常混乱的真实代码和示例代码的组合。 IViewModelBuilder 与 IBuilder 有什么关系,A 类实际上会以 ModelBuilder 的名称结尾吗?等等。

标签: c# .net structuremap


【解决方案1】:

DoGetInstance 的代码也应该是通用的。基本上它可能看起来像这样

public T Do<T> ()
{
     return ObjectFactory.GetInstance<T>().Create();
}

【讨论】:

  • 我不能使 Do 通用,因为我创建了 Do 将在运行时接收的类型
  • 我更新了我的帖子并添加了我使用的真实代码。如果你能看看我会很高兴
【解决方案2】:

你不能让Do() 通用吗?

var m = Do<B>();

public T Do<T>()
{ 
   var builder = (IViewModelBuilder<T>)ObjectFactory.GetInstance(typeof(T));
   return builder.Create("");
}

如果你不能,使用非泛型接口可能是你最好的选择,但还有其他选择,比如使用反射或 C# 4 的dynamic

var m = Do(typeof(B));

public object Do(Type t)
{ 
   dynamic builder = ObjectFactory.GetInstance(t);
   return builder.Create("");
}

【讨论】:

  • 我不能使 Do 通用,因为我创建了 Do 将在运行时接收的类型。动态实用还是重写我的代码更好?如果我在运行时获取类型,我只是不知道如何重写
  • 在我看来,您的代码中根本不需要泛型。只需使用非泛型IViewModelBuilder,即返回IModel
【解决方案3】:

我唯一能想到的就是你创建一个接口或一个基类来继承你的视图模型。即:

public class Model1 : ModelBase
{
}

public class ModelBase
{
}

public ModelBase Do(Type t)
{
    var builder = ObjectFactory.GetInstance(t);
    return t.GetMethod("Create").Invoke(builder, new object[] { "" }) as ModelBase;
}

【讨论】:

  • @Torbjon,我已经在使用某种 ModelBase。如果有帮助,我更新了我的帖子。我想避免使用Invoke,因为如果我将Create 更改为Create2,我会忘记在GetMethod 中更改它,但是使用真实接口如果我更改方法的名称,我会收到编译错误
【解决方案4】:

如果要在非泛型场景中调用,则需要引入非泛型IViewModelBuilder 接口。通用的IViewModelBuilder&lt;T&gt; 将实现IViewModelBuilder

唯一的另一种选择是通过反射调用 create 方法,但我不明白为什么会首选:

var builder = ObjectFactory.GetInstance(builderType);
var method = builderType.GetMethod("Create");
return (IModel) method.Invoke(builder, new[]{""});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多