关闭传入接口参数的Case语句

时间:2014-01-12 00:02:37

标签: c#

我试图以某种方式根据我的界面确定输入的类型,然后对该类型进行一些验证。根据进入的类型验证不同。

  public static bool RequestIsValid(IPaymentRequest preAuthorizeRequest)
    {
        switch (preAuthorizeRequest)
        {
             case    
        }
    }

但要么我不能用界面做到这一点,要么我没有做一些能让它发挥作用的东西。

如果我不能在一个看起来很可能的界面上这样做,因为我认为switch需要一个具体的类型,那么我该怎么做呢?只是定期if语句检查typeof?

这是唯一的方法吗?

3 个答案:

答案 0 :(得分:1)

您可以像这样使用isas

public static bool RequestIsValid(IPaymentRequest preAuthorizeRequest)
{
    if (preAuthorizeRequest is PaymentRequestClassA)
    {
         var classA = (PaymentRequestClassA)preAuthorizeRequest;
         // handle PaymentRequestTypeA
    }
    else if (preAuthorizeRequest is PaymentRequestClassB)
    {
         var classA = (PaymentRequestClassB)preAuthorizeRequest;
         // handle PaymentRequestTypeB
    }
}

或者

public static bool RequestIsValid(IPaymentRequest preAuthorizeRequest)
{
    var classA = preAuthorizeRequest as PaymentRequestClassA;
    var classB = preAuthorizeRequest as PaymentRequestClassB;
    if (classA != null)
    {
         // handle PaymentRequestTypeA
    }
    else if (classB != null)
    {
         // handle PaymentRequestTypeB
    }
}

答案 1 :(得分:1)

您必须使用GetType方法和typeof(),但遗憾的是您无法使用switch / case做出决定:

  

切换表达式或案例标签必须是boolcharstringintegralenum或相应的可空类型。

您可以使用if / else语句或准备Dictionary<Type, Func<IPaymentRequest, bool>>并使用它来执行验证逻辑。

private static Dictionary<Type, Func<IInterface, bool>> _validationFunctions
   = new Dictionary<Type, Func<IInterface, bool>>() {
       { typeof(ClassA), (input) => false },
       { typeof(ClassB), (input) => true }
   };

public static bool RequestIsValid(IInterface preAuthorizeRequest)
{
    return _validationFunctions[preAuthorizeRequest.GetType()](preAuthorizeRequest);
}

答案 2 :(得分:1)

仅为完整性:

如果您不需要“默认”处理,您还可以为IPaymentRequests的不同实现重载方法,并删除将接口作为参数的方法。这也更安全,因为添加明显可能需要特殊处理的新实现不会默认为某些东西,但需要另一种具有匹配签名的方法

public static bool RequestIsValid(PaymentRequestImplementation1 preAuthorizeRequest)
{
}

public static bool RequestIsValid(PaymentRequestImplementation2 preAuthorizeRequest)
{
}

...

如果你真的想保持方法采用IRequest,你也可以使用反射来调用更具体的方法,以防你的调用者在IRequest中转换你的参数:

public static bool RequestIsValid(IRequest preAuthorizeRequest)
{
    var member = typeof (YourType).GetMethod(
        "RequestIsValid",
        BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.Public,
        null,
        new [] {preAuthorizeRequest.GetType()},
        null);

    if (member.GetParameters()[0].ParameterType != typeof (IRequest))
    {
        member.Invoke(null, new[] {Convert.ChangeType(preAuthorizeRequest, preAuthorizeRequest.GetType())});
    }

    // default
}