Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casting an object to two interfaces at the same time, to call a generic method

I want to call a generic method that constrains the input type T to implement two interfaces:

interface IA { }
interface IB { }
void foo<T>(T t) where T : IA, IB { }

How can I fix the last line of

void bar(object obj)
{
    if (obj is IA && obj is IB)
    {
        foo((IA && IB)obj);
    }
}

?

Reflection probably allows to do the call, but I would like to stay within the language.

like image 960
Bruno Martinez Avatar asked May 24 '10 17:05

Bruno Martinez


3 Answers

It seems that you're misunderstanding how generics work: when calling a method which has a generic parameter T, T must be statically known at compile time. Although the compiler can sometimes infer it (and you therefore don't always need to explicitly write it down), some T must be supplied when calling the method. In your case, all you know is that obj is an IA and an IB, but this doesn't give you enough information to call foo<T>, since you have no idea what T ought to be. You'll either have to use reflection, cast to a specific type which implements both IA and IB, or make a more dramatic design change.

like image 166
kvb Avatar answered Nov 06 '22 23:11

kvb


Does the C# 4.0 dynamic keyword get you out of jail (mostly) free? After all - you are already doing the type checking.

interface IC : IA, IB { }

void bar(object obj)
{
  if (obj is IA && obj is IB)
  {
    IC x = (dynamic)obj;
    foo(x);
  }
}

Does that break if foo tries to cast the parameter to T? I don't know.

like image 4
Amy B Avatar answered Nov 07 '22 00:11

Amy B


I agree with the other responders that you probably have a design issue if you need to do this, but you could accomplish it with a proxy object that implements both interfaces and delegates the calls to the two casted interface instances of the unknown Object. Now, when you call this method, you can construct the proxy for any type that supports both interfaces.

like image 4
Dan Bryant Avatar answered Nov 07 '22 00:11

Dan Bryant