views:

408

answers:

2

How can i make the following code compile?

    Action<MyClass<object, object>> func = x => Console.WriteLine(x.ToString());

    public void Apply<T1, T2>(MyClass<T1, T2> target)
    {
        func.Invoke(target);
    }

I know it doesnt work because a MyClass<T1, T2> isnt a MyClass<object, object>, but what can i do?

Can i make the function generic? or Can i cast target?

either way, how?

If it helps, nothing in the func will ever do anything T1 or T2 specific. I know this assumption could make it fragile, but unit tests should catch any issues.

Edit: I'm avoiding the problem at the moment with loads of empty interfaces that i'd rather do away with!

Thanks

+7  A: 

Well, one option is to write a generic method to return the right type of function:

public void Apply<T1, T2>(MyClass<T1, T2> target)
{
    GetFunc<T1,T2>().Invoke(target);
}

private Action<MyClass<T1,T2>> GetFunc()
{
    return x => Console.WriteLine(x.ToString());
}

Alternatively, if you really want to be able to declare an "I can work with any MyClass" action, I suggest you create a non-generic type MyClass, and make MyClass<T1,T2> derive from it:

public class MyClass
{
    // Put common stuff in here
}

public class MyClass<T1, T2> : MyClass
{
    // Put stuff using T1 and T2 here
}

Then you can just use an Action<MyClass> instead.

Jon Skeet
doh, generic method of course! I hate late night coding! cheers
Andrew Bullock
A: 

In the particular case you have mentioned, you simply need to change Action> to Action, because you are not using any methods particular to 'MyClass'.

If you want to use methods particular to 'MyClass' which do not depend on the generic types, then you should define a base class containing those methods, derive MyClass from it, and use the base type as your argument type for the delegate.

If you want to use methods particular to 'MyClass' which do depend on the generic types, then you should create a delegate with the correct types at call-time.

Strilanc