คุณช่วยอธิบายให้ฉันดูได้where T : class, new()
ในบรรทัดต่อไปนี้
void Add<T>(T item) where T : class, new();
คุณช่วยอธิบายให้ฉันดูได้where T : class, new()
ในบรรทัดต่อไปนี้
void Add<T>(T item) where T : class, new();
คำตอบ:
นั่นคือข้อ จำกัด T
ในพารามิเตอร์ทั่วไป มันจะต้องเป็นclass
(ประเภทการอ้างอิง) และจะต้องมีการกำหนดค่าเริ่มต้นน้อยพารามิเตอร์สาธารณะ
นั่นหมายความว่าT
ไม่สามารถจะเป็นint
, float
, double
, DateTime
หรืออื่น ๆstruct
(ประเภทค่า)
มันอาจจะเป็นstring
หรือประเภทอ้างอิงที่กำหนดเองอื่น ๆ ตราบใดที่มันมีค่าเริ่มต้นหรือตัวสร้างพารามิเตอร์น้อย
new()
ระบุอย่างแม่นยำ "ต้องมีตัวสร้างพารามิเตอร์แบบไม่มีพารามิเตอร์สาธารณะ"
นั่นเป็นข้อ จำกัด ประเภททั่วไป ในกรณีของคุณมีสองคน:
where T : class
หมายความว่าประเภทนั้นT
จะต้องเป็นประเภทอ้างอิง (ไม่ใช่ประเภทค่า)
where T : new()
หมายความว่าประเภทT
ต้องมีตัวสร้างพารามิเตอร์น้อย การมีข้อ จำกัด นี้จะช่วยให้คุณทำสิ่งที่ต้องการT field = new T();
ในรหัสของคุณซึ่งคุณจะไม่สามารถทำได้
จากนั้นคุณทั้งสองรวมกันโดยใช้เครื่องหมายจุลภาคเพื่อรับ:
where T : class, new()
โดยที่ T: struct
อาร์กิวเมนต์ type ต้องเป็นประเภทค่า ชนิดของค่าใด ๆ ยกเว้น Nullable สามารถระบุได้ ดูการใช้ประเภทที่มีค่า Nullable (คู่มือการเขียนโปรแกรม C #) สำหรับข้อมูลเพิ่มเติม
โดยที่ T: class
อาร์กิวเมนต์ type ต้องเป็นชนิดการอ้างอิงรวมถึงคลาส, อินเตอร์เฟส, ผู้รับมอบสิทธิ์หรือชนิดอาร์เรย์ (ดูหมายเหตุด้านล่าง)
โดยที่ T: new () อาร์กิวเมนต์ type ต้องมีตัวสร้างพารามิเตอร์แบบไม่มีพารามิเตอร์สาธารณะ เมื่อใช้ร่วมกับข้อ จำกัด อื่น ๆ จะต้องระบุข้อ จำกัด ใหม่ () ล่าสุด
โดยที่ T: [ชื่อคลาสฐาน]
อาร์กิวเมนต์ type ต้องเป็นหรือสืบทอดมาจากคลาสฐานที่ระบุ
โดยที่ T: [ชื่ออินเตอร์เฟส]
อาร์กิวเมนต์ type ต้องเป็นหรือใช้อินเตอร์เฟสที่ระบุ สามารถระบุข้อ จำกัด หลาย ๆ อินเตอร์เฟสได้ อินเทอร์เฟซที่ จำกัด ยังสามารถทั่วไป
โดยที่ T: U
อาร์กิวเมนต์ type ที่ระบุสำหรับ T ต้องเป็นหรือสืบทอดมาจากอาร์กิวเมนต์ที่ให้สำหรับ U ซึ่งเรียกว่าข้อ จำกัด ประเภทเปล่า
class
และnew
มี 2 ข้อ จำกัด T
ในพารามิเตอร์ประเภททั่วไป
พวกเขามั่นใจตามลำดับ:
class
อาร์กิวเมนต์ type ต้องเป็นชนิดการอ้างอิง สิ่งนี้ใช้ได้กับคลาส, อินเทอร์เฟซ, ตัวแทนหรือประเภทอาร์เรย์
new
อาร์กิวเมนต์ type ต้องมีตัวสร้างพารามิเตอร์แบบไม่มีพารามิเตอร์สาธารณะ เมื่อใช้ร่วมกับข้อ จำกัด อื่น ๆ จะต้องระบุข้อ จำกัด ใหม่ () ล่าสุด
การรวมกันของพวกเขาหมายความว่าประเภทT
จะต้องเป็นประเภทอ้างอิง (ไม่สามารถเป็นประเภทค่า ) และต้องมีตัวสร้างแบบพารามิเตอร์
ตัวอย่าง:
struct MyStruct { } // structs are value types
class MyClass1 { } // no constructors defined, so the class implicitly has a parameterless one
class MyClass2 // parameterless constructor explicitly defined
{
public MyClass2() { }
}
class MyClass3 // only non-parameterless constructor defined
{
public MyClass3(object parameter) { }
}
class MyClass4 // both parameterless & non-parameterless constructors defined
{
public MyClass4() { }
public MyClass4(object parameter) { }
}
interface INewable<T>
where T : new()
{
}
interface INewableReference<T>
where T : class, new()
{
}
class Checks
{
INewable<int> cn1; // ALLOWED: has parameterless ctor
INewable<string> n2; // NOT ALLOWED: no parameterless ctor
INewable<MyStruct> n3; // ALLOWED: has parameterless ctor
INewable<MyClass1> n4; // ALLOWED: has parameterless ctor
INewable<MyClass2> n5; // ALLOWED: has parameterless ctor
INewable<MyClass3> n6; // NOT ALLOWED: no parameterless ctor
INewable<MyClass4> n7; // ALLOWED: has parameterless ctor
INewableReference<int> nr1; // NOT ALLOWED: not a reference type
INewableReference<string> nr2; // NOT ALLOWED: no parameterless ctor
INewableReference<MyStruct> nr3; // NOT ALLOWED: not a reference type
INewableReference<MyClass1> nr4; // ALLOWED: has parameterless ctor
INewableReference<MyClass2> nr5; // ALLOWED: has parameterless ctor
INewableReference<MyClass3> nr6; // NOT ALLOWED: no parameterless ctor
INewableReference<MyClass4> nr7; // ALLOWED: has parameterless ctor
}
() ใหม่:การกําหนดใหม่ () จำกัด วิธีการพิมพ์ T ต้องใช้นวกรรมิก parameterless ดังนั้นวัตถุที่สามารถ instantiated จากมัน - ดูการก่อสร้างเริ่มต้น
class:หมายถึง T ต้องเป็นประเภทอ้างอิงดังนั้นจึงไม่สามารถเป็น int, float, Double, DateTime หรือ struct อื่น ๆ (ประเภทค่า)
public void MakeCars()
{
//This won't compile as researchEngine doesn't have a public constructor and so can't be instantiated.
CarFactory<ResearchEngine> researchLine = new CarFactory<ResearchEngine>();
var researchEngine = researchLine.MakeEngine();
//Can instantiate new object of class with default public constructor
CarFactory<ProductionEngine> productionLine = new CarFactory<ProductionEngine>();
var productionEngine = productionLine.MakeEngine();
}
public class ProductionEngine { }
public class ResearchEngine
{
private ResearchEngine() { }
}
public class CarFactory<TEngine> where TEngine : class, new()
{
public TEngine MakeEngine()
{
return new TEngine();
}
}
นั่นหมายความว่าประเภทนั้นT
จะต้องเป็นคลาสและมีตัวสร้างที่ไม่มีอาร์กิวเมนต์ใด ๆ
ตัวอย่างเช่นคุณต้องสามารถทำสิ่งนี้:
T t = new T();
ข้อ จำกัด ใหม่ () ให้คอมไพเลอร์ทราบว่าอาร์กิวเมนต์ประเภทใด ๆ ที่ระบุต้องมีพารามิเตอร์ที่สามารถเข้าถึงได้ - หรือค่าเริ่มต้น - คอนสตรัคเตอร์
ดังนั้นควรจะT
ต้องเป็นคลาสและมีตัวสร้างพารามิเตอร์ที่ไม่สามารถเข้าถึงได้ - หรือตัวสร้างเริ่มต้น
สิ่งที่เกิดขึ้นหลังจาก "Where" เป็นข้อ จำกัด ของประเภททั่วไป T ที่คุณประกาศดังนั้น:
classหมายถึงว่า T ควรเป็นคลาสและไม่ใช่ประเภทของค่าหรือโครงสร้าง
ใหม่ ()ระบุว่าคลาส T ควรมีคอนสตรัคเตอร์เริ่มต้นที่ไม่มีพารามิเตอร์สาธารณะ
มันเรียกว่า 'ข้อ จำกัด ' ในพารามิเตอร์ทั่วไป T ซึ่งหมายความว่า T จะต้องเป็นประเภทการอ้างอิง (คลาส) และต้องมีตัวสร้างค่าเริ่มต้นสาธารณะ
นี่เป็นส่วนหนึ่งของกลไก Generics โดยที่ where คำสำคัญเพิ่มข้อ จำกัด ประเภทที่ต้องดำเนินการเพื่อใช้เป็นพารามิเตอร์ประเภท
เมื่อใช้คลาสในข้อ จำกัด หมายความว่าคุณสามารถใช้ประเภทการอ้างอิงได้เท่านั้นสิ่งอื่นที่จะเพิ่มคือเมื่อใช้ข้อ จำกัดใหม่ ()จะต้องเป็นสิ่งสุดท้ายที่คุณเขียนในข้อกำหนดของข้อ จำกัด