【问题标题】:How to instantiate an interface object with implementation that is passed in to current method in C#?如何使用传递给 C# 中当前方法的实现来实例化接口对象?
【发布时间】:2016-02-29 23:30:24
【问题描述】:

给定一个简单的界面

public interface IIdTracker
{
    int Id { get; }
}

我有两个实现它的类

public class human : IIdTracker
{
    public int Id { return 0; }
}

public class robot : IIdTracker
{
    public int Id { return 1; }
}

如何在不知道谁或什么正在实施 IIdTracker 的情况下实例化作为 IIdTracker 传递的任何类?

public void TrackId(IIdTracker idt)
{
    // this is the code I am not sure of
    var being = new idt.GetType();
}

【问题讨论】:

  • 您需要IIdTracker 的新实例吗?您已经在idt拥有一个实例。
  • 是的,我想要单独的 IIdTracker,但我想要传入的类型。
  • 您也许可以使用反射(或通过新的通用约束)创建一个新实例,但您希望它返回相同的 Id 值吗?

标签: c# dynamic interface instantiation typeof


【解决方案1】:

经过一番研究,我发现

var being = Activator.CreateInstance(idt.GetType()) as IIdTracker;

作为解决方案。

【讨论】:

    【解决方案2】:

    使用泛型的更好方法是:

        public void TrackId<T>(T idt)
            where T:IIdTracker, new()
        {
            var being = new T();
        }
    

    并为您的类添加一个公共无参数构造函数,例如

    public class Human : IIdTracker
    {
        public Human() { }
        public int Id { return 0; }
    }
    

    或者,如果,正如您的编辑所说,您不能这样做,因为最终您会得到一个 ListIIdTracker 对象,您正在尝试克隆,那么更好的方法可能是添加一个 .Clone 方法进入您的IIdTracker 界面,或创建一个新界面IIdCloneable,以便人类或机器人每个人都知道如何创建自己的克隆。或者,您有一个CloneFactory,并且每种类型都向克隆工厂注册自己,因此它知道如何创建任何一种。克隆工厂可以像Dictionary&lt;Type,Func&lt;IIdTracker&gt;&gt; 一样简单,它存储创建人类、机器人或其他任何东西的操作。例如factory.Add(typeof(Human), () =&gt; new Human());

    【讨论】:

    • 为了让这个工作编译器告诉我我的 IIdTracker 必须有无参数的构造函数。但它是接口......这只适用于抽象类吗?
    • @publicst119 通用约束强制 T 既是实现 IIdTracker 的类,又具有无参数构造函数(这是方法定义中的 new() 约束)。您的方法和这个方法都不会创建“IIdTracker 的实例”,它们都在创建实现 IIdTracker 的类的实例。
    • @publicst119 我为 Preston 的 cmets 添加了一些代码,显示了您需要做什么。
    • 我知道我们的解决方案都没有创建IIdTracker 的实例。这很好。但是,当我限制使用where T:IIdTracker, new() 时,我的编译器在调用TrackId&lt;T&gt; 的位置抛出错误,说明idt 必须具有无参数构造函数。接口的实现确实有无参数的构造函数,但它超出了这个项目的知识。
    • @publicst119 是的,泛型将通过您的解决方案传播出去,如果您从另一个采用 IIdTracker 的方法调用它,您也需要在那里修复它并使该方法也通用。或者也许你让整个类通用,然后方法不需要是通用的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-09
    • 1970-01-01
    • 2021-06-06
    • 2016-04-22
    • 1970-01-01
    • 2020-11-14
    相关资源
    最近更新 更多