Accessing Implemented Interface Methods in other classes - c#

I'm a C# newbie and am trying to implement an interface. I know I can't put access modiefiers onto interface methods so how do I get access to 'TestValue' in the public static 'Create' method of 'TestClass2' below? the error I get is...
'TestClass1' does not contain a definition for 'TestValue' and no extension method 'TestValue' accepting a first argument of type 'TestClass1' could be found
public interface IParent
{
string TestValue { get; }
}
public class TestClass1 : IParent
{
string IParent.TestValue
{
get { return "hello"; }
}
}
public class TestClass2
{
private string _testValue;
public static TestClass2 Create(TestClass1 input)
{
TestClass2 output = new TestClass2();
output._testValue = input.TestValue;
return output;
}
}

Add the public access modifier in your concrete implementation:
public class TestClass1 : IParent
{
private TestClass1 _testValue;
public string TestValue
{
get { return "hello"; }
}
}
EDIT: as you actually wrote an explicit interface implementation, I recommend you to see the following SO question: C# Interfaces. Implicit implementation versus Explicit implementation

You don't need access modifiers in the interface declaration because the point of an interface is to define the publicly accessible contract for any class implementing the interface. Essentially, although you don't specify an access modifier in the definition, all methods/properties are taken to be public.
This means that when you implement the interface, you're contractually bound to provide a public method/property that matches the interface's method/property signature.
In a nutshell, add the public access modifier to your concrete classes implementations and you'll be sweet.

I tried converting the object into the interface to get the solution like so
public class TestClass2
{
private string _testValue;
public static TestClass2 Create(TestClass1 input)
{
TestClass2 output = new TestClass2();
output._testValue = ((ITestInterface)input).TestValue;
return output;
}
}
This works too but I prefer the simpler solution.

Related

Declare a generic type as property of an interface?

