Ключевое слово, введенное для связывания во время выполнения в C # 4: dynamic
.
public static void myfunc(dynamic x)
Это позволяет вам делать предположения о x, которые не проверяются во время компиляции, но потерпят неудачу во время выполнения, если эти предположения окажутся недействительными.
public static void MakeTheDuckQuack(dynamic duck)
{
Console.WriteLine(duck.Quack());
}
Предположение, сделанное здесь, состоит в том, что параметр будет иметь метод с именем Quack
, который не принимает аргументов и возвращает значение, которое затем можно использовать в качестве аргумента для Console.WriteLine
. Если какое-либо из этих предположений неверно, вы получите сбой во время выполнения.
Данные классы определены как
class Duck
{
public string Quack()
{
return "Quack!";
}
}
class FakeDuck
{
public string Quack()
{
return "Moo!";
}
}
И вызовы методов
MakeTheDuckQuack(new Duck());
MakeTheDuckQuack(new FakeDuck());
MakeTheDuckQuack(42);
Первые два успешно выполняются при успешном связывании во время выполнения, а третье приводит к исключению, поскольку System.Int32
не имеет метода с именем Quack
.
Вообще говоря, вам следует избегать этого, если это возможно, поскольку вы, по сути, оговариваете, что аргумент должен выполнять какой-либо интерфейс без строгого его определения. Если вы работаете в сценарии взаимодействия, возможно, это то, что вам нужно сделать. Если вы работаете с типами, которые вы контролируете, то вам лучше справиться с попытками обеспечить безопасность времени компиляции через интерфейсы и / или базовые классы. Вы даже можете использовать различные стратегии (например, Pattern Adapter ), чтобы типы, которые вы не контролируете (или не можете изменять), соответствовали заданному интерфейсу.