传递对象时是否应该进行显式转换?

时间:2019-04-04 14:56:49

标签: c# casting

我要测试的代码:

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 个答案:

答案 0 :(得分:2)

在更新后的代码中,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 :(得分:1)

两个通话都没有意义,因为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实现。

如果不是,则取决于是否有从YankeeIBingo定义的隐式或显式强制转换。 as运算符在任何情况下都可以使用。

答案 2 :(得分:1)

隐式转换 从类到其直接或间接基类或接口中的任何一个,始终存在隐式转换。不需要特殊的语法,因为派生类始终包含基类的所有成员。

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;