如何为枚举列表创建 InstanceDescriptor?

How to create InstanceDescriptor for List of enum?

类似问题:Passing int list as a parameter to a web user control
枚举类型有没有类似的例子?

我正在创建一个 asp.net 自定义控件,我想在其中将逗号分隔的枚举列表作为 属性.
传递 我正在写一个 TypeConverter 用于将逗号分隔的字符串值转换为枚举列表。

ConvertTo方法中,
如何为枚举列表创建 InstanceDescriptor 对象?

我现在的代码如下:

//enum
public enum MyEnum {Hello, World}

//main method
List<MyEnum> list = new List<MyEnum>();
list.Add(MyEnum.Hello);
list.Add(MyEnum.World);
ConstructorInfo constructor = typeof(List<MyEnum>).GetConstructor( Type.EmptyTypes );
InstanceDescriptor idesc = new InstanceDescriptor(constructor, list);

失败并显示消息

Length mismatch

不知道为什么

您的列表应该是一个空集合,因为 constructor 是无参数的 constructor 您的代码应该如下所示:

List<MyEnum> list = new List<MyEnum>();
ConstructorInfo constructor = typeof(List<MyEnum>).GetConstructor(Type.EmptyTypes);
InstanceDescriptor idesc = new InstanceDescriptor(constructor, list);

或使用空 constructor:

ConstructorInfo constructor = 
  typeof(List<MyEnum>).GetConstructor(BindingFlags.ExactBinding, null,Type.EmptyTypes, null);

这意味着:在 GetConstructor 方法之一中使用 EmptyTypes 字段来获取不带参数的 constructor

发生 "Length mismatch" 错误是因为您检索了 default List<T> constructor,它有 ZERO 个参数,然后您要求 InstanceDescriptor 调用它具有 两个 个参数的构造函数,MyEnum.HelloMyEnum.World.

您可能认为可以使用接受单个 IEnumerable<T> 参数的 alternate List<T> constructor

ConstructorInfo constructor =
    typeof(List<MyEnum>).GetConstructor(new[] { typeof(IEnumerable<MyEnum>) });
InstanceDescriptor idesc = new InstanceDescriptor(constructor, new[] { list });

这让 InstanceDescriptor 很高兴,但不幸的是,您会发现 ASP.NET 现在抛出 NullReferenceException(与 question you linked to 相同),因为 ASP.NET不知道如何处理IEnumerable<T>参数。

这里有两种方法可以解决问题。

解决方案 1: 将自定义控件和类型转换器更改为使用 MyEnum[] 而不是 List<MyEnum>。这是可行的,因为 ASP.NET 可以处理数组。

解决方案 2: 创建一个从数组创建 List<MyEnum> 的静态辅助方法:

public static List<MyEnum> ToList(MyEnum[] values)
{
    return new List<MyEnum>(values);
}

然后更改您的类型转换器以创建一个调用辅助方法的 InstanceDescriptor,将其作为数组传递给您的列表:

MethodInfo method = typeof(MyEnumListConverter).GetMethod("ToList");
InstanceDescriptor idesc = new InstanceDescriptor(method, new[] { list.ToArray() });