天天看點

C#筆記 泛型 Generic

使用泛型(generic)

unity裡還是很常見的,這裡<>裡填寫你需要的類型。

例如:

// 拿到元件
GetComponent<Render>().sortingOrder = ;

// 可排序對象
public class B : IComparable<B>

// 泛型集合,字典等
Dictionary<string, B> mydic = new Dictionary<string, B>();

// 等等
           

泛型的可以避免強轉

c#2(版本)出現了泛型。在c#1時隻能使用強轉,例如在使用非泛型集合(ArrayList)的時候。如果強制轉換了錯誤的類型……

下面代碼在mylist位置3插入了另外的類型。

ArrayList mylist;
mylist = new ArrayList();
A a1 = new A();
myList.Add(a1);
A a2 = new A();
myList.Add(a2);
B b = new B();
myList.Add(b);// 竟然加入一個别的類型元素

for ( int i = ; i < mylist.Count; i ++ )
{
    A a = (A)mylist[i]; //強轉騙過了編譯器
    a.DoSomething();
}
           

where關鍵字

where T :後面的内容可以限制T是什麼。

public class SomeClass
{
        public T GenericMethod<T>( T param ) where T : class
        {
            return param;
    }
}
           

比較常見的where後面會跟:

class表示T是一個引用類型。可以使用null。

struct表示T是一個值類型。

new()表示T有個public的無參數的構造函數。

MonoBehavior(一個類)表示T是這個類。

IEnumerable(一個接口)表示T有這個接口的實作。

自己主動使用泛型

處理算法相似隻是要處理的類型不同的時候,可以考慮把統一的算法用泛型來處理。

比如各種容器類(List、Array等)會碰到。

比如一個Line的封裝,可以是2D或3D。這時寫一個Line,可以是Line Line。

比如讀取XML的一部分,如下:

public static void SetObjectValue<T>( T obj, string fieldname, object value )
{
    System.Reflection.FieldInfo info = obj.GetType().GetField(fieldname);
    if ( info != null )
    {
        info.SetValue(obj, value);
    }
}

public class Player
{
    public string name = string.Empty;
    public int id = ;
};

Player p = new Player();
SetObjectValue<Player>( p, "name", "tom" );
SetObjectValue<Player>( p, "level",  );
           

比如泛型委托,如下:

public class ImplementingClass
{
        public float WhichIsBig( int a, float b )
        {
            if ( a > b )
                return a;
            else
                return b;
        }
}
public delegate float CallDelegate<T,S>( T t, S s );

CallDelegate<int, float> delegateBig = new CallDelegate<int, float>( new ImplementingClass().WhichIsBig );
float big = delegateBig( , f );