Функция Тип параметра определяется во время выполнения? - PullRequest
0 голосов
/ 30 декабря 2011

Возможно ли в любом случае (желательно без использования сторонних библиотек) создать функцию, тип которой определяется во время выполнения в C #?

например,

public static void myfunc(var x)
{
     System.Windows.Forms.MessageBox.Show(x); //just an example
}

ПРИМЕЧАНИЕ: IЯ хочу, чтобы среда выполнения определяла тип параметра, и не хочу впоследствии приводить параметр к другому типу, что было бы необходимо, если бы я использовал обобщенные значения.например, я не хочу:

 myfunc<T>(T x) 
 // and then :
 MessageBox.Show((string)m);

ОБНОВЛЕНИЕ: я на самом деле делаю парсер функций для моего языка программирования , который переводится в код C #.На моем языке я хотел, чтобы типы параметров определялись во время выполнения всегда .Я искал хорошую функцию C # для легкого перевода.например, в моем языковом синтаксисе:

 function msg << x
     MessageBox.Show x
 end

необходимо было преобразовать во что-то, что не запрашивало тип во время компиляции, но понадобилось бы во время выполнения.например,

public static void msg(var x)
{
     System.Windows.Forms.MessageBox.Show(x);
}

Ответы [ 3 ]

10 голосов
/ 30 декабря 2011

Ключевое слово, введенное для связывания во время выполнения в 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 ), чтобы типы, которые вы не контролируете (или не можете изменять), соответствовали заданному интерфейсу.

2 голосов
/ 30 декабря 2011

Если вам нужно знать тип ... тогда вам нужно знать тип.Вы не можете получить свой торт и съесть его тоже.

Во-первых, приведение в вашем примере не является необходимым, поскольку все объекты реализуют ToString().Вместо того, чтобы говорить нам, что вы думаете, что вам нужно, скажите нам, какую проблему вы пытаетесь решить.Почти наверняка есть решение с помощью обобщений или использования ключевого слова dynamic (хотя dynamic требуется редко), но нам нужно больше информации.Если вы добавите больше, я обновлю этот ответ.

0 голосов
/ 30 декабря 2011

Вы можете использовать тип объекта или, если вы не знаете, сколько элементов доступно, вы можете использовать массив объектов params , т.е. params object[] cParams.

...