(二)语法复习(下)

访问修饰符

虚属性、虚方法

父类中用virtual修饰的属性和方法即为虚属性、虚方法,子类可重写这些属性和方法,重写时加上override关键字修饰

class Car
{
	public virtual string Color{ get; set; }

	public virtual void Run()
	{
		Console.WriteLine("abstract car run");
	}
}
class Aodi:Car
{
	public override string Color { get; set; }

	public override void Run()
	{
		Console.WriteLine("aodi run");
	}
}

隐藏方法

当子类和父类有签名一样的方法时,子类需要在方法上添加修饰符new,从而隐藏父类的方法。

class Car
{
	public void OpenDoor()
	{
		Console.WriteLine("abstract car opendoor");
	}
}
class Aodi:Car
{
	public new void OpenDoor()
	{
		Console.WriteLine("aodi opendoor");
	}
}

泛型

C#的泛型是真正的泛型,不会被擦除,编译后依然存在,比如List<string>和List<int>编译后是两种不同的类型。

关于泛型类型的约束

约束描述
where T:struct对于结构的约束,类型T必须为值类型
where T:class类约束 指定类型T必须是引用类型
where T:IFly指定类型T必须实现接口IFly
where T:Car指定类型T必须继承基类Car
where T:new()构造函数约束,指定类型T必须有一个默认构造函数
where T1:T2裸类型约束 指定类型T1派生自类型T2

注意:关于构造函数约束,只能为默认构造函数定义约束,不能为其他构造函数定义约束。

泛型类的静态成员

泛型类的静态成员只能在一个类的实例中共享,下面是两个类型的两份静态成员code。

public class Demo<T>
{
	public static string code;
}
[TestClass]
public class V
{

	[TestMethod]
	public void TestVar()
	{
		Demo<string>.code = "qq";
		Demo<int>.code = "pp";
		Console.WriteLine(Demo<string>.code);
		Console.WriteLine(Demo<int>.code);
	}
}

泛型的抗变和协变

协变  ,参数:父类的引用 一可以传子类的对象

抗变,返回:返回父类,不能用子类的引用接受

如果泛型类型用out修饰,那么泛型接口就是协变的,意味着返回类型只能是T。

public interface IMoveable<out T>
{
	T GetObject();
}

如果泛型类型用in修饰,那么泛型接口就是抗变的,接口只能把泛型类型T用作方法参数。‘

public interface IMoveable1<in T>
{
	void move(T t);
}

’方法的参数是协变的,方法的返回值是抗变的。

参数类型可以传入子类,返回值类型可以返回父类。

可空类型

//Nullable<T>类型 T派生于struct,也就是值类型
//基本类型和struct都有对应的可空类型
int? money;
//常用
bool p = a.HasValue;
int q = a.Value;
int m = a.GetValueOrDefault();

迭代器

包含yield语句的为迭代块,迭代块必须返回IEnumerator或IEnumerable接口或,它们的泛型版本,迭代块可以包含多个yield return或yield break,但不能包含return。

yield return 返回集合的一个元素 并移动到下个元素,yield break可停止迭代。

foreach语句中默认调用GetEnumerator()方法

using System.Collections.Generic;

[TestClass]
public class IEnumerateTest
{
	   [TestMethod]
	   public void testEnumable()
	   {
			   MyIEnumable m = new MyIEnumable();
			   foreach (string i in m)
			   {
					  Console.WriteLine(i);
			   }
	   }
}
class MyIEnumable
{
	   private string[] vs={"aa","ss","bb"};
	   public IEnumerator<string> GetEnumerator()
	   {
			   for(int i=0;i<vs.Length;i++)
			   {
					  yield return vs[i];
			   }
	   }
}

运算符

溢出检测

byte b = 255;
checked
{
	b++;
}
Console.WriteLine(b.ToString());
int c = 0;
int s = checked(c);

运算符重载

所有运算符重载都用public和static修饰。

注意:在重载 == 和 !=时,还要重写Equals()和 GetHashCode()方法

public class Water
{
	private int capacity;
	public Water(int capacity)
	{
		this.capacity = capacity;
	}

	public int getCapacity()
	{
		return this.capacity;
	}

	public static Water operator +(Water w1,Water w2)
	{
		return new Water(w1.getCapacity() + w2.getCapacity());
	}
}

可重载的运算符

隐式类型转换和显示类型转换

和运算符重载有些类似,隐式类型转换用implicit关键字,显示类型转换用explicit关键字。

public class Water
{
	private int capacity;
	public Water(int capacity)
	{
		this.capacity = capacity;
	}

	public int getCapacity()
	{
		return this.capacity;
	}

	public static Water operator +(Water w1,Water w2)
	{
		return new Water(w1.getCapacity() + w2.getCapacity());
	}

	public static implicit operator int(Water w)
	{
		return w.getCapacity();
	}

	public static explicit operator Water(int c)
	{
		return new Water(c);
	}

	public void Test()
	{
		Water w = (Water)0;
		int c = w;
	}
}

元组

最后一个参数也是元组类型,所以可以包含任意多个项

public class Tuple<T1, T2, T3, T4, T5, T6, T7, TRest>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值