泛型:如何从两个类之一派生出来?

时间:2010-03-18 20:49:51

标签: c# generics

我有以下c#类:

class A : Object
{
   foo() {}
}

class B : Object
{
   foo() {}
}

我想写一个适用于两者的通用方法:

void bar<T>(T t)
{
  t.foo();
}

这不会编译抱怨foo()不是T的成员。我可以为T派生一个约束来从其中一个类派生:

void bar<T>(T t) where T : A

但我怎么能同时拥有它呢?

6 个答案:

答案 0 :(得分:5)

简单地说你不能。但是有几种方法可以解决这个问题。

最常见的是使用界面。说IMyType

interface IMyType { void foo(); }
class A : IMyType ...
class B : IMyType ...

void bar<T>(T t) where T : IMyType {
  t.Foo();
}

虽然需要对解决方案进行元数据更改,但这有点重要。更便宜的方法是提供一个调用适当函数的lambda表达式。

void bar<T>(T t, Action doFoo) {
  ...
  doFoo();
}

var v1 = new A();
var v2 = new B();
bar(v1, () => v1.Foo());
bar(v2, () => v2.Foo());

答案 1 :(得分:2)

您应该定义一个界面:

interface IFoo
{
   void foo();
}


class A : IFoo
{
   public void foo() {}
}

class B : IFoo
{
   public void foo() {}
}

你的通用方法:

void bar<T>(T t) where T:IFoo
{
  t.foo();
}

答案 2 :(得分:1)

定义包含 foo 方法的接口,并使用A&amp;类; B实现那个接口。然后在泛型类型上定义接口约束。

答案 3 :(得分:1)

除非你:

,否则你不能这样做
  1. 从基类派生
  2. 从界面导出
  3. 我更喜欢界面,因为它不会强迫你分享行为:

    public interface IHasFoo
    {
        void foo();
    }
    
    public class B : IHasFoo // you don't need to explicitly subclass object
    {
        public void foo()
        {
        }
    }
    
    public class A : IHasFoo // you don't need to explicitly subclass object
    {
        public void foo()
        {
        }
    }
    
    void bar<T>(T t) where T : IHasFoo
    {
        t.foo(); // works
    }
    

答案 4 :(得分:1)

这可以在.NET 4.0中使用dynamic

void bar(dynamic t)
{
  t.foo();
}

答案 5 :(得分:0)

你为什么要这个通用?只是重载方法。

 void bar(A a) { a.Foo(); }
 void bar(B b) { b.Foo(); }

泛型是存在的,因此您可以制作潜在的无限bar()方法。