การทำให้เป็นจริงหมายถึงโดยทั่วไป (นอกวิทยาศาสตร์คอมพิวเตอร์) "เพื่อทำให้บางสิ่งเป็นจริง"
ในการเขียนโปรแกรมเป็นสิ่งที่reifiedถ้าเราสามารถที่จะเข้าถึงข้อมูลเกี่ยวกับเรื่องนี้ในภาษาของตัวเอง
สำหรับตัวอย่างที่ไม่เกี่ยวข้องกับยาชื่อสามัญอย่างสมบูรณ์ในสองสิ่งที่ C # ทำและไม่ได้รับการแก้ไขเราจะใช้วิธีและการเข้าถึงหน่วยความจำ
โดยทั่วไปภาษา OO มีวิธีการ (และหลาย ๆ อย่างที่ไม่มีฟังก์ชั่นที่คล้ายกัน แต่ไม่ได้ผูกไว้กับคลาส) เช่นนี้คุณสามารถกำหนดวิธีการในภาษาดังกล่าวเรียกมันว่าอาจจะแทนที่มันและอื่น ๆ ไม่ใช่ทุกภาษาที่ให้คุณจัดการกับวิธีการดังกล่าวเป็นข้อมูลในโปรแกรมได้ C # (และจริงๆแล้ว. NET แทนที่จะเป็น C #) ช่วยให้คุณสามารถใช้ประโยชน์จากMethodInfo
วัตถุที่เป็นตัวแทนของวิธีการดังนั้นในวิธีการ C # จะมีการปรับใหม่ วิธีการใน C # คือ "วัตถุชั้นหนึ่ง"
ทุกภาษาในทางปฏิบัติมีวิธีการบางอย่างในการเข้าถึงหน่วยความจำของคอมพิวเตอร์ ในภาษาระดับต่ำเช่น C เราสามารถจัดการกับการแมประหว่างที่อยู่ตัวเลขที่ใช้โดยคอมพิวเตอร์โดยตรงดังนั้นการกดไลค์int* ptr = (int*) 0xA000000; *ptr = 42;
นั้นสมเหตุสมผล (ตราบใดที่เรามีเหตุผลที่ดีที่จะสงสัยว่าการเข้าถึงที่อยู่หน่วยความจำ0xA000000
ด้วยวิธีนี้จะชนะ ' ไม่ระเบิดอะไร) ใน C # นี้ไม่สมเหตุสมผล (เราสามารถบังคับได้ใน. NET แต่ด้วยการจัดการหน่วยความจำ. NET ที่เคลื่อนย้ายสิ่งต่าง ๆ รอบตัวมันไม่น่าจะมีประโยชน์มาก) C # ไม่ได้แก้ไขที่อยู่หน่วยความจำใหม่
ดังนั้นในขณะที่การปฏิเสธหมายถึง "ทำให้เป็นจริง" "ประเภทการแก้ไข" เป็นประเภทที่เราสามารถ "พูดถึง" ในภาษาที่เป็นปัญหาได้
ในยาชื่อสามัญนี้หมายถึงสองสิ่ง
หนึ่งคือนั่นList<string>
คือประเภทเช่นเดียวกับstring
หรือint
เป็น เราสามารถเปรียบเทียบประเภทนั้นได้ชื่อและสอบถามเกี่ยวกับมัน:
Console.WriteLine(typeof(List<string>).FullName); // System.Collections.Generic.List`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]
Console.WriteLine(typeof(List<string>) == (42).GetType()); // False
Console.WriteLine(typeof(List<string>) == Enumerable.Range(0, 1).Select(i => i.ToString()).ToList().GetType()); // True
Console.WriteLine(typeof(List<string>).GenericTypeArguments[0] == typeof(string)); // True
ผลที่ตามมาคือเราสามารถ "พูดถึง" ประเภทของพารามิเตอร์ (หรือวิธีของคลาสทั่วไป) ของเมธอดภายในเมธอดเอง:
public static void DescribeType<T>(T element)
{
Console.WriteLine(typeof(T).FullName);
}
public static void Main()
{
DescribeType(42); // System.Int32
DescribeType(42L); // System.Int64
DescribeType(DateTime.UtcNow); // System.DateTime
}
ตามกฎแล้วการทำเช่นนี้มากเกินไปคือ "ส่งกลิ่น" แต่มีหลายกรณีที่มีประโยชน์ ตัวอย่างเช่นดูที่:
public static TSource Min<TSource>(this IEnumerable<TSource> source)
{
if (source == null) throw Error.ArgumentNull("source");
Comparer<TSource> comparer = Comparer<TSource>.Default;
TSource value = default(TSource);
if (value == null)
{
using (IEnumerator<TSource> e = source.GetEnumerator())
{
do
{
if (!e.MoveNext()) return value;
value = e.Current;
} while (value == null);
while (e.MoveNext())
{
TSource x = e.Current;
if (x != null && comparer.Compare(x, value) < 0) value = x;
}
}
}
else
{
using (IEnumerator<TSource> e = source.GetEnumerator())
{
if (!e.MoveNext()) throw Error.NoElements();
value = e.Current;
while (e.MoveNext())
{
TSource x = e.Current;
if (comparer.Compare(x, value) < 0) value = x;
}
}
}
return value;
}
สิ่งนี้ไม่ได้ทำการเปรียบเทียบมากมายระหว่างประเภทของTSource
และประเภทต่าง ๆ สำหรับพฤติกรรมที่แตกต่างกัน (โดยทั่วไปเป็นสัญญาณที่คุณไม่ควรใช้ยาชื่อสามัญเลย) แต่มันจะแบ่งระหว่างเส้นทางรหัสสำหรับประเภทที่สามารถnull
(ควรกลับมาnull
ถ้า ไม่พบองค์ประกอบและจะต้องไม่ทำการเปรียบเทียบเพื่อค้นหาขั้นต่ำหากหนึ่งในองค์ประกอบที่เปรียบเทียบคือnull
) และเส้นทางรหัสสำหรับประเภทที่ไม่สามารถnull
(ควรโยนถ้าไม่พบองค์ประกอบและไม่ต้องกังวลเกี่ยวกับความเป็นไปได้ของnull
องค์ประกอบ )
เนื่องจากTSource
เป็น "ของจริง" ภายในวิธีการเปรียบเทียบนี้สามารถทำได้ทั้งในขณะรันไทม์หรือเวลา jitting (โดยทั่วไปคือเวลา jitting แน่นอนกรณีดังกล่าวข้างต้นจะทำเช่นนั้นในเวลา jitting และไม่ผลิตรหัสเครื่องสำหรับเส้นทางที่ไม่ได้ถ่าย) และเรามี แยกรุ่น "ของจริง" ของวิธีการสำหรับแต่ละกรณี (แม้ว่าจะเป็นการเพิ่มประสิทธิภาพ แต่รหัสเครื่องจะถูกใช้ร่วมกันสำหรับวิธีการที่แตกต่างกันสำหรับพารามิเตอร์ประเภทประเภทการอ้างอิงที่แตกต่างกันเพราะสามารถทำได้โดยไม่ส่งผลกระทบต่อสิ่งนี้และด้วยเหตุนี้เราจึงสามารถลดจำนวนเครื่องรหัส jitted)
(ไม่ใช่เรื่องธรรมดาที่จะพูดคุยเกี่ยวกับการทำให้เป็นประเภททั่วไปใน C # ยกเว้นว่าคุณจัดการกับ Java เพราะใน C # เราเพิ่งใช้ reification นี้เพื่อให้สิทธิ์; ทุกประเภทจะถูก reified ใน Java ประเภทที่ไม่ใช่ประเภททั่วไปจะเรียกว่าreifiedเพราะ คือความแตกต่างระหว่างพวกเขาและประเภททั่วไป)