Должен ли я делать явное приведение при передаче объекта? - PullRequest
0 голосов
/ 04 апреля 2019

Мой кусок кода для теста:

static void TestMethod(IBingo obj)
{
// Access the property
Console.WriteLine($"The value is {obj.Point}" );
}
...
class Yankee : IBingo {
// Some stuff
}
// inside Main
Yankee obj = new Yankee();
if(obj is IBingo)
{
// So the object does have the IBingo functionality!
TestMethod((IBingo)obj); 
// Is this implicit casting recommended for any reason?
TestMethod(obj); // Runs perfectly fine
}

Мое первоначальное предположение состоит в том, что этот приём полезен только тогда, когда правильная проверка не сделано так, что программа выдаст исключение.

Ответы [ 3 ]

2 голосов
/ 04 апреля 2019

В вашем обновленном коде Yankee равно всегда и IBingo.Компилятор знает это, и он упрощает ваш код до:

if (obj != null)
{
    TestMethod(obj);
    TestMethod(obj);
}

SharpLab .

Как вы можете видеть, он сократил проверку типов до нулевой проверкии он удалил ваше бессмысленное приведение.

Поскольку вы звоните TestMethod, который берет IBingo, ваш Yankee будет всегда понижаться до IBingo, когдаВы называете метод.Добавлять в дополнительный состав бессмысленно.


Старый ответ (из вашего отредактированного вопроса)

Предполагается, что вы хотели написать (как указано в комментариях)

if (obj is IBingo test)
{
    TestMethod((IBingo)test); 
    TestMethod(test);
}

Разницы нет.Переменная test уже имеет тип IBingo - здесь даже нет неявного преобразования.Компилятор удаляет приведение в первом случае, поэтому обе строки становятся TestMethod(test). SharpLab

1 голос
/ 04 апреля 2019

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

Derived d = new Derived();  
Base b = d; // Always OK.  

Явное преобразование Если преобразование не может быть выполнено без риска потери информации,Компилятор требует, чтобы вы выполнили явное преобразование, которое называется приведением

// Create a new derived type.  
Giraffe g = new Giraffe();  

// Implicit conversion to base type is safe.  
Animal a = g;  

// Explicit conversion is required to cast back  
// to derived type. Note: This will compile but will  
// throw an exception at run time if the right-side  
// object is not in fact a Giraffe.  
Giraffe g2 = (Giraffe) a;  
1 голос
/ 04 апреля 2019

Нет никакого смысла в любом вызове, потому что test уже приведен к IBingo.Вы можете написать:

if(obj is IBingo test)
{
    TestMethod(test); 
}

Вы используете форму сопоставления с шаблоном if, что означает, что блок будет введен только , если obj можно привести к IBingo.Когда это произойдет, результат приведения будет сохранен в переменной test.Эта переменная будет находиться в области видимости только внутри этого блока.

Этот код сопоставления с образцом эквивалентен:

var test = obj as IBingo;
if (test!=null)
{
    TestMethod(test);
}

Обновление

Модифицированныйкод не нуждается в приведении, потому что Yankee класс является реализацией IBingo.

Если это не так, это будет зависеть от того, было ли явное или явное приведениеопределяется от Yankee до IBingo.Оператор as будет работать в любом случае.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...