【问题标题】:C# Generic Copy ConstructorC# 通用复制构造函数
【发布时间】:2010-10-08 11:23:18
【问题描述】:

我有一个接口和两个实现该接口的类。这些类具有泛型类型。我想从一个类的实例克隆到另一个类。

interface IFoo
{
    // stuff
}

class Foo<T> : IFoo
{
    // foo stuff
    // ifoo implementation
}

class Bar<T> : IFoo
{
    // bar stuff
    // ifoo implementation
}

我有一个 Foo 并且想要一个 Bar。 Bar 有一个带有 IFoo 参数的复制构造函数。 我创建了一个扩展方法来实现克隆:

public static Bar<T> Clone<T>(this IFoo foo) 
{
    return new Bar<T>(foo);
}

调用方法需要类型:

someFoo.Clone<T> ...

有没有办法通过修改扩展方法或任何其他方式在调用方法时省略声明类型,以允许只传入实例而不关心其底层类型?

更新 以下是如何使用它来更好地说明情况。

在一个方法中,我迭代一个集合并返回一个 IFoo 的枚举。在方法中,我查看源集合的属性并确定 Foo 的类型。

IFoo foo = null;

string type = element.Attribute("Type").Value;
switch (type)
{
    case "int":
        foo = new Foo<int>();
        break;

    case "string":
        foo = new Foo<string>();
        break;

    // etc
}
// other stuff

yield return foo;

调用方法有一个List。后来我从这个列表中选择了单个项目以供使用,此时我想要一个 Bar 而不是 Foo。从列表中选择时,实例的类型为 IFoo,因为它们只能看到“this IFoo foo”的扩展方法。我不想将 IFoo 转换为 Foo,这需要重新声明 T 的类型。我只想让 Foo 告诉 Bar 它是什么。这可能吗?

【问题讨论】:

  • 也许我遗漏了一些东西,但如果你的扩展函数采用 IFoo,如果它是 Foo 类型,它应该如何将它“克隆”到 Bar 中?
  • 我只关心 IFoo 属性中的值从 Foo 复制到 Bar。

标签: c# interface clone generics


【解决方案1】:

如果它适用于您的场景,您可以使用IFoo&lt;T&gt;。此外,如果您不介意使用特定的扩展方法,您可以收到Foo&lt;T&gt;。您确实需要传递一些引用 T 的内容,以便编译器可以推断出适当的类型。

【讨论】:

    【解决方案2】:

    所以你一切正常,但你希望能够使用语法

    someFoo.Clone()
    

    而不是

    someFoo.Clone<int>()
    

    您希望 int 被隐含而不是显式地放置它?

    在代码示例中不能这样做的原因是 IFoo 没有引用创建 Bar&lt;T&gt; 所需的泛型类型 T。

    我建议你真的需要另一个接口:IFoo&lt;T&gt;

    如果你有,你的扩展方法看起来像这样:

    public static Bar<T> Clone<T>(this IFoo<T> foo) 
    {
        return new Bar<T>(foo);
    }
    

    那么你使用就没有问题了

    IFoo<int> someFoo = new Foo<int>();
    Bar<int> someBar = someFoo.Clone();
    

    希望有帮助

    【讨论】:

      【解决方案3】:

      尝试这样定义方法

      public static Bar<T> Clone<T>(this Foo<T> foo)
      {
          return new Bar<T>(foo);
      }
      

      这样,参数将具有泛型类型,并且编译器将具有用于推断类型的源。

      【讨论】:

        【解决方案4】:

        当您需要完全控制您的深拷贝克隆时,这种模式非常好:

        public class FooBase
        {
            private int x;
        
            public FooBase() { /* standard contructor */ }
        
            protected FooBase(FooBase clone)
            {
                this.x = clone.x;
            }
        
            public FooBase Clone() { return new FooBase(this); }
        }
        
        public class Foo : FooBase
        {
            private int y;
        
            public Foo() { /* standard contructor */ }
        
            protected Foo(Foo clone) : base(clone)
            {
                this.y = clone.y;
            }
        
            public Foo Clone() { return new Foo(this); }
        }
        

        为克隆定义受保护的构造函数 - 这样派生类就可以克隆基类中的值。 此模式必须手工编写(或借助良好的 T4 模板生成),但非常适合深度克隆。

        更新:我想我误解了这个问题,并且已经实施了克隆。 Freddy 是对的——编译器必须知道它应该推断出哪种类型,而它不能从 IFoo 类型中推断出来。它可以在 (this Foo foo) 中做到这一点。

        【讨论】:

          【解决方案5】:

          这对灵感有帮助吗?:How would you improve this shallow copying class?

          本质上它是一种通用的基于反射的属性复制方法。试试看。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2023-03-22
            • 2013-12-19
            • 1970-01-01
            • 1970-01-01
            • 2018-10-17
            • 2011-07-17
            相关资源
            最近更新 更多