Является ли новая функция C# 4.0 - "Необязательные параметры" CLS-совместимой?
Эта новая функция действительно удобна.
В последнее время я прочитал документ "Microsoft All-In-One Code Framework" и упоминает, что "Необязательные параметры" не совместимы с CLS.
Поэтому я протестировал его с помощью "Необязательных параметров" в публичном API и включил FxCop, затем скомпилировал и FxCop ни на что не жаловался. В то же время FxCop действительно сообщал о предупреждении, когда я добавлял API, у которого в качестве типа возврата используется uint.
Так что теперь я в замешательстве, CLS-совместимые "Необязательные параметры" или нет?
И как лучше всего узнать, совместима ли новая языковая функция с CLS?
3 ответа
Необязательные аргументы являются своего рода CLS-совместимыми. Методы с необязательными аргументами являются законными и могут быть успешно скомпилированы с CLSCompliant
атрибут, но вызывающие эти методы не обязательно должны принимать во внимание значения параметров по умолчанию или необязательный атрибут. (В этом случае эти методы будут вести себя точно так же, как стандартные методы, требуя, чтобы все аргументы были явно указаны на сайте вызова.)
Методы, которые используют параметры по умолчанию, разрешены согласно Спецификации общего языка (CLS); однако CLS позволяет компиляторам игнорировать значения, назначенные этим параметрам. Код, написанный для компиляторов, которые игнорируют значения параметров по умолчанию, должен явно предоставлять аргументы для каждого параметра по умолчанию. Чтобы поддерживать поведение, которое требуется для разных языков программирования, методы, использующие параметры по умолчанию, должны быть заменены перегрузками методов, предоставляющими параметры по умолчанию.
(Взято из документации для "CA1026: Параметры по умолчанию не должны использоваться".)
Я интерпретирую ваш вопрос как о дополнительных аргументах.
Если это так, то я считаю, что они совместимы с CLS, и вы можете проверить с помощью атрибута CLSCompliant:
using System;
[assembly: CLSCompliant(true)]
namespace ConsoleApplication1
{
public class Program
{
public static int Test(int val=42)
{
return val;
}
static void Main(string[] args)
{
System.Console.WriteLine(Test());
}
}
}
Это компилируется без предупреждений.
Посмотрите на спецификации CLS.
Со страницы 41:
Ограничение vararg может быть включено, чтобы указать, что все аргументы после этой точки являются необязательными. Когда это появляется, соглашение о вызовах должно быть тем, которое поддерживает переменные списки аргументов.
Но в поле справа внизу написано:
Правило 15 CLS: ограничение vararg не является частью CLS, и единственное соглашение о вызовах, поддерживаемое CLS, - это стандартное соглашение об управляемых вызовах