【问题标题】:Extension method and Explicit casting扩展方法和显式转换
【发布时间】:2012-01-08 13:08:59
【问题描述】:

我正在使用某些程序集中的类(源代码不可用),因此无法更改其代码 我需要为显式转换运算符添加扩展方法,有什么方法可以实现吗? (我尝试添加为常规扩展方法,但没有成功)

 public static explicit operator MembershipUser(this MembershipUser membership, User user)
    {
        return new MembershipUser("SimplyMembershipProvider", user.UserName, user.UserId, user.Email, null, null, user.IsApproved, user.IsLocked,
            user.CreateDate, user.LastLoginDate, user.LastActivityDate, user.CreateDate, DateTime.MinValue);
    }

我该如何解决这个问题?

【问题讨论】:

标签: c# .net casting extension-methods explicit-conversion


【解决方案1】:

不,您不能添加扩展转换。

只有当您控制其中一种类型的源代码时,才能定义显式或隐式转换。在您的情况下,您可以控制MembershipUserUser,您不需要同时控制两者。但是你必须控制一个。

如果您都不控制,您只需在其他类的方法中定义转换,该类的工作就是控制这种转换。

class UserConverter 
{
    public MembershipUser ConvertFrom(User user) 
    {
        return ...
    }
}

【讨论】:

    【解决方案2】:

    您不能通过扩展方法重载运算符。

    使用扩展方法可以做到的最好的事情:

    public static MembershipUser ConvertToMembershipUser(this User user)
    {
        return new MembershipUser("SimplyMembershipProvider", 
                                  user.UserName, 
                                  user.UserId, 
                                  user.Email, 
                                  null, 
                                  null, 
                                  user.IsApproved, 
                                  user.IsLocked,
                                  user.CreateDate, 
                                  user.LastLoginDate, 
                                  user.LastActivityDate,
                                  user.CreateDate, 
                                  DateTime.MinValue);
    }
    
    MembershipUser membershipUser = aUser.ConvertToMembershipUser();
    

    【讨论】:

    • 快速迂腐点:您根本不能 覆盖 运算符 - 您可以 重载 它们 - 但不能使用扩展方法,如您所说。
    • @JonSkeet - 交替使用覆盖和重载是我的一个坏习惯,尽管我知道得更好。 :)
    【解决方案3】:

    正如其他人所说,您不能使用扩展方法重载运算符 - 但简单的扩展方法仍然有用:

    public static MembershipUser ToMembershipUser(this User user)
    {
        return new MembershipUser("SimplyMembershipProvider",
            user.UserName, user.UserId, user.Email, null, null, 
            user.IsApproved, user.IsLocked, user.CreateDate, 
            user.LastLoginDate, user.LastActivityDate, user.CreateDate,
            DateTime.MinValue);
    }
    

    然后将其用作:

    User user = ...;
    MembershipUser membershipUser = user.ToMembershipUser();
    

    我个人觉得这比使用显式转换更清楚——我很少使用运算符重载。特别是,考虑到这些类确实听起来相关,一个天真的用户可能会期望这个代码:

    User user = ...;
    MembershipUser membershipUser = (MembershipUser) user;
    

    ... 是一个普通的引用转换,期望MembershipUser 是一个派生自User 的类。这在对象身份方面很重要 - 如果 的情况,它不会更改所涉及的对象(并且对 user 引用的对象的更改仍然可以通过 @987654327 看到@)。

    创建ToMembershipUser 方法可以更清楚地表明您正在从一种形式转换为另一种类型的新对象。当然,所有 IMO :)

    【讨论】:

      【解决方案4】:

      不是说这是一个好习惯(阅读其他答案,了解为什么不希望这样做,但如果类没有密封,这是可能的,只是不使用扩展方法)。

      基本上,您可以创建一个代理类,继承定义强制转换运算符的 User,例如:

          class UserSurrogate : User
          {
              public static explicit operator UserSurrogate(MemberShipUser other)
              {
                  return  new UserSurrogate() { Name = other.Name };
              }
          }
      
          class User
          {
              public string Name { get; set; }
          }
      
          class MemberShipUser
          {
              public string Name { get; set; }   
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-04-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多