I've a Generic type, which is used to give some meta data on an object to persist:
public class PersistedElementDefinition<T> where T: IPersistedObject{
List<PersistedPropertyDefinition<T>> PropertiesToPersist {get;set;}
}
public class PersistedPropertyDefinition<T> where T: IPersistedObject{
public Func<T, object> PropertyGetter{get;set;}
public Action<T, object> PropertySetter {get;set;}
}
and I've my IPersistedObject which can give his definition
public interface IPersistedObject{
PersistedElementDefinition<TypeOfTheImplementingType> Definition {get;}
}
The idea is that if I implement IPersistedObject I should implement it like this:
public class MyPersistedObject:IPersistedObject{
PersistedElementDefinition<MyPersistedObject> Definition{get;}
}
When I persist my class have the following thing:
I can't do the following:
public interface IPersistedObject<T>{
PersistedElementDefinition<T> Definition {get;}
}
because:
It would allow to have a MyPersistedObject<SomeOtherObject
At some point I receive an object, and I should be able to see if it implements the IPersistedObject and do some custom action with it.
For the 2, here is an example of what kind of issue I'm facing if I've a Generic interface:
public void Persist<T>(T objectToPersist)where T:IPersistedObject{
...
foreach(PersistedPropertyDefinition<T> property in objectToPersist.PropertiesToPersist){
object objectToSerialize = property.ObjectGetter(objectToPersist);
if(objectToSerialize is IPersistedObject<___Don't know how to put something generic here___>){
Persist((IPersistedObject<___Don't know how to put something generic here___>)objectToSerialize);
}
}
...
}
Is there a possibility in c# to declare an interface with a generic property of the implementing type?
You can use the curiously recurring template pattern to lock this down a bit further. It isn't bulletproof, but assuming you're not a masochist, and you don't mind the fact that it is theoretically possible to create nonsensical implementations of the interface that violate the invariants you are trying to guarantee, you can do this:
public interface IPersistedObject<T> where T : IPersistedObject<T>
{
PersistedElementDefinition<T> Definition {get;}
}
public class PersistedElementDefinition<T> where T: IPersistedObject<T>
{
...
}
public class MyPersistedObject : IPersistedObject<MyPersistedObject>
{
// Here, you are forced to implement a PersistedElementDefinition<MyPersistedObject>,
// which presumably is the reason behind this whole song and dance
PersistedDefinition<MyPersistedObject> Definition { get; }
}
The problem with this, as you noticed at the outset, is that you could simply define public class MyPersistedObject : IPersistedObject<MyOtherPersistedObject>, and end up breaking the contract you are trying to cobble together, which in plain words is the following:
A persisted object must have a gettable definition that is a persisted element definition of its own type
The C# type system is simply not equipped to handle this elegantly. My advice is to get out early, change to object or dynamic where possible and learn to live with the loss of certain compile time guarantees.
Assuming you're willing to sacrifice some compile time safety, you could do things like so:
class Program
{
static void Main(string[] args)
{
var mpo = new MyPersistedObject();
var ptp = mpo.Definition.PropertiesToPersist;
}
}
public class PersistedElementDefinition<T> where T : IPersistedObject
{
private readonly List<PersistedPropertyDefinition<T>> _propsToPersist = new List<PersistedPropertyDefinition<T>>();
public List<PersistedPropertyDefinition<T>> PropertiesToPersist
{
get { return _propsToPersist; }
}
}
public class PersistedPropertyDefinition<T> where T : IPersistedObject
{
public Func<T, object> PropertyGetter { get; set; }
public Action<T, object> PropertySetter { get; set; }
}
public interface IPersistedObject
{
dynamic Definition { get; }
}
public class MyPersistedObject : IPersistedObject
{
private readonly PersistedElementDefinition<MyPersistedObject> _definition = new PersistedElementDefinition<MyPersistedObject>();
public dynamic Definition { get { return _definition; } }
}

Defining interface dependency that implements generics

This will be generics 101 for many but below is sample code so I can understand better.
public interface IRecordedItemsProcessor<T>
{
ObservableCollection<RecordedItem> Load(string name);
void Save();
RecordedItem Parse(T itemToParse);
}
public class FileLoadingProcessor : IRecordedItemsProcessor<string>
{
public ObservableCollection<RecordedItem> Load(string name)
{
}
public void Save()
{
}
public RecordedItem Parse(string itemToParse)
{
}
}
public class MyClass
{
public MyClass(IRecordedItemsProcessor<T> processor)
{
}
}
The issue is that MyClass needs a dependency on IRecordedItemsProcessor<T> but will not compile as it does not know what T is. How can this be resolved? Making MyClass implement a seems odd as all it needs to do is call Load/Save
Thanks
First solution is the most simple one: lift generic declaration to class level, like
public class MyClass<T>
{
public MyClass(IRecordedItemsProcessor<T> processor)
{
}
}
Then you could instantiate MyClass as following:
var myClass = new MyClass<string>(new FileLoadingProcessor());
Console.WriteLine (myClass);
Second solution is a removing generic input from constructor and inferring types. Then you don't need to specify generic exactly from call. Class declaration will look like:
public class MyClass
{
public void Process<T>(IRecordedItemsProcessor<T> processor)
{
}
}
And then you can call simply
var my = new MyClass();
my.Process(new FileLoadingProcessor());
The Idea is that you always need to specify class-level generics explicitly, but method level generics can be inferred by the compiler.
Third solutions is to encapsulate creation mechanisms inside MyClassFactory. This is quite flexible, but it might seem a little bit complicated, because descendants of IRecordedItemsProcessor<T> don't define generic at class level, so we should go to implemented interfaces and grab there generic types. And only then we can construct Generic MyClass. Listing is given below:
public class MyClassFactory
{
public MyClass<T> MakeMyClassFor<T>(IRecordedItemsProcessor<T> processor)
{
var processorGenericType = processor.GetType()
.GetInterfaces()
.Single(intr=>intr.Name == "IRecordedItemsProcessor`1")
.GetGenericArguments()[0];
var myClassType = typeof(MyClass<>).MakeGenericType(processorGenericType);
return Activator.CreateInstance(myClassType, processor) as MyClass<T>;
}
}
Now you can create MyClass very simply
var myClassFactory = new MyClassFactory();
var res = myClassFactory.MakeMyClassFor(new FileLoadingProcessor());
Console.WriteLine (res);
All of these three approaches have their pros and cons. Consider taking into account the context, in which you are going to use them.
You could do the following:
Create a new interface IRecordedItemsProcessor (non-generic)
Move Load and Save to this IRecordedItemsProcessor
Make IRecordedItemsProcessor<T> inherit from this IRecordedItemsProcessor
Make MyClass expect IRecordedItemsProcessor in its constructor
This makes it clear that MyClass doesn't care what type the processor might be able to parse, or even that it can parse things at all - it only knows that it can save and load.
You could inherit from a non-generic marker interface, this removes the need to know about T in your class:
public interface IRecordedItemsProcessor
{
}
public interface IRecordedItemsProcessor<T> : IRecordedItemsProcessor
{
ObservableCollection<RecordedItem> Load(string name);
void Save();
RecordedItem Parse(T itemToParse);
}
And then you can use any IRecordedItemsProcessor like:
public class MyClass
{
public MyClass(IRecordedItemsProcessor processor)
{
}
}
The generic type, as written, is being declared on the MyClass constructor which means the generic type must be defined at the MyClass level:
public class MyClass<T>
{
public MyClass(IRecordedItemsProcessor<T> processor)
{
}
}
However, if the generic type was declared at a method level, it would only have to be defined at the method level:
public class MyClass
{
public void MyMethod<T>( IRecordedItemsProcessor<T> processor )
{
}
}
EDIT
Based on your comment:
I want a class that can call the Load/Save methods but not be worried
that T is.
Then you'll need 2 interfaces: 1 for the load/save and then one with the parsing. In this case, you could use inheritance:
public interface IRecordedItems
{
ObservableCollection<RecordedItem> Load( string name );
void Save();
}
public interface IRecordedItemsProcessor<T> : IRecordedItems
{
RecordedItem Parse( T itemToParse );
}
public class MyClass : IRecordedItems
{
#region Implementation of IRecordedItems
public ObservableCollection<RecordedItem> Load( string name )
{
throw new NotImplementedException();
}
public void Save()
{
throw new NotImplementedException();
}
#endregion
}
EDIT 2
Based on your gist example, the type dependency could be moved off of the interface and directly into the interface method:
public class RecordedItem {}
public interface IRecordedItemsProcessor
{
ObservableCollection<RecordedItem> Load( string name );
void Save();
RecordedItem Parse<T>( T itemToParse );
}
public class MyClass
{
private readonly IRecordedItemsProcessor _processor;
public MyClass( IRecordedItemsProcessor processor )
{
_processor = processor;
processor.Parse<string>( "foo" );
processor.Parse<int>( 10 );
processor.Parse<RecordedItem>( new RecordedItem() );
}
}

How can I access a static property of type T in a generic class?

I am trying to accomplish the following scenario that the generic TestClassWrapper will be able to access static properties of classes it is made of (they will all derive from TestClass). Something like:
public class TestClass
{
public static int x = 5;
}
public class TestClassWrapper<T> where T : TestClass
{
public int test()
{
return T.x;
}
}
Gives the error:
'T' is a 'type parameter', which is not valid in the given context.
Any suggestions?
You can't, basically, at least not without reflection.
One option is to put a delegate in your constructor so that whoever creates an instance can specify how to get at it:
var wrapper = new TestClassWrapper<TestClass>(() => TestClass.x);
You could do it with reflection if necessary:
public class TestClassWrapper<T> where T : TestClass
{
private static readonly FieldInfo field = typeof(T).GetField("x");
public int test()
{
return (int) field.GetValue(null);
}
}
(Add appropriate binding flags if necessary.)
This isn't great, but at least you only need to look up the field once...
Surely you can just write this:
public int test()
{
return TestClass.x;
}
Even in a nontrivial example, you can't override a static field so will always call it from your known base class.
Why not just return TestClass.x?
Generics do not support anything related to static members, so that won't work. My advice would be: don't make it static. Assuming the field genuinely relates to the specific T, you could also use reflection:
return (int) typeof(T).GetField("x").GetValue(null);
but I don't recommend it.
Another solution is to simply not make it static, and work with the new() constraint on T to instantiate the object. Then you can work with an interface, and the wrapper can get the property out of any class that implements that interface:
public interface XExposer
{
Int32 X { get; }
}
public class TestClass : XExposer
{
public Int32 X { get { return 5;} }
}
public class XExposerWrapper<T> where T : XExposer, new()
{
public Int32 X
{
get { return new T().X; }
}
}
In fact, you can change that to public static Int32 X on the TestClassWrapper and simply get it out as Int32 fetchedX = XExposerWrapper<TestClass>.X;
Though since whatever code calls this will have to give the parameter T those same constraints, the wrapper class is pretty unnecessary at this point, since that calling code itself could also just execute new T().X and not bother with the wrapper.
Still, there are some interesting inheritance models where this kind of structure is useful. For example, an abstract class SuperClass<T> where T : SuperClass<T>, new() can both instantiate and return type T in its static functions, effectively allowing you to make inheritable static functions that adapt to the child classes (which would then need to be defined as class ChildClass : SuperClass<ChildClass>). By defining protected abstract functions / properties on the superclass, you can make functions that apply the same logic on any inherited object, but customized to that subclass according to its implementations of these abstracts. I use this for database classes where the table name and fetch query are implemented by the child class. Since the properties are protected, they are never exposed, either.
For example, on database classes, where the actual fetching logic is put in one central abstract class:
public abstract class DbClass<T> where T : DbClass<T>, new()
{
protected abstract String FetchQuery { get; }
protected abstract void Initialize(DatabaseRecord row);
public static T FetchObject(DatabaseSession dbSession, Int32 key)
{
T obj = new T();
DatabaseRecord record = dbSession.RetrieveRecord(obj.FetchQuery, key);
obj.Initialize(record);
return obj;
}
}
And the implementation:
public class User : DbClass<User>
{
public Int32 Key { get; private set;}
public String FirstName { get; set;}
public String LastName { get; set;}
protected override String FetchQuery
{ get { return "SELECT * FROM USER WHERE KEY = {0}";} }
protected override void Initialize(DatabaseRecord row)
{
this.Key = DbTools.SafeGetInt(row.GetField("KEY"));
this.FirstName = DbTools.SafeGetString(row.GetField("FIRST_NAME"));
this.LastName = DbTools.SafeGetString(row.GetField("LAST_NAME"));
}
}
This can be used as:
User usr = User.FetchObject(dbSession, userKey);
This is a rather simplified example, but as you see, this system allows a static function from the parent class to be called on the child class, to return an object of the child class.
T is a type, not parameter or variable so you cannot pick any value from any members. Here is a sample code.
public class UrlRecordService
{
public virtual void SaveSlug<T>(T entity) where T : ISlugSupport
{
if (entity == null)
throw new ArgumentNullException("entity");
int entityId = entity.Id;
string entityName = typeof(T).Name;
}
}
public interface ISlugSupport
{
int Id { get; set; }
}
cjk and Haris Hasan have the most-correct answers to the question as asked. However in this comment the OP implies that he is after something else not quite possible in C#: a way to define a contract for a static member in a derived class.
There isn't a way to strictly define this, but it is possible to set up a pattern that may be implied by a base class (or interface); e.g.:
public class TestClass
{
private static int x;
public virtual int StaticX => x;
}
or if not intended to be used directly
public abstract class AbstractTestClass
{
public abstract int StaticX {get;}
}
or (my preference in this contrived example)
public interface ITest
{
int StaticX {get;}
}
Elsewhere, this pattern of a StaticXxx member may be (loosely) associated with implementations that should back the member with static fields (as in TestClass above).
What's kind of fun is that this can be (re)exposed as static by the generic wrapper, because generic statics are isolated to each type used.
public class TestClassWrapper<T> where T : ITest, new()
{
private readonly static T testInstance = new T();
public static int test() => testInstance.x;
}
This uses a new() condition, but an associated static, generic factory pattern for creating ITest (or TestClass or AbstractTestClass) instances may also be used.
However this may not be feasible if you can't have long-lived instances of the class.
In this situation you assume that T is a subclass of TestClass. Subclasses of TestClass will not have the static int x.

Can't define static abstract string property

I've run into an interesting problem and am looking for some suggestions on how best to handle this...
I have an abstract class that contains a static method that accepts a static string that I would like to define as an abstract property. Problem is that C# doesn't doesn't support the following (see the ConfigurationSectionName and Current properties):
public abstract class ProviderConfiguration : ConfigurationSection
{
private const string _defaultProviderPropertyName = "defaultProvider";
private const string _providersPropertyName = "providers";
protected static string ConfigurationSectionName { get; }
public static Configuration Current
{
get { return Configuration)ConfigurationManager.GetSection(ConfigurationSectionName); }
}
}
I suppose one way to handle this would be to make ConfigurationSectionName NOT abstract and then create a new definition of ConfigurationSectionName in the derived classes, but that feels pretty hackish. Any suggestions would be most welcome.
Gratias!!!
Static members do not have polymorphism, so they can't be abstract. :(
If that's what you need, consider making a Singleton object, and reading the property off that object.
Just use new to override a static method in a derived class. Nothing that makes new a bad thing to do for virtual methods and properties applies since the type name must be supplied:
public class BaseClass
{
public static int Max { get { return 0; } }
}
public class InteriorClass : BaseClass
{
}
public class DerivedClass : InteriorClass
{
public new static int Max { get { return BaseClass.Max + 1; } }
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("BaseClass.Max = {0}", BaseClass.Max);
Console.WriteLine("InteriorClass.Max = {0}", InteriorClass.Max);
Console.WriteLine("DerivedClass.Max = {0}", DerivedClass.Max);
Console.ReadKey();
}
}
Ok, this is not exactly to create an static abstract property, but you can achieve the desired effect.
You can get this by using generics:
public abstract class MyAbstractClass<T>
{
public static string MyAbstractString{ get; set; }
public static string GetMyAbstracString()
{
return "Who are you? " + MyAbstractString;
}
}
public class MyDerivedClass : MyAbstractClass<MyDerivedClass>
{
public static new string MyAbstractString
{
get
{
return MyAbstractClass<MyDerivedClass>.MyAbstractString;
}
set
{
MyAbstractClass<MyDerivedClass>.MyAbstractString = value;
}
}
}
public class MyDerivedClassTwo : MyAbstractClass<MyDerivedClassTwo>
{
public static new string MyAbstractString
{
get
{
return MyAbstractClass<MyDerivedClassTwo>.MyAbstractString;
}
set
{
MyAbstractClass<MyDerivedClassTwo>.MyAbstractString = value;
}
}
}
public class Test
{
public void Test()
{
MyDerivedClass.MyAbstractString = "I am MyDerivedClass";
MyDerivedClassTwo.MyAbstractString = "I am MyDerivedClassTwo";
Debug.Print(MyDerivedClass.GetMyAbstracString());
Debug.Print(MyDerivedClassTwo.GetMyAbstracString());
}
}
So, calling the test class you will get:
"Who are you? I am MyDerivedClass"
"Who are you? I am MyDerivedClassTwo"
So, you have an static method in an abstract class but the abstract value is different for each derived class, nice :D
Ok, so, what's going here? The trick is the generic tag, the compiler is generating a different abstract class for each derived type.
As I said it's not an abstract property, but you get all benefits of abstract static properties, which are programming static functions on your abstract class but using different static parameters per type.
Elsewhere on this page, #Gusman proposes the nice solution distilled here:
abstract class AbstractBase { };
abstract class AbstractBase<T> : AbstractBase
{
public static String AbstractStaticProp { get; set; }
};
class Derived1 : AbstractBase<Derived1>
{
public static new String AbstractStaticProp
{
get => AbstractBase<Derived1>.AbstractStaticProp;
set => AbstractBase<Derived1>.AbstractStaticProp = value;
}
};
class Derived2 : AbstractBase<Derived2>
{
public static new String AbstractStaticProp
{
get => AbstractBase<Derived2>.AbstractStaticProp;
set => AbstractBase<Derived2>.AbstractStaticProp = value;
}
};
Moving the static property from a non-generic to generic class means there is no longer necessarily a single global instance. There will be a unique AbstractStaticProp for each distinct type T, so the idea is that specifying the type of the derived class(es) themselves for T guarantees each of them generates a unique static for themselves. There are a few hazards to note with this, however.
If for some reason it is not acceptable for AbstractBaseClass to be generic, then you've only moved the problem elsewhere (albeit more clearly distilled), because you still have to figure out how to statically call from AbstractBase to AbstractBase<T>.
Mainly, there is nothing to enforce or require that any/every given derived class actually does "implement" the (psudo-) "overridden" static property;
Related to this, since there is no compiler (polymorphic) unification going on here, correct signatures (method name, parameter arity, typing, etc.) for the "overridden" methods aren't enforced either.
Although the generic parameter is intended to be "TSelf" of a derived class, in reality T is unconstrained and essentially arbitrary. This opportunizes two new classes of bug: if base class specification Y : AbstractBase<...> mistakenly references a different AbstractBase‑der­ived class X, the values of the "abstract static property" for X and Y will be incorrectly conflated -- and/or -- any usage call-site AbstractBase<T>.AbstractStaticProp with a mistaken type argument (such as DateTime) will spontaneously--and silently--demand a fresh new "instance" of the static property.
The last bullet point can be somewhat mitigated by adding a constraint on the generic base:
/// v---- constraint added
abstract class AbstractBase<TSelf> where TSelf : AbstractBase<TSelf>
{
public static String AbstractStaticProp { get; set; }
};
This eliminates the possibility of class Derived2 : AbstractBase<DateTime> { /*...*/ }, but not the error class Derived2 : AbstractBase<Derived1> { /*...*/ }. This is due to a recurring conundrum that foils all attempts at constraining a generic type to some exact branch of the type-inheritance hierarchy:
The "TSelf problem"
Generic constraints are always at the mercy of the type arguments that are supplied, which seems to entail that it's impossible to construct a generic constraint that guarantees that some particular TArg within its scope refers to a type that is derived from itself, that is, the immediate type being defined.
The error in this case is an example of this; while the constraint on AbstractBase<TSelf> rules out incompatible disjoint types, it can't rule out the unintended usage Derived2 : AbstractBase​<Derived1>. As far as AbstractBase is concerned, the supplied type argument Derived1 satisfies its constraint just fine, regardless of which of its subtypes is deriving itself (im-)properly. I've tried everything, for years, to solve TSelf; if anyone knows a trick I've missed, please let me know!
Anyway, there are still a couple other points to mention. For example, unless you can immediately spot the problem in the following code, you'll have to agree that it's a bit dangerous:
public static new String AbstractStaticProp
{
get => AbstractBase<Derived1>.AbstractStaticProp;
set => AbstractBase<Derived2>.AbstractStaticProp = value;
}
Ideally, you want to get the compiler to do what it's meant to, namely, understand that all AbstractStaticProp property instances are related and thus somehow enforce their unification. Since that's not possible for static methods, the only remaining option is to eliminate the extra versions, effectively reducing the problem to the unification of just one, a vacuous operation, obviously.
It turns out that the original code is being too elaborate; the generic-base class approach wants to collapse on the simpler solution all by itself without having to explicitly request it, such as those new-marked properties seem to be doing with the qualification in AbstractBase<Derived1>.​AbstractStaticProp".
You can already refer to each respective independent copy of the static property by qualifying with the derived class name instead (in fact, #Gusman's test harness shows this), so the end result is that the property declarations in the derived class aren't necessary at all. Without further ado, here is the complete simplified version:
abstract class AbstractBase { };
abstract class AbstractBase<TSelf> : AbstractBase
where TSelf : AbstractBase<TSelf>
{
public static String AbstractStaticProp { get; set; }
};
class Derived1 : AbstractBase<Derived1> { };
class Derived2 : AbstractBase<Derived2> { };
This works identically to the code at the top. The test harness gives the same results as before.
static void Test()
{
Derived1.AbstractStaticProp = "I am Derived1";
Derived2.AbstractStaticProp = "I am Derived2";
Debug.Print(Derived1.AbstractStaticProp); // --> I am Derived1
Debug.Print(Derived2.AbstractStaticProp); // --> I am Derived2
}
What you're trying to do is impossible, as others have mentioned.
I'd try something like this
public abstract class ProviderConfiguration : ConfigurationSection
{
public string ConfigurationSectionName { get; set; }
public static ProviderConfiguration Provider { get; set; }
public static Configuration Current
{
get { return (Configuration)ConfigurationManager.GetSection(Provider.ConfigurationSectionName); }
}
}
Then in practice:
public void DoStuff()
{
var provider = new DerivedProviderConfiguration();
ProviderConfiguration.Provider = provider;
}

.net generic constraints and object inheritance compiling issue

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
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.
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?

Categories