Принуждение с плавающей точкой быть детерминированным в .NET?

class A {}
class B : A {}

public void SomeFunction()
{
    var someListOfB = new List<B>();
    someListOfB.Add(new B());
    someListOfB.Add(new B());
    someListOfB.Add(new B());
    SomeFunctionThatTakesA(someListOfB);
}

public void SomeFunctionThatTakesA(IEnumerable<A> input)
{
    // Before C# 4, you couldn't pass in List<B>:
    // cannot convert from
    // 'System.Collections.Generic.List<ConsoleApplication1.B>' to
    // 'System.Collections.Generic.IEnumerable<ConsoleApplication1.A>'
}

В принципе, всякий раз, когда у вас есть функция, которая принимает перечислимый тип одного типа, вы не можете передавать в Enumerable производного типа без явно его литья.

Просто, чтобы предупредить вас о ловушка хотя:

var ListOfB = new List<B>();
if(ListOfB is IEnumerable<A>)
{
    // In C# 4, this branch will
    // execute...
    Console.Write("It is A");
}
else if (ListOfB is IEnumerable<B>)
{
    // ...but in C# 3 and earlier,
    // this one will execute instead.
    Console.Write("It is B");
}

Это ужасный код в любом случае, но он существует, и изменение поведения на C # 4 может привести к тонким и трудным для поиска ошибкам, если вы используете такую ​​конструкцию.

45
задан Community 23 May 2017 в 12:33
поделиться