Tôi đã nghĩ rằng Generics trong C# đã được thực hiện sao cho một lớp/phương thức/những gì bạn có được tạo ra, vào thời gian chạy hoặc biên dịch, khi một kiểu generic mới được sử dụng, tương tự như các mẫu C++ (mà tôi chưa bao giờ thực sự nhìn vào và tôi rất tốt có thể sai, về việc tôi sẵn sàng chấp nhận sự điều chỉnh).C# Generics được triển khai như thế nào?
Nhưng trong mã của tôi, tôi đã đưa ra một phản ví dụ chính xác:
static class Program {
static void Main()
{
Test testVar = new Test();
GenericTest<Test> genericTest = new GenericTest<Test>();
int gen = genericTest.Get(testVar);
RegularTest regTest = new RegularTest();
int reg = regTest.Get(testVar);
if (gen == ((object)testVar).GetHashCode())
{
Console.WriteLine("Got Object's hashcode from GenericTest!");
}
if (reg == testVar.GetHashCode())
{
Console.WriteLine("Got Test's hashcode from RegularTest!");
}
}
class Test
{
public new int GetHashCode()
{
return 0;
}
}
class GenericTest<T>
{
public int Get(T obj)
{
return obj.GetHashCode();
}
}
class RegularTest
{
public int Get(Test obj)
{
return obj.GetHashCode();
}
}
}
Cả hai của những giao diện điều khiển dòng in.
Tôi biết rằng lý do thực tế điều này xảy ra là cuộc gọi ảo đến Object.GetHashCode() không giải quyết thành Test.GetHashCode() vì phương thức trong Kiểm tra được đánh dấu là mới thay vì ghi đè. Vì vậy, tôi biết nếu tôi sử dụng "ghi đè" thay vì "mới" trên Test.GetHashCode() thì trả về 0 sẽ đa hình đè lên phương thức GetHashCode trong đối tượng và điều này sẽ không đúng, nhưng theo sự hiểu biết của tôi (trước) của C# generics nó sẽ không có vấn đề vì mỗi trường hợp của T sẽ được thay thế bằng Test, và do đó các cuộc gọi phương thức sẽ có tĩnh (hoặc tại thời gian giải quyết chung) đã được giải quyết cho phương pháp "mới".
Vì vậy, câu hỏi của tôi là: Làm thế nào Generics được thực hiện trong C#? Tôi không biết mã bytecode CIL, nhưng tôi biết Java bytecode vì vậy tôi hiểu cách các ngôn ngữ CLI hướng đối tượng hoạt động ở mức thấp. Cảm thấy tự do để giải thích ở cấp độ đó. Là một sang một bên, tôi nghĩ C# generics đã được thực hiện theo cách đó bởi vì tất cả mọi người luôn luôn gọi hệ thống chung trong C# "True Generics", so với hệ thống loại tẩy xóa của Java.
bất kỳ lý do gì để truyền tới đối tượng ở đây 'gen == ((object) testVar) .GetHashCode()'? – AlwaysAProgrammer
Mặc dù nó không trực tiếp trả lời câu hỏi của bạn, http://blogs.msdn.com/b/ericlippert/archive/2012/07/10/when-is-a-cast-not-a-cast.aspx có một số câu hỏi hay thông tin về cách generics được đúc và cách chúng liên quan với nhau trong C#. – devstruck
@Yogendra Thực hiện việc này truy cập phương thức Object.GetHashCode() thay vì phương thức "mới" Test.GetHashCode(). Đó là lý do tại sao nó trả về một giá trị khác (vì nó chạy một phương thức hoàn toàn khác). – Carrotman42