【问题标题】:Create a delegate which returns enum's underlying int, without knowing the enum type at runtime创建一个返回枚举的底层 int 的委托,而不知道运行时的枚举类型
【发布时间】:2021-09-14 10:06:47
【问题描述】:

我正在编写一个设置系统,它依赖于向属性添加属性,然后使用反射。

例如,我通过将 SliderAttribute 添加到浮动属性来创建滑块,然后找到所有这些属性并创建委托来修改相关属性,如下所示:

Func<float> getterDelegate = Delegate.CreateDelegate(typeof(Func<float>), arg, property.GetGetMethod()) as Func<float>;
Action<float> setterDelegate = Delegate.CreateDelegate(typeof(Action<float>), arg, property.GetSetMethod()) as Action<float>;

settingObj = new Slider(sliderAttribute, getterDelegate, setterDelegate);

现在,我想通过对枚举值应用相同的逻辑来创建多项选择对象。那就是我想生成通过底层类型修改枚举属性的 getter/setter 委托(我们可以假设它总是 int。)

理想情况如下,返回错误ArgumentException: method return type is incompatible。如果我使用“枚举”类型,结果相同。

Func<int> getterDelegate = Delegate.CreateDelegate(typeof(Func<int>), arg, property.GetGetMethod()) as Func<int>;
Action<int> setterDelegate = Delegate.CreateDelegate(typeof(Action<int>), arg, property.GetSetMethod()) as Action<int>;

settingObj = new MultipleChoice(multipleChoiceAttribute, getterDelegate, setterDelegate, property.PropertyType);

【问题讨论】:

  • 一定要给MultipleChoice的构造函数一个Action&lt;int&gt;Func&lt;int&gt;吗?或者Action&lt;TheActualEnumType&gt;Func&lt;TheActualEnumType&gt; 也可以工作?
  • @Sweeper 问题是我在创建代表的阶段不知道枚举类型。
  • 我的意思是,您确实知道枚举类型。只是property.PropertyType。您可以创建Action&lt;TheActualEnumType&gt; 的实例。当然,它只有Delegate 的编译时类型。我的问题是,MultipleChoice 构造函数采用什么参数?是否需要Delegate 作为参数?如果不是,那么首先创建Action&lt;TheActualEnumType&gt; 毫无意义,我不会将其作为答案发布。
  • MultipleChoice 接受参数: (MultipleChoiceInfoAttribute info, Func getter, Action setter, Type enumType) 我可以访问 property.PropertyType 中的枚举类型,但我几乎不能将其用作“CreateDelegate”函数中的类型参数?
  • 可以CreateDelegate的第一个参数中使用它,但是由于MultipleChoice只需要一个Action&lt;int&gt;,你不能直接将它传递给构造函数.让我看看我能不能想出点什么……

标签: c# reflection enums system.reflection


【解决方案1】:

您可以创建返回并采用实际枚举类型的委托,如下所示:

Delegate getterEnumDelegate = Delegate.CreateDelegate(
    typeof(Func<>).MakeGenericType(property.PropertyType), arg, property.GetGetMethod()
);
Delegate setterEnumDelegate = Delegate.CreateDelegate(
    typeof(Action<>).MakeGenericType(property.PropertyType), arg, property.GetSetMethod()
);

要将这些转换为Action&lt;int&gt;Func&lt;int&gt;,您只需:

Func<int> getterDelegate = () => (int)getterEnumDelegate.DynamicInvoke();
Action<int> setterDelegate = x => setterEnumDelegate.DynamicInvoke(x);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-10
    • 1970-01-01
    • 2012-11-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多