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

认知属性(Attribute )

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

此属性(Attribute )而非彼属性(Property)。MSDN描述:属性(Attribute )能够提供功能强大的方法,以将声明信息与 C# 代码(类型、方法、属性等)相关联。一旦属性与程序实体关联,即可在运行时使用名为反射的技术对属性进行查询。属性 (Attribute) 描述如何将数据序列化,指定用于强制安全性的特性,并限制实时 (JIT) 编译器的优化,从而使代码易于调试。属性 (Attribute) 还可以记录文件名或代码作者,或在窗体开发阶段控制控件和成员的可见性等等。
"@#LuWd0
{C0z]Q1B]:s%I0属性具有以下特点:ITPUB个人空间a+i} KZ u D6x ^
1、属性可向程序中添加元数据。元数据是嵌入程序中的信息,如编译器指令或数据描述。
vR(]4A%wUS02、程序可以使用反射检查自己的元数据。请参见使用反射访问属性。ITPUB个人空间&[?9_S1gl[:D
3、通常使用属性与 COM 交互。ITPUB个人空间 b9qKK"l-u;s

V A]R/y0经过对属性的研究我们做一个小示例,用于阐明属性的使用。我们尝试写个方法,它以两个对象为参数,然后将源对象运行时的所有字段值都拷贝给目标对象。按照一般情况,只要是可序列化的类、字段和方法都可以通过反射机制完成上述操作。但是如果遇到[NonSerialized]限定的字段我们将无从下手。面对这种情形我们创建一个方法,不仅可以存取[Serialized]限定的字段,还可以还原那些经[NonSerialized]限定的字段并在运行时重新赋值!ITPUB个人空间)YK L;~X*ZJ&\
ITPUB个人空间[-~*NqAFd/z'b-w
我们先创建一个可序列化的类:ITPUB个人空间"mk*j_"pow
[Serializable]ITPUB个人空间r:x [^ucKP4i r
public class FooClass
E:OV;cM5D%M }`;\0{ITPUB个人空间Q4d:_&Txt
    public int data1;ITPUB个人空间3Aad M8P3dFC~6_
    [NonSerialized] public int data2;ITPUB个人空间 ?:C6v?$p
    public FooClass(int data1, int data2)
b+G4~ f@Q0    {
3B/fDRB*o0        this.data1 = data1;
X9]+\#d@0        this.data2 = data2;
1|6] n DkD0    }ITPUB个人空间(D9| dD0K b
}
z'Ri'm,@E&Q;?rR}0
xx Nrh0然后在Button1的Click事件中添加如下代码:
hA.CS*{0        private void button1_Click(object sender, EventArgs e)
+}RPf ?7},]d~0        {ITPUB个人空间K}j~PJ%[g%c
            FooClass destObject = new FooClass(10, 20);
GO'q i0EW9n;W0            FooClass sourceObject = new FooClass(10, 30);ITPUB个人空间;ze}5lM.PLE
            MessageBox.Show("destObject.data2: "+destObject.data2+'\n'+"sourceObject.data2: "+sourceObject.data2);ITPUB个人空间h%l)K|kX
            RestoreUtils.RestoreNonSerialized(destObject, sourceObject);
6m/h n Qjx7RyF0            MessageBox.Show("destObject.data2: " + destObject.data2 + '\n' + "sourceObject.data2: " + sourceObject.data2);
%vAh0Hx4`1R pS0        }ITPUB个人空间'??K&k]:|#t
ITPUB个人空间d!ww;zf
运行结果如下:ITPUB个人空间-OV@,|OCX1k

Oc^*Gb#P3\0ITPUB个人空间.z&m7na)C
注意,RestoreUtils.RestoreNonSerialized()方法,ITPUB个人空间"aI6o2H/m$w
    public class RestoreUtils
-`*h s*G3Xo0    {
3Mx;KtN0        const BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;
_ a3qr*C7k_0
4W/MdAL)GbEE#\0        public static void RestoreNonSerialized(object dest, object source)ITPUB个人空间~H2\0r0~
        {ITPUB个人空间c8Z I1[le A p;w%m!G y
            if (dest == null || source == null)
vnI_Jt)[0                return;
.g:Cih t&t/B0
DM1g!a5GpT0`0            Type bjectType = dest.GetType();
KWB,W.K0            if (objectType.IsPrimitive | objectType.IsValueType)
-dV H\)yS D Y e(F0                return;
,x r RLM.v0ITPUB个人空间 u3Td*R5aMH A
            FieldInfo[] dstFieldsInfo = objectType.GetFields(flags);
D%z.ja'n!a ^IU!\4L0            FieldInfo[] srcFieldsInfo = source.GetType().GetFields(flags);
gqt6g,P0
W8e1o9Gw0            for (int fieldIndex = 0; fieldIndex < dstFieldsInfo.Length; fieldIndex++)
d!r!e1O3{;d0            {ITPUB个人空间h#N5W%AR{
                FieldInfo fieldInfo = dstFieldsInfo[fieldIndex];ITPUB个人空间#GIM Sr_5R)_
                if (fieldInfo.IsNotSerialized)
#pT)]a?\0                {
.O,\O z;AX#c0                    object newValue = srcFieldsInfo[fieldIndex].GetValue(source);
b:m0y |%YK0                    fieldInfo.SetValue(dest, newValue);ITPUB个人空间&I;fL5Z']3Ls
                    continue;ITPUB个人空间wha)t!Abw)@5] z
                }
)@h3jo@W,v0
yJ2~SsUx:[$`0                object dstFieldObject = fieldInfo.GetValue(dest);ITPUB个人空间lS;W6co| NF'_(W!j
                object srcFieldObject = srcFieldsInfo[fieldIndex].GetValue(source);
t%VN DV\ut6c9{Q0                if (dstFieldObject != null && srcFieldObject != null)ITPUB个人空间Tk2v ??zd
                    RestoreNonSerialized(dstFieldObject, srcFieldObject);ITPUB个人空间:D)E1n~ tix
            }
f0ZlW(d0Y0ITPUB个人空间7c(t.x$X,jtn[2a4a
            IEnumerable dstEnumerable = dest as IEnumerable;ITPUB个人空间-DfS l8O6x/?d
            if (dstEnumerable != null)ITPUB个人空间m8gi;h|
            {
H+T1nSV0                IEnumerable srcEnumerable = source as IEnumerable;ITPUB个人空间2zX!S/N#W#g1pb
                if (srcEnumerable != null)ITPUB个人空间/V&H6]#|FJ(N
                {ITPUB个人空间r;LC|3D6s8F4Kv
                    IEnumerator srcEnumerator = srcEnumerable.GetEnumerator();
6H? Pzf tw*Q?"d0                    foreach (Object dstItem in dstEnumerable)ITPUB个人空间Jd(T+H!hVeF
                    {
U%\0^9r!aU0                        bool next = srcEnumerator.MoveNext();ITPUB个人空间hgoXvN-w5f
                        if (!next)
6M-q*B K] c0                            break;
y`*`yB{#N j0                        Object srcItem = srcEnumerator.Current;
]a.jr0a0ITPUB个人空间#|U0m)@l
                        RestoreNonSerialized(dstItem, srcItem);
dc9pT;{)| Y0                    }
8n!jOy@Um0                }
8[o!m&Sh6M;G0            }
N;vO R5NX0        }
u?w&]:B%g$F2e7I(D#s0    }ITPUB个人空间d;XD+Qm E'B

Uz|*~TQ$} g0我们会发现,FooClass类的data2字段为不可序列化字段,在没有还原不可序列化的字段之前,destObject.data2和sourceObject.data2的值是不同的,为20和30,当我们还原并将sourceObject.data2在运行时的值拷贝给destObject.data2后,两个FooClass类的实例的data2字段就完全一样了。ITPUB个人空间 ]#xu#HXZ(dn
ITPUB个人空间!t0}Tr&T;`%e)q[

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 :( :)

日历

« 2010-03-16  
 123456
78910111213
14151617181920
21222324252627
28293031   

数据统计

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

RSS订阅

Open Toolbar