Сценарии, скомпилированные во время выполнения, не могут вызвать метод с необязательными аргументами

Мы добавили возможность для наших пользователей писать сценарии C # для выполнения приложения, которые компилируются и запускаются во время выполнения. Скрипты могут обращаться к API, который мы предоставили, и они компилируются / запускаются CSharpCodeProvider.

Я обнаружил, что код, скомпилированный во время выполнения, имеет проблемы при вызове метода с необязательными аргументами, например:

public void BlackmailColonelMustard(int amount, string myAlias, bool tellHisWifeAnyway = true)

Если скомпилированный во время выполнения сценарий вызывает BlackmailColonelMustard (10000, «Mr Boddy»), компилятор жалуется на отсутствие перегруженного метода с двумя аргументами, вместо того, чтобы распознавать значение по умолчанию для третьего параметра.

Естественно, он отлично работает при вызове из предварительно скомпилированного кода. Кто-нибудь знает, что я делаю не так?

Это потому, что VS2010 (даже до .NET 4) достаточно умен, чтобы скомпилировать код, использующий необязательные параметры, но среда выполнения .NET 3.5 еще не научилась этому трюку?


person wilee    schedule 22.06.2012    source источник
comment
Если вы ориентируетесь на .NET 3.5, возможно, CSharpCodeProvider использует правила C # 3.0, которые исключают использование необязательных параметров.   -  person dlev    schedule 23.06.2012
comment
Я думаю, что в любом случае у меня могут возникнуть проблемы с использованием параметров по умолчанию. Это должно быть достаточно безопасно, если мы реализуем IronPython (Python использует значения параметров по умолчанию) в какой-то момент, но мне интересно, захотим ли мы реализовать другой язык DLR, который плохо сочетается с этим подходом. Ваш комментарий может согласиться с этой статьей: Параметры по умолчанию не следует использовать   -  person wilee    schedule 23.06.2012


Ответы (1)


Необязательные аргументы были введены в C # 4.0. Если возможно, установите версию компилятора 4.0:

Dictionary<string, string> options = new Dictionary<string, string>();
options.Add("CompilerVersion", "v4.0");
CSharpCodeProvider provider = new CSharpCodeProvider(options);
person kol    schedule 22.06.2012
comment
Это может работать локально, но я не думаю, что смогу скомпилировать его таким образом, поскольку целевые машины развертывания работают под .NET 3.5, но не обязательно .NET 4.0. Думаю, я только что перепутал изящную функцию VS2010 с функцией .NET. - person wilee; 23.06.2012
comment
Другого решения нет. Если вы действительно хотите использовать функции C # 4.0, вам необходимо обновить платформу на машинах развертывания до версии 4 (или выше). Если обновление невозможно, боюсь, вам придется отказаться от использования этих функций. - person kol; 23.06.2012
comment
@wilee Это не функция VS2010, это функция C # 4.0. .Net на самом деле не имеет необязательных аргументов. Если вы компилируете свой код с версией CSharpCodeProvider .Net 4.0, он должен иметь возможность использовать C # 4.0 (поскольку .Net 4.0 включает компилятор C # 4.0). - person svick; 23.06.2012
comment
У .NET всегда были необязательные аргументы, но компилятор C # поддерживает их только начиная с C # 4.0. - person usr; 23.06.2012