【问题标题】:C# Templates and special constructorsC# 模板和特殊构造函数
【发布时间】:2009-02-03 22:26:02
【问题描述】:

我有一组类,它们都可以用作为特定接口实例的参数来构造。由于它们都可以由同一个对象构造(并且这种构造发生的过程在所有情况下都基本相同),我认为模板可能会起作用。基本上,我想做这样的事情:

public static void dostuff<T, U> (List<T> items)
{
    foreach (T item in items)
    {
        func(new U(item).SpecialMember);
    }
}

当然,这不会编译,因为 U 是模板化的,因此缺少 SpecialMember 以及 T 构造函数。

基本上,接口T 的任何给定实现都具有某些特性。 UT which has an additional feature that is needed *and* which can be constructed from an any instance ofU` 的实现。

建议?

【问题讨论】:

    标签: c# generics oop templates


    【解决方案1】:

    不幸的是,虽然约束会让你一些到达那里,但没有办法指定一个类型有一个带有特定参数的构造函数:你唯一需要的构造函数是一个无参数的构造函数。

    就我个人而言,我希望使用"static interfaces"(仅可用于类型约束)的想法来看到这种变化,但目前最好的是类型工厂或反射 - 或者可能是无参数构造函数 界面中的“Init”方法。坦率地说,这些都不是很好的选择。

    【讨论】:

      【解决方案2】:

      您可以将constraints 添加到通用参数中,这将允许您访问 SpecialMember,例如:

      public class SpecialObjFactory<T,U> where T : ISpecialMethod
      where u : new()
      {
      }
      

      【讨论】:

        【解决方案3】:

        你想要一个Factory 模式。将工厂方法添加到返回 U 类型的 T 接口。

        【讨论】:

          【解决方案4】:

          您不能使用泛型来创建这样的对象。您可以像这样约束泛型类型:

          public static void dostuff<T, U> (List<T> items) where T : SomeClass where U : SomethingElse
          {
          }
          

          但这只会让您访问这些类/接口的成员,而不是构造函数。

          要扩展 Joel 的答案,您应该向 T 接口(在我的示例中为 SomeClass)添加一个方法,该方法接受一个 T 对象并返回一个新的 U 对象。类似于以下内容:

          public class SomeClass    
          {
              CreateInstanceOfSomethingElse() { return new SomethingElse(this); }
          }
          
          public static void dostuff<T, U> (List<T> items) where T : SomeClass, U : SomethingElse
          {
              foreach (T item in items)
              {
                  func(item.CreateInstanceOfSomethingElse().SpecialMember);
              }
          
          }
          

          作为另一种完全不同的方法,您可以指定 doStuff 方法也采用 Func&lt;T, U&gt;,它应该从 T 对象创建一个 U。

          public static void dostuff<T, U> (List<T> items, Func<T, U> createU)
          {
              foreach (T item in items)
              {
                  func(createU(item).SpecialMember);
              }
          
          }
          

          如果您的对象创建比像这样的简单lamba 更复杂,这会变得一团糟

          t =&gt; new U(t)

          【讨论】:

            【解决方案5】:
            public static void dostuff<T, U> (List<T> items)
            {
                foreach (T item in items)
                {
                    U obj = ( U )System.Activator.CreateInstance( typeof( U ), item );
                    func(obj.SpecialMember);
                }
            }
            

            【讨论】:

              猜你喜欢
              • 2016-12-04
              • 2010-12-26
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-09-15
              • 1970-01-01
              • 2016-01-02
              • 2011-02-09
              相关资源
              最近更新 更多