c#cast with is和as

我需要一些帮助。 这很简单。 我有这段代码,我想讨论它是否正确,或者你是否建议采用更好的方法。 我对答案有所了解,但我希望看到你的答案。 在这里

if (myObject is ClassA) { var myObjectA = myObject as ClassA; myObjectA?.MethodJustInA(); } else if (myObject is ClassB) { var myObjectB = myObject as ClassB; myObjectB?.MethodJustInB(); myObjectB?.OtherMethodJustInB(); } 

我认为没有必要在每个if之后创建一个新对象,只需:

 (ClassB)myObjectB.MethodJustInB(); 

并且没有必要检查它是否为null,因为如果它在if中是因为不是null

谢谢

有一些可能的优化。

  • 如果myObject is ClassA ,则不需要软转换。 相反,你可以直接进行转换: var myObjectA = (ClassA)myObject;
  • 既然如此,你只需调用一个方法,就不需要分配一个新的变量: ((ClassA)myObject)?.MethodJustInA();
  • 并且因为如果myObject为null, myObject is ClassA求值为false,则不需要再次检查: ((ClassA)myObject).MethodJustInA();

所以:

 if (myObject is ClassA) { ((ClassA)myObject).MethodJustInA(); } else if (myObject is ClassB) { var myObjectB = (ClassB)myObject; myObjectB.MethodJustInB(); myObjectB.OtherMethodJustInB(); } 

我更喜欢使用as进行null然后检查null ,这样你就可以跳过is check。 另外,您不需要elvis操作员?. 因为你知道对象不是null。

 var myObjectA = myObject as ClassA; var myObjectB = myObject as ClassB; if (myObjectA != null) { myObjectA.MethodJustInA(); } else if (myObjectB != null) { myObjectB.MethodJustInB(); myObjectB.OtherMethodJustInB(); } 

如果您正在测试多种类型,那么as + null检查更有效 (只有一次转换,而不是+转换):

 var a = myObject as ClassA; if (a != null) a.MethodJustInA(); var b = myObject as ClassB; if (b != null) b.MethodJustInB(); 

在给定的场景中,我甚至会制作这样的局部范围

 { var obj = myObject as ClassA; if (obj != null) obj.MethodJustInA(); } { var obj = myObject as ClassB; if (obj != null) obj.MethodJustInB(); } 

{ }可以重复使用相同的变量名称(更容易复制/粘贴,在我的意见中,阅读)。


我有点匆匆忙忙,并没有考虑过else情况(当myObject is ClassA你不想把它当作b等等)。 通常我会在每次成功后return if和相应的方法调用。 if else if代码,我无法构造好看的if / else if


另一个想法是使用C#6.0空条件运算符:

 (myObject as ClassA)?.MethodJustInA(); (myObject as ClassB)?.MethodJustInB(); 

看起来非常整洁,但它会不必要地转换为B并产生副作用:如果ClassBinheritanceClassA ,那么两个方法都将被调用,因为两个转换都会成功。

注意:不幸的是,提到的副作用适用于所有提议的片段。

在那些if语句中,您可以像这样转换对象:

 var myObjectB = (ClassB)myObject; 

或直接投射:

 ((ClassB)myObject).MethodJustInB(); 

如果您以这种方式使用它,您只需要将其转换为:

 var myObjectA = (myObject as ClassA); if (myObjectA != null) { myObjectA.MethodJustInA(); } else { var myObjectB = (myObject as ClassB); if (myObjectB != null) { myObjectB.MethodJustInB(); } } 

在C#7.0中你可以这样做:

 if (myObject is ClassA myObjectA) myObjectA.MethodJustInA(); else if (myObject is ClassB myObjectB) myObjectB.MethodJustInB();