简体   繁体   English

如何使用Func <>参数创建自定义属性

[英]How to create custom attribute with Func<> parameter

I have a class that helps me read data from an MS SQL database into a list of objects. 我有一个可以帮助我从MS SQL数据库读取数据到对象列表的类。 For the most part it's pretty straightforward; 在大多数情况下,这非常简单。 I can assume the property name of the class matches the column name of the table and just assign it accordingly, but sometimes I need to be able to transform data. 我可以假定该类的属性名称与表的列名称匹配,并相应地对其进行分配,但是有时我需要能够转换数据。

I have created a custom attribute to put on my class properties: 我创建了一个自定义属性来放置我的类属性:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class TransformDataAttribute : Attribute
{
    public Func<object, string, object> TransformThisData { get; set; }
}

Now, let's say I want to create the Func on the fly, like this: 现在,假设我想即时创建Func,如下所示:

    [TransformData(TransformThisData = new Func<object, string, object>((v, p) => "My name is " + v.ToString()))]
    public string Name { get; set; }

The error that I am seeing is 'TransformThisData' is not a valid named attribute argument because it is not a valid attribute parameter type. 我看到的错误是“ TransformThisData”不是有效的命名属性参数,因为它不是有效的属性参数类型。

What is the best way to accomplish Func as a property attribute? 实现Func作为属性的最佳方法是什么?

Well, here's the best I have been able to come up with. 好吧,这是我所能想到的最好的。

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class TransformDataAttribute : Attribute
{
    public string TransformDataClass { get; set; }
    // This method must contain these parameters: (object value, PropertyInfo pi)
    public string TransformDataMethod { get; set; }
}

I put it on the class property, like so... 我把它放在class属性上,就像这样...

  public class Tracker
  {
    [TransformData(TransformDataClass = "CompanyTracker.DataTransformation", TransformDataMethod = "FunkyData")]
    public string FunkyData { get; set; }
  }

I can have a single data transformation class with different methods of transformation: 我可以有一个具有不同转换方法的数据转换类:

public class DataTransformation
{
    public object FunkyData(object value, PropertyInfo pi)
    {
        // if data is this, return that, blah, blah
        return value;
    }
}

A static utility method for interpreting the three parameters: 解释三个参数的静态实用程序方法:

    public static object CallThisMethod(string className, string methodName, object[] parms)
    {
        Type type = Type.GetType(className);
        MethodInfo theMethod = type.GetMethod(methodName);
        object classInstance = Activator.CreateInstance(type);

        return theMethod.Invoke(classInstance, parms);
    }

...and then in my ADO Helper code, when it comes to assigning values to properties: ...然后在我的ADO Helper代码中,为属性分配值时:

        TransformDataAttribute attr = Utility.GetPropertyAttribute<TransformDataAttribute>(pi);
        if (attr != null)
        {
            object[] parms = new object[] { value, pi };
            value = Utility.CallThisMethod(attr.TransformDataClass, attr.TransformDataMethod, parms);
        }
        pi.SetValue(t, value, null);

It works. 有用。 I hate to depend on Reflection of embedded strings for classes and methods, and it just doesn't seem like good design, but sometimes you just have to get things done. 我讨厌依赖于嵌入式字符串的反射来实现类和方法,但这似乎并不是一个好的设计,但是有时候您只需要把事情做好即可。 If anyone has a more elegant way to do this I'd be glad to hear about it. 如果有人能以更优雅的方式做到这一点,我将很高兴听到它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM