【问题标题】:C# Nested Property Accessing overloading OR Sequential Operator OverloadingC# 嵌套属性访问重载或顺序运算符重载
【发布时间】:2010-04-15 17:59:00
【问题描述】:

嘿,我一直在寻找解决我们在代码库中遇到的棘手问题的方法。

首先,我们的代码如下所示:

class User
{ 
   int id;
   int accountId;

   Account account
   {
     get { return Account.Get(accountId); }
   }     
}

class Account
{
   int accountId;
   OnlinePresence Presence
   {
      get { return OnlinePresence.Get(accountId); }  
   } 
   public static Account Get(int accountId)
   {
      // hits a database and gets back our object.
   }
}

class OnlinePresence
{
   int accountId;
   bool isOnline;
   public static OnlinePresence Get(int accountId)
   {
      // hits a database and gets back our object.
   }
}

我们在代码中经常做的是尝试通过以下方式访问用户的帐户状态

var presence = user.Account.Presence;

问题在于这实际上是向数据库发出两个请求。一个获取 Account 对象,然后一个获取 Presence 对象。如果我们执行以下操作,我们可以轻松地将其归结为一个请求:

var presence = UserPresence.Get(user.id);

这可行,但有点要求开发人员了解 UserPresence 类/方法,这样可以很好地消除。

我想了几个很酷的方法来处理这个问题,我想知道是否有人知道这些是否可行,是否有其他方法来处理这个问题,或者我们是否需要更多地思考我们正在编写代码并执行 UserPresence.Get 而不是使用属性。

  1. 重载嵌套访问器。 如果在 User 类中我可以编写某种“扩展”,它会说“任何时候访问 User 对象的 Account 属性的 Presence 对象,都可以这样做”。

  2. 重载 .操作员知道接下来会发生什么。 如果我能以某种方式使 .运算符仅在右侧的对象也被“点缀”的情况下会很棒。

这两个似乎都可以在编译时处理,但也许我遗漏了一些东西(反射会使这变得困难吗?)。我是否完全错误地看待事物?有没有一种方法可以消除业务逻辑用户的负担?

谢谢! 蒂姆

【问题讨论】:

    标签: c# properties operator-overloading accessor


    【解决方案1】:

    为什么不采用存储库模式并拥有以下内容:

    public class UserPresenceRepository
    {
        public UserPresenceRepository(string connString)
        {
            // configure db properties
        }
    
        public UserPresence GetPresence(User user)
        {
            // get precense from user.accountId if possible 
            // and skip the trip for Account
        }
    }
    

    所以你的调用代码看起来像:

    UserPresenceRepository repo = new UserPresenceRepository(connString);
    repo.GetPresence(user);
    

    如果您需要用户状态信息,最终结果是要调用的存储库的明确定义。 GetPresence 方法也清楚地对User 对象进行操作,而不是要求开发人员知道要传入哪个 Id。

    这里的另一个选项是停止延迟加载您的对象。这样一来,您就可以一次将所需的所有内容加载到数据库中并准备就绪。

    【讨论】:

      【解决方案2】:

      认为代理模式更好。

      class User
      {
          int id;
          int accountId;
      
          Account Account
          {
              get { return new ProxyAccount(accountId); }
          }
      }
      
      abstract class Account
      {
          protected int accountId;
      
          protected Account(int accountId)
          {
              this.accountId = accountId;
          }
      
          public OnlinePresence Presence
          {
             get { return new ProxyOnlinePresence(accountId); }
          }
      
          /*
              other properties of the Account go here as abstract properties
      
              public abstract string SomeProperty { get; set; }
      
          */
      
          public static Account Get(int accountId)
          {
              // hits a database and returns an instance of DBAccount.
          }
      }
      
      class ProxyAccount : Account
      {
          private Account account;
          public ProxyAccount(int accountId) : base(accountId)
          {
          }
      
          private Account GetAccount()
          {
              if (account == null)
                  account = Account.Get(accountId);
              return account;
          }
      
          /*
              Accounts abstract properties are implemented here
      
              public override string SomeProperty
              {
                  get { return GetAccount().SomeProperty; }
                  set { GetAccount().SomeProperty = value; }
              }
          */
      }
      
      class DBAccount : Account
      {
          public DBAccount(int accountId) : base(accountId)
          {
          }
      
          /*
              Accounts abstract properties are implemented here
      
              public override string SomeProperty { get; set; }
          */
      }
      

      我只是向您展示了仅使用 Account 类的方法,但您也必须使用 OnlinePresence 来实现(如您所见,我假设您将拥有一个 ProxyOnlinePresence 类)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-10-11
        • 2018-04-28
        • 2023-04-03
        • 2011-11-15
        • 1970-01-01
        • 2014-04-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多