1

I want to have a method which can accepts only two/three enums that I have created.

If instead of Enum, if we say for class, we can do it using the Interface.

class A :IMyInterface
{
}
class B :IMyInterface
{
}
class C :IMyInterface
{
}

public class Test
{
  public void MyTestMethod(IMyInterface classA_B_C)
  {
  }
}

Similarly if I have

public enum A{}
public enum B{}
public enum C{}

And I want a method

public void MyEnumTesting(AnyEnumA_B_C)  <--

so I want a way to pass one Enum out of 2/3 I declared.

UPDATE Its not the duplicate of Enum "Inheritance" I don't want common values in both enums. I want a method which can accept any one of two Enums

Community
  • 1
  • 1
Deepak Sharma
  • 4,124
  • 1
  • 14
  • 31
  • Which IoC container are you using? – Chris Mantle Aug 02 '15 at 16:18
  • possible duplicate of [Enum "Inheritance"](http://stackoverflow.com/questions/757684/enum-inheritance) – Preston Guillot Aug 02 '15 at 16:19
  • @ChrisMantle no.. i am not using the Ioc container.. I just told it to set the example to make you all understood, what I am expecting as solution – Deepak Sharma Aug 02 '15 at 16:21
  • @PrestonGuillot I dont want to inherit one, with another. I want two Separate enums , and pass any to one specific method – Deepak Sharma Aug 02 '15 at 16:23
  • @DeepakSharma Do you require that the `MyTestMethod` accept the enum types? How will you decide in the method to use the enum values within the method? – Tyree Jackson Aug 02 '15 at 17:23
  • yes enum types.. any one out of multiple(I declared). I need to ensure a user can pass any enum to method. I need to check if `enum_A_B_C = Enum1.First` OR `enum_A_B_C = Enum2.OtherValue` – Deepak Sharma Aug 03 '15 at 06:31

3 Answers3

1

For achieving that functionality, use methods overloading:

public void MyEnumTesting(A enumA);
public void MyEnumTesting(B enumB);
public void MyEnumTesting(C enumC);

In the containing class, just add those 3 methods with same name but different argument type.

If you expect in the future to have more enums that that you want to support by this method, then I would recommend you to define your class as partial and in each file that you define enam, just make extenssion to this partial class by adding this method.

file A.cs

enum A{...}

partial class MyClass
{
    public void MyEnumTesting(A enumA);
}

file B.cs

enum B{...}

partial class MyClass
{
    public void MyEnumTesting(B enumB);
}
Rami Yampolsky
  • 465
  • 4
  • 12
  • yes not doubt we can do.. but I just want to know if the way I asked is also possible by some hook-cook, else yes of-course we can do with method overloading. – Deepak Sharma Aug 02 '15 at 16:33
  • Are you actually asking if you can define reference of type that can reference to any of those Enums? As this is a different question... – Rami Yampolsky Aug 02 '15 at 16:36
0

There is no direct way to have a more general reference to Enums, but you can do design that let you acheive this functionality:

    public class AWrapper: IMyInterface
    {
      public A Value;
      public enum A{}
    }

    public class BWrapper: IMyInterface
    {
      public B Value;
      public enum B{}
    }

    public class CWrapper: IMyInterface
    {
      public C Value;
      public enum C{}
    }

Then you can write same way you actually shown with classes, but with some hybrid usage of enums...

public class Test
{
  public void MyTestMethod(IMyInterface classA_B_C)
  {
  }
}
Rami Yampolsky
  • 465
  • 4
  • 12
  • but as the are define inside the drived class, inside the MyTestMethod, I can not use these enum untill-unless I type cast the interface reference object to specific class. so again that can not ful fill.. I thnk I will have to take the help of Class-Interface relationship.. can not directly do with enum. anyways thanks. for you time. :) – Deepak Sharma Aug 02 '15 at 17:18
  • Enums are concrete, if you are asking for kind of abstraction, you probably should define what is common between the entities in your application. If you would follow your hypothetical way that you presented, you would see that somewhere you need to cast. – Rami Yampolsky Aug 02 '15 at 17:29
0

You might trying using an intermediary with a set of implicit operators like this:

public enum A { A1, A2, A3 }
public enum B { B1, B2, B3  }
public enum C { C1, C2, C3 }

public class A_B_C_Caster
{
    public int Value { get; private set; }

    private A_B_C_Caster() {}

    public static implicit operator A_B_C_Caster(A value) { return new A_B_C_Caster() {Value = (int) value}; }
    public static implicit operator A_B_C_Caster(B value) { return new A_B_C_Caster() {Value = (int) value}; }
    public static implicit operator A_B_C_Caster(C value) { return new A_B_C_Caster() {Value = (int) value}; }
}

Use it like this:

public class Test
{
    public void TestCallingMyTestMethod()
    {
        this.MyTestMethod(A.A1);
        this.MyTestMethod(B.B1);
        this.MyTestMethod(C.C1);
    }

    public void MyTestMethod(A_B_C_Caster classA_B_C)
    {
        var value = classA_B_C.Value;
    }
}

The approach above limits the range of acceptable arguments to only the three enums by way of the private constructor and implicit operators on the A_B_C_Caster class. Inside of the method you have to use the least common denominator type of the three enums which would be the int type in this case.

UPDATE:

Here are some generic versions of the caster class. Unfortunately I had to do a boxing operation in this version in the implicit operators. You may be able to use Jon Skeet's Unconstrained Melody to work around this issue though.

public class MultiIntEnum<TRawType, TEnum1, TEnum2>
    where TEnum1 : struct
    where TEnum2 : struct
{
    public TRawType Value { get; private set; }
    private MultiIntEnum() {}
    public static implicit operator MultiIntEnum<TRawType, TEnum1, TEnum2>(TEnum1 value) { return new MultiIntEnum<TRawType, TEnum1, TEnum2>() {Value = (TRawType) (object) value}; }
    public static implicit operator MultiIntEnum<TRawType, TEnum1, TEnum2>(TEnum2 value) { return new MultiIntEnum<TRawType, TEnum1, TEnum2>() {Value = (TRawType) (object) value}; }
}

public class MultiIntEnum<TRawType, TEnum1, TEnum2, TEnum3>
    where TEnum1 : struct
    where TEnum2 : struct
    where TEnum3 : struct
{
    public TRawType Value { get; private set; }
    private MultiIntEnum() {}
    public static implicit operator MultiIntEnum<TRawType, TEnum1, TEnum2, TEnum3>(TEnum1 value) { return new MultiIntEnum<TRawType, TEnum1, TEnum2, TEnum3>() {Value = (TRawType) (object) value}; }
    public static implicit operator MultiIntEnum<TRawType, TEnum1, TEnum2, TEnum3>(TEnum2 value) { return new MultiIntEnum<TRawType, TEnum1, TEnum2, TEnum3>() {Value = (TRawType) (object) value}; }
    public static implicit operator MultiIntEnum<TRawType, TEnum1, TEnum2, TEnum3>(TEnum3 value) { return new MultiIntEnum<TRawType, TEnum1, TEnum2, TEnum3>() {Value = (TRawType) (object) value}; }
}

public class MultiIntEnum<TRawType, TEnum1, TEnum2, TEnum3, TEnum4>
    where TEnum1 : struct
    where TEnum2 : struct
    where TEnum3 : struct
    where TEnum4 : struct
{
    public TRawType Value { get; private set; }
    private MultiIntEnum() {}
    public static implicit operator MultiIntEnum<TRawType, TEnum1, TEnum2, TEnum3, TEnum4>(TEnum1 value) { return new MultiIntEnum<TRawType, TEnum1, TEnum2, TEnum3, TEnum4>() {Value = (TRawType) (object) value}; }
    public static implicit operator MultiIntEnum<TRawType, TEnum1, TEnum2, TEnum3, TEnum4>(TEnum2 value) { return new MultiIntEnum<TRawType, TEnum1, TEnum2, TEnum3, TEnum4>() {Value = (TRawType) (object) value}; }
    public static implicit operator MultiIntEnum<TRawType, TEnum1, TEnum2, TEnum3, TEnum4>(TEnum3 value) { return new MultiIntEnum<TRawType, TEnum1, TEnum2, TEnum3, TEnum4>() {Value = (TRawType) (object) value}; }
    public static implicit operator MultiIntEnum<TRawType, TEnum1, TEnum2, TEnum3, TEnum4>(TEnum4 value) { return new MultiIntEnum<TRawType, TEnum1, TEnum2, TEnum3, TEnum4>() {Value = (TRawType) (object) value}; }
}

public class MultiIntEnum<TRawType, TEnum1, TEnum2, TEnum3, TEnum4, TEnum5>
    where TEnum1 : struct
    where TEnum2 : struct
    where TEnum3 : struct
    where TEnum4 : struct
    where TEnum5 : struct
{
    public TRawType Value { get; private set; }
    private MultiIntEnum() {}
    public static implicit operator MultiIntEnum<TRawType, TEnum1, TEnum2, TEnum3, TEnum4, TEnum5>(TEnum1 value) { return new MultiIntEnum<TRawType, TEnum1, TEnum2, TEnum3, TEnum4, TEnum5>() {Value = (TRawType) (object) value}; }
    public static implicit operator MultiIntEnum<TRawType, TEnum1, TEnum2, TEnum3, TEnum4, TEnum5>(TEnum2 value) { return new MultiIntEnum<TRawType, TEnum1, TEnum2, TEnum3, TEnum4, TEnum5>() {Value = (TRawType) (object) value}; }
    public static implicit operator MultiIntEnum<TRawType, TEnum1, TEnum2, TEnum3, TEnum4, TEnum5>(TEnum3 value) { return new MultiIntEnum<TRawType, TEnum1, TEnum2, TEnum3, TEnum4, TEnum5>() {Value = (TRawType) (object) value}; }
    public static implicit operator MultiIntEnum<TRawType, TEnum1, TEnum2, TEnum3, TEnum4, TEnum5>(TEnum4 value) { return new MultiIntEnum<TRawType, TEnum1, TEnum2, TEnum3, TEnum4, TEnum5>() {Value = (TRawType) (object) value}; }
    public static implicit operator MultiIntEnum<TRawType, TEnum1, TEnum2, TEnum3, TEnum4, TEnum5>(TEnum5 value) { return new MultiIntEnum<TRawType, TEnum1, TEnum2, TEnum3, TEnum4, TEnum5>() {Value = (TRawType) (object) value}; }
}

They can be used like this:

public class Test
{
    static void Main()
    {
        MyTestMethod(A.A1);
        MyTestMethod(B.B2);
        MyTestMethod(C.C3);

        Console.ReadKey();
    }

    static void MyTestMethod(MultiIntEnum<int, A,B,C> classA_B_C)
    {
        var value = classA_B_C.Value;
        Console.WriteLine(value);
    }
}
Tyree Jackson
  • 2,588
  • 16
  • 22