C# 嵌套属性访问重载或顺序运算符重载
嘿,我一直在寻找我们的代码库遇到的棘手问题的解决方案。
首先,我们的代码类似于以下内容:
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 而不是使用属性。
重载嵌套访问器。 如果在 User 类中我可以编写某种“扩展”,表示“只要访问 User 对象的 Account 属性的 Presence 对象,就执行此操作”,那就太酷了。
超载 .操作员知道接下来会发生什么。 如果我能以某种方式使 .运算符仅在右侧对象也被“点缀”的情况下使用,那就太好了。
这两件事看起来都可以在编译时处理,但也许我遗漏了一些东西(反射会让这变得困难吗?)。我看待事物的方式完全错误吗?有没有一种方法可以强制执行此操作,从而减轻业务逻辑用户的负担?
谢谢! 蒂姆
Hey, I've been searching around for a solution to a tricky problem we're having with our code base.
To start, our code resembles the following:
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.
}
}
What we're often doing in our code is trying to access the account Presence of a user by doing
var presence = user.Account.Presence;
The problem with this is that this is actually making two requests to the database. One to get the Account object, and then one to get the Presence object. We could easily knock this down to one request if we did the following :
var presence = UserPresence.Get(user.id);
This works, but sort of requires developers to have an understanding of the UserPresence class/methods that would be nice to eliminate.
I've thought of a couple of cool ways to be able to handle this problem, and was wondering if anyone knows if these are possible, if there are other ways of handling this, or if we just need to think more as we're coding and do the UserPresence.Get instead of using properties.
Overload nested accessors.
It would be cool if inside the User class I could write some sort of "extension" that would say "any time a User object's Account property's Presence object is being accessed, do this instead".Overload the . operator with knowledge of what comes after.
If I could somehow overload the . operator only in situations where the object on the right is also being "dotted" it would be great.
Both of these seem like things that could be handled at compile time, but perhaps I'm missing something (would reflection make this difficult?). Am I looking at things completely incorrectly? Is there a way of enforcing this that removes the burden from the user of the business logic?
Thanks!
Tim
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
为什么不采用存储库模式并具有以下内容:
因此您的调用代码将如下所示:
最终结果是一个存储库的明确定义,如果您需要用户状态信息,则可以调用该存储库。
GetPresence
方法还明确地对User
对象进行操作,而不是要求开发人员知道要传入哪个 Id。此处的另一个选项是停止延迟加载对象。这样您就可以一次性加载所需的所有内容到数据库并准备就绪。
Why not go with the Repository pattern and have the following:
So your calling code would look like:
The end result is a clear definition of a Repository to call if you need User Presence information. The
GetPresence
method also clearly operates on theUser
object instead of requiring developers to know which Id to pass in.The other option here would to stop lazy loading your objects. That way you can load everything you need in one trip to the database and have it ready.
认为代理模式更好。
我刚刚向您展示了仅使用 Account 类的方法,但您还必须使用 OnlinePresence 来完成此操作(如您所见,我假设您将有一个 ProxyOnlinePresence 类)。
Think it's better the Proxy pattern.
I just showed you the way only with Account class, but you also have to do it with OnlinePresence as well (as you can see, I've assumed you'll have a ProxyOnlinePresence class).