Почему System.Collections.Generic.IEnumerable<T>
нельзя присвоить типу параметра System.Collections.Generic.IEnumerable<object>
, учитывая, что object
является базовым классом C #?
Я наткнулся на это любопытство, когда делал что-то похожее на следующий код. Это универсальный метод, вызывающий перегруженный неуниверсальный метод.
void Main()
{
List<object> objects = new List<object>();
Method(objects); // This calls the method with IEnumerable, as expected
MethodCaller(objects);
}
void MethodCaller<T> (IEnumerable<T> objects)
{
Method(objects); // Calls method overload 2, with object as parameter - why?
// Why is the following line required to call the method overload 1?
// Can't C# do this automatically, given that object is the ultimate base class for everything?
IEnumerable<object> casted = (IEnumerable<object>) objects;
Method(casted); // Calls method overload 1
}
void Method (IEnumerable<object> param)
{
// Method overload 1
Console.WriteLine("Method overload 1 - with IEnumerable<object> as parameter");
}
void Method (object param)
{
// Method overload 2
Console.WriteLine("Method overload 2 - with object as parameter");
}
Я не понимаю, почему универсальный метод не должен вызывать первую перегрузку вместо второй. Я думал, что компилятор должен быть в состоянии сказать, что любой <T>
может быть неявно приведен к object
, поэтому IEnumerable<T>
должен быть неявно приведен к IEnumerable<object>
.
Другими словами:
IEnumerable<object> casted = (IEnumerable<object>) objects;
Почему эта строка требуется для вызова перегрузки метода 1? Разве C # не может сделать это автоматически, учитывая, что этот объект является основным базовым классом?
Это потому, что C # предполагает, что я могу передать <T>
, который не совместим с типом object
- даже если все на самом деле object
?