【问题标题】:Possible to get Value from Attribute?可以从属性中获取值吗?
【发布时间】:2012-12-12 22:41:08
【问题描述】:

我正在使用文件助手,我把我的班级放在首位 [DelimitedRecord("|")]

我想检查该值是否为“|”如果没有,那么我想抛出一个异常..

public void WriteResults<T>(IList<T> resultsToWrite, string path, string fileName) where T: class
        {      
            var attr =  (DelimitedRecordAttribute)Attribute.GetCustomAttribute(typeof(T), typeof(DelimitedRecordAttribute));

            if (attr.HasValue("|")) // has value does not exist.
            {
                FileHelperEngine<T> engine = new FileHelperEngine<T>();
                engine.HeaderText = String.Join("|", typeof(T).GetFields().Select(x => x.Name));

                string fullPath = String.Format(@"{0}\{1}-{2}.csv", path, fileName, DateTime.Now.ToString("yyyy-MM-dd"));

                engine.WriteFile(fullPath, resultsToWrite);
            }


        }

我可以使用什么来检查该属性是否在具有该值的类上?

编辑

这是我认为可用的属性

【问题讨论】:

    标签: c# attributes custom-attributes filehelpers


    【解决方案1】:

    您可以像这样检索DelimitedRecordAttribute 的实例:

    // t is an instance of the class decorated with your DelimitedRecordAttribute
    DelimitedRecordAttribute myAttribute =
            (DelimitedRecordAttribute) 
            Attribute.GetCustomAttribute(t, typeof (DelimitedRecordAttribute));
    

    如果DelimitedRecordAttribute 公开了获取参数的方法(它应该这样做),您可以通过该方法(通常是属性)访问该值,例如类似:

    var delimiter = myAttribute.Delimiter
    

    http://msdn.microsoft.com/en-us/library/71s1zwct.aspx

    更新

    由于在您的情况下似乎没有公共属性,您可以使用反射来枚举非公共字段并查看是否可以找到包含该值的字段,例如像

    FieldInfo[] fields = myType.GetFields(
                         BindingFlags.NonPublic | 
                         BindingFlags.Instance);
    
    foreach (FieldInfo fi in fields)
    {
        // Check if fi.GetValue() returns the value you are looking for
    }
    

    更新 2

    如果此属性来自 filehelpers.sourceforge.net,则您要查找的字段是

    internal string Separator;
    

    该类的完整源代码是

    [AttributeUsage(AttributeTargets.Class)]
    public sealed class DelimitedRecordAttribute : TypedRecordAttribute
    {
        internal string Separator;
    
    /// <summary>Indicates that this class represents a delimited record. </summary>
        /// <param name="delimiter">The separator string used to split the fields of the record.</param>
        public DelimitedRecordAttribute(string delimiter)
        {
            if (Separator != String.Empty)
                this.Separator = delimiter;
            else
                throw new ArgumentException("sep debe ser <> \"\"");
        }
    
    
    }
    

    更新 3

    像这样获取分隔符字段:

    FieldInfo sepField = myTypeA.GetField("Separator", 
                            BindingFlags.NonPublic | BindingFlags.Instance);
    
    string separator = (string)sepField.GetValue();
    

    【讨论】:

    • 是的,我正在查看 msdn 示例。我没有看到任何我可以使用的属性,期望用于名为 TypeId 的东西是一个对象。尽管存储了管道,但我没有看到任何东西。
    • @chobo2:如果没有暴露值的属性,您可能仍然可以通过反射获取它(您当然可以通过反射获取它,除非该值从未存储在实例中)。跨度>
    • @chobo2:更新了我的帖子,向您展示如何枚举非公共字段(如果没有公共属性,很可能存储值)。你需要检查这些字段,看看是否有你想要的值。
    • @chobo2:如果这是来自filehelpers.sourceforge.net,那是开源的,所以你可以添加一个公开值的属性。
    • 你确定是GetFields吗?因为当我这样做时,我只是获得了该属性所在的类中的所有属性。但我没有看到属性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-21
    • 2016-03-04
    相关资源
    最近更新 更多