// 需求: // 在类中定义一个数组,让这个类具备设置数据和访问数据的能力。 /* .NET含有以下5种泛型约束 * where T : class | T必须是一个类 * where T : struct | T必须是一个结构类型 * where T : new() | T必须要有一个无参构造函数 * where T : NameOfBaseClass | T必须继承名为NameOfBaseClass的类 * where T : NameOfInterface | T必须实现名为NameOfInterface的接口 */ public class MyClassType { public int a; public MyClassType(int value) { this.a = value; } } public class MyClass15<T> where T:MyClassType { private T[] m_array; public MyClass15(int size) { m_array = new T[size]; } public void Set(int index, T value) { m_array[index] = value; } public int Get(int index) { return m_array[index].a; } } public class TClass : MonoBehaviour { void Start() { /*MyClass15 myClass = new MyClass15(5); myClass.Set(0, 1); myClass.Set(1, 2); int a = myClass.Get(0); int b = myClass.Get(1); Debug.LogFormat("第{0}位,值为{1}", 0, a); Debug.LogFormat("第{0}位,值为{1}", 1, b);*/ /*MyClass15<string> myClass = new MyClass15<string>(5); myClass.Set(0, "哈哈哈"); myClass.Set(1, "嘿嘿嘿"); string a = myClass.Get(0); string b = myClass.Get(1); Debug.LogFormat("第{0}位,值为{1}", 0, a); Debug.LogFormat("第{0}位,值为{1}", 1, b);*/ MyClass15<MyClassType> myClass = new MyClass15<MyClassType>(5); myClass.Set(0, new MyClassType(1)); myClass.Set(1, new MyClassType(2)); int a = myClass.Get(0); int b = myClass.Get(1); Debug.LogFormat("第{0}位,值为{1}", 0, a); Debug.LogFormat("第{0}位,值为{1}", 1, b); } } // 还有一种情况,基类是泛型类 public class Parent<T, X> { } public class Child1<T, X> : Parent<T, X> { } public class child2 : Parent<int, string> { } public class child3<T, X, Y, A> : Parent<T, X> { } public class child4<T, X> : Parent<int, string> { }
5. 接口
interface + name,这将变成一个接口。
接口的特点:
接口只声明接口函数,不能包含实现;
接口函数访问修饰符,必须是public,默认也就是public;
接口成员函数的定义是派生类的责任,接口提供了派生类应遵循的标准结构;
接口不可被实例化,即不可 new ;
接口可继承其他接口,可进行多继承;
一个类不能继承多个类,但是可以继承多个接口。
接口一般用在 约束一些行为规范时 。
C#中一个类继承接口,必须实现接口中定义的函数方法,实现方法可分为隐式实现和显式实现:
public interface BaseInterface1 { void ShowWindow(); void HideWindow(); } public interface BaseInterface2 { void PlaySound(); void CloseSound(); } public interface MyInterface : BaseInterface1, BaseInterface2 { } public class MyClass16 : MyInterface { // 显式实现 void BaseInterface2.CloseSound() { throw new System.NotImplementedException(); } void BaseInterface1.HideWindow() { throw new System.NotImplementedException(); } void BaseInterface2.PlaySound() { throw new System.NotImplementedException(); } void BaseInterface1.ShowWindow() { throw new System.NotImplementedException(); } // 隐式实现 public void CloseSound() { throw new System.NotImplementedException(); } public void HideWindow() { throw new System.NotImplementedException(); } public void PlaySound() { throw new System.NotImplementedException(); } public void ShowWindow() { throw new System.NotImplementedException(); } }
int[] d = {1, 2, 3}; int[] c = d as int[]; if (c != null) { Debug.Log(c.Length); // 打印3 } public class Base { } public class Son : Base { } public class Test { void start() { Son son = new Son(); if (son as Son != null) { Debug.Log("son as Son"); // 成功打印语句 } if (son as Base != null) { Debug.Log("son as Base"); // 成功打印语句 } } }
3. 什么是装箱&拆箱
类型:
值类型
内置值类型
用于定义的值类型
枚举类型
引用类型
指针类型
接口类型
自描述类型
数组
类类型
用户定义的类
已装箱的值类型
委托
装箱:值类型转换为引用类型;
拆箱:引用类型转换为值类型。
public class Box { void Start() { int a = 20; Object b = (Object) a; // 装箱,发生GC 内存分配 int c = (int) b; // 拆箱 } }
// 测试程序 public class TestClass { public string name = "张三"; public int num = 10; } public class HeapStack : MonoBehaviour { void Start() { Example(); } void Example() { TestClass[] test = { new TestClass(), new TestClass(), new TestClass() }; TestClass test01 = test[0]; test01.name = "李四"; TestClass test02 = test[0]; test02.name = "王五"; Debug.Log(test01.name); } }