C#在强制转换后访问类成员

本文关键字:访问 成员 转换 | 更新日期: 2023-09-27 17:58:06

我一直在使用C#和XAML,想知道在强制转换类成员后是否有更好的方法来访问它们。这是一个我通常不得不做的事情的例子:

private void MyButton_Clicked(object sender,  RoutedEventtArgs e)
{
    ((PlaneProjection)((Button)sender).Projection).RotationX = 20;
}

每次点击按钮时都会旋转按钮,但对于更复杂的操作,我需要越来越多的括号。我知道我可以使用as,这会让它更容易阅读,但这仍然会使它:

((sender as Button).Projection as PlaneProjection).RotationX = 20;

这仍然是比我想要的更多的括号。

我是走了很长的路还是错过了什么?或者就是这样,我将不得不处理像这样更难阅读的代码的可能性?

C#在强制转换后访问类成员

(A)严格来说,不,没有办法。在进行强制转换之后,会留下一个不同类型的临时值,并且在强制转换之后几乎没有语法分支,无论是普通强制转换还是AS运算符。您必须将其插入括号并立即使用,或者必须将其存储在变量中。

(B) 说得松散一点,有一种方法:就是根本不做演员。但请注意,它将:

  • 需要更新的.Net平台
  • 不太安全(编译时名称检查关闭)
  • 更不安全(运行时TYPE检查关闭,如果找到属性名称,则使用它,而不管变量中的obejct类型是什么)
  • 性能稍差(简单地说,动态操作比编译操作慢)

好吧,正如我所说的动态,它使用CLR4.0动态表达式:

private void MyButton_Clicked(object sender,  RoutedEventtArgs e)
{
    dynamic tmp = sender;
    tmp.Projection.RotationX = 20;
}

但是,我真的不建议这样做只是为了跳过一些括号。。此表达式中存在ZERO类型检查。这是百分之百的打字。对于按钮来说,这是可以的,因为按钮的API实际上不太可能改变。但对于您自己的代码(经常会发生变异),要小心——或者包括适当的单元测试以确定属性的存在性。

var button = sender as Button;
if (button == null)
    return;
var projection = button.Projection as PlaneProjection;
if (projection == null)
    return;
projection.RotationX = 20;

是一种更安全的方法,因为您要确保强制转换不会引发NullReferenceException。

但是,我必须指出,我宁愿创建一个包含Double X {get;set;}Command的ViewModel,按钮可以绑定到它们,而不是在代码后面操作UI元素。

如果不喜欢括号,可以创建变量。

var button = (Button)sender; // or 'sender as Button'
var planeProjection = (PlaneProjection)button.Projection; // or 'button.Projection as PlaneProjection'

我看不出有任何方法可以获得圆括号和类型转换的簧片。

你不能把它分成吗

var planeProjection = (PlaneProjection)((Button)sender).Projection;

然后

planeProjection.RotationX = 20;
planeProjection.RotationY = 20;
planeProjection.RotationZ = 20;