By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,286 Members | 2,364 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,286 IT Pros & Developers. It's quick & easy.

Generic method: cannot convert 'T' to ...

P: n/a
class A {}

class B {}

interface MyInterface
{
void method(A a);
void method(B b);
}

class Foo
{
public Foo(MyInterface myInterface)
{
_myInterface = myInterface;
}

private bool Process<T>(T t)
{
if (t == null) return false;
_myInterface.method(t);

// The previous line generates 2 errors
// Error 1: The best overload method match for 'MyInterface.method(A)'
// has some invalid argument
// Error 2: cannot convert from 'T' to 'A'

return true;
}

// I would like to avoid to implement the core of Process
// for each type as follows:
// private bool Process(A a)
// {
// if (a == null) return false;
// _myInterface.method(a);
// return true;
// }
// private bool Process(B b)
// {
// if (b == null) return false;
// _myInterface.method(a);
// return true;
// }

public void Process(object o)
{
if (Process(o as A)) return;
if (Process(o as B)) return;
throw new Exception();
}

private MyInterface _myInterface;
}

I would like to avoid to implement Process for each type. How can I do
this in C# ?

Thanx.

Jun 26 '06 #1
Share this Question
Share on Google+
2 Replies


P: n/a
Christophe,

It is not possible to pull this off with generics.

The reason why you get this error message is that the compiler doesn't know
at the time of compilation what the real type of the object is.
In your case because it doesn't know the type of the object the compiler
cannot verify that the parameter can be converted to A type in order to call
the method. This can be overcome using constraints.
Unfortunately there might be only one type constriant, but we need to have
two in our case. You can rework the sample a little bit by marking the
classes with marker interfaces. The reason for doing this is because we may
have more than one interface constraint

interface IA{}
class A:IA { }

interface IB{}
class B:IB { }

interface MyInterface
{
void method(IA a);
void method(IB b);
}

class Foo
{
MyInterface _myInterface;
public Foo(MyInterface myInterface)
{
_myInterface = myInterface;
}

private bool Process<T>(T t) where T:IA,IB
{
if (t == null) return false;
_myInterface.method(t);

// The previous line generates 2 errors
// Error 1: The best overload method match for 'MyInterface.method(A)'
// has some invalid argument
// Error 2: cannot convert from 'T' to 'A'

return true;
}
}
Now if you try to compile this code you'll get antoher error, which I
believe is more easier to understand:
Error 2 The call is ambiguous between the following methods or properties:
'ConsoleApplication1.Program.MyInterface.method(Co nsoleApplication1.Program.IA)'
and
'ConsoleApplication1.Program.MyInterface.method(Co nsoleApplication1.Program.IB)'
D:\Projects\Delme2005\WindowsApplication1\ConsoleA pplication1\Program.cs 50
5 ConsoleApplication1

And this is why you scenario cannot be implemented. The compiler doesn't
know the real type of the paramter, but it knows that it implements certain
interfaces, now when it comes to calling the methods it cannot decide which
one to call, both are possible. This sample by the way is not correct again
because neither B nor A implemets both interfaces, but it demonstrates what
error you'll eventually get.

Once again:
1. Without using constraints the effective base class for *t* is Object and
there is no conversion from Object to neither A or B.
2. There is no constraints that could help you in this case.
3. Even if there were such constraints the compiler eventually will stumble
with choosing the correct method overload to call.
These are my two cents. I hope other guys in the group will throw their
opinions on the problem.
--
HTH
Stoitcho Goutsev (100)
"Christophe" <ch******@swing.be> wrote in message
news:11**********************@y41g2000cwy.googlegr oups.com...
class A {}

class B {}

interface MyInterface
{
void method(A a);
void method(B b);
}

class Foo
{
public Foo(MyInterface myInterface)
{
_myInterface = myInterface;
}

private bool Process<T>(T t)
{
if (t == null) return false;
_myInterface.method(t);

// The previous line generates 2 errors
// Error 1: The best overload method match for 'MyInterface.method(A)'
// has some invalid argument
// Error 2: cannot convert from 'T' to 'A'

return true;
}

// I would like to avoid to implement the core of Process
// for each type as follows:
// private bool Process(A a)
// {
// if (a == null) return false;
// _myInterface.method(a);
// return true;
// }
// private bool Process(B b)
// {
// if (b == null) return false;
// _myInterface.method(a);
// return true;
// }

public void Process(object o)
{
if (Process(o as A)) return;
if (Process(o as B)) return;
throw new Exception();
}

private MyInterface _myInterface;
}

I would like to avoid to implement Process for each type. How can I do
this in C# ?

Thanx.

Jun 26 '06 #2

P: n/a
Thanx a lot. Good contribution :-)

Christophe

Jun 27 '06 #3

This discussion thread is closed

Replies have been disabled for this discussion.