依赖于条件的属性分配

时间:2013-07-28 21:22:12

标签: c# .net design-patterns compilation

最近,我正在重写一些旧代码,特别是缩减太长的函数(减少开销,扩展可读性等等)。因此,我弄清楚实际上有用的东西:

班级定义

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?

有人可以向我解释一下这是如何运作的吗?这巫术是什么?当然,我可以像共享一个公共基类一样处理这两个实例,但是我只将其中一个投射到基类中,并且我正在根据条件进行属性赋值。此外,这被认为是一种好的做法,还是有任何重大的缺点,我看不到?

3 个答案:

答案 0 :(得分:1)

您正在使用conditional operator(?)类似于此更加可更新的if

if (a == null)
    b.BaseProperty = "...";
else
    a.BaseProperty = "...";
Console.WriteLine(b.BaseProperty);

此代码中的演员

(a == null ? (BaseClass)b : a).BaseProperty = "..."
只需要

因为条件运算符需要知道类型。条件表达式的类型必须对两者都一致。

所以在我看来这是不好的做法,因为你不清楚你在做什么。


为什么需要转换为BaseClass:C#5.0规范的相关部分是7.14,条件运算符:

?:运算符的第二个和第三个操作数x和y控制条件表达式的类型。

  • 如果x的类型为X,则y的类型为Y.
    • 如果从X到Y存在隐式转换(第6.1节),而不是从Y到X,则Y是条件表达式的类型。
    • 如果从Y到X存在隐式转换(第6.1节),而不是从X到Y,则X是条件表达式的类型。
  • 否则,无法确定表达式类型,并且发生编译时错误

因为ClassAClassB之间没有隐式转换(它们只有相同的基类),所以你必须将其转换为mnaually。

答案 1 :(得分:1)

 (a == null ? (BaseClass)b : a)

 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;

答案 2 :(得分:1)

  

有人可以向我解释这是如何运作的吗?

当然 - 它只是一个表达式,使用条件运算符来选择用于表达式的 rest 的值。表达式的整体类型为BaseClass,因为这是第二个操作数的确切类型,第三个操作数可以转换为它。您需要对操作数的一个进行强制转换,因为表达式的整体类型必须 第二个操作数的类型第三个操作数的类型......但ClassAClassB都不合适。

  

此外,这被视为一种良好的做法,还是有任何重大的缺点,我看不到?

对我来说这看起来很难看。我会使用null-coalescing运算符,为了清楚起见将其提取到一个单独的局部变量中:

BaseClass target = a ?? (BaseClass) b;
target.BaseProperty = "Jon Skeet prefers this approach";

可以仍然在一个语句中执行它,但我发现它的可读性较低:

(a ?? (BaseClass) b).BaseProperty = "Jon Skeet doesn't like 'clever' code.";

更好的做法是将ab声明为BaseClass类型,此时您不需要演员。