[英]Condition-depending property assignment
Recently, I was rewriting some old code, especially shrink too long functions (reduce overhead, extend readability etc..). 最近,我正在重写一些旧代码,尤其是缩小太长的功能(减少开销,扩展可读性等)。 Thereby I stumpled about something that actually works:
因此,我为实际起作用的东西而苦恼:
public abstract class BaseClass {
public string BaseProperty { get; set; }
}
public sealed class ClassA : BaseClass {
public string PropertyA { get; set; }
}
public sealed class ClassB : BaseClass {
public string PropertyB { get; set; }
}
ClassA a = null;
ClassB b = new ClassB();
(a == null ? (BaseClass)b : a).BaseProperty = "What would Jon Skeet think about this?";
Console.WriteLine(b.BaseProperty);
What would Jon Skeet think about this?
Can someone explain to me how this works? 有人可以向我解释这是如何工作的吗? What is this sorcery?
这是什么法术? Of course I can handle both instances the same way as they share a common base class, but I'm only casting one of them to the base class and I'm doing a property assignment based on a condition.
当然,我可以用它们共享一个公共基类的方式来处理这两个实例,但是我只将其中一个强制转换为基类,并且根据条件进行属性分配。 Also, is this considered as a good practice or are there any significant downsides I just can't see?
另外,这被认为是一种好的做法吗?或者我是否看不到任何重大的缺点?
You are using the conditional operator(?) similiar to this more redable if
: 您正在使用条件运算符(?)类同这更redable
if
:
if (a == null)
b.BaseProperty = "...";
else
a.BaseProperty = "...";
Console.WriteLine(b.BaseProperty);
The cast in this code 此代码中的演员表
(a == null ? (BaseClass)b : a).BaseProperty = "..."
is just needed because the conditional operator needs to know the type. 仅需要此操作是因为条件运算符需要知道类型。 The type of the conditional expression must be consistent for both.
这两个条件表达式的类型必须一致。
So in my opinion it's bad practise since it's not clear what you're doing. 因此,我认为这是不好的做法,因为不清楚您在做什么。
Why the cast to BaseClass
is required: the relevant section of the C# 5.0 spec is 7.14, the conditional operator: 为什么需要
BaseClass
为BaseClass
:C#5.0规范的相关部分为7.14,条件运算符为:
The second and third operands, x and y, of the ?: operator control the type of the conditional expression. ?:运算符的第二和第三操作数x和y控制条件表达式的类型。
So since there is no implicit conversion between ClassA
and ClassB
(they have just the same base class), you have to cast it mnaually. 因此,由于在
ClassA
和ClassB
之间没有隐式转换(它们具有相同的基类),因此您必须手动转换它。
(a == null ? (BaseClass)b : a)
is 是
BaseClass x = null;
if(a == null)
x = (BaseClass)b;
else
x = (BaseClass)a; // Here is implicit cast to the type of the second argument of ? operator
return x;
Can someone explain to me how this works?
有人可以向我解释这是如何工作的吗?
Sure - it's just an expression using the conditional operator to pick which value to use for the rest of the expression. 当然-这只是一个使用条件运算符的表达式,用于选择在表达式的其余部分中使用哪个值。 The overall type of the expression is
BaseClass
because that's the exact type of the second operand, and the third operand can be converted to it. 表达式的整体类型为
BaseClass
因为这是第二个操作数的确切类型,第三个操作数可以转换为该类型。 You need the cast on one of the operands, because the overall type of the expression has to be either the type of the second operand or the type of the third operand... but neither ClassA
nor ClassB
are suitable. 您需要对其中一个操作数进行强制转换,因为表达式的整体类型必须是第二个操作数的类型或第三个操作数的类型……但是
ClassA
和ClassB
都不适合。
Also, is this considered as a good practice or are there any significant downsides I just can't see?
另外,这被认为是一种好的做法吗?或者我是否看不到任何重大的缺点?
Well it looks pretty ugly to me. 好吧,对我来说看起来很丑。 I'd use the null-coalescing operator instead, and extract it into a separate local variable for clarity:
我将改用null-coalescing运算符,并将其提取到一个单独的局部变量中以清楚显示:
BaseClass target = a ?? (BaseClass) b;
target.BaseProperty = "Jon Skeet prefers this approach";
You could still do it in one statement, but I find that less readable: 你仍然可以做到这一点在一个声明中,但我发现,不易阅读:
(a ?? (BaseClass) b).BaseProperty = "Jon Skeet doesn't like 'clever' code.";
Even better would be to declare either a
or b
as being of type BaseClass
, at which point you don't need the cast. 更好的方法是将
a
或b
声明为BaseClass
类型,此时您不需要强制转换。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.