【本博文章除在标题明确注明 [转载] 外,均为作者原创!若无特别注明,本博所有原创文章均为IT168首发!任何个人/团队/公司在未经作者同意下不得擅自转载!】 本博文章所附带的源码(以下简称:源码)均遵循GPL开源协议,任何个人和团体都可以引用/修改/衍生该源码,并且可以再次开源/免费使用,使用时请在源码中保留作者信息!但是,决不可以将该源码以任何非开源形式发布及任何形式的商业用途!

认知属性(Attribute )

上一篇 / 下一篇  2008-11-01 11:24:27 / 个人分类:.Net [C#]

此属性(Attribute )而非彼属性(Property)。MSDN描述:属性(Attribute )能够提供功能强大的方法,以将声明信息与 C# 代码(类型、方法、属性等)相关联。一旦属性与程序实体关联,即可在运行时使用名为反射的技术对属性进行查询。属性 (Attribute) 描述如何将数据序列化,指定用于强制安全性的特性,并限制实时 (JIT) 编译器的优化,从而使代码易于调试。属性 (Attribute) 还可以记录文件名或代码作者,或在窗体开发阶段控制控件和成员的可见性等等。
MC"cl3u C0
:n5`&KASZ0属性具有以下特点:
p.VM:bee!Ub01、属性可向程序中添加元数据。元数据是嵌入程序中的信息,如编译器指令或数据描述。
j2Gibgl S*U02、程序可以使用反射检查自己的元数据。请参见使用反射访问属性。
'Gy4K u4r_4W03、通常使用属性与 COM 交互。
ho:OGGe0ITPUB个人空间h.^;USI2nx#KA
经过对属性的研究我们做一个小示例,用于阐明属性的使用。我们尝试写个方法,它以两个对象为参数,然后将源对象运行时的所有字段值都拷贝给目标对象。按照一般情况,只要是可序列化的类、字段和方法都可以通过反射机制完成上述操作。但是如果遇到[NonSerialized]限定的字段我们将无从下手。面对这种情形我们创建一个方法,不仅可以存取[Serialized]限定的字段,还可以还原那些经[NonSerialized]限定的字段并在运行时重新赋值!
@{l b9d Kk0ITPUB个人空间GJ%@[@0e(@
我们先创建一个可序列化的类:ITPUB个人空间 V;F5x` H
[Serializable]
Ld.SQQ C0public class FooClass
5n5\f+]|l$w0{ITPUB个人空间V#I;r q5F)Rr
    public int data1;ITPUB个人空间EHA o/}$|#G(A5Mp
    [NonSerialized] public int data2;ITPUB个人空间v~:~ F$Q3U
    public FooClass(int data1, int data2)ITPUB个人空间)h,jx;\\2{0J
    {
] d`F ^%D ]0        this.data1 = data1;ITPUB个人空间hr8o&l)b H E,e.x
        this.data2 = data2;ITPUB个人空间1Px"fM*MN!mR)A6YNZ
    }
h:U:p`ATj Zs1{0}
Nh;S!V s(G!j0
R2?%U)Kp&Z*AE+u0然后在Button1的Click事件中添加如下代码:ITPUB个人空间 sT _6heC
        private void button1_Click(object sender, EventArgs e)
sx"A%f${I&L3p*l0        {ITPUB个人空间 z:e/Hf0E
            FooClass destObject = new FooClass(10, 20);
,e9|p,rb^(h8t5FD2Y0            FooClass sourceObject = new FooClass(10, 30);
e+G(kyU] N:Y\0            MessageBox.Show("destObject.data2: "+destObject.data2+'\n'+"sourceObject.data2: "+sourceObject.data2);ITPUB个人空间v]Zl? [r3mKS
            RestoreUtils.RestoreNonSerialized(destObject, sourceObject);ITPUB个人空间rIv^v'Lq0P%`S
            MessageBox.Show("destObject.data2: " + destObject.data2 + '\n' + "sourceObject.data2: " + sourceObject.data2);ITPUB个人空间3gw$B-w\4d lm&a
        }
rb#Dr9H0ITPUB个人空间$Q.hcGIu O v0l
运行结果如下:
g1Kn'U'kfEW0
.oF,C~+T"l0
.lSR+p!}!Gx0注意,RestoreUtils.RestoreNonSerialized()方法,
{$Jgz,l%M8O0    public class RestoreUtilsITPUB个人空间0d1dP6xl Q }2vJ%e
    {ITPUB个人空间 wx:?'c&F avRU
        const BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;ITPUB个人空间qO4T` ZW1Q

@0L2a7LV:z ?g'j)g.p0        public static void RestoreNonSerialized(object dest, object source)
t;T0h![M-KoT0        {ITPUB个人空间1@^"f?;P}8z0N\3F `
            if (dest == null || source == null)ITPUB个人空间#d\#e6d8M8kx4tP.E;i2|#i
                return;ITPUB个人空间z pM Z p

${Wp{)R&H~ `&r0            Type bjectType = dest.GetType();ITPUB个人空间 q4C3HO `NVf
            if (objectType.IsPrimitive | objectType.IsValueType)ITPUB个人空间`e7yhDZ Q[^*q
                return;
2A `7`~p*A1p4OFUF_0ITPUB个人空间,Db L$AE)nd
            FieldInfo[] dstFieldsInfo = objectType.GetFields(flags);
3_*j%CZj_#b2tZ0            FieldInfo[] srcFieldsInfo = source.GetType().GetFields(flags);
9|u)O7dgB(Jq0
\Nv*s ?(R^_+g0            for (int fieldIndex = 0; fieldIndex < dstFieldsInfo.Length; fieldIndex++)
#T.knY7]}@0            {
0@*ud ^V;P;l%L0                FieldInfo fieldInfo = dstFieldsInfo[fieldIndex];ITPUB个人空间N T5ng3nbn8BmV
                if (fieldInfo.IsNotSerialized)
7Z U%k.P G3`K0                {ITPUB个人空间TNb5Xt%u ?8t? pV
                    object newValue = srcFieldsInfo[fieldIndex].GetValue(source);
)]^4MU]1Y0                    fieldInfo.SetValue(dest, newValue);ITPUB个人空间9ZR1f1K W!m
                    continue;ITPUB个人空间$kO._4NJ^p h
                }ITPUB个人空间?#So{YgO
