【问题标题】:Creating objects of different Types using a unified Signature使用统一的签名创建不同类型的对象
【发布时间】:2013-09-18 18:05:07
【问题描述】:

想象以下两个类:

class A
{
    public A()
    {
    }
}
class B : A
{
    public B()
    {
    }
}

我是否可以以强制 B 类具有无参数构造函数的方式定义 A 或接口?或者,更概括地说,一个构造函数(或静态方法)能够创建具有给定签名的 B 类型实例?

我确实想将B类限制为只能使用该签名构造,但我想确保B类可以使用该签名构造(是它是无参数的,或指定某些参数)。

需要说明的是:我不是在寻找需要我在运行时使用反射或任何其他方法来解决这个问题的解决方案(我对此没有问题,但它会使代码的可读性降低,在这种情况下通常看起来是个坏主意)。

有没有办法做到这一点?

我写了一篇博文,更深入地介绍了我正在努力实现的目标here

【问题讨论】:

    标签: c# serialization interface constraints factory


    【解决方案1】:

    没有可以应用于该类型的接口或基类型,以确保它具有无参数构造函数。您可以进行此类约束的唯一上下文是通用约束:

    public static void Foo<T>()
        where T : new() {}
    

    在这种情况下,唯一可以与Foo 一起使用的类型必须具有无参数构造函数。

    【讨论】:

    • 如果我想强制对象总是有一个构造函数,它接受一个 List 类型的参数,这是否也可用?或者我想要的任何其他数量和组合的论点?如果构造函数是不可能的,也许强制该类有一个构造自身实例的静态方法(当然也能够强制该方法采用某些参数)?如果没有,它不适用于我的情况,仍然感谢您的快速回复:)
    • @user2791287 这是不可能的,不。
    • 编辑了最初的问题,并附上了我正在尝试做的事情的链接,也许这可以更准确地了解我想要做什么,也许还有我忽略的替代方案:
    • @user2791287 鉴于您给出的问题的限制,这根本不可能。如果这不是一个很难解决的问题,那么已经有解决方案了。现有解决方案存在问题的原因在于尝试这样做的固有问题和局限性。
    【解决方案2】:

    您可以定义工厂来实例化A(和派生类型)类型的对象:

    interface IFactory<T> where T : A
    {
        T Create(int i);
        T Create(string s);
        // and so on...
    }
    

    并且需要工厂实现,当你想创建一个对象时。
    这将确保在编译时调用代码,它会尝试使用给定的参数集创建一个对象。

    当然,没有什么可以阻止 NotImplementedException 在运行时实现具体的 IFactory&lt;T&gt;

    【讨论】:

    • 我想过这个,但它并没有真正起作用,因为即使是工厂也必须假设它实例化的对象只是支持某种构造它的方式。我不能使用工厂来强制我可以以这种方式构造对象。我不想这样做的另一个原因是,我试图约束的类是在运行时编译的,这意味着我基本上会强制每个脚本类也实现一个工厂。即使那样,我也不能强制脚本允许我以某种方式创建工厂......
    【解决方案3】:

    这是一个后续,因为我做了一些研究,至少设法想出了一个有点令人满意的答案。

    所以在挖掘了一段时间并试图弄清楚 C# 中内置的序列化/反序列化是如何工作的之后,我发现 C# 有一个名为 GetUninitializedObject() 的方法。这个方法看起来像是一个 hack,因为它只是避免一开始就调用对象的构造函数,但它至少给了我一种方法来完成我最初想要的:能够反序列化任意类型的对象。使用它,我可以对未初始化的创建对象使用方法(并通过接口强制实现它们)。

    我发现这很符合我的需求,虽然它没有达到我最初想要的效果,但它允许我实现一种适合我的目的的模式。

    最好的问候

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-12
      • 2018-10-31
      • 1970-01-01
      相关资源
      最近更新 更多