Reputation: 24426
I have the following c# classes:
class A : Object
{
foo() {}
}
class B : Object
{
foo() {}
}
I want to write a generic method that applies to both:
void bar<T>(T t)
{
t.foo();
}
this does not compile complaining the foo() is not a member of T. I can add a constraint for T to derive from one of the classes:
void bar<T>(T t) where T : A
but how can I have it for both?
Upvotes: 2
Views: 316
Reputation: 2265
Why are you making this generic? Just overload the method.
void bar(A a) { a.Foo(); }
void bar(B b) { b.Foo(); }
Generics are there so that you can make potentially infinite bar()
methods.
Upvotes: 0
Reputation: 5242
This is possible in .NET 4.0 using dynamic
.
void bar(dynamic t)
{
t.foo();
}
Upvotes: 1
Reputation: 171864
You should define an interface:
interface IFoo
{
void foo();
}
class A : IFoo
{
public void foo() {}
}
class B : IFoo
{
public void foo() {}
}
And your generic method:
void bar<T>(T t) where T:IFoo
{
t.foo();
}
Upvotes: 2
Reputation: 28426
You can't do that unless you:
I prefer the interface because it doesn't force you to share behavior:
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
}
Upvotes: 1
Reputation: 755229
Simply put you can't. There are a couple of approaches to work around this problem though.
The most common is to use an interface. Say IMyType
interface IMyType { void foo(); }
class A : IMyType ...
class B : IMyType ...
void bar<T>(T t) where T : IMyType {
t.Foo();
}
This is a bit heavy weight though is it requires a metadata change for a solution. A cheaper approach is to provide a lambda expression which calls the appropriate function.
void bar<T>(T t, Action doFoo) {
...
doFoo();
}
var v1 = new A();
var v2 = new B();
bar(v1, () => v1.Foo());
bar(v2, () => v2.Foo());
Upvotes: 5
Reputation: 3428
Define an interface that contains the foo method, and have classes A & B implement that interface. Then define an interface constraint on your generic type.
Upvotes: 1