zoukankan      html  css  js  c++  java
  • C#特性Attribute学习

    起初一直纠结于如何调用特性附着在下面那个成员的值,后来发现不需要调用,通过反射加载的时候是自动绑定上去的,即 获得成员对象之后,有一个方法可以获得特性标签。

    其实从类库提供者,和类库使用者的角度,分开来看就很容易理解了。

    类库提供者(MyClassLib类):

    MyClassLib类有一个ShowString(object obj, string name)方法,可以打印出string信息。

    并且提供一个StringLenAttribute特性,控制字符串长度。

    类库使用者:

    使用这个名为MyClassLib的类,来打印信息

    下面看例子

    使用者:

    public class User
    {
        [StringLen(3)]
        string myName;
    
        [StringLen(50)]
        string myDetail;
    
        public void Go()
        {
            myName = "Tim Cook";
            myDetail = "Apple company CEO";
    
            MyClassLib cl = new MyClassLib();
            cl.ShowString(this, myName);
            cl.ShowString(this, myDetail);
            //Output:
            //字符串过长! 打印失败
            //Apple company CEO
        }
    }
    Use

    [StringLen(xx)]

    这个是自定义的特性

    来看看提供者方面的代码

    提供者:

    定义自定义特性:

    [AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = true)]
    public sealed class StringLenAttribute : Attribute
    {
        public int Len { get; set; }
    
            
        public StringLenAttribute(int len)
        {
            this.Len = len;
        }
    }

    然后是打印字符串这个方法,和应用特性:

    public class MyClassLib
    {
        public void ShowString(object obj, string name)
        {
            var atts = obj.GetType().GetFields(BindingFlags.Instance|BindingFlags.NonPublic);
    
            foreach (var item in atts)
            {
                var tmp = item.GetCustomAttributes(typeof(StringLenAttribute), false);
                string tmp2 = string.Empty;
    
                if (tmp.Length > 0 && (string)item.GetValue(obj) == name)
                {
                    var stringLenAtt = (StringLenAttribute)tmp[0];
    
                    if (name.Length > stringLenAtt.Len)
                    {
                        Console.WriteLine("字符串过长! 打印失败");
                        return;
                    }
                }
            }
    
            Console.WriteLine(name);
        }
    }
    Provider


     

    反射调用的话,应该是必须得到对象才能使用里面成员,所以要传入2个参数,真正编写的时候肯定涉及自己的结构类,所以这个问题并不明显。如果以后找到解决方法,会更新这篇文章。

  • 相关阅读:
    09-2:跳台阶
    09:菲波那切数列
    08:旋转数组的最小值
    07:用两个栈实现队列
    06:重建二叉树
    05:从尾到头打印链表
    04:替换字符
    centos7安装Jenkins更改默认端口并配置Ldap服务器进行用户认证
    Jira配置openLdap服务器进行用户认证
    定时自动从FTP服务器取数据脚本
  • 原文地址:https://www.cnblogs.com/hont/p/3209338.html
Copyright © 2011-2022 走看看