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;
这仍然是比我想要的更多的括号。
我是走了很长的路还是错过了什么?或者就是这样,我将不得不处理像这样更难阅读的代码的可能性?
(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;