2

I have a class, something like this one (C#):

public class MyFavoriteClass 
{
   public string Name { get; set; }

   public string Description { get; set; }

   (...)

   public ReferencedClass1 ReferencedClass1 {get; protected set;}

   public ReferencedClass2 ReferencedClass2  {get; protected set;}

   public ReferencedClass3 ReferencedClass3  {get; protected set;}

   public AnotherReferencedClass1 AnotherReferencedClass1  {get; protected set;}

   public AnotherReferencedClass2 AnotherReferencedClass2  {get; protected set;}

   public AnotherReferencedClass3 AnotherReferencedClass3  {get; protected set;}
}

Referenced classes dont have any common ancestor class.

There are constrains:

Object (instance of MyFavoriteClass) can have setted only one of properties ReferencedClass1, ReferencedClass2 and ReferencedClass3. Others have to be null.

Same rule for AnotherReferencedClass1, AnotherReferencedClass2 and AnotherReferencedClass3.

Whats the best way to enforce these constraints? In factory pattern? Should I write nine methods in this factory? Or should i wrapp these options in another object?

  • Have you missed the types off some properties? – Ewan Apr 22 '16 at 12:57
  • It looks i forgot to type names of some properties.. Now it is corrected. – ingenyyr Apr 22 '16 at 14:54
  • The concept you are looking for is "Discriminated Union". It's directly supported in some languages, but not C#. See stackoverflow.com/questions/3151702/… – kevin cline Apr 22 '16 at 19:18
1

Looks like MyFavoriteClass itself is a problem and should be split. Create specializations of this class which can only contain a specific pair of referenced types, that's how you get the constraint.

Then use a factory which is capable of emitting the correct specializations of MyFavoriteClass. You may either provide an overload for each combination of possible parameters or just rely on dynamic type detection - that's your choice.


Alternative approach, only create a wrapper class including specializations encapsulating each of the triplets - that way MyFavoriteClass doesn't need to know about specific details and you can avoid having to create all 9 combinations.

That's only if MyFavoriteClass doesn't need to care about special cases though.

|improve this answer|||||
  • yeah, the splitting of first one triple coud be the best way. I could also modify some other behavior this way. The second one could use wrapper class. – ingenyyr Apr 22 '16 at 15:00
0

You could use generics, but its not quite the same as your example.

MyFaveClass<T>
{
    public T OnlyOneOfThese { get; set; }
}


var x = new MyFaveClass<AnotherClass>();

Here is another method which allows you to set the object. The as operator returns null if it cant do the cast, so this relys on the classes not inheriting from each other

MyFaveClass
{
    public ClassA opt1
    {
         get {
             return onlyOneOfThese as ClassA;
         }
         set {
             onlyOneOfThese = value;
        }
    }
    public ClassB  opt2
    {
         get {
             return onlyOneOfThese as ClassB;
         }
         set {
             onlyOneOfThese = value;
        }
    }
    private object onlyOneOfThese;
}
|improve this answer|||||
  • In other cases generics could be option. In this case its kind of overkill I quess. – ingenyyr Apr 22 '16 at 15:12
  • I think its going to be much less code than a factory plus 'check to see which one isnt null' code. – Ewan Apr 22 '16 at 17:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.