views:

58

answers:

2

I have the following situation below. This code will throw a compiler error for Test2

The type 'InheritedChild' cannot be used as type parameter 'T' in the generic type or method 'panelGenericIOGrid'. There is no implicit reference conversion from 'InheritedChild' to 'SerializerBase'.

public class SerializerBase<T> 
{  
}
public class DirectChild    : SerializerBase<DirectChild> 
{ 
}
public class InheritedChild : DirectChild 
{ 
}

public  class panelGenericIOGrid<T> : UserControl
   where T: SerializerBase<T>, new()
{
}

...
panelGenericIOGrid<DirectChild> test;
panelGenericIOGrid<InheritedChild> test2;
...

I'm pretty convinced my implentation is funadmentally wrong. I want the following situation, both DirectChild and InheritedChild will give their appropriote type to the SerializerBase constuctor.

How do I get the code to work the way it needs to? Thanks!

Some info on the actual information. SerializerBase has a set of static functions that are implemented to automatically serialize and deserialize themselves based on their type.

DirectChild has a set of strings that are going to be stored on disk and recovered.

Inhertiedchild has all the members of DirectChild plus more.

Basically I'm going to need DirectChild.Serialize(filename), and IndirectChild.Serialize(filename), where the Serialize is a public member of SerializeBase

+2  A: 

The problem is that InheritedChild doesn't implement SerializerBase<InheritedChild>, so it doesn't fulfil the constraints for T in panelGenericIOGrid<T>.

Unfortunately it's not clear that the solution is meant to be as we don't know what you're trying to achieve.

What are the members of SerializerBase<T> in real life? If you could give us more context, it would help us to help you.

Jon Skeet
See edit, I added some info
greggorob64
+1  A: 

It seems to me that you're missing an interface:

public interface ISerializerBase<T> { }
public class SerializerBase<T> : ISerializerBase<T> { } 
public class DirectChild : SerializerBase<DirectChild> { }
public class InheritedChild : DirectChild, ISerializerBase<InheritedChild> { } 
public class panelGenericIOGrid<T> where T: ISerializerBase<T>, new() { } 

I don't know how that will change your design though. It might be that you'll need to reimplement some inherited methods or some interface methods in the InheritedChild.

But, maybe you can do this otherwise:

public interface MSerializable {}
public static class Serializable {
  public static void Serialize(this MSerializable self, string fileName) { 
    // self will refer to the right type, 
    // no need to use generics if all you want is to serialize it ...
  }
}

public class DirectChild : MSerializable { }
public class InheritedChild : DirectChild { } 
public class panelGenericIOGrid<T> where T: MSerializable, new() { } 

Will you do a binary serialization, or will you serialize it to XML?

Jordão
I think the interface is the best way to go. Its going to be some extra code, but since every method in BaseSerializer is static, its not too much extra work. Thanks!
greggorob64
If every method is static, I think you should really go with the mixin approach.... Inheritance doesn't make sense in this case, since you cannot have static methods in an interface and you can't implement interface methods with static ones.
Jordão