ITPUB个人空间,m _qaOe)S
                object dstFieldObject = fieldInfo.GetValue(dest);
z1cY:Q)P.f7H R^0                object srcFieldObject = srcFieldsInfo[fieldIndex].GetValue(source);
H*M.H,RU4?]z7e0                if (dstFieldObject != null && srcFieldObject != null)ITPUB个人空间%Qg~ByKjM
                    RestoreNonSerialized(dstFieldObject, srcFieldObject);ITPUB个人空间6R$t]g2n|XfY
            }
!P9p!W/buH NPWhz0
&S!si*s5mG0            IEnumerable dstEnumerable = dest as IEnumerable;ITPUB个人空间,weC(p0GzV
            if (dstEnumerable != null)ITPUB个人空间R_A\!JU-c9d
            {ITPUB个人空间/Oq0W R3qqQ_L4R^\G
                IEnumerable srcEnumerable = source as IEnumerable;ITPUB个人空间5p2E4As.[i
                if (srcEnumerable != null)
^%\Z!v2o7z&|Q8f3lR0                {ITPUB个人空间y:d _6~V5?H$?
                    IEnumerator srcEnumerator = srcEnumerable.GetEnumerator();
.tB0`/[VMV0                    foreach (Object dstItem in dstEnumerable)ITPUB个人空间*[c$^1K `[-V
                    {
:U.W5gim e:R0                        bool next = srcEnumerator.MoveNext();
CC:o(L,_Nq0U0                        if (!next)ITPUB个人空间)_ab$v? Q8o*j
                            break;
@ },E)N:O Y0                        Object srcItem = srcEnumerator.Current;
A d3CSqT.vKW0ITPUB个人空间1G:e/eZ ]
                        RestoreNonSerialized(dstItem, srcItem);
]L6jV f|Zf0                    }
k T-WOpt uSO:c0                }ITPUB个人空间^"lA$?3pffD{:K*_
            }
.g1E"VMP&x)^R0        }
+q|#}u$J_DTQ"`0    }
6h mQx*PkZY Q0
+aJCbH@0我们会发现,FooClass类的data2字段为不可序列化字段,在没有还原不可序列化的字段之前,destObject.data2和sourceObject.data2的值是不同的,为20和30,当我们还原并将sourceObject.data2在运行时的值拷贝给destObject.data2后,两个FooClass类的实例的data2字段就完全一样了。ITPUB个人空间'b.acxjCq:\7O6G

R4r[3S4O2Ka!Z!p0

TAG:

引用 删除 Guest   /   2009-11-24 11:24:04
5
引用 删除 Guest   /   2009-02-06 16:31:22
5
 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

日历

« 2012-02-10  
   1234
567891011
12131415161718
19202122232425
26272829   

数据统计

  • 访问量: 36979
  • 日志数: 35
  • 文件数: 14
  • 建立时间: 2008-07-29
  • 更新时间: 2009-05-09

RSS订阅

Open Toolbar