【问题标题】:How do you put a Func in a C# attribute (annotation)?如何将 Func 放入 C# 属性(注释)中?
【发布时间】:2012-01-17 19:37:39
【问题描述】:

我有一个 C# 注释:

[AttributeUsage(AttributeTargets.Method)]
public class OperationInfo : System.Attribute {
    public enum VisibilityType {
        GLOBAL,
        LOCAL,
        PRIVATE
    }
    public VisibilityType Visibility { get; set; }
    public string Title { get; set; }
    public Func<List<string>, List<string>> Func;

    public OperationInfo(VisibilityType visibility, string title, Func<List<string>, List<string>> function) {
        Visibility = visibility;
        Title = title;
        Func = function;
    }
}

如您所见,有一个属性是 Func,我想动态调用它。基本上,我想解析所有有这个注解的方法,然后调用绑定到注解的Func。

我想这样使用它(这是一个简单的 echo 函数示例,它获取一个字符串并返回相同的字符串):

[OperationInfo(OperationInfo.VisibilityType.GLOBAL, "echo", IDoEcho)]
    public static string DoEcho(string a)
    {
        return a;
    }

    [OperationInfo(OperationInfo.VisibilityType.PRIVATE, null, null)]
    public static List<string> IDoEcho(List<string> param) {
        return new List<string>() { DoEcho(param[0]) };
    }

我的 Annotation 类没有错误,但是在重新生成整个解决方案时,每次我声明一个带有注释的方法时,我都会遇到一个错误,告诉我必须在注释中使用文字。

我知道存在限制,但有什么办法可以避免这个问题吗?我知道我可以使用字符串而不是 Func,并动态查找名称与字符串相同的函数,但我不想这样做。

感谢您的帮助:)

【问题讨论】:

  • 它可能看起来不太漂亮,但您经常会发现字符串作为属性的参数,因为在编译时必须知道这些值。

标签: c# reflection attributes


【解决方案1】:

我认为不可能,c# 只允许你使用仅具有常量值的属性。

这样做的一种方法是创建一个类而不是一个函数,然后将该类的类型传递给属性。 然后你需要用反射实例化它并在其中执行一个方法。

所以一个例子是:

public interface IDoStuff
{
    IList<string> Execute();
}

那么您的属性将采用类型而不是 Func

public OperationInfo(VisibilityType v, string title, Type type)
{
   ///...
}

然后您将创建一个实现您的接口的类并将其传递给属性。尽管这意味着(至少在最初,并且不知道您的问题)您每次想要返回不同的结果时都需要创建一个新类。

【讨论】:

    【解决方案2】:

    来自 C# 规范:

    17.1.3 属性参数类型

    属性类的位置参数和命名参数的类型仅限于属性参数类型,它们是:

    · 以下类型之一:bool、byte、char、double、float、int、long、sbyte、short、string、uint、ulong、ushort。

    · 类型对象。

    · System.Type 类型。

    · 枚举类型,前提是它具有公共可访问性,并且它所嵌套的类型(如果有)也具有公共可访问性(第 17.2 节)。

    · 上述类型的一维数组。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-04-30
      • 2018-12-29
      • 1970-01-01
      • 2015-07-03
      • 1970-01-01
      • 1970-01-01
      • 2012-05-22
      相关资源
      最近更新 更多