Error casting delegate in non-generic class
-
I started with a generic class which has a delegate. The consumer of this class could set a method callback which requires invoking but they may not also. To address this I check if the callback is ISyncronizeInvoke, if it is then I will call BeginInvoke. This works great as long as the class is a generic class:
public class TestClassGeneric<T>
{
public delegate void GetMe();
private GetMe _call;public TestClassGeneric(GetMe theCall) { \_call = theCall; System.ComponentModel.ISynchronizeInvoke si = \_call as System.ComponentModel.ISynchronizeInvoke; }
}
Since I don't need the class to be generic I want to make it just a standard class:
public class TestClassGeneric
{
public delegate void GetMe();
private GetMe _call;public TestClassGeneric(GetMe theCall) { \_call = theCall; System.ComponentModel.ISynchronizeInvoke si = \_call as System.ComponentModel.ISynchronizeInvoke; }
}
But then I get a compile error: "Cannot convert type 'PureLibrary.TestClassGeneric.GetMe' to 'System.ComponentModel.ISynchronizeInvoke' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion" Could someone please help me understand why this makes such a difference? Since the delegate signature didn't change it seems the casting would be the same. Thank you.
- Kalvin
-
I started with a generic class which has a delegate. The consumer of this class could set a method callback which requires invoking but they may not also. To address this I check if the callback is ISyncronizeInvoke, if it is then I will call BeginInvoke. This works great as long as the class is a generic class:
public class TestClassGeneric<T>
{
public delegate void GetMe();
private GetMe _call;public TestClassGeneric(GetMe theCall) { \_call = theCall; System.ComponentModel.ISynchronizeInvoke si = \_call as System.ComponentModel.ISynchronizeInvoke; }
}
Since I don't need the class to be generic I want to make it just a standard class:
public class TestClassGeneric
{
public delegate void GetMe();
private GetMe _call;public TestClassGeneric(GetMe theCall) { \_call = theCall; System.ComponentModel.ISynchronizeInvoke si = \_call as System.ComponentModel.ISynchronizeInvoke; }
}
But then I get a compile error: "Cannot convert type 'PureLibrary.TestClassGeneric.GetMe' to 'System.ComponentModel.ISynchronizeInvoke' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion" Could someone please help me understand why this makes such a difference? Since the delegate signature didn't change it seems the casting would be the same. Thank you.
- Kalvin
Very interesting question. I have an idea why this might happen. 1. Generic class:
TestClassGeneric<T>
. GetMe is unknown during the compile-time, because it's defined inside a generic class and the typeparamT
may vary at run-time (actually,GetMe
in this case will beTestClassGeneric<T>.GetMe
). 2. Non-ceneric class:TestClassGeneric
. GetMe is non-generic too, and the compiler may "guess" that the conversion will fail. Some facts:System.Action
is built-in delegate, it's defined aspublic delegate void Action()
If you replaceGetMe
withAction
, you will get an error in two cases.- At the run-time, the conversion will fail, and
si
will benull
. - If you replace
si = _call as System.ComponentModel.ISynchronizeInvoke;
withsi = (System.ComponentModel.ISynchronizeInvoke)_call;
, both generic and non-generic will fail.
Thanks! I'll remember this - it's a very good task and needs understanding of generics in .NET Framework :thumbsup:
Die Energie der Welt ist konstant. Die Entropie der Welt strebt einem Maximum zu.
modified on Wednesday, June 9, 2010 2:13 PM