《C#高级教程》学习笔记4 && 5

这篇博客详细介绍了C#的高级特性,包括函数成员如方法、属性、构造函数的使用,如方法的参数类型(ref、out、命名参数、可选参数)、静态构造函数的特性;属性的读写、访问修饰符及自动实现;构造函数的调用和继承。此外,还讲解了结构(struct)与类的区别、匿名类型、静态类和对象的生命周期。最后,引入了泛型的概念,强调了泛型在性能、类型安全和代码重用方面的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第四天:
3.3.2函数成员
1方法
(1)方法声明略

(2)调用方法略

(3)给方法传递参数
引用类型通过引用传递,值类型通过值传递
注:字符串作参数传递,修改了不影响原字符串

(4)ref参数
在要传的值前加个ref,把值传递变成引用传递
注:在函数参数里及调用方法时都要加ref

(5)out参数
像ref那样用,作用是可以传没初始化的参数,参数变为引用的
例:
static void A(int i){
    i=1;
}
public static void Main(){
    int i;
    A(i);
    Console.WriteLine(i);
    return 0;
}

(6)命名参数
参数顺序可任意
例:
String A(string firstName,string lastName){
    return firstName+" "+secondName;
}
调用:
A("a","b");
A(lastName:"b",firstName:"a");

(7)可选参数


(8)方法重载
虽然重要但学过编程的都懂,略

2属性(property)
例:
public string A{
    get{
        return "";
    }
    set{
        //do something
    }
}

(1)只读与只写属性:set或get只有一个

(2)属性的访问修饰符
属性可以有公有的get访问器和私有或受保护的set访问器

(3)自动实现的属性
public int Age(get;set;)
不需要声明private int age编译器会自动创建它

3构造函数
普通构造函数略

第五天:

(1)静态构造函数
C#的一个新特征是可以给类编写无参数的构造函数,这种构造函数只执行一次,不同与实例构造函数每次创建类都执行
class A{
    static A(){
    }
}
静态构造函数没有访问修饰符,不带任何参数,一个类中只能有一个。
只能访问类中的静态变量。
无参数的实例构造函数与静态构造函数可以在同一个类中同时定义。
例:
namespace Wrox.ProCSharp.StaticConstructorSample{
    public class UserPreferences{
        public static readonly Color BackColor;
        static UserPreferences{
            DateTime now=DateTime.Now;
            if(now.DayOfWeek==DateTime.Saturday||now.DayOfWeek==DateTime.Sunday)
                BackColor=Color.Green;
            else
                BackColor=Color.Red;
        }
        private UserPerferces(){}
    }
}
代码中里到了Frameword里的两个有用的结构System.DateTime和System.Drawing.Color
为了使用Color结构需要编译System.Drawing.dll,所以必须为System.Drawing名称空间添加一条using语句
using System;
using System.Drawing;
测试:
class MainEntryPoint{
    static void Main(string[] args){
        Console.WriteLine(UserPerferences.BackColor.ToString());
    }
}

(2)从构造函数中调用其他构造函数
形式:
class A{
    public A(int a,int b){
        ……
    }
    public A(int a):this(a,1){
        ……
    }
    ……
}
这里,this关键字仅调用参数最匹配的那个构造函数

3.3.3只读字段
readonly关键字比const灵活得多,允许把一个字段设置为常量,但还需要执行一些计算,以确定它的初始值。
与const不同,如果要把只读字段设置为静态,就必须显式声明它。
不能在构造函数外赋值
如果没有赋值,它的值就是其特定数据类型的默认值,或者在声明时给它的初始化的值。这适用于只读的静态字段和实例字段

3.4 匿名类型
var与new关键字一起使用时,可以创建匿名类型。
匿名类型只是一个继承自Object且没有名称的类。该类的定义从初始化器中推断,类以于隐式类型化的变量
(试验机本人感觉用起来很容易出错,看来我患有弱类型恐惧症)

3.5结构
主用于存小的数据结构
相对于类用class关键字,结构用stuct关键字
结构是值类型,不是引用类型。结构存在栈或内联(inline)中。类存在堆中。(因此结构应该比类小,速度快)

3.5.1结构是值类型
在语法上常常可以把它们当作类来处理。
可用new,但工作方式与类的不同。
结构的new并不分配堆中的内存,而是只调用相应的构造函数,根据传送给它的参数,初始化所有的字段。即不用new也行。
结构遵循其他数据类型都遵循的规则:在使用前所有的元素都必须进行初始化。
如果结构定义为类的成员字段时,在初始化包含的对象时,该结构会自动初始化为0
结构作为参数传递时是结构的内容复制,而不是引用,性能下降,所以最好用ref

3.5.2结构和继承
结构不是为继承设计的。即结构不能从一个结构中继承。但结构都继承于System.Object(本人称为可恶的最终boss,跟JAVA差不多)
注:每个结构派生自System.ValueType类,此类又派生自System.Object

3.5.3结构的构造函数
跟类差不多,但不允许定义无参数的构造函数

3.6弱引用(麻烦的东西)
平常new类的然后创建一个变量引用该实例是强引用。
这意味着垃圾回收器不会清理这个对象的内存。
有时对象很大,不经常访问时希望能被垃圾回收器给回收掉,所以有弱引用。
由于有存在问题,一般不会这样做,但在特定情况下使用是合理的。
弱引用是使用WeakReference类创建的。因为对象可能在任意时刻初回收。所以在引用该对象前必须确认它的存在。
例:
static void Main(){
    WeakReference mathReference=new WeakReference(new MathText());
    MathText math;
    math=mathReference.Target as MathText;
    if(math!=null){
        math.Value=30;
        Console.WriteLine("引用可用");//执行
    }
    else{
        Console.WriteLine("引用不可用");
    }
    GC.Collect();//回收垃圾
    if(mathReference.IsAlive){
        math=mathReference.Target as MathText;
    }
    else{
        Console.WriteLine("引用不可用");
    }
}

