您的位置:

首页 >

365体育官网备用网址 >

365体育官网备用网址:C# 设计模式系列教程-代理模式 >

365体育官网备用网址:C# 设计模式系列教程-代理模式

2016-11-01 04:12:20

分类:365体育官网备用网址

1. 概述  为其它对象提供一种代理以控制对这个对象的访问。  解决的问题:如果直接访问对象比较困难,或直接访问会给使用者或系统带来一系列问题。这样对于客户端(调用者)来说,就不需要直接与真实对象进行交互,解除了调用者与真实对象的耦合。2. 模式中的角色  2.1 抽象实体(Subject):定义了真实实体(RealSubject)和代理(Proxy)的公共接口,这样就在任何时候使用真实实体(RealSubject)的地方使用代理(Proxy)。  2.2 代理(Proxy):保存一个引用使得代理可以直接访问真实实体,并提供一个与Subject的接口相同的接口,这样代理就可以代替真实实体。  2.3 真实实体(RealSubject):定义Proxy所代表的真实实体。3. 模式解读  3.1 代理模式的类图  3.2 代理模式的代码实现    3.2.1 抽象实体,定义真实实体与代理的公共接口 /// <summary> /// 抽象实体,定义真实实体与代理的公共接口 /// </summary> public interface ISubject { void Function1(); void Function2(); }    3.2.2 真实实体,真正的功能实现者 /// <summary> /// 真实实体,真正的功能实现者 /// </summary> public class RealSubject:ISubject { public void Function1() { Console.WriteLine("This is the first function."); } public void Function2() { Console.WriteLine("This is the second function."); } }    3.2.3 代理,用来控制和访问真实实体 /// <summary> /// 代理,用来访问真实的实体 /// </summary> public class Proxy : ISubject { /// <summary> /// 保存一个真实实体,用以在代理中访问真实实体的功能。 /// </summary> private RealSubject realSubject; public Proxy() { realSubject = new RealSubject(); } /// <summary> /// 实现与Subject相同的接口,实际调用的是RealSubject的Function1() /// </summary> public void Function1() { realSubject.Function1(); } /// <summary> /// 实现与Subject相同的接口,实际调用的是RealSubject的Function2() /// </summary> public void Function2() { realSubject.Function2(); } }    3.2.4 客户端的调用 class Program { static void Main(string[] args) { // 实例化代理 ISubject subjectProxy = new Proxy(); // 通过代理调用具体功能 subjectProxy.Function1(); subjectProxy.Function2(); Console.Read(); } }    3.2.5 运行结果  4. 模式总结  4.1 优点    4.1.1 对客户端来说,隐藏了真实对象的细节及复杂性。    4.1.2 实现了客户端(调用者)与真实对象的松耦合。    4.1.3 远程代理使得客户端可以访问在远程机器上的对象,远程机器可能具有更好的性能与处理速度,可以快速响应并处理客户端请求。    4.1.4 虚拟代理通过使用一个小对象来代表一个大对象,可以减少系统资源的消耗,对系统进行优化并提高运行速度。    4.1.5 安全代理可以控制对真实对象的使用权限。  4.2 缺点    4.2.1 实现代理需要而为增加一个访问控制层,增加了额外工作。有的代理实现起来非常复杂。  4.3 适用场景    4.3.1 远程代理: 为一个位于不同地址空间的的对象提供一个本地的代理。    4.3.2 虚拟代理:如果需要创建一个消耗较大的对象,先创建一个消耗较小的对象来表示,真实对象只在需要时才被真实创建。    4.3.3 安全代理:用来控制对真实对象的访问权限    4.3.4 智能指引:当调用真实对象时,代理提供一些额外的操作。如将对象被操作的次数记录起来等。    4.3.5 缓冲代理:为某一个目标操作提供临时的存储空间,以便更多客户端共享此结果。    4.3.6 防火墙代理:保护目标不让恶意用户接近。    4.3.7 同步化代理:使几个用户能同时使用一个对象而没有冲突。5. 应用举例  5.1 远程代理;.NET的WCF的远程代理  5.2 虚拟代理;HTML图片加载以上就是本文的全部内容,希望能给大家一个参考,也希望大家多多支持脚本之家。

C# 当前系统时间获取及时间格式      最近学习C# 的知识,对获取系统时间和时间格式进行了总结,这是本文在网上整理的详细资料,大家看下!--DateTime 数字型 System.DateTime currentTime=new System.DateTime(); 取当前年月日时分秒 currentTime=System.DateTime.Now; 取当前年 int 年=currentTime.Year; 取当前月 int 月=currentTime.Month; 取当前日 int 日=currentTime.Day; 取当前时 int 时=currentTime.Hour; 取当前分 int 分=currentTime.Minute; 取当前秒 int 秒=currentTime.Second; 取当前毫秒 int 毫秒=currentTime.Millisecond; (变量可用中文) 取中文日期显示——年月日时分 string strY=currentTime.ToString("f"); //不显示秒 取中文日期显示_年月 string strYM=currentTime.ToString("y"); 取中文日期显示_月日 string strMD=currentTime.ToString("m"); 取当前年月日,格式为:2003-9-23 string strYMD=currentTime.ToString("d"); 取当前时分,格式为:14:24 string strT=currentTime.ToString("t"); DateTime.Now.ToString();//获取当前系统时间 完整的日期和时间 DateTime.Now.ToLongDateString();//只显示日期 xxxx年xx月xx日 ,一个是长日期 DateTime.Now.ToShortDateString();//只显示日期 xxxx-xx-xx 一个是短日期 //今天 DateTime.Now.Date.ToShortDateString(); //昨天 的 DateTime.Now.AddDays(-1).ToShortDateString(); //明天 的 DateTime.Now.AddDays(1).ToShortDateString(); //本周(注意这里的每一周是从周日始至周六止) DateTime.Now.AddDays(Convert.ToDouble((0 - Convert.ToInt16(DateTime.Now.DayOfWeek)))).ToShortDateString(); DateTime.Now.AddDays(Convert.ToDouble((6 - Convert.ToInt16(DateTime.Now.DayOfWeek)))).ToShortDateString(); //上周,上周就是本周再减去7天 DateTime.Now.AddDays(Convert.ToDouble((0 - Convert.ToInt16(DateTime.Now.DayOfWeek))) - 7).ToShortDateString(); DateTime.Now.AddDays(Convert.ToDouble((6 - Convert.ToInt16(DateTime.Now.DayOfWeek))) - 7).ToShortDateString(); //下周 本周再加上7天 DateTime.Now.AddDays(Convert.ToDouble((0 - Convert.ToInt16(DateTime.Now.DayOfWeek))) + 7).ToShortDateString(); DateTime.Now.AddDays(Convert.ToDouble((6 - Convert.ToInt16(DateTime.Now.DayOfWeek))) + 7).ToShortDateString(); //本月 本月的第一天是1号,最后一天就是下个月一号再减一天。 DateTime.Now.Year.ToString() + DateTime.Now.Month.ToString() + "1"; //第一天 DateTime.Parse(DateTime.Now.Year.ToString() + DateTime.Now.Month.ToString() + "1").AddMonths(1).AddDays(-1).ToShortDateString();//最后一天 另一种方法: DateTime now = DateTime.Now; DateTime d1 = new DateTime(now.Year, now.Month, 1); //本月第一天 DateTime d2 = d1.AddMonths(1).AddDays(-1); //本月最后一天 PS: DateTime.Now.DayOfWeek.ToString();//英文星期显示,Wednesday (int)DateTime.Now.DayOfWeek 数字,若是周三,结果对应为3 DateTime.Now.ToString("dddd", new System.Globalization.CultureInfo("zh-cn")); //中文星期显示 DateTime.Now.ToString("dddd");//中文星期显示 DateTime.Now.ToString("dddd,MMMM,dd ,yyyy", new System.Globalization.DateTimeFormatInfo());//显示日期格式Friday,July, 01,2009 DateTime.Now.ToString("dddd,dd MMMM,yyyy") //输出 星期三,30 一月,2008 出处:http://msdn.microsoft.com/zh-cn/vstudio/bb762911(VS.95).aspx,如何:从特定日期中提取星期几 datetime类型在tostring()format的格式设置  参数format格式详细用法    格式字符 关联属性/说明    d ShortDatePattern    D LongDatePattern    f 完整日期和时间(长日期和短时间)    F FullDateTimePattern(长日期和长时间)    g 常规(短日期和短时间)    G 常规(短日期和长时间)    m、M MonthDayPattern    r、R RFC1123Pattern    s 使用当地时间的 SortableDateTimePattern(基于 ISO 8601)    t ShortTimePattern    T LongTimePattern    u UniversalSortableDateTimePattern 用于显示通用时间的格式    U 使用通用时间的完整日期和时间(长日期和长时间)    y、Y YearMonthPattern  下表列出了可被合并以构造自定义模式的模式。这些模式是区分大小写的     d 月中的某一天。一位数的日期没有前导零。    dd 月中的某一天。一位数的日期有一个前导零。    ddd 周中某天的缩写名称,在 AbbreviatedDayNames 中定义。    dddd 周中某天的完整名称,在 DayNames 中定义。    M 月份数字。一位数的月份没有前导零。    MM 月份数字。一位数的月份有一个前导零。    MMM 月份的缩写名称,在 AbbreviatedMonthNames 中定义。    MMMM 月份的完整名称,在 MonthNames 中定义。    y 不包含纪元的年份。如果不包含纪元的年份小于 10,则显示不具有前导零的年份。    yy 不包含纪元的年份。如果不包含纪元的年份小于 10,则显示具有前导零的年份。    yyyy 包括纪元的四位数的年份。    gg 时期或纪元。如果要设置格式的日期不具有关联的时期或纪元字符串,则忽略该模式。     h 12 小时制的小时。一位数的小时数没有前导零。    hh 12 小时制的小时。一位数的小时数有前导零。    H 24 小时制的小时。一位数的小时数没有前导零。    HH 24 小时制的小时。一位数的小时数有前导零。 感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

一、结构和类的区别1、结构的级别和类一致,写在命名空间下面,可以定义字段、属性、方法、构造方法也可以通过关键字new创建对象。2、结构中的字段不能赋初始值。3、无参数的构造函数无论如何C#编译器都会自动生成,所以不能为结构定义一个无参构造函数。4、在构造函数中,必须给结构体的所有字段赋值。5、在构造函数中,为属性赋值,不认为是对字段赋值,因为属性不一定是去操作字段。6、结构是值类型,在传递结构变量的时候,会将结构对象里的每一个字段复制一份拷贝到新的结构变量的字段中。7、不能定义自动属性,因为字段属性会生成一个字段,而这个字段必须要求在构造函数中,但我们不知道这个字段叫什么名字。8、声明结构体对象,可以不使用new关键字,但是这个时候,结构体对象的字段没有初始值,因为没有调用构造函数,构造函数中必须为字段赋值,所以,通过new关键字创建结构体对象,这个对象的字段就有默认值。9、栈的访问速度快,但空间小,堆的访问速度慢,但空间大,当我们要表示一个轻量级的对象的时候,就定义为结构,以提高速度,根据传至的影响来选择,希望传引用,则定义为类,传拷贝,则定义为结构。二、Demo复制代码 代码如下:struct Point    {        public Program p;        private int x;        public int X        {            get { return x; }            set { x = value; }        }        private int y;        public int Y        {            get { return y; }            set { y = value; }        }        public void Show()        {            Console.Write("X={0},Y={1}", this.X, this.Y);        }        public Point(int x,int y)        {            this.x = x;            this.y = y;            this.p = null;        }        public Point(int x)        {            this.x = x;            this.y = 11;            this.p = null;        }        public Point(int x, int y, Program p)        {            this.x = x;            this.y = y;            this.p = p;        }    }    class Program    {        public string Name { get; set; }        static void Main(string[] args)        {            //Point p = new Point();            //p.X = 120;            //p.Y = 100;            //Point p1 = p;            //p1.X = 190;            //Console.WriteLine(p.X);            //Point p;            //p.X = 12;//不赋值就会报错            //Console.WriteLine(p.X);            //Point p1 = new Point();            //Console.WriteLine(p1.X);//此处不赋值不会报错,原因见区别8            Program p = new Program() { Name="小花"};            Point point1 = new Point(10, 10, p);            Point point2 = point1;            point2.p.Name = "小明";            Console.WriteLine(point1.p.Name);//结果为小明,

通常我们的情况是,双击一个exe文件,就运行一个程序的实体,再双击一次这个exe文件,又运行这个应用程序的另一个实体。就拿QQ游戏来说吧,一台电脑上一般只能运行一个QQ游戏大厅(不过以前听说过有双开的外挂)。那我们的程序也能像QQ游戏那里禁止多次启动吗,答案是可以的,下面介绍下一个简单的实现方法,那就是Mutex(互斥)。      Mutex(mutual exclusion,互斥)是.Net Framework中提供跨多个线程同步访问的一个类。它非常类似了Monitor类,因为他们都只有一个线程能拥有锁定。而操作系统能够识别有名称的互斥,我们可以给互斥一个唯一的名称,在程序启动之前加一个这样的互斥。这样每次程序启动之前,都会检查这个命名的互斥是否存在。如果存在,应用程序就退出。复制代码 代码如下:static class Program    {        /// <summary>        /// The main entry point for the application.        /// </summary>        [STAThread]        static void Main()        {            bool createdNew;            //系统能够识别有名称的互斥,因此可以使用它禁止应用程序启动两次            //第二个参数可以设置为产品的名称:Application.ProductName            //每次启动应用程序,都会验证名称为SingletonWinAppMutex的互斥是否存在            Mutex mutex = new Mutex(false, "SingletonWinAppMutex", out createdNew);            //如果已运行,则在前端显示            //createdNew == false,说明程序已运行            if (!createdNew)            {                Process instance = GetExistProcess();                if (instance != null)                {                    SetForegroud(instance);                    Application.Exit();                    return;                }            }            Application.EnableVisualStyles();            Application.SetCompatibleTextRenderingDefault(false);            Application.Run(new MainForm());        }        /// <summary>        /// 查看程序是否已经运行        /// </summary>        /// <returns></returns>        private static Process GetExistProcess()        {            Process currentProcess = Process.GetCurrentProcess();            foreach (Process process in Process.GetProcessesByName(currentProcess.ProcessName))            {                if ((process.Id != currentProcess.Id) &&                     (Assembly.GetExecutingAssembly().Location == currentProcess.MainModule.FileName))                {                    return process;                }            }            return null;        }        /// <summary>        /// 使程序前端显示        /// </summary>        /// <param name="instance"></param>        private static void SetForegroud(Process instance)        {            IntPtr mainFormHandle = instance.MainWindowHandle;            if (mainFormHandle != IntPtr.Zero)            {                ShowWindowAsync(mainFormHandle, 1);                SetForegroundWindow(mainFormHandle);            }        }        [DllImport("User32.dll")]        private static extern bool SetForegroundWindow(IntPtr hWnd);        [DllImport("User32.dll")]        private static extern bool ShowWindowAsync(IntPtr hWnd,

复制代码 代码如下:using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace ConsoleApplication1 {     class Program     {         static void Main(string[] args)         {             Console.WriteLine("Main ThreadId = " + Thread.CurrentThread.ManagedThreadId);             //给委托赋值             Func<long, long> delegateMethod = new Func<long, long>(CalcSum);             //异步执行委托,这里把委托本身作为asyncState对象传进去,在回调函数中需要使用委托的EndInvoke来获得结果             delegateMethod.BeginInvoke(200, DoneCallback, delegateMethod);             //异步执行委托,抛出异常             delegateMethod.BeginInvoke(10000000000, DoneCallback, delegateMethod);             Console.ReadLine();         }         //委托回调函数         static void DoneCallback(IAsyncResult asyncResult)         {             //到这儿委托已经在异步线程中执行完毕             Console.WriteLine("DoneCallback ThreadId = " + Thread.CurrentThread.ManagedThreadId);             Func<long, long> method = (Func<long, long>)asyncResult.AsyncState;             //委托执行的异常会在EndInvoke时抛出来             try {                 //使用BeginInvoke时传入委托的EndInvoke获得计算结果,这时候计算结果已经出来了,有异常的话也在这儿抛出来                 long sum = method.EndInvoke(asyncResult);                 Console.WriteLine("sum = {0}",

焦点访谈

最新最热的文章

更多 >

COPYRIGHT (©) 2017 Copyright ©2017 365体育在线备用网址 网站地图

联系我们

827570882

扫描二维码分享到微信