【问题标题】:Should explicit operators return null in c#?显式运算符应该在 C# 中返回 null 吗?
【发布时间】:2011-10-18 03:30:21
【问题描述】:

我正在编写一些显式运算符来将数据库模型类型转换为我的域模型。像这样(简化示例):

public static explicit operator DomainModel.Role(Role roleEntity)
{
   DomainModel.Role role = new DomainModel.Role
   {
      RoleId = roleEntity.RoleId,
      Name = roleEntity.Name
   };

   return role;
}

但是,roleEntity 参数可能为空。大多数时候,在 .net 框架中,空实例的显式转换会导致异常。像这样:

user.Role = (DomainModel.Role)_userRepository.GetRole(user); // Would normally results in a NullReferenceException

但是如果显式操作符被调整,上面将按预期运行:

public static explicit operator DomainModel.Role(Role roleEntity)
{
   DomainModel.Role role = roleEntity == null ? null : new DomainModel.Role
   {
      RoleId = roleEntity.RoleId,
      Name = roleEntity.Name
   };

   return role;
}

问题:

  • 创建这样的显式运算符是否合乎逻辑?

【问题讨论】:

  • 我会认真考虑用命名空间前缀编写第二个角色。

标签: c# .net casting operators


【解决方案1】:

对于标题问题:允许抛出显式运算符(而隐式运算符不应该)。

但是null 是否是这样做的正当理由是一个设计决定,我认为不是。

考虑:

object x = null;
string t = (string)x;

抛出。

【讨论】:

  • 我猜你是对的。抛出 NullReferenceException 是某种预期的行为。
【解决方案2】:

我会使用诸如AutoMapper 之类的库来促进相似类型之间的转换。您可以获得更大的灵活性并编写更少的代码。恕我直言,在阅读代码时使用显式转换运算符不太容易理解,当它可能是非常复杂的映射代码时,它给人的印象是这是一种廉价的操作。

【讨论】:

  • 了解您的想法。感谢您的建议。
【解决方案3】:

我认为是的。将null 引用转换为另一种类型通常会产生null 引用,以匹配正常语义。

例如因为这有效:

object x = null;
var role = (DomainModel.Role)x;

这也应该有效:

Role x = null;
var role = (DomainModel.Role)x;

【讨论】:

    【解决方案4】:

    恕我直言不,你不应该这样做。

    我认为两者之间没有任何区别:

     string myString= (string)null;
    

     Object o = null;
     string myString= (string)o;
    

    在这两种情况下,我都希望返回 null,这是默认行为(我也不推荐 NullReferenceException,因为上面的两个代码 sn-ps 都完全有效:两个显式转换都返回 null)。

    null 引用可以以某种方式转换为默认对象,这有点令人困惑:

    object o = null;
    string myString = (string)o; //myString == String.Empty WTF?
    

    如果这种情况有意义,我将通过构造函数或特定的静态方法来实现它,很明显您正在创建一个新对象,从不通过隐式或显式运算符。

    强制转换操作符应该做的就是应该做的:从一种类型转换为另一种类型。 null 只能“转换”为null

    【讨论】:

    • @Henk Holterman:一点也不。问题是我不确定 C# 中的默认行为是什么。一旦我确认强制转换 null 不会抛出,那么答案是显而易见的 IMO(我一开始错误地认为默认行为是抛出)。基本思想保持不变:不要改变预期的行为。
    猜你喜欢
    • 1970-01-01
    • 2016-03-29
    • 1970-01-01
    • 2011-03-24
    • 1970-01-01
    • 2015-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多