Có thể hơi phức tạp, nhưng tôi tự hỏi tại sao. Trong System.Linq.Enumerable.cs
của System.Core.dll
ta có:Phương pháp mở rộng và kiểm tra thời gian biên dịch
public static int Count<TSource>(this IEnumerable<TSource> source);
trong mã của tôi Tôi đang làm một cái gì đó xấu xa:
namespace Test
{
public static class Extensions
{
public static int Count<TSource>(this IEnumerable<TSource> source)
{
return -1; //evil code
}
}
//commented temporarily
//public static class CommentedExtensions
//{
// public static int Count<TSource>(this IEnumerable<TSource> source)
// {
// return -2; //another evil code
// }
//}
public static void Main(string[] args)
{
Console.WriteLine(Enumerable.Range(0,10).Count()); // -1, evil code works
Console.Read();
}
}
Nếu tôi bỏ ghi chú CommentedExtensions
, tôi sẽ nhận được một lỗi biên dịch nói "gọi đây là mơ hồ blabla " như mong đợi. Nhưng tại sao tôi không nhận được lỗi này ở lần đầu tiên? Nó cũng mơ hồ!
EDIT Sau một thử nghiệm khác, tôi thấy rằng tôi sẽ không nhận được lỗi biên dịch nếu phương thức mở rộng ở các không gian tên khác nhau, thậm chí chúng hoàn toàn giống nhau. Tại sao nó được phép? Nó mang lại sự gọi mơ hồ về các phương thức trong C#.
EDIT2 Tôi biết thực tế hai số Count
khác nhau trong IL. Trong thực tế nó đang gọi
Enumerable.Count(Enumerable.Range(0,10))
và phương pháp khuyến nông ác của tôi đang kêu gọi:
MyExtension.Count(Enumerable.Range(0,10))
vì vậy họ là khác nhau. Nhưng tôi vẫn nghĩ đó là mùi hôi. Chúng ta có phương pháp mở rộng "thực sự" không? mà có thể ngăn chặn hành vi xấu xa?