Making arrays to hold polymorphed generics - c#

The question I asked here brought me thus far on my project:
abstract class Base<T> where T:ContentBase
{
//base functionality
}
class Foo : Base<FooContent>
{
//overrides
}
class Bar : Base<BarContent>
{
//overrides
}
Is there a way to make an array or List that can hold both Foo and Bar objects or would I have to look at making a record or something?
Thanks in advance.

You could add a non-generic abstract class Base that Base<T> inherits from, and then make a List<Base>. So extending your code might look something like this:
abstract class Base
{
//base functionality (non-generic)
}
abstract class Base<T> : Base where T : ContentBase
{
//base functionality acting on T
}
class Foo : Base<FooContent>
{
//overrides
}
class Bar : Base<BarContent>
{
//overrides
}

I'm assuming from the example code that FooContent and BarContent derive from ContentBase. I'm also assuming that the code follows the SOLID principles and especially LSP.
A generic collection could be defined in terms of ContentBase.
var collection = new List<ContentBase>();
The collection can hold instances of FooContent, BarContent, and ContentBase.
But apparently that is a need to hold the ContentBase and derived types within another type. (It is not clear from the question why this is needed.)
public class ContentAdaptor
{
public ContentAdaptor(ContentBase content)
{
_content = content;
}
...
private ContentBase _content;
}
The ContentAdaptor type holds a reference to an instance of ContentBase. The instance could be of a derived type.
A collection of ContentAdaptor:
var collection = new List<ContentAdaptor>();
I have a suspicion that FooContent and BarContent may violate LSP and are not substitutable for each other. Is that the case? If you have types that are fundamentally different but you want to process the objects in a polymorphic way, consider an interface.
public interface IProcess
{
bool Process();
}
Here ContentBase implements the IProcess interface. But note that a SomeOtherContent type that doesn't derive from ContentBase can also implement the IProcess interface.
public class ContentBase : IProcess
{
// Implement the IProcess interface.
}
A collection of IProcess:
var collection = new List<IProcess>();
The Process method can be called on each object in the collection. Each type provides its own implementation of the Process method.

Related

Can I define a method of interface type inside a class

abstract class someClass
{
public abstract IProduct SomeMethod();
}
public interface IProduct
{
string Operation();
}
I have seen the above code having a method define inside abstract class with type interface, I wonder the use of this. Can anybody explain?
You are asking about this:
abstract class SomeBaseClass
{
public abstract IProduct SomeMethod();
}
In this case, IProduct may represent any object that implements the interface, and the method SomeMethod() is guaranteed to return an object of some class implementing IProduct.
This has many uses where the design dictates that all classes that derive from SomeBaseClass be able to create objects that adhere to the IProduct interface.
In c# interfaces are like contracts that guarantee specific behavior and properties.
This means that regardless of the actual implementation, code like this below is valid
SomeBaseClass f = ...
IProduct p = f.SomeMethod();
string op = p.Operation();

C# generics: what's the point of the "X<T> where T: X<T>" generic type constraint?

Reading a book: NHibernate 3: Beginners guide I found a fragment that made me curious:
Time for action – Creating a base entity
(...)
Add a new class to the folder Domain of the project and call it Entity. Make the class abstract and generic in T. Your code should look similar to the following code snippet:
using System;
namespace OrderingSystem.Domain
{
public abstract class Entity<T> where T : Entity<T>
{ }
}
My question is: what is the point of the fragment where T : Entity<T>?
I understand that the where section can be applied to add constraints on the type T, but the code above looks like it would be never possible to instantiate such class (if it weren't abstract anyway).
This is most likely meant to provide additional type safety for methods which return (or take in) an instance of the more derived type, saving the callers from having to cast the result to the more derived type.
abstract class Cloneable<T> where T : Cloneable<T>
{
public abstract T Clone();
}
sealed class MyCloneable : Cloneable<MyCloneable>
{
public override MyCloneable Clone()
{
return new MyCloneable();
}
}
MyCloneable instance = new MyCloneable();
MyCloneable clone = instance.Clone();
EDIT
As per #siride's comment, this is known as the curiously recurring template pattern. Eric Lippert has written a great article on its application in C#:
https://blogs.msdn.microsoft.com/ericlippert/2011/02/03/curiouser-and-curiouser/
P.S. And just to illustrate what the above example would look like if you were to take away the generic constraint:
abstract class Cloneable
{
public abstract Cloneable Clone();
}
sealed class MyCloneable : Cloneable
{
public override Cloneable Clone()
{
return new MyCloneable();
}
}
MyCloneable instance = new MyCloneable();
MyCloneable clone = (MyCloneable)instance.Clone(); // Note the cast.

c# runtime polymorphism with abstract base class

I am trying to clean up an existing code base, and am having trouble with using a generic reference name to the different derived classes of an abstract class.
For instance:
public abstract class Base<T> : Utilities.CommonRequiredObject
{
protected List<T> RawContents = new List<T>();
.
.
public abstract void LoadContents(List<T> Contents); // Each Class needs to load and process differently
protected List<T> Contents;
public virtual void DoSomething() // Default here for common use. Defined in Each class for its specifics (if needed)
{
...
}
public abstract List<T> FunctionToGetContents();
}
public class FOO : Base<string>
{
public override void DoSomething() ...
public override List<string> FunctionToGetContents() ...
}
public class BAR : Base<byte>
{
public override void DoSomething() ...
public override List<byte> FunctionToGetContents() ...
}
Main Logic to try to use common variable. I want to create a new class to use, but want to use it then in a runtime polymorphic way. As the classes have the common functionality, and have overrides where needed, I want to be able to create an instance, and then use it:
IE: Base<T> ObjectToUse;
This way, I can simply refer to the ObjectToUse in the following code and call common methods. As I inherited some common routines from another base class, I am not sure if I can use an interface or not.
if(variable)
{
FOO ObjectToUse = new FOO();
}
else
{
BAR ObjectToUse = new BAR();
}
ObjectToUse.LoadContents(ObjectToUse.FunctionToGetContents());
ObjectToUse.DoSomething();
...
Edit:
Based on the comments I received quickly (thanks again everyone) would it be better than to remove the Generic (Base<T>) and have the classes all of type Base(), then I could define the ObjectToUse simply as Base ObjectToUse; I believe.
This cannot be done.
By utilizing a reference that requires a generic type parameter, you must give it one. You could utilize dynamic here so that the type is run-time evaluated, but thats the best you will get.
Even utilizing something like a template method pattern, you would need to specify the generic type argument. If you just want the DoSomething method for this, it would need to be promoted to a higher base class (or an interface) so you could hold a reference to that type, and call that (non-generic) function.
To your comment, the solution I would take is this; refactor the common code into a template method pattern within the base class. Then have the "triggering" function be a non-generic inherited member from a non-generic base class (or interface). Now, you can hold a reference to that type, and invoke the template method to cause the other calls to occur.
public void DoAwesomeStuff() //inherited from non-generic parent or interface
{
LoadContents(FunctionToGetContents());
DoSomething();
}
Then:
IDoesAwesomeStuff ObjectToUse = new FOO();
ObjectToUse.DoAwesomeStuff();

Generic base class with multiple children

I currently have a small object hierarchy that looks like this:
public class BaseClass {
// this class is empty and exists only so the others can extend it and share the
// same base type
}
public class ChildA : BaseClass {
public Subject<AssociatedClassA> Results;
}
public class ChildB : BaseClass {
public Subject<AssociatedClassB> Results;
}
In my design I would like to enforce that every class that extends from BaseClass should contain a Subject<SomeType> called Results. I'm wondering if there is a way that I can move Results into the base class or an interface such that I can supply the generic type for the Subject when constructing the base class. For example, it would be awesome if I could do something like this:
ChildA<AssociatedClassA> instance = new ChildA<AssociatedClassA>();
Or even better since there should really only be one template parameter that matches with ChildA if when I constructed it that could be taken care of for me:
ChildA instance = new ChildA();
// Results is automatically set to Subject<AssociatedClassA>
I'm stuck trying to implement this now as if I try to move Results into the base class the Subject requires a template parameter which I can't necessarily supply. There could potentially be more than 2 derived classes and I don't like the idea that someone extending this system has to know to add Results manually to each child class.
Following the suggestions of the 2 answers below this solves my desire to move Results into the base class, however I've run into another issue in that I was hoping to be able to use BaseClass as a generic parameter to methods such that any of the derived classes could be used. For example:
public void ProcessBaseClass(BaseClass base) {
// base could be ChildA or ChildB here
}
This no longer works since BaseClass now requires a type argument. Is there any way that I can have the best of both worlds here or am I stuck due to my design choices?
If appropriate, you can make the parent generic:
public class BaseClass<T> {
public Subject<T> Results;
}
public class ChildA : BaseClass<AssociatedClassA> {
}
public class ChildB : BaseClass<AssociatedClassB> {
}
You can make the base class itself generic:
public class BaseClass<T> {
public T Results { get; protected set; }
}

C# abstract class static field inheritance

I feel like I skipped a C# class or two, but here's my dilemma:
I have an abstract class from which I derive multiple child classes.
I know for sure that for each of the child classes I will have a constructor that needs a certain static object as a model and this object will be different for each of the child classes.
My first approach was to make a public static object in the abstract parent class and then, before I start creating any instances of the child classes, I would modify it for each of them, but it turns out that this way I actually make only ONE static object, for the abstract class, and each of it's child classes uses it.
How could I solve the problem?
To be more exact, here is the pseudocode:
The parent abstract class:
abstract class AbstractClass
{
static public ModelObject Model;
...
}
One of the child classes:
class Child : AbstractClass
{
...
public Child()
{
this.someField = Model.someField;
}
}
EDIT:
The Model needs to be a member of the "ModelObject" class, it should NOT be a singleton or anything else.
EDIT2:
To be even more exact, i chose this implementation for a game of chess: I have an abstract class for the chess pieces and the child classes represent the concrete pieces of the game: pawns, knights, et cetera.
The abstract class inherits from MeshMatObject, a class that represents generic 3d objects with the basic functionality, like rotations, meshes, materials, textures and so on and it defines abstract methods for chess game pieces, like GetPossibleMoves().
The Model object I was talking about above is a member of the MeshMatObject and, in my opinion, should be defined outside the class just once and then used for all the pieces. I mean: for example all the pawns have the same mesh and texture, so I don't see the point of giving a model as a parameter every time you want to make a pawn.
You can get around the shared static field by making your Abstract class generic. Each generic class will get it's own copy of the static fields.
abstract class AbstractClass<T>
{
static public ModelObject Model;
...
}
Then each child class will use a different instance of the static field.
class Child : AbstractClass<Child>
{
...
public Child()
{
this.someField = Model.someField;
}
}
It doesn't matter that AbstractClass doesn't reference the generic parameter. You are only using it to give each child class a unique instance of the base class.
I tend to use something similar to #shf301's solution. Depending on your needs it may useful to setup the base class as:
abstract class AbstractClass
{
}
abstract class AbstractClass<TModel> : AbstractClass
where TModel : ModelObject
{
static public TModel Model;
...
}
This allows me a common base class that I can work with in non-generic functions. This also allows derived types to choose the exact model type and can cut down on casting.
How about a factory to decouple your classes from an inherited Model:
public static class ModelObjectFactory
{
public static ModelObject GetModel<T>(T obj)
{
// return ModelObject according to type of parameter
}
}
class Child
{
public Child()
{
ModelObject mo = ModelObjectFactory(this);
this.someField = mo.someField;
}
}

Categories

Resources