繁体   English   中英

C#嵌套属性访问重载或顺序运算符重载

[英]C# Nested Property Accessing overloading OR Sequential Operator Overloading

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

首先,我们的代码类似于以下内容:

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. 重载。 操作员了解之后的情况。 如果我能以某种方式让它超载。 仅在右边的对象也被“点缀”的情况下,才算是最佳操作员。

两者似乎都可以在编译时进行处理,但是也许我缺少了一些东西(反射会很难吗?)。 我完全看错了吗? 有没有一种执行此方法的方法,可以减轻业务逻辑用户的负担?

谢谢! 提姆

为什么不采用存储库模式并具有以下功能:

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。

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

认为最好使用代理模式。

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类)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM