2012-04-09 2 views
2

Я начал использовать C# 4.0 и любя динамическое ключевое слово. Тем не менее, я не уверен, что я делаю, можно считать хорошей практикой. См. Код ниже:C# dyanmic type и conditionals

static void Main() 
{ 
    NoobSauceObject noob = new NoobsauceObject(); 

    dynamic theReturnType = noob.do(param); 

    if (theReturnType.GetType().ToString().Contains("TypeOne")) 
     theReturnType.ExecuteMethodOfTypeOne(); 
    else if (theReturnType.GetType().ToString().Contains("TypeTwo")) 
     theReturnType.ExecuteMethodOfTypeTwo(); 
    else 
     throw new ArgumentException(""); 
} 

Есть ли лучший способ сделать это? Я нашел этот метод довольно простым и использовал его, но не уверен, что это то, что я должен придерживаться в долгосрочной перспективе.

EDIT: Если бы я должен был сделать то же самое с использованием .NET 3.5 или ниже или без динамического ключевого слова, что было бы хорошей реализацией?

Спасибо заранее! :)

+0

Что не так с 'as'? –

+0

Эндрю: хорошая точка! Я все еще изучаю C#, поэтому иногда забываю о некоторых очень важных понятиях. –

ответ

6

Мне кажется, что вы просто проводите типовой тест между двумя несвязанными типами. Если возможно, я бы посмотрел на полиморфизм здесь или, по крайней мере: внедрение общего интерфейса. Однако, следующий была бы тоже хорошо:

var typeOne = theReturnType as TypeOne; 
if(typeOne != null) typeOne.ExecuteMethodOfTypeOne(); 
else { 
    var typeTwo = theReturnType as TypeTwo; 
    if(typeTwo != null) typeTwo.ExecuteMethodOfTypeTwo(); 
    else throw new ArgumentException("somethingMeaningful"); 
} 

Однако мой предпочтительный вариант:

var typed = theReturnType as ISomeInterface; 
if(typed != null) typed.SomeMethod(); 
else throw new ArgumentException("somethingMeaningful"); 

где TypeOne и TypeTwo могут использовать явную реализацию интерфейса, чтобы выставить метод на их API:

public class TypeOne : ISomeInterface { 
    void ISomeInterface.SomeMethod() { ExecuteMethodOfTypeOne(); } 
    public void ExecuteMethodOfTypeOne() { 
     // ... 
    } 
} 

(и аналогичным образом TypeTwo)

Я не вижу реального использования для dynamic здесь; Для возвращаемого типа noob.do(param), object будет в порядке в первом примере - или ISomeInterface будет еще лучше.

+0

Марк: Благодарю вас за отзыв. Я использовал динамический, потому что объект theReturnType может быть типа из двух разных классов. Хорошо узнать что-то новое повседневное :) –

+0

Интерфейсы @noobsauce могут охватывать несвязанные классы - это действительно часть *** точечных интерфейсов ***, p –

+0

Марк: Я реализовал вашу технику. Это потрясающе. Это был прекрасный урок, и я рад, что задал этот вопрос. –