• C#相关


    1.索引器

     索引器允许类或结构的实例按照与数组相同的方式进行索引。索引器类似于属性,不同之处在于它们的访问器采用参数。它可以像数组那样对对象使用下标。它提供了通过索引方式方便地访问类的数据信息的方法。

      要声明类或结构的索引器,使用this关键字。

     class SampleCollection<T>
        {
            private T[] arr = new T[100];
            public T this[int i]
            {
                get {
                    return arr[i];
                }
                set {
                    arr[i] = value;
                }
            }
        }
        class Program
        {
            static void Main(string[] args)
            {
               //SampleCollection<int> i=new SampleCollection<int>();
               //i[0] = 1;
              // Console.WriteLine(i[0]);
                SampleCollection<string> s = new SampleCollection<string>();
                s[0] = "HELLO";
                Console.WriteLine(s[0]);
                Console.ReadKey();
             }
        }

    2.静态构造函数的使用方法

      这道题比较有意思,先看下代码及运行的结果:

    class Class1
        {
            public static int Count = 0;
            static Class1()
            {
                Count++;
            }
            public Class1()
            {
                Count++;
            }
        }
        class Program
        {
            static void Main(string[] args)
            {
    
                Class1 o1 = new Class1();
                Class1 o2 = new Class1();
                Console.WriteLine(Class1.Count);
                Console.ReadKey();
             }
        }

    从调试的结果来看,运行到这行代码Class1 o1 = new Class1();调用static Class1() { Count++; }函数,然后会接着调用public Class1() { Count++; },再运行到Class1 o2 = new Class1();这行代码时,就只调用public Class1() { Count++; },(刚开始会认为只执行其中的一个函数,没想到结果会是这样,他们不是重载的关系吗?)

    解释:

    使用静态函数(静态方法),编译器会在编译程序代码的时候,将静态方法当作全局函数对待。
    可以说静态函数(方法)是属于类的;
    普通函数(方法)是属于对象的。

    3.又一有意思的题目(这样的题目可以看出水平呀。。。)

     直接上代码和运行结果了

     public class A
        {
            public virtual void Fun1(int i)
            {
                Console.WriteLine(i);
            }
            public void Fun2(A a)
            {
                a.Fun1(1);
                Fun1(5);
            }
        }
        public class B : A
        {
            public override void Fun1(int i)
            {
                base.Fun1(i+1);
            }
        }
        class Program
        {
            static void Main(string[] args)
            {
    
                B b = new B();
                A a = new A();
                a.Fun2(b);
                b.Fun2(a);
                Console.ReadKey();
             }
        }
    View Code

    分析:a.Fun2(b)是指先执行A类下的Fun2函数。Fun2函数下第一步是a.Fun1(1),但实际的实参是b,也就是b.Fun(1),由于重写(Override),其内容是base.Fun1(i+1),也就是执行Fun1(1+1)结果是2.

    b.Fun2(a)是指先执行B类下的Fun2函数,可是B类本身没有Fun2函数,只有执行它的基类的Fun2函数。但实参是a,也就是执行a.Fun1(1),结果是1,下一行代码是Fun1(5) 实际上执行的是b.Fun1(5),实际执行结果是base.Fun1(5+1).

    这个题的关键要搞清楚:一个函数的执行必须在一个具体的对象中实现。如果函数明确告诉是那个对象,则在该对象下执行;如果没有,则在默认的对象下执行。

    4.C#委托和观察者模式(早就感觉这两之间有点关系,嘿,真的来了)

     程序设计:猫大叫一声,所有的老鼠都开始逃跑,主人被惊醒。要求:一要有联动性,老鼠和主人的行为是被动的。二考虑可扩展性,猫的叫声可能引起其他联动效应

    观察者模式:

    public interface Subject
        {
            void Register(Observer ob);
        }
        public interface Observer
        {
            void Response();
        }
        public class Mouse : Observer
        {
            private string name;
            public Mouse(string name, Subject sub)
            {
                this.name = name;
                sub.Register(this);//观察者注册
            }
            public void Response()
            {
                Console.WriteLine(name+" attempt to escape");
            }
        }
        public class Master : Observer
        {
            private string name;
            public Master(Subject sub)
            {
                sub.Register(this);//观察者注册
            }
            public void Response()
            {
                Console.WriteLine("the host waken!");
            }
        }
        public class Cat : Subject
        {
            private ArrayList observers;//用以数组保存所有观察者
            public void Register(Observer ob)
            {
                this.observers.Add(ob);
            }
            public Cat()
            {
                observers = new ArrayList();//构造函数初始化
            }
            public void Cry()//触发事件发生,并通知所有观察者
            {
                Console.WriteLine("cat cryed");
                foreach (Observer obs in this.observers)
                {
                    obs.Response();//所有观察者给出相应的回应
                }
            }
        }
       
        class Program
        {
            static void Main(string[] args)
            {
                Cat cat = new Cat();
                Mouse mouse1 = new Mouse("mouse1",cat);
                Mouse mouse2 = new Mouse("mouse2", cat);
                Master master = new Master(cat);
                cat.Cry();
                Console.ReadKey();
             }
        }
    View Code

    委托:

     public delegate void SubEventHandler();
        public abstract class Subject
        {
            public event SubEventHandler subEvent;
            protected void FireAway()
            {
                if (this.subEvent != null)
                    this.subEvent();//熟悉却又陌生
            }
        }
        public class Cat : Subject
        {
            public void Cry()
            {
                Console.WriteLine("cat cryed!");
                this.FireAway();//触发绑定的事件
            }
        }
        public abstract class Observer
        {
            public Observer(Subject sub)
            {
                sub.subEvent += new SubEventHandler(Response);
            }
            public abstract void Response();
        }
        public class Mouse : Observer
        {
            private string name;
            public Mouse(string name, Subject sub):base(sub)//初始化列表
            {
                this.name = name;
            }
            public override void Response()
            {
                Console.WriteLine(name + "attempt to escape!");
                //throw new NotImplementedException();
            }
        }
        public class Master : Observer
        {
            public Master(Subject sub) : base(sub) { }
            public override void Response()
            {
                Console.WriteLine("host woken!");
                //throw new NotImplementedException();
            }
        }
        class Program
        {
            static void Main(string[] args)
            {
                Cat cat = new Cat();
                Mouse mouse1 = new Mouse("mouse1",cat);
                Mouse mouse2 = new Mouse("mouse2", cat);
                Master master = new Master(cat);
                cat.Cry();
                Console.ReadKey();
             }
        }
    View Code

     5.值类型和引用类型比较

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Collections;
    
    namespace JiDan
    {
        public class RefPoint {
            public int x;
            public RefPoint(int x)
            {
                this.x = x;
            }
        }
        class Program
        {
            static void Main(string[] args)
            {
                bool result;
                RefPoint rPoint1 = new RefPoint(1);
                RefPoint rPoint2 = new RefPoint(1);
    
                result = (rPoint1 == rPoint2);
                Console.WriteLine(result);      // 返回 false;
    
                result = rPoint1.Equals(rPoint2);//对于引用类型,即使类型的实例(对象)包含的值相等,如果变量指向的是不同的对象,那么也不相等。这个很关键
                Console.WriteLine(result);      // #2 返回false
                result = (rPoint1.x).Equals(rPoint2.x);//这样就会相等了
                Console.WriteLine(result); //true
                object m1 = 1;
                object m2 = 1;
                result = m1.Equals(m2);//true,更清晰地理解是"=="用于比较引用是否相等,也就是是否指向同一个对象,如果指向的是同一个对象,那么Equal肯定相等
                //Equal用于值类型是否相等,也就是堆栈上的值。。只是初步的,更深地要对Equal原型方法熟悉。。
                Console.WriteLine(result);  
                Console.ReadKey();
             }
        }
    }
    View Code
    6.ref和out的区别:
    最近在许多论坛上看到关于了ref和out的区别,发现解释的都不非常理想。
    我想抄写点官方的解释,然后再来我自己的解释

    //如下

    方法参数上的 out 方法参数关键字使方法引用传递到方法的同一个变量。当控制传递回调用方法时,在方法中对参数所做的任何更改都将反映在该变量中。
    当希望方法返回多个值时,声明 out 方法非常有用。使用 out 参数的方法仍然可以返回一个值。一个方法可以有一个以上的 out 参数。
    若要使用 out 参数,必须将参数作为 out 参数显式传递到方法。out 参数的值不会传递到 out 参数。
    不必初始化作为 out 参数传递的变量。然而,必须在方法返回之前为 out 参数赋值。
    属性不是变量,不能作为 out 参数传递

    方法参数上的 ref 方法参数关键字使方法引用传递到方法的同一个变量。当控制传递回调用方法时,在方法中对参数所做的任何更改都将反映在该变量中。
    若要使用 ref 参数,必须将参数作为 ref 参数显式传递到方法。ref 参数的值被传递到 ref 参数。
    传递到 ref 参数的参数必须最先初始化。将此方法与 out 参数相比,后者的参数在传递到 out 参数之前不必显式初始化。
    属性不是变量,不能作为 ref 参数传递

    //上面的理解起来非常不好理解。下面我说说我自己的看法。

    首先:两者都是按地址传递的,使用后都将改变原来的数值。很多人在论坛上解释说out是按数值传递,是错误的。简单的测试后可以知道out使用也能改变数值的,所以肯定是按照地址传递的。
    其次:rel可以把参数的数值传递进函数,但是out是要把参数清空,就是说你无法把一个数值从out传递进去的,out进去后,参数的数值为空,所以你必须初始化一次。这个就是两个的区别,或者说就像有的网友说的,rel是有进有出,out是只出不进。经典!!!
    作者:wj704    出处:http://www.cnblogs.com/wj204/   
  • 相关阅读:
    【中文分词】条件随机场CRF
    【中文分词】最大熵马尔可夫模型MEMM
    【中文分词】二阶隐马尔可夫模型2-HMM
    【中文分词】隐马尔可夫模型HMM
    Elasticsearch的CRUD:REST与Java API
    d3的比例尺和坐标轴
    webpack DllPlugin的用法
    webpack单独启动目录方法
    d3的常用方法和数据类型
    d3中的enter,exit,update概念
  • 原文地址:https://www.cnblogs.com/wj204/p/3358250.html
Copyright © 2020-2023  润新知