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);
}
}