参数类型取决于另一个参数

时间:2011-03-05 08:51:53

标签: c# .net

我怀疑这是可能的,但我想要做的是让参数的类型取决于另一个参数的值。因为它在大多数情况下是静态定义的,所以它应该可以工作(在我的情况下,它将始终静态使用)。

如,

假设我们有一个函数myFunc,它的第一个参数是myEnum类型的枚举。

myFunc(myEnum.SomeValue);

但现在假设我们希望第二个参数的类型依赖于第一个参数的值。

所以

myFunc(myEnum.Value1, x)
myFunc(myEnum.Value2, y)

在这种情况下,x将具有与Value1和y与Value2相关的类型。

如果我们可以指定一个映射,编译器直接确定第二个参数的类型应该是完全有效的。我们可能需要一个新类型来处理它,但只要第一个参数是编译时常量,就应该没有问题。人们可以使用多态来处理各种情况,或者在我的情况下,使用工厂。

编译器不能推断出第二个参数类型的唯一类型是当第一个不是编译时常量时,如果第二个参数不是正确的时间,则可以抛出运行时错误。

这样做的要点是将大枚举打破为形成层次结构的较小枚举。人们可以简单地使用包含所有组合的单个大枚举,但它会很快失控。

我非常怀疑C#是否支持这样的功能,但也许有可能让它工作(使用属性或其他)?


行为举例

    public enum Value1Types { Type1, Type2 }

    public enum Value2Types { TypeA, TypeB }

    public class FakeEnum
    {
        public class EnumTypes
        {
            public abstract class BaseEnum { public abstract int Value { get; } }
            public class Value1 : BaseEnum { public override int Value { get { return 1; } } }
            public class Value2 : BaseEnum { public override int Value { get { return 2; } } }
        }

        public static class EnumValues
        {
            // Singletons
            public static readonly EnumTypes.Value1 Value1 = new EnumTypes.Value1();
            public static readonly EnumTypes.Value2 Value2 = new EnumTypes.Value2();
        }

        public void AcceptValue(EnumTypes.Value1 typeController, Value1Types s) { Console.WriteLine("Value1 " + s.ToString()); }
        public void AcceptValue(EnumTypes.Value2 typeController, Value2Types s) { Console.WriteLine("Value2 " + s.ToString()); }

        public void Test()
        {
            // Notice how the same method's second arugment's type depends on the value of the first
            AcceptValue(EnumValues.Value1, Value1Types.Type1); // valid
            AcceptValue(EnumValues.Value2, Value2Types.TypeA); // valid
            //AcceptValue(EnumValues.Value1, Value2Types.TypeB); // Invalid, compile error
        }
    }

2 个答案:

答案 0 :(得分:2)

如果你可以用明确的类型替换枚举,你可以做这样的事情 就个人而言,我认为最后一点编译时间检查需要做很多工作。

public class FakeEnum
{
    public class EnumTypes
    {
        public abstract class BaseEnum
        {
            public abstract int Value { get; }
        }

        public class Value1 : BaseEnum
        {
            public override int Value
            {
                get { return 1; }
            }
        }

        public class Value2 : BaseEnum
        {
            public override int Value
            {
                get { return 2; }
            }
        }
    }
    public static class EnumValues
    {
        // Singletons
        public static readonly EnumTypes.Value1 Value1 = new EnumTypes.Value1();
        public static readonly EnumTypes.Value2 Value2 = new EnumTypes.Value2();
    }

    public void AcceptValue(EnumTypes.Value1 typeController, string s)
    {
        Console.WriteLine("Value1 " + s);
    }

    public void AcceptValue(EnumTypes.Value2 typeController, int i)
    {
        Console.WriteLine("Value2 " + i);
    }

    public void Test()
    {
        AcceptValue(EnumValues.Value1, "with value1"); // valid
        AcceptValue(EnumValues.Value2, 1); // valid
        //AcceptValue(EnumValues.Value1, 4); // Invalid, compile error
    }
}

答案 1 :(得分:0)

我不知道任何具有此功能的语言,也不知道它有用的原因。 如果你想要一个不同类型的函数,那么使用重载,即

void myFunc(TypeX x);

void myFunc(TypeY y);

然后,您可以决定在代码中调用哪个:

TypeX x = new TypeX();
TypeY y = new TypeY();

switch (myEnum) 
{
    case myEnumType.Value1:
        myFunc(x);
        break;
    case myEnumType.Value2:
        myFunc(y);
        break;
}

在编译器级别尝试实现它可能会涉及到边缘情况的一些讨厌的语法。