2014-01-12 2 views
0

Я пытаюсь каким-то образом определить на основе моего интерфейса, какой тип пришел, а затем сделать некоторую проверку на этом типе. Validation differes на основе типа, который приходит.Case Statement from входящий интерфейс Параметр

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

но либо я не могу сделать это с помощью интерфейса или я не делаю что-то, что будет делать эту работу.

Если я не могу сделать это на интерфейсе, который выглядит, вероятно, потому, что я думаю, что переключатель нуждается в конкретном типе, то как бы я это сделал? Просто регулярные инструкции if, которые проверяют typeof?

Это единственный способ?

ответ

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 
} 
+0

Хорошая точка, что на самом деле может быть лучше. – PositiveGuy

+0

Я думал, что это было самое чистое ... так и с этим. – PositiveGuy

1

Вы можете использовать is или as вроде этого:

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 
    } 
} 
+0

другой хороший пункт, используя. Благодарю. – PositiveGuy

1

Вы должны были бы использовать GetType метод и typeof(), но, к сожалению, вы не можете использовать switch/case сделать решение:

Выражение выключателя или метка корпуса должно быть bool, char, string, integral, enum, или соответствующий тип с нулевым значением.

Вы можете использовать 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); 
} 
+1

Вы можете использовать 'object.GetType(). Name' в переключателе. – Harrison

+0

, но я оцениваю параметр интерфейса, а не объект – PositiveGuy

+0

, и я бы не хотел, чтобы базовый код на имени объекта был хрупким. – PositiveGuy