2016-08-03 3 views
1

Рассмотрим небольшой пример:Сокращенный вариант назначения члена производного класса экземпляром базового класса

public class BaseClass { } 
public class DerivedClass : BaseClass { public int Field; } 

public static class Program 
{ 
    public static void Main(string[] args) 
    { 
     BaseClass baseVar = new DerivedClass(); 

     if(baseVar is DerivedClass) 
     { 
      var derivedVar = (DerivedClass)baseVar; 

      derivedVar.Field = 1; 

      baseVar = derivedVar; 
     } 
    } 
} 

У меня есть много кода, как это в случае, условия. Есть ли сокращенная версия этого, так что мне не нужно создавать временную производную переменную?

+2

Обратите внимание, что этот тип кода упоминается как кодовый запах. Попробуйте найти общий интерфейс или базовый класс, чтобы объединить общие классы и попытаться использовать этот интерфейс. Он менее подвержен ошибкам и снижает затраты на обслуживание. – ckruczek

ответ

3

Одним из способов было бы безопасно типажей:

BaseClass base = new DerivedClass(); 
DerivedClass derived = base as DerivedClass; 
derived?.Field = 1; 

Примечание: as безопасен отливка - который будет либо литым или возвращать нуль. ? - это функция C# 6, где метод или назначение выполняются, когда переменная не является nullPtr. Вам не нужно писать baseVar = derivedVar, так как оба связаны ссылкой. Когда вы создаете и изменяете поле, эта ссылка не изменилась вообще.

Кроме того, вот статья MSDN по нулевому распространения в C# 6,0 https://msdn.microsoft.com/de-de/magazine/dn802602.aspx

Ради соблюдения, это veriant ОП выбрали:

BaseClass base = new DerivedClass(); 
(base as DerivedClass)?.Field = 1; 
+2

или все меньше: '(base as DerivedClass) ?. Поле = 1;' ... –

+0

Я хотел сохранить его в духе данного примера. Короткие - это хорошо, но я думаю, что для удобства и ясности, потянув этот бит друг от друга, кажется намного яснее (и, надеюсь, оптимизируется компилятором на ваше решение в любом случае). Но я согласен, это тоже работает. –

+0

Спасибо! Я поеду с комментарием @ZoharPeled выше! (У меня есть несколько hundrets таких выражений, в настоящее время все завернуты в if-conditions. Чем короче, тем лучше на данный момент :) – user5997884

1

Назначение

baseVar = derivedVar; 

является избыточным, поэтому вы можете просто сделать

if(baseVar is DerivedClass) { 
    ((DerivedClass)baseVar).Field = 1; 
} 
+0

Спасибо! Я думал, что приведение woul приведет к временной переменной, которая будет немедленно отброшена, если не будет назначена? Кажется, я ошибся – user5997884

+0

Будет. Но переменная сохраняет только ссылку - не все данные объекта. Отказ от ссылки не приведет к отбрасыванию изменений объекта. –

+0

Итак, это иначе, чем C/C++? – user5997884

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