I’m attempting to convert Java code to C# but I’m running into a problem when it comes to generic casts.
I have an interface type called Copyable which exposes the following method…
interface Copyable { void copyTo(Copyable target); }
And an AtomicObject type which takes as a parameter a generic type which is restricted to implement the Copyable interface…
class AtomicObject<T> where T : class, Copyable {
public T openRead();
I store AtomicObjects in a Dictionary of object types, but I need to cast the objects back to AtomicObjects to call the “openRead” method that is specific to the AtomicObject class…
foreach (KeyValuePair<object, object> entry in dict)
{
AtomicObject<Copyable> obj = (AtomicObject<Copyable>)entry.Key;
Copyable dest = (Copyable)obj.openRead();//get the destination
}
I have implemented a ListNode type which plays the role of the parameter for the AtomicObject…
class ListNode<T> : Copyable
AtomicObject<ListNode<string>> atomic = new AtomicObject<ListNode<string>>();
I can compile this code, but when I run this program it produces an “InvalidCastException” because the runtime system is unable to convert an object of type…
AtomicObject<ListNode<string>>
to…
AtomicObject<Copyable>.
Yet the ListNode is of type Copyable. Can anyone explain why this cannot be cast correctly? Most importantly, can anyone suggest a fix which does not rely on the Dictionary or the foreach loop having to know what type of parameter a ListNode contains? For example, in Java I could have done…
AtomicObject<?> obj = (AtomicObject<?>)entry.Key;
But this is not possible in C-Sharp.
You won’t be able to do that, because you need covariance, and classes can’t be covariant.
So you’ll have to extract interface from your
AtomicObject:(please note
outin generic declaration), and make yourAtomicObjectclass implement it.After that you should be able to run following code
Also please note that .net standards recommend prefixing interface names with I.