3.7部分类
partial关键字允许把类,结构或接口放在多个文中。
即同名类放在不同cs文件,class前加个partial,然后在运行时这同名类会合并为一个类。
那部分类编译到类型中时,属性,XML注释,接口,泛型类型的参数属性和成员会合并。

3.8静态类
如果类只包含静态的方法和属性,该类就是静态的。
static class A{    
}
静态类在功能上与使用私有静态构造函数创建的类相同。
不能创建静态类的实例。使用static关键字,编译器可检查用户是否不经意间给该类添加了实例成员。是则生成一个编译错误。

3.9 Object类
所有.NET类都派生自System.Object。定义类时没指定基类时,会自动指定为Object。

3.9.1 System.Object()方法

ToString()方法:是获取对象的字符串表示的一种便捷方式

GetHashCode()方法:把对象放在名为映射(也称为散列表或字典)的数据结构中。(本试验机十分害怕手敲哈希表)

Equals()(两个版本)和ReferenceEquals()方法:用于比较对象相等性的不同方法,在使用方式上与"=="有微妙的不同。以后会介绍到。

Finalize()方法:以后介绍,接近C++风格的析构函数(?)

GetType()方法:这个方法返回从System.Type派生的类的一个实例。这个对象可以提供对象成员所属类的更多信息,包括基本类型,方法,属性等。

MemberwiseClone()方法:复制对象,并返回对副本的一个引用。

3.9.2 ToString()方法
快速获取对象的字符串表示的最便捷方式。
很多预定义数据类型都应该重写过该方法吧,自己也可重写
public override string ToString(){……}

3.10扩展方法
扩展类。
有一个类A,
定义一个静态类B,里面有一个静态方法,静态方法第一个参数为类A,该参数最前面加个this
这等同于类B中的该方法是类A中的一个方法,以此达到扩展类。
同名则不会调用扩展方法。

第四章继承
4.1继承
4.2继承的类型
4.2.1实现继承和接口继承

4.2.2多继承
C#不支持多继承,可用接口代替现实(像JAVA一样)

4.3实现继承
class A:B{
}
A继承了B,B可以是类,亦可以是接口。感觉有点像C++
没指定继承的基类,默认为System.Object

4.3.1虚方法
把一个基类函数声明为virtual,就可以在任何派生类中重写该函数
属性也可以用virtual,
在派生类重写时要加override

4.3.2隐藏方法
如果签名相同的方法在基类和派生类中都进行了声明,但该方法没有分别声明为virtual和override,派生类方法就会隐藏基类方法
大多数情况,最好重写方法而不要隐藏方法,隐藏方法有出错的危险
在C#中,要隐藏一个声明应使用new关键字声明(感觉很少用到,略)

4.3.3调用函数的基类版本
使用base,相对于this,约等于JAVA的super略

4.3.4抽象类和抽象函数
C#允许把类和函数声明为abstract,抽象类不能实例化,而抽象函数不能直接实现,必须在非抽象的派生类中重写

4.3.5密封类和密封方法
C#允许把类和方法声明为sealed。类不能被继承,方法则不能被重写。
.NET基类库大量使用了密封类。例:string类。

4.3.6派生类的构造函数
内容一大堆,个人总结:
不断向上调用构造函数,如果自己写的构造函数没有调用上一个父类的构造函数会默认调用父类的无参构造函数。(大概吧?)
总之,执行顺序就是从最低层的构造函数从上执行吧。即先执行基类的构造函数。
在层次结构中添加带参的构函数。
class A:B{
    public A(int a):base(a){}
}
调用自己类中的其它构造函数用this替base,
执行顺序好像是先基类的再执行自己那个构造函数,再执行this的那个构造函数(看书时头有点晕)

4.4修饰符
4.4.1可见性修饰符
修饰符            应用于                    说明
public        所有类型成员                任何代码均可以访问该项
protected    类型和内嵌类型的所有成员    只有派生的类型能访问该项
internal    所有类型成员                只能在包含它的程序集中访问该项
private     类型和内嵌类型的所有成员    只能在它所属的类型中访问该项
protected internal    类型和内嵌类型的所有成员    只能在包含它的程序集和派生类型的任何代码中访问该项

4.4.2其它修饰符略

4.5接口
public interface IA{
    void a();
}
接口与JAVA差不多,大部分内容略
接口强大在于它可以引用任何实现该接口的类,略

4.5.2派生的接口
接口彼此间可继承,方式与类相似

第五章:泛型(我最害怕其中之一)

5.1 泛型概述
有了泛型,就可以创建独立于被包含类型的类和方法。(减少代码)
另一减少代码的选项是使用Object,但Object类不是类型安全的。

5.1.1性能
对值类型使用非泛型集合类,在转型时要装箱和拆箱操作。
如下:
var list = new ArrayList();
list.Add(44);    //装箱
int i1=(int)list[0]; //要解箱
foreach(int i2 in list){
    Console.WriteLine(i2);  //要解箱
}
下面用泛型
var list = new List<int>();
list.Add(44);    //不用装箱
int i1=list[0];    //不可解箱
foreach(int i2 in list){
    Console.WriteLine(i2);    //不要解箱
}

5.1.2类型安全
一看就知道安全了,略

5.1.3二进制代码的重用
泛型允许更好地重用二进制代码,泛型类可以定义一次,并且可以用许多不同的类型实例化。不需要像C++模板那样访问源代码
泛型类型可以在一种语言中定义,在任何其他.NET语言中使用。

5.1.4代码的扩展

(注:116页,还有1517-116=1401,还有十五分之十四)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值