此篇隨筆僅僅作為記錄和參考。
在寫項目的時候看到了一段比較有意思的單例.如下圖:
using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary> /// 單例模型 /// </summary> /// <typeparam name="T">模板</typeparam> public class MonoSingleton<T> : MonoBehaviour where T :Component { private static T _instance; private static readonly object _lock = new object(); public static T Instance { get { if(_instance == null) { lock (_lock) { _instance = FindObjectOfType<T>(); if(_instance == null) { GameObject obj = new GameObject("TempObj"); _instance = obj.AddComponent<T>(); } } } return _instance; } } }
在這里面我最好奇的是為什么要使用這一段
public class MonoSingleton<T> : MonoBehaviour where T :Component
后來我打算去找答案,東西很久沒有用都忘了什么作用了。
2.where 在SQL語句中是限制條件的意思
select column_name ,column_name form table_name WHERE column_name operator value;
3.where在C# 指的是約束
為什么要使用約束?官方給的解釋是:
使用約束的原因
約束指定類型參數的功能和預期。 聲明這些約束意味着你可以使用約束類型的操作和方法調用。 如果泛型類或方法對泛型成員使用除簡單賦值之外的任何操作或調用 System.Object 不支持的任何方法,則必須對類型參數應用約束。 例如,基類約束告訴編譯器,僅此類型的對象或派生自此類型的對象可用作類型參數。 編譯器有了此保證后,就能夠允許在泛型類中調用該類型的方法。 以下代碼示例演示可通過應用基類約束添加到(泛型介紹中的)GenericList<T> 類的功能。
4.為了驗證一下,我將where 后面的
where T :Component
這一部分刪除,發現
_instance = FindObjectOfType<T>(); //提示是:類型“T”不能用作泛型類型或方法“Object.FindObjectOfType<T>()"中的類型參數”T“. //沒有從”T“到”UnityEngine.Object"裝箱轉換或者類型參數轉換
第一反應是有點懵,官方 指的 和這個有什么關系嘛
約束指定類型參數的功能和預期。
//在 Object 中找到了該方法 public static T FindObjectOfType<T>() where T : Object;
用我目前理解到了東西來說,應該是 要求 泛型T 是繼承自 Object 的,才可以使用 FindObjectOfType<T>() 這個函數 ,所以我覺得
Component 必定也是繼承自 Objet 的,所以才可以使用這函數。
//在Component 類中找到了這個 public class Component : Object
簡單的說就是,還是直接用官方的說法:
約束告知編譯器類型參數必須具備的功能。 在沒有任何約束的情況下,類型參數可以是任何類型。 編譯器只能假定 System.Object 的成員,它是任何 .NET 類型的最終基類。
詳情直接看文檔比較實在,水平有限做個記錄。文檔網址: https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/generics/constraints-on-type-parameters