2016-08-25 2 views
2

У меня есть простая иерархия классов (базовый класс A, производный класс B: A, производный класс C: A и т. Д.). У меня есть следующий код:Должен ли я использовать динамическое ключевое слово для оптимизации конверсий?

void computation(A base_class) 
{ 
    if (base_class is B) 
    { 
     //Do some stuff with (base_class as B) 
    } 
    if (base_class is C) 
    { 
     //Do some stuff with (base_class as C) 
    } 
} 

Я вспомнил о динамическом ключевом слове языка C#. Как я понял, я могу использовать следующий код (для оптимизации дополнительных преобразований).

void computation(A base_class) 
{ 
    dynamic temp = base_class as B; 
    if (temp != null) 
    { 
     //Do some stuff with temp 
    } 
    temp = base_class as C; 
    if (temp != null) 
    { 
     //Do some stuff with (base_class as C) 
    } 
} 

Какой вариант лучше использовать? Как насчет выполнения этих подходов?

+2

'B temp = base_class as B;' 'dynamic' не имеет к этому никакого отношения. Это, безусловно, не улучшит производительность. –

+0

@ Dennis_E, можете ли вы рассказать подробнее? Я немного не понимаю вас – LmTinyToon

+1

Вам не нужно использовать 'dynamic', если вы знаете тип, на который вы производите. В этом случае вы можете просто использовать B B = base_class как B; if (b! = null) {...} ' – Lee

ответ

5

Это пахнет преждевременной оптимизацией, и мне не нравится использование dynamic здесь.

Также имейте в виду, что dynamic делает конкретные вещи, как (цитата из MSDN):

Динамический тип позволяет операции, в которых это происходит, чтобы обойти во время компиляции проверки типов. Вместо этого эти операции разрешаются во время выполнения.

Так что, я думаю, что обход проверки типа времени компиляции - это не то, что вы хотите.

Вместо этого я рекомендую использовать var. Imho это улучшает читаемость, отладка проще и использование as вместо is + литье также немного быстрее.

void computation(A base_class) 
{ 
    var b = base_class as B; 
    if (b != null) 
    { 
     //Do some stuff with temp 
    } 
    var c = base_class as C; 
    if (c != null) 
    { 
     //Do some stuff with (base_class as C) 
    } 
} 
+0

@ АлександрЛысенко У них разные типы, поэтому вам нужно. –

+0

@ АлександрЛысенко Смотрите мое редактирование. – ViRuSTriNiTy

+3

Я бы помнил, что var статически типизирован, а динамика - нет. Это то, что нужно знать: https://blogs.msdn.microsoft.com/jennifer/2010/06/16/what-is-the-difference-between-var-and-dynamic-in-c/ –

5

Это у вас есть иерархия наследования, но во время выполнения вы должны знать, что конкретный класс, вы имеете дело с того, чтобы знать, что делать - есть вероятность, что вы делаете это неправильно!

public abstract class A 
{ 
    public abstract void DoSomething(); 
} 

public class B: A 
{ 
    public override void DoSomething() { .. do B's thing ... } 
} 

public class C : A 
{ 
    public override void DoSomething() { .. do C's thing ... } 
} 


... 
public void Consumer(A a) 
{ 
    a.DoSomething(); // calls the right DoSomething, B or C. 
} 
... 

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

+1

Иногда вы не имеют этой роскоши, потому что, например, классы - от вечеринки/запечатывания и т. д. Но действительно. – ViRuSTriNiTy

+0

@ViRuSTriNiTy, хорошее упоминание – LmTinyToon

Смежные вопросы