C#动态getter和setter取决于应用程序上下文
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了C#动态getter和setter取决于应用程序上下文,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3637字,纯文字阅读大概需要6分钟。
内容图文
![C#动态getter和setter取决于应用程序上下文](/upload/InfoBanner/zyjiaocheng/816/195fdac3e36e42a691fa3ef22b81125e.jpg)
我们有一个函数库,一些实用程序变量以两种不同的方式存储,具体取决于应用程序上下文桌面应用程序/网站
在网站中我们使用Sessions和桌面静态变量,我们希望联合并自动化这些变量的getter // setter而不会影响性能太多
例:
public static class Cons
{
public static bool webMode;
}
public static class ConsWEB
{
public static string Username
{
get{ return HttpContext.Current.Session["username"].ToString();}
set{ HttpContext.Current.Session["username"]=value;}
}
}
public static class ConsAPP
{
private static string _username;
public static string Username
{
get{ return _username;}
set{ _username=value;}
}
}
解决方案1我们认为,使用IF(对性能似乎不好,多次考虑访问变量,在某些情况下变量是具有复杂内容的自定义类):
public static class Cons
{
public static bool webMode;
public static string Username
{
get{ return webMode? ConsWEB.Username : ConsAPP.Username; }
set
{
if(webMode) { ConsWEB.Username = value; }
else { ConsAPP.Username = value; }
}
}
}
解决方案2使用委托,在静态类构造函数中将委托方法关联到每个get和set,具体取决于具体情况.如果webMode指向ConsWEB的get / set方法,否则指向ConsAPP的get / set方法…
解决方案2是性能最佳的解决方案吗?这种情况还有其他方法吗?
解决方法:
两者都不是最佳的……
首先,先忘掉性能思维设计.
你应该通过一个接口或类似的方式来做:
public interface IConsProvider
{
string UserName { get; set; }
}
现在你的实现(注意:你不应该在同一个程序集中同时编译桌面和Web.例如,System.Web在Client Profile中不可用 – 你应该真正用于桌面应用程序).
public class WebConsProvider : IConsProvider
{
public string UserName
{
// DON'T USE .ToString()! If it's null you get NullReferenceException!
get{ return HttpContext.Current.Session["username"] as string; }
set{ HttpContext.Current.Session["username"]=value; }
}
}
public class DefaultConsProvider : IConsProvider
{
public string UserName
{
get; set;
}
}
然后你的环境静态:
public static class Cons
{
//initialise to default as well - only web apps need change it
private static IConsProvider _provider = new DefaultConsProvider();
public static IConsProvider Provider
{
get { return _provider; }
set { _provider = value; /* should check for null here and throw */ }
}
//if you really want you can then wrap the properties
public static string UserName
{
get {
return _provider.UserName;
}
set {
_provider.UserName = value;
}
}
}
现在您拥有一个可扩展的提供程序,您无需担心其实现.
我个人也有一个包装HttpContext.Current的问题 – 但是在大多数情况下工作正常 – 但是如果你有任何异步,那么你必须要小心.
另外 – 正如我在评论中提到的那样 – 你现在不再需要将属性包装为Cons中的静态属性.实际上,通过更改这样的代码,您获得了大量的可测试性和可扩展性:
public void TraceUserName()
{
Trace.WriteLine(Cons.UserName ?? "[none]");
}
对此:
public void TraceUserName(IConsProvider provider)
{
Trace.WriteLine(provider.UserName ?? "[none]");
}
相信我会在你的代码中有些时候你会希望“只是为了这个调用我想覆盖UserName – 但我不能,因为它是一个静态属性”.
最后,您现在可以使用另一种扩展性机制,而不是使用静态扩展方法.
假设您为字符串的接口添加了一个通用存储机制:
string this[string key] { get; set; }
所以这是一个字符串索引器,允许我们为不可预见的值实现类似字典的功能.假设它们都已实现,使用Dictionary< string,string>在DefaultConsProvider中并将Session包装在WebConsProvider中).
现在,如果我正在为您的项目编写一个额外的模块,需要一些额外的字符串值 – 我可以这样做:
public static MySettingsExtensions
{
public static string GetMySetting(this IConsProvider provider)
{
//TODO: argument null checks
return provider["MySetting"];
}
public static void SetMySetting(this IConsProvider provider, string val)
{
provider["MySetting"]=val;
}
}
(抱歉必须更新最后一位因为某些原因我参数化了密钥 – 这是没有意义的!)
也就是说 – 我们现在可以通过扩展方法开始扩展提供者提供的强类型设置的范围 – 而无需更改任何原始代码.
内容总结
以上是互联网集市为您收集整理的C#动态getter和setter取决于应用程序上下文全部内容,希望文章能够帮你解决C#动态getter和setter取决于应用程序上下文所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。