2010-03-18 74 views
2

我有以下的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 

但我怎麼能爲它們都?

+0

從問題中轉移得很少。 如果這是用例,它是否有意義有一個通用的方法? 爲什麼不簡單地將接口'IFoo'實現爲A和B,並將該方法聲明爲 void bar(IFoo f){ f.foo(); } – Biswanath 2010-03-18 20:58:50

回答

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

定義一個接口,該接口包含foo方法,並且具有類A & B實現該接口。然後在你的泛型類型上定義一個接口約束。

1

你不能這樣做,除非你:

  1. 從一個接口基類
  2. 導出導出

我喜歡的界面,因爲它不強制你分享行爲:

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 
} 
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(); 
} 
1

這可能是在.NET 4.0中使用dynamic

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

你爲什麼使這個通用?只需重載該方法。

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

泛型在那裏,所以你可以使潛在的無限bar()方法。

相關問題