0

I've been fighting windmills trying to wrap my head around this problem in C#. The short version is that I have two sets of classes in C#. The first set are objects (which inherit from a base object class) and the second set are parameters for those objects (which inherit a base parameter class). Starting with the parameter classes:

// Object types (parameter classes)

public interface IObjectType<in T> where T : BaseObject
{
    public void Foo(BaseObject object);
}

public class ObjectTypeA : IObjectType<ObjectA>
{
    public void Foo(ObjectA object) {}
}

public class ObjectTypeA : IObjectType<ObjectB>
{
    public void Foo(ObjectB object) {}
}

Function Foo in this case is used to execute some configuration on a given BaseObject object depending on its type. This works fine, so far, but to have this work with my objects, I need to have an IObjectType property in the BaseObject interface. Below I'll try to illustrate what I'm hoping my object classes would look like.

// Objects

public interface Object
{
    public IObjectType<?> type;
    public void SetType(IObjectType<?> type);
}

public class ObjectA
{
    // type is automatically IObjectType<ObjectA> aka ObjectTypeA
    // public void SetType(ObjectTypeA type) {}
}

public class ObjectB
{
    // type is automatically IObjectType<ObjectB> aka ObjectTypeB
    // public void SetType(ObjectTypeB type) {}
}

After many trials with covariance, contravariance, generic abstract classes and other steps I can't recall or am ashamed to admit, I've run out of options on how to implement a generic IObjectType property which would automatically cast to the derived type it finds itself in.

At this point I'm not sure if I'm treading down into antipattern territory or if I'm missing some piece of C# functionality - has anyone ever approached the same problem before? Should I just abandon my hopes of finding a solution here and try a different approach?

Nimantha
  • 6,405
  • 6
  • 28
  • 69
  • In your interface did you try making parameter of Foo generic : `void Foo(T obj);` Or something else prevents you to do ? – Eldar Nov 25 '21 at 19:36
  • Does this answer your question? [How to write a good curiously recurring template pattern (CRTP) in C#](https://stackoverflow.com/questions/10939907/how-to-write-a-good-curiously-recurring-template-pattern-crtp-in-c-sharp) See also https://ericlippert.com/2011/02/02/curiouser-and-curiouser/ – Charlieface Nov 25 '21 at 20:20
  • Basically, you just make `public interface Object where T : Object` Looks weird, but it works, and hacks around the lack of a `where T : this` constraint – Charlieface Nov 25 '21 at 20:22
  • Thanks for the answers folks, my general answer is that I ended up realizing I was overthinking and overengineering my problem, so I scraped it up to the basics. The more specific answer, the CRTP template was exactly what I was looking for, but in the end it turned out to be overkill. – Julzerino Szach Nov 26 '21 at 23:20

0 Answers0