linux wordpress南京百度提升優(yōu)化
c#中的約束
在C#中,約束(Constraints)用于限制泛型類型參數(shù)的類型,以確保泛型類型或方法在編譯時能夠滿足特定的要求。約束允許開發(fā)者指定泛型類型參數(shù)必須滿足的條件,比如實現(xiàn)特定的接口或繼承自特定的類。以下是一些常見的約束類型:
-
類類型約束 (
class
或struct
):-
class
約束指定類型參數(shù)必須是引用類型。 -
struct
約束指定類型參數(shù)必須是值類型。
public class MyClass<T> where T : class {// T 必須是引用類型 }
-
-
接口約束 (
interface
):-
接口約束指定類型參數(shù)必須實現(xiàn)一個或多個特定的接口。
public interface IInterfaceA { } public interface IInterfaceB { } ? public class MyGenericClass<T> where T : IInterfaceA, IInterfaceB {// T 必須同時實現(xiàn) IInterfaceA 和 IInterfaceB }
-
-
構(gòu)造函數(shù)約束 (
new()
):-
構(gòu)造函數(shù)約束指定類型參數(shù)必須有一個無參數(shù)的公共構(gòu)造函數(shù)。
public class MyGenericClass<T> where T : new() {public T CreateInstance() => new T();// T 必須有一個無參數(shù)的公共構(gòu)造函數(shù) }
-
-
基類約束 (
: BaseType
):-
基類約束指定類型參數(shù)必須是指定基類的子類。
public class MyBaseClass { } ? public class MyGenericClass<T> where T : MyBaseClass {// T 必須是 MyBaseClass 的子類 }
-
-
多個約束:
-
可以對類型參數(shù)應(yīng)用多個約束,它們可以組合使用。
public class MyGenericClass<T> where T : class, IInterfaceA, new() {// T 必須是引用類型,實現(xiàn) IInterfaceA 接口,并有一個無參數(shù)的公共構(gòu)造函數(shù) }
-
-
類型參數(shù)默認(rèn)值約束 (
default
):-
從C# 8.0開始,可以使用
default
約束來指定類型參數(shù)必須有一個可用的默認(rèn)實現(xiàn)。
public class MyGenericClass<T> where T : IInterfaceA = default(T) {// T 必須實現(xiàn) IInterfaceA 接口,并且有一個可用的默認(rèn)實現(xiàn) }
-
TimeSpan
在C#中,TimeSpan
是一個結(jié)構(gòu)體(struct
),用于表示兩個 DateTime
對象之間的時間差,或者表示一個持續(xù)時間。TimeSpan
結(jié)構(gòu)體包含了時間的天、小時、分鐘、秒和毫秒部分。
TimeSpan
提供了多種方法來創(chuàng)建和操作時間間隔,例如:
-
TimeSpan.FromSeconds(double)
:根據(jù)秒數(shù)創(chuàng)建TimeSpan
。 -
TimeSpan.FromMinutes(double)
:根據(jù)分鐘數(shù)創(chuàng)建TimeSpan
。 -
TimeSpan.FromHours(double)
:根據(jù)小時數(shù)創(chuàng)建TimeSpan
。 -
TimeSpan.FromDays(double)
:根據(jù)天數(shù)創(chuàng)建TimeSpan
。
此外,TimeSpan
也支持算術(shù)運算,如加法和減法,以及與其他 TimeSpan
結(jié)構(gòu)體的比較。
這里是一個簡單的使用 TimeSpan
的示例:
// 創(chuàng)建一個表示2小時30分鐘的時間間隔
TimeSpan interval = new TimeSpan(2, 30, 0);
?
// 創(chuàng)建一個表示15秒的時間間隔
TimeSpan shortInterval = TimeSpan.FromSeconds(15);
?
// 計算兩個DateTime之間的時間差
DateTime start = new DateTime(2024, 1, 1);
DateTime end = new DateTime(2024, 1, 2);
TimeSpan duration = end - start;
TimeSpan
結(jié)構(gòu)體是不可變的,這意味著一旦創(chuàng)建了一個 TimeSpan
實例,它的值就不能被修改。任何修改操作都會返回一個新的 TimeSpan
實例。
c#中的defult
在C#中,default
關(guān)鍵字用于獲取一個類型的默認(rèn)值。每種類型的默認(rèn)值定義如下:
-
對于值類型(例如
int
,double
,struct
),默認(rèn)值是將所有位都設(shè)置為0。例如,int
的默認(rèn)值是0
,double
的默認(rèn)值是0.0
。 -
對于引用類型(例如
class
,string
),默認(rèn)值是null
。 -
對于
bool
類型,沒有默認(rèn)值,因為bool
是一個值類型,并且它只有兩個可能的值:true
和false
。 -
對于
Nullable<T>
類型(可以為 null 的類型),默認(rèn)值是null
。
使用 default
關(guān)鍵字可以提高代碼的可讀性和可維護(hù)性,特別是當(dāng)你需要初始化一個變量到其類型的默認(rèn)值時。例如:
int number = default(int); // 初始化為 0
string text = default(string); // 初始化為 null
double value = default(double); // 初始化為 0.0
此外,default
也可以用于泛型類型參數(shù),編譯器會根據(jù)類型參數(shù)推斷出正確的默認(rèn)值:
List<T> list = new List<T>();
T item = default(T); // 根據(jù) T 的類型,編譯器推斷出默認(rèn)值
default
關(guān)鍵字是一個表達(dá)式,它在編譯時確定類型,并在運行時返回該類型的默認(rèn)值。
c#中operator
在C#中,operator
關(guān)鍵字用于定義和重載運算符,使得自定義類型可以像內(nèi)置類型一樣使用標(biāo)準(zhǔn)的運算符,如 +
, -
, ==
, !=
等。這提高了代碼的可讀性和一致性。
以下是一些常見的運算符重載示例:
-
一元運算符:如
+
,-
,!
,++
,--
。public struct Point {public int X { get; set; }public int Y { get; set; } ?public static Point operator +(Point p1, Point p2){return new Point { X = p1.X + p2.X, Y = p1.Y + p2.Y };} ?public static Point operator -(Point p){return new Point { X = -p.X, Y = -p.Y };} }
-
二元運算符:如
+
,-
,*
,/
,%
,==
,!=
。public static bool operator ==(Point p1, Point p2) {return p1.X == p2.X && p1.Y == p2.Y; } ? public static bool operator !=(Point p1, Point p2) {return !(p1 == p2); }
-
遞增和遞減運算符:
++
和--
。public class Counter {private int _value; ?public int Value{get { return _value; }set { _value = value; }} ?public static Counter operator ++(Counter c){c._value++;return c;} ?public static Counter operator --(Counter c){c._value--;return c;} }
-
關(guān)系運算符:
<
,>
,<=
,>=
。public class Fraction {private int _numerator;private int _denominator; ?public static bool operator <(Fraction f1, Fraction f2){// 實現(xiàn)比較邏輯} ?public static bool operator >(Fraction f1, Fraction f2){// 實現(xiàn)比較邏輯} }
-
賦值運算符:
=
。public class MyClass {public int Value { get; set; } ?public static MyClass operator =(MyClass a, int value){a.Value = value;return a;} }
-
邏輯運算符:
&&
,||
。public class BooleanWrapper {private bool _value; ?public static BooleanWrapper operator &&(BooleanWrapper b1, BooleanWrapper b2){return new BooleanWrapper { _value = b1._value && b2._value };} ?public static BooleanWrapper operator ||(BooleanWrapper b1, BooleanWrapper b2){return new BooleanWrapper { _value = b1._value || b2._value };} }
重載運算符時,需要遵循一些規(guī)則和最佳實踐:
-
運算符重載應(yīng)該是直觀的,并且與內(nèi)置類型的行為一致。
-
重載的運算符應(yīng)該保持對稱性,例如,如果重載了
==
,也應(yīng)該重載!=
。 -
重載
==
和!=
時,也應(yīng)該重載GetHashCode
和Equals
方法。 -
重載
+
時,也應(yīng)該考慮重載-
以及可能的+=
和-=
。 -
避免重載
&
,|
,&=
,|=
等位運算符,除非你的類型是位字段。