Всегда ли EnumBuilder создает перечисления, несовместимые с CLS? Как сделать enum совместимым с CLS?

В приведенном ниже примере кода создается файл TempAssembly.dll с перечислением Elevation в нем.

 public static void Main()
        {
            AppDomain currentDomain = AppDomain.CurrentDomain;
            AssemblyName aName = new AssemblyName("TempAssembly");
            AssemblyBuilder ab = currentDomain.DefineDynamicAssembly(aName, AssemblyBuilderAccess.RunAndSave);
            ModuleBuilder mb = ab.DefineDynamicModule(aName.Name, aName.Name + ".dll");
            EnumBuilder eb = mb.DefineEnum("Elevation", TypeAttributes.Public, typeof(int));
            eb.DefineLiteral("Low", 0);
            eb.DefineLiteral("High", 1);
            Type finished = eb.CreateType();
            ab.Save(aName.Name + ".dll");
            foreach (object o in Enum.GetValues(finished))
            {
                Console.WriteLine("{0}.{1} = {2}", finished, o, ((int)o));
            }
        }

Я сослался на TempAssembly.dll и использовал перечисление Elevation в другом проекте (скажем, в проекте TestA). Поскольку я хочу, чтобы код был CLS-совместимым, я добавил в проект TestA следующий атрибут.

[сборка: System.CLSCompliant (true)]

Код, в котором я получаю предупреждение:

public class TestClass
{
    public Elevation Elev { get; set; } 
}

Предупреждение

Предупреждение 1 Тип TestA.TestClass.Elev не соответствует требованиям CLS

Я проверил документацию о том, как писать код, совместимый с CLS, но я не могу многое сделать, поскольку перечисление создается динамически. Любые предложения, как я могу сделать enum CLS совместимым?


person Vaibhav    schedule 13.10.2014    source источник


Ответы (2)


Вы пробовали пометить сборку как CLS-совместимую?

ab.SetCustomAttribute(new CustomAttributeBuilder(
        typeof(CLSCompliantAttribute).GetConstructor(new[] { typeof(bool) }),
        new object[] { true }));

Вы тоже сможете сделать то же самое на eb:

eb.SetCustomAttribute(new CustomAttributeBuilder(
        typeof(CLSCompliantAttribute).GetConstructor(new[] { typeof(bool) }),
        new object[] { true }));
person Marc Gravell    schedule 13.10.2014

Когда вы применяете CLSCompliantAttribute к сборке TestA, вам также необходимо добавить атрибут CLSCompliantAttribute в динамически созданную сборку TempAssembly. Поскольку атрибут в нем не определен, он по умолчанию не соответствует требованиям CLS.

См. Также MSDN для получения дополнительной информации:

Если к элементу программы не применяется CLSCompliantAttribute, то по умолчанию:

  • Сборка несовместима с CLS.
  • Тип является CLS-совместимым, только если его включающий тип или сборка CLS-совместимы.
  • Член типа является CLS-совместимым, только если тип является CLS-совместимым.

Итак, у вас есть два варианта. Удалите CLSCompliantAttribute из сборки TestA или добавьте CLSCompliantAttribute в свой TempAssembly.

person Jehof    schedule 13.10.2014
comment
Или третий вариант: удалить перечисление Elevation из публичного интерфейса сборки TestA. (Это не мешает его внутреннему использованию.) - person ; 13.10.2014