如何将 Func 放入 C# 属性(注释)中?
我有一个 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,并动态查找名称与字符串相同的函数,但我不想这样做。
感谢您的帮助:)
I have a C# annotation which is :
[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;
}
}
As you can see, there is a property which is a Func and I want to call it dynamically. Basically, I'd like to parse all the methods which have this annotation and then call the Func binded to the annotation.
I'd like to use it like this (this is a simple example of an echo function, which gets a string and return the same string):
[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]) };
}
I've got no error in my Annotation class but when it comes to regenerate the entire solution, each time I declare a method with the annotation I've got an error which tells me that I must use literals in an annotation.
I understand there is limitations, but is there any way I can avoid this problem? I know I can use a string instead of a Func, and look dynamically for the function whose name is the same as the string, but I would like not to do so.
Thanks for helping :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我认为这是不可能的,c# 只允许您使用具有常量值的属性。
执行此操作的一种方法是创建一个类而不是 func,然后将该类的类型传递到属性中。
然后,您需要使用反射实例化它并执行其中的方法。
因此,一个例子是:
然后您的属性将采用类型而不是 Func,
然后您将创建一个实现您的接口的类并将其传递到属性中。尽管这意味着(至少在最初,并且在不知道您的问题的情况下)您每次想要返回不同的结果时都需要创建一个新类。
I don't think it is possible, c# only allows you to use Attributes with constant values only.
One way of doing this would be to create a class instead of a func, and then you pass the type of that class into the attribute.
You'd then need to instantiate it with reflection and execute a method in it.
So an example would be:
then your attribute would take a type instead of a Func
you then would create a class that implements your interface and pass it into the attribute. Although this would mean that (at least initially, and without knowing your problem) you will need to create a new class every time you want to return different results.
来自 C# 规范:
From the C# spec:
因此,我今天正在研究一些自定义身份验证,并且自己遇到了这个问题,所以我认为添加我的解决方案可能会有所帮助,以防这对任何人都有帮助。我的具体目标是拥有三个 Func<,>结构如下:
第一个函数从上下文中提取(例如)各种请求标头,第二个函数通过安全机制处理这些标头,然后第三个函数测试第二个函数的输出的有效性。
我解决这个问题的方法是将两个类型参数传递给属性类:
创建一个包含属性所需方法的接口:
然后从我的生产代码中创建该接口的新具体实现:
这实际上使我能够每个控制器有不同的授权过程,使用相同的属性但传递不同的类类型。
So, I was working on some custom authentication today and came across this issue myself, so I figured it might help to add my solution in case this helps anyone. What I was specifically aiming to do was to have three Func<,> structured as:
Where the first function extracts (for example) various request headers from the context, the second processes those headers through a security mechanism and then the third tests the output of the second function for validity.
My solution to the problem was to pass two type parameters to the attribute class:
Create an interface which contains the methods that the Attribute requires:
And then create a new concrete implementation of the interface from within my production code:
This effectively allows me to have different authorisation procedures for each controller, using the same attribute but passing a different class type.