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

认知属性(Attribute )

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

此属性(Attribute )而非彼属性(Property)。MSDN描述:属性(Attribute )能够提供功能强大的方法,以将声明信息与 C# 代码(类型、方法、属性等)相关联。一旦属性与程序实体关联,即可在运行时使用名为反射的技术对属性进行查询。属性 (Attribute) 描述如何将数据序列化,指定用于强制安全性的特性,并限制实时 (JIT) 编译器的优化,从而使代码易于调试。属性 (Attribute) 还可以记录文件名或代码作者,或在窗体开发阶段控制控件和成员的可见性等等。ITPUB个人空间3^b ?8Q7r
ITPUB个人空间t}(SAuH~;j
属性具有以下特点:ITPUB个人空间8Ij |PE;TX\1\ `8?
1、属性可向程序中添加元数据。元数据是嵌入程序中的信息,如编译器指令或数据描述。ITPUB个人空间 _ h+z$q S+a]t
2、程序可以使用反射检查自己的元数据。请参见使用反射访问属性。ITPUB个人空间 I)V%Z3Zj/Q s$LJS
3、通常使用属性与 COM 交互。
I](g]:t+D0
S{,B \ B5M/y{EUg'M0经过对属性的研究我们做一个小示例,用于阐明属性的使用。我们尝试写个方法,它以两个对象为参数,然后将源对象运行时的所有字段值都拷贝给目标对象。按照一般情况,只要是可序列化的类、字段和方法都可以通过反射机制完成上述操作。但是如果遇到[NonSerialized]限定的字段我们将无从下手。面对这种情形我们创建一个方法,不仅可以存取[Serialized]限定的字段,还可以还原那些经[NonSerialized]限定的字段并在运行时重新赋值!
Lu&^!POE,h0ITPUB个人空间B/q Vrt|SC
我们先创建一个可序列化的类:
h}%kzks0[Serializable]
r2R8wTWV.`0public class FooClassITPUB个人空间-[W B^\f
{
LU!kN!R,@ e0    public int data1;
PUrcQ0    [NonSerialized] public int data2;
S`D/A$Xa'H0    public FooClass(int data1, int data2)ITPUB个人空间 E c4i6p-S8Y
    {
dPC,BZ;Afc*S#u0        this.data1 = data1;
m+g1d,r~ h e4W([0        this.data2 = data2;ITPUB个人空间 E;vp+}?UCp!s+q(B
    }ITPUB个人空间U%wdKX
}
!U"?!H3]3dJ F0
G mE n$a(?c0然后在Button1的Click事件中添加如下代码:
9^k;w&gGf3{0        private void button1_Click(object sender, EventArgs e)ITPUB个人空间%Q!`;gE&O.Y} Y!U2k
        {ITPUB个人空间)N,L6Q hH T
            FooClass destObject = new FooClass(10, 20);
M5u.TitGObe8U0            FooClass sourceObject = new FooClass(10, 30);
X DG#Br/sNp0            MessageBox.Show("destObject.data2: "+destObject.data2+'\n'+"sourceObject.data2: "+sourceObject.data2);ITPUB个人空间+{*JI i{F2X @P0`s
            RestoreUtils.RestoreNonSerialized(destObject, sourceObject);ITPUB个人空间y?G,|4x$f7T
            MessageBox.Show("destObject.data2: " + destObject.data2 + '\n' + "sourceObject.data2: " + sourceObject.data2);
;_ME:Tv p@g0        }
~8rW.?|6US-iJ*l0ITPUB个人空间K!` DM%n7`$~p E9W@
运行结果如下:
B)M d'q u md9~MW:V0
b |JQQ%C0
8?1EN Y;Og0注意,RestoreUtils.RestoreNonSerialized()方法,ITPUB个人空间c'YEUe4B
    public class RestoreUtils
0ieU5f@0    {
$L(En"y6RF i2j(d|0        const BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;ITPUB个人空间(OYw:f1J0Q4?i g
ITPUB个人空间1n#q(t%U6Y^
        public static void RestoreNonSerialized(object dest, object source)ITPUB个人空间 ?}h'Tsr~r'N
        {ITPUB个人空间bi%n K t!C}5f-d-y
            if (dest == null || source == null)ITPUB个人空间$y:{VJ2p U!K:g e
                return;
yOS*e_2j!}#x0
%w)a ~UgG0t h;MNh0            Type bjectType = dest.GetType();
,EC/n9O%sM%N_ V0            if (objectType.IsPrimitive | objectType.IsValueType)
P+\ N{8}U4M@qw0                return;
Hb4FN M6^p0
&^2Z!a(ImZ'z0            FieldInfo[] dstFieldsInfo = objectType.GetFields(flags);
ie d3N5W ^;OE0            FieldInfo[] srcFieldsInfo = source.GetType().GetFields(flags);ITPUB个人空间W~#x7R&u

[m W"S1? X'WZ XX0            for (int fieldIndex = 0; fieldIndex < dstFieldsInfo.Length; fieldIndex++)ITPUB个人空间'[v c9m-w7d
            {
YZ%IE {8k^0                FieldInfo fieldInfo = dstFieldsInfo[fieldIndex];ITPUB个人空间oQ/E1I D
                if (fieldInfo.IsNotSerialized)
z2oXt"[9y"j2w,X~0                {ITPUB个人空间0L!v)j}z_
                    object newValue = srcFieldsInfo[fieldIndex].GetValue(source);ITPUB个人空间 f$p&QGX%L}{
                    fieldInfo.SetValue(dest, newValue);
Dh$yCjh!{HB0                    continue;
6z;W8`ZABy8~H0                }ITPUB个人空间2?:n f nyQ&^
ITPUB个人空间-WT-|;f*ok'?;H
                object dstFieldObject = fieldInfo.GetValue(dest);ITPUB个人空间o^+@:n"I2j!udyP,m6V
                object srcFieldObject = srcFieldsInfo[fieldIndex].GetValue(source);
2\?\"OF%h,a~7J0                if (dstFieldObject != null && srcFieldObject != null)
ap!I+SZ ``Y0                    RestoreNonSerialized(dstFieldObject, srcFieldObject);ITPUB个人空间 fA8]x!TA#S
            }ITPUB个人空间^ \"W1e'Du4rc

(?1P d}q&QXi0\'o-z0            IEnumerable dstEnumerable = dest as IEnumerable;ITPUB个人空间6QRjI e*E#y#O0]K
            if (dstEnumerable != null)
$|.oi3t%Ap&GQ0            {ITPUB个人空间(Om&VD F0@M
                IEnumerable srcEnumerable = source as IEnumerable;
)beM4AFuL0                if (srcEnumerable != null)
g |^GpK0                {
x6J-c+JPFe0                    IEnumerator srcEnumerator = srcEnumerable.GetEnumerator();
6S?2?0S#C0                    foreach (Object dstItem in dstEnumerable)
:t;SQ1J D0                    {
|%P&{:VtyV ?%x,a0                        bool next = srcEnumerator.MoveNext();
5Ya,n#m,t0                        if (!next)
+QkU2Ny R6P y[~5i0                            break;
C]vZr#}d4l!X0                        Object srcItem = srcEnumerator.Current;
.?E*{ODvA0
-W6j(Mwg0                        RestoreNonSerialized(dstItem, srcItem);ITPUB个人空间1NM^%k}#]
                    }
b0{ }aKPrm&q"kE0                }
5J!`%q Ge0            }
z:UHI%j2N1c {0        }ITPUB个人空间iR&d5v-A
    }ITPUB个人空间OH X:oH
ITPUB个人空间@[c3b$a9O&^ ^3S r7Q
我们会发现,FooClass类的data2字段为不可序列化字段,在没有还原不可序列化的字段之前,destObject.data2和sourceObject.data2的值是不同的,为20和30,当我们还原并将sourceObject.data2在运行时的值拷贝给destObject.data2后,两个FooClass类的实例的data2字段就完全一样了。ITPUB个人空间7Kr(u#Bi-D

?_#H7Ij-d0

TAG:

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

评分:0

我来说两句

显示全部

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

日历

« 2009-07-04  
   1234
567891011
12131415161718
19202122232425
262728293031 

数据统计

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

RSS订阅

Open Toolbar