.NET精辟要点整理(补充中...)




Dispose()Close()的区别

NewOverride的区别

ref关键字

C#读写INI文件

接口

显式接口

抽象类

抽象类与接口的区别

静态变量

const  static readonly的区别

sealed关键字

索引指示器

类与结构的区别

using修饰符

构造函数

静态构造函数

string

string到底是值类型,还是引用类型?

展示一下具有值类型特征的操作

StringBuilderString的区别

params

 

.NET精辟要点整理

Close()的区别

要实现一个具有Dispose()功能的类,首先该类必须继承自一个具有Close()方法的类,并自己实现一个Dispose(bool)方法,此函数是Protected型的重载函数.

注意,其实Close()方法里面调用了IDisposable接口的Dispose()方法(此方法是显式实现的,请查阅如果显式实现接口方法),Dispose()方法里面又调用了Dispose(bool)方法.所以,如果你要写一个带有释放资源功能的类,你只需实现Dispose(bool)方法即可.

提示:最好Dispose(bool)方法里,实现托管释放和非托管释放,false/true区别,并且,为了保险起见,Dispose(bool)方法中,也要释放父类的资源(因为子类要执行父类的构造函数,如果父类在它的构造函数里申请了资源,那当然要释放,如果没有的话,就可选了,但我觉得,最好释放一下,没坏处).

class MyClass : SysClass //实现一个自己类里的Close()方法

  {

     private IntPtr m_anotherMemory;

     private Bitmap m_anotherImage;

     private bool m_disposed = false;

     public MyClass()

      {

         m_anotherMemory = Marshal.AllocCoTaskMem(20);

         m_anotherImage = new Bitmap(25,25);

     }

     //实现Dispose(bool)

     //如果传入false,就只释放非托管资源;传入true,全部释放

     protected override void Dispose(bool isDisposing)

      {

         if(!m_disposed)

          {

             if(isDisposing)

              {

                 //在此处释放托管资源

                 m_anotherImage.Dispose();//m_anotherImage就是托管资源

             }

             //在此处释放非托管资源

             Marshal.FreeCoTaskMem(m_anotherMemory);

                 //子类会执行父类的构造函数,这里还需释放父类

             base.Dispose(isDisposing);

             m_disposed = true;

         }

     }    

     ~MyClass()

      {

              //假如您有非托管资源,忘记手动释放,不用担心,这里会执行释放

         Dispose(false);

     }

 }

public static void Main (string[] args)

  {

     SysClass sc = new MyClass();

     sc.Close(); //正确

     sc.Dispose(); //错误

     ((IDisposable)sc).Dispose(); //正确

 }

 

Override的区别

override相当于C++中的重载,C++中的重载可以是同名且不同参(数目),override则是样子一模一样的方法的重载,需要与virtual关键字配合使用;
new,
说实话,不写也无妨,只是编译器会报警告,而它通常出现在子类与父类同名的函数中.

 

关键字

       使参数按引用传递.若要使用 ref 参数,则方法定义和调用方法都必须显式使用 ref 关键字.

public class MyClass

{

    private int num = 256;

    public void Show()

    { Console.WriteLine(num); }

    public void Set(ref int num)

    { this.num = num; }

    public static void Main ()

    {

        MyClass m = new MyClass();

        int value = 1024;

        m.Set(ref value);

          //输出 1024

        m.Show();

    }

}

 

读写INI文件

//申明INI文件的写操作函数WritePrivateProfileString()

[DllImport("kernel32")]

 private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);

//申明INI文件的读操作函数GetPrivateProfileString()

[DllImport("kernel32")]

 private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);

private void readIni_Click(object sender, EventArgs e)

{

  StringBuilder strb = new StringBuilder(); 

  int get_val = GetPrivateProfileString("name", "sex", "", strb, 255, "test.ini");

  MessageBox.Show(strb.ToString());

}  

 

不能有static成员、默认public但不写、子类方法若与父类同须用new、实现父类全部方法.

显式说明的接口成员最优先实现

如果两个或多个父接口中存在同名成员,就产生二义性.此时,最好使用显式声明.

public class MyClass

    {

        public interface Animal

        { void Walk(); }

        public interface Person : Animal

        { void Walk(); }

        public class Man : Person

        {

                //父接口和爷爷接口有两个同样的方法,需显式实现,不然不知道哪个对哪个

                //显式实现接口方法是public,不需要public,但它是public.非显式的可要加上public!

            void Person.Walk()

            { Console.WriteLine("Person is walking..."); }

            void Animal.Walk()

            { Console.WriteLine("Animal is walking..."); }

        }

        public static void Main ()

        {

            Man m = new Man();

            Person p = (Person)m;

                //显式接口的访问:必须通过接口的对象访问

            p.Walk();

            Animal a = (Animal)m;

            a.Walk();

        }

}

Output:

Person is walking...

Animal is walking...

 

       abstract修饰符可以用于类、方法、属性、事件和索引指示器.抽象类不能被实例化;不能sealed修饰符让它无法被继承;抽象子类必须实现所有抽象父类的方法;抽象类中的方法是隐式Virtual方法.

    public class MyClass

    {

        public abstract class AMedia

        {

            public abstract void Play();

                  //抽象类里可以实现方法(千万不要在该方法前面加上abstract)

            public void Close()

            { Console.WriteLine("have closed..."); }

        }

        public class Audio : AMedia

        {

                  //记得override

            public override void Play()

            { Console.WriteLine("is plaing..."); }

        }

        public static void Main ()

        {

            Audio a = new Audio();

            a.Play();

            a.Close();

        }

    }

 

抽象类 是从一系列对象中抽象出来的概念,因此反映事物的内部共性;

接口   是为了满足外部调用而定义的一个功能约定,因此反映的是事物的外部特性.

不同点:抽象类可以包含实现的类,而接口只能包含定义;抽象类的抽象方法默认隐式Virtual,而接口类方法默认public;抽象类不能被实例化,接口却可以;

相同点:都能被继承;都需要实现父类的所有方法;

分析对象,提炼内部共性形成抽象类,用以表示对象本质,是什么”;

为外部提供调用或功能需要扩充时优先使用接口.

 

需使用类名访问

    public class MyClass

    {

        static int staNum = 100;

        public static void Main ()

        { MyClass.staNum = 10000; }

}

 

 static readonly的区别

1.        const 是在编译期间初始化;

2.        static readonly 是在运行期间初始化.

调用方法: 都需要使用类名访问!

 

关键字

1.        修饰类时,该类不能被继承;

2.        修饰方法和属性时,该方法和属性也不能被继承.(修饰方法时,sealed总是和override连用,由此说明该方法肯定是virtaul)

        sealed类可以有虚函数吗? 可以,但基类中的虚函数隐式转换成非虚函数.

class Base

{

    public virtual void Show()

    { Console.WriteLine("I am Base..."); }

}

sealed class Son : Base

{

    // Base中的虚函数Show()已隐式转换为非虚函数了.

    //Son类不能自己再定义虚函数!

}

 

 

         像数组一样,唯一不同的是,[]中不局限于int.

        public int this[int Index]

        {

            get { }

            set { }

        }

 

不同点:    类是引用类型(在堆上,手动释放),结构是值类型(在栈上,自动释放)

相同点:    结构也有构造函数,前提是一个带参数的构造函数;

效率: 类实例的赋值只是复制了引用;而结构的赋值却是产生一个新的对象.

 

修饰符

       引用空间名,为空间名起别名;

释放资源.

 

不能有参数,且只能操作静态成员;

public class Static

{

    static int i = 100;

    static Static()

    {

        Static.i = 999;

    }

}

若父类没有定义无参数的构造函数,在定义子类构造函数时,显式初始化父类的构造函数

public class Dad

{

    private int dadAge;

    public Dad(int age)

    { dadAge = age; }

}

public class Son : Dad

{

    private int sonAge;

    public Son(int age)

        : base(0) //显式初始化父类的构造函数

    { sonAge = age; }

}

 

总结:

到底是值类型,还是引用类型?

:我可以很肯定的告诉你,引用类型,只不过它在某些操作上会表现出值类型的特征.函数参数,==.

string的一个特殊性就在于它不会变”.

何为不会变”,展示一下:

    public class MyClass

    {

        public static void Main ()

        {

            string str1 = "I am a number";

            string str2 = str1;

            Console.WriteLine("str1 = " + str1);

            Console.WriteLine("str2 = " + str2);

            str1 = "I am another number";

            Console.WriteLine("after str1 changed... str1 = " + str1);

            Console.WriteLine("after str1 changed... str2 = " + str2);

        }

}

Output:

str1 = I am a number

str2 = I am a number

after str1 changed...str1 = I am another number

after str1 changed...str2 = I am a number

public static void Main ()

{

    string str = "china";

    Change(str);

    Show(str);

}

//这里的参数传递,实质上 = 过程,和上例一样,会产生一个新的引用

public static void Change(string str)

{ str = "china yangzhou "; }

public static void Show(string str)

{ Console.WriteLine(str); }

Output:

china

 

String的区别

       String虽然是引用类型,但在赋值时却会产生新的对象;

StringBuilder则不会,所以在处理大量字符串时,它是首选.

 

该关键字用在方法的参数列表中,为该方法参数提供了可变的能力.它只能出现一次,且只能定义在所有参数最后.

//params 定义的参数后面不可以再定义其它参数

public static void UseParams(string str, params object[] list)

{

    Console.WriteLine(str);

    for (int i = 0; i < list.Length; i++)

    { Console.WriteLine(list[i]); }

}

static void Main (string[] args)

{

    String[] str = new string[] { "I", "LOVE", "YOU" };

    Program.UseParams("Hello", str);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值