Attributes.  'l'hc Reflection API And Conditionals - Ct!  The Basics - Bctal Page I of IS

14

Attributes,  The Reflection ...
Attributes.  The Reflection API And Conditionals - C# The Basics - Beta2 Page 2 of 15

an

class zzz

{

public static voi...
Attributes.  The Reflection API And Conditionals - C1? The Basics - Betal Page 3 of 15

(

[Fteld0lYset(0)] public int l; ...
Attributes.  The Reflection API And Conditionals - C1? The Basics - Betal Page 4 of 15

a. cs{10.2):  error CS1501: No ove...
Attributes.  The Reflection API And Conditionals - Ctr The Basics - Betal Page 5 of 15

public vljay(strIng s , Inl:  I)

...
Attributes.  The Reflection API And Conditionals - C# The Basics - Beta2 Page 6 of 15

(

%
[Attri: uteUsage(Attribul: eTa...
Attributes.  The Reflection API And Conditionals - Cit The Basics - Betal Page 7 of 15

Output
lrit32 System. lnt32
lnt32 ...
Attributes.  The Reflection API And Conditionals - C# The Basics - Beta2 Page 8 of 15

foreach(Memberlnfoainn)

(

Cansole...
Attributes.  The Reflection API And Conditionals — C9‘!  The Basics — Bctal Page 9 of 15

{

get { return 52; )

set { 52 ...
Attributes.  The Reflection API And Conditionals - C# The Basics - Beta2 Page I0 of 15

)

[vi]ey("hl1",10, sonal s 'bye1'...
Attributes.  The Reflection API And Conditionals - C# The Basics - Bcta2 Page I l of 15

)

}

[vijay("hl1",1o,  sonal - "...
Attributes.  The Reflection API And Conditionals - C1? The Basics - Betal Page I2 of 15

Y! Y

VQBY

W31
We have two attri...
Attributes.  The Reflection API And Conditionals - C# The Basics - Bcta2 Page l3 of 15

(
public static void Maln()

{

i
...
Attributes.  The Reflection API And Conditionals - C1? The Basics - Betal Page 14 of 15

wv 8 =  new wvl); 
Mb¢(): 

}

}
...
Attributes.  The Reflection API And Conditionals - Cit The Basics - Beta2 Page 15 of 15

preproccssor symbol.  In this  it...
Upcoming SlideShare
Loading in...5
×

Csharp_Chap14

1,105

Published on

Published in: Technology, Sports
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
1,105
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
51
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Transcript of "Csharp_Chap14"

  1. 1. Attributes. 'l'hc Reflection API And Conditionals - Ct! The Basics - Bctal Page I of IS 14 Attributes, The Reflection API And Conditionals Attributes a. cs class zzz ( public static void Main() ( ) ) lvllavl class yw ( ) Compiler Error a. cs(7.2): errot CS0246: The type 0! namespace name ‘vijay' could not be found [are you missing a using uroctrvc or an assembly tolerance? ) Anything in a square bracket is called an attribute. We tried to create an attribute called vijay. which (VI. for sunie teamm. does not seem to tecugnize. a. cs class 222 { public static void Main() { } } class vijav : Systenmttribute ( } [vllav] class yw { } All that we have done is created a class vijay that has been denved from the class System"-ttributc and the error simply disappears. Thus an attribute is simply a class that derives from S_vsIcm. Attrihutc. To understand attributes lets take an example with structures. li le : //E: ! KrarCSharpcshaupthebasicslchap l 4.htm 9/29/2007
  2. 2. Attributes. The Reflection API And Conditionals - C# The Basics - Beta2 Page 2 of 15 an class zzz { public static void Main() { vw a - new mt); a. i - 6$S36+512+3; Systern. Console. WriteUne(a. i + ' ' + a. j + " " + a. l<); } } SW€tYYY{ piblic int i; public short J; public byte It; } Output 66051 0 0 A simple revision once again. We have created a structure a. that looks like yyy and initialized only one member i. Hence we see the warnings. The other members j and it get a default value of zero. ates using System; class zzz ( unsafe public static void Main() { Console. writet. ine(siz: eof(byt: e) + ' " + sizeof(short) + " " + sizeof(int) + " ' + sizeof(Iong)); } } >086 3.88 Compiler Error a. cs(4.27l: error CS0227: Unsafe code may only appear if compiling with Iunsafe The error here says that you have to use the [unsafe option while compiling any unsafe code. >csc a. cs Iunsate Output 1 2 48 We shall explain the modifier unsafe in the next chuptet. Sizouf tells us how much memory Cl allocates for a data type. A byte is allocated one memory location. short 2. int 4 and a long 8. us using Syst1eni. Ruritlme. Intaei'opServtos; class 222 { public static void Main() { WV 3 ' View WYO: at - 655364-512+3; System. Console. WriteUne(a. i + ‘ “ + a. j + ‘ " + a. |t); } } [Struct1.ayout(l. ayoutKind. Explloit)] struct yyy file 2// E.: ! KrarCSharpcsharpthebasieschap l4.htm 9/29/2007
  3. 3. Attributes. The Reflection API And Conditionals - C1? The Basics - Betal Page 3 of 15 ( [Fteld0lYset(0)] public int l; [FieldOffset10)] public short j; gfieldOl'fset(0)] public byte It; Output 66051 515 3 We are using an attribute StmctLiiyout that belongs to the namespacc Systcm. Runtimc. lntcropServit~cs. In the earlier program. we had used an attribute called vijny. Thus. StructLayout is a class derived from Attribute. We are passing a parameter LayoutKind. Explicit to it. The output now differs dramatically. Every variable is stored in memory. Fieldoffset indicates the starting position of the variable within the memory location. Offset of 0 will position i. j. and It. all three variables at the same memory address of a. Explicit requires F ieldOffset to be mentioned in we are explicitly laying the order for the variables held in the stmcuuirc. LayoutKind-Sequentinl and LayoutKini: l.Auto gives different memory locations to each of the variable. We will explain the reasons at little later in the coming chapter ‘Unsafe Code‘. We have seen how important attributes are so lets delve deeper into them. LQ class zzz { public static void Main() { } } class vijaymxrbute : Sysuem. Alxnbtne ( } lvllavl class yyy ( } lvilavkttributel class yyyt { } We are allowed a little leeway in the name of the attribute. By convention. the attribute class should end with the word Attribute and when we use the attribute. the name attribute is optional. i, §§ class zzz { public static void Main() { ) } class vijay : Systenthttrlbute ( ) [V| l3V('h| ")l class yyy ( } Compiler Error Ftle: llE. :! KrarCSh: trpcsharpthebasicslchapl4.htm 9/29/2007
  4. 4. Attributes. The Reflection API And Conditionals - C1? The Basics - Betal Page 4 of 15 a. cs{10.2): error CS1501: No overload tor method 'vijay' takes '1' arguments We had used the attribute Struetlayout earlier where we passed a parameter. When we do the same thing with our attribute vijay, we get the above error. a. cs classzzz { ptbllc static vold Maln() { i class vijay : Systeamttrtbute { public vijay(string s) ) } [Vll6v('h| ")l class yyy ( } We forgot to add a constructor that accepts a string as a parameter. If we had passed a number to our atuibute vijay, we would have to create a constructor that accepts an int. Thus if we pass 2 parameters to vijay. we need the appropriate constructor. DLS class zzz { public static void Main() i class vijay : Systeumttribute { | (>ublic vtjawstrlng s , lnt i) l [vt]ay(‘hI”,10,niuIttI - 200)] class yyy { } Compiler Error a. cs(13.16): error CS0103: The name 'mul<hi‘ does not exist in the class or namespaco ‘vijay‘ What we tried to do is. tatlte at won] called muldii and initialize it to 200. Cll comes back and tells us that it does not know what mukhi is. as class zzz gttlic static void Main() i class may : Systemmtrlbute filezl/ E:! Kt'ar'lCSh: trpcsharpthebasicslchapl4.htm 9/29/2007
  5. 5. Attributes. The Reflection API And Conditionals - Ctr The Basics - Betal Page 5 of 15 public vljay(strIng s , Inl: I) } public int multhi; } [vi]ay(''hl'',10,mt. i|thi - 200)] class yw ( } multhi. now. is called a named parameter. It can also be temted as a property. gs class zzz { public static void Maint) } } class vijay : Systenmttribute { | ()lbll: vijay(strlng s , lnt i) ) public int mulml; publlc string sonal [vl]ay(‘hI",10, multhl = 200, sonal = "bye')] dass yyy { } A mined parameter is a non-static field or a non-rearlonly property. A positional parameter is what we pass on to a oonstructor. We have 2 positional parameters as our constmctor has two parameters and mukhi and sonal are our named parameters. The named parameters come after the positional ones. The positional pararneters order is important. but the named parameters can be in any order. If we don't follow this rule we will get an error as follows. Compiler Error a. cs(19.22): error cs1o1s: Named attribute argument expected When we place the attribute before a function. the cn'or disappears. 3.55 usina 5YSlJern. Rut1lime. Inberop$ervioes; usinfl Svslnem; class zzz { public static void Maln() Ftle: llE: !KrarCSh: trpcsharpthebasicslchapl4.htm 9/29/2007
  6. 6. Attributes. The Reflection API And Conditionals - C# The Basics - Beta2 Page 6 of 15 ( % [Attri: uteUsage(Attribul: eTangets. Class)] class vijay : systermtttnbute { public vijay(string 5 , int i) ( } public it mtldtiz | (>ublic string sonal get { return 'ss'; ) sell ; ) } } class yyy { [vi]ay("hi",10, sonal - "bye", n1r. Id1i - 200 )1 public void abco {} Compiler Error a. ce[24.2): error CS0592: Attrtute 'vijay' is not valid on this declaration type. It is valid on 'dass' declarations only. Attributeusagc is one more attribute class derived from Attribute. It gives us the option to decide where the user can use the Attrihute. The parameter in this case is class and hence we can use it only in front of a class and not in front of a method. The default is anywhere. The Reflection API Reflection or introspection is when you look within to find out about your true self. In the same way we need a method by means of which. our program can find out all about a class. We need to know how many methods. properties etc while our program is executing or nrnning. This distinction is important and we could always read the documentation if we wanted to know more about the functionality of a class. But. Ci! gives us a large number of functions that tell us the innards of a class. These functions put together have to he used in a certain way. The functions have to be called in a certain order and the parameters to them have to conform to certain data types. This concept is called an API or a Application Program Interface. In short. an API is how a programmer uses functions to get a desired result. #423 using Svstem; class zzz ( public static void Main() ( Tvve m; m = tweoftint); System. Console. Wrtnel. lne(m. Nar'ne + " " + m. Fu| Name); m - tweoftsvstzm-Int32): System. Console. wrltet. lr1e(m. Name + " " + m. FuIlrame); m ' ! YP60f(YW): System. Coneole. wrtteLine(m. Narr1e + " " 4- mfulllame); } } class yyy { } file 2// E.: ! KrarCSharpcsharpthebasicschap l4.htm 9/29/2007
  7. 7. Attributes. The Reflection API And Conditionals - Cit The Basics - Betal Page 7 of 15 Output lrit32 System. lnt32 lnt32 System. lnt32 WV WY Typcof is a keyword. It needs a class name as a parameter. In the first case. we are specifying a class called int. typeof tctums an object that looks like Type. This class has two members Name. which gives the name of the class and FullName which is the name preceded with the name of the Namespace. When we use int as the name of the class, the member Name does not display int but lnt32; we mentioned earlier int is an alias for a structure M32 in the System namespaoe. This is what FullN: ime tells us. We thus have visible proof that int is an alias for a structure. yyy is class belonging to no namespace and hence the Name and FullName members are similar. public static void Main() ( ‘Me m = tweoftvwlz Membertnlo [] n; n I m. GetMenibers(); Console. writiet. ine(n. Lengtn); foreach ( Membertnto a in n) { Consote. writet. ine(aName); } ) } class yyy { piblic void abc() (} private int pqr( inti ) ( retum 0;} I}>I'°t1'-md string Xv! (string 9 . tn! 9) (return "": } Output 6 Gettlashcode Equals Tostrlng ax Gefiype clot We are now displaying the members of a class yyy. The class Type has a function called GetMembers that returns an army of type Member-Info. Every array has a field called Length that retums the size of the array. In our specific case it is 6. We then use a forcach to run through each member of the Mcmbcrlnfo array and are displaying the mime of each function using the field Name from dirt class Memberlnfo. gs using System; using Siyslietnxeflection; class 222 ( public static void Malno ( TYD8 M = tVl>80‘(WY): Memberlnfo [] n; n = m. GetMerrbers(); Oorisote. wrtt: u1e(n. Length); file: llE: !Ki'ar'lCSh: trpcshai1)thebasicschapl4.htm 9/29/2007
  8. 8. Attributes. The Reflection API And Conditionals - C# The Basics - Beta2 Page 8 of 15 foreach(Memberlnfoainn) ( Cansole. writeune((MemberInfo}a + ' ' + a. DeclaririgType); } } } class yw { ptblic int i; ptblic void abc() {} vublyc import int I ) { return 0;) | ))I. I)llC string xyz (string 9 , int p) (return ""; } Output 9 M32 i yyy IM32 Getl-lashcodeti Systemobjeca Boolean Equalstsyslemobjocti Systarnobiact Systomstrlng Tostrlngt) Systamobioct Void abet) yyy lnt32 pcp(Int32) yyy Systamstring xyz(Syslem. String, Int32) yyy Systermtype GetType() Systemobject Void . ctor() yyy The first concept you need to be clear with is that we can inspect only details of public members and protectai or private like pqr and xy-L. Also variables are part of the members of a class. The Memberlnfo object has a Tostring function that displays the entire function in all its glory including parameters and their data types. The names of the parameter variables an: however not being displayed. The DeclaringType member mums the class name that the member belongs to. Thus we can differeritiate which class created the function. Let us new display the attributes used on a class. us using Sysl: ern. Rur1time. InterooSenrioes; using System; using Syslaernkeflection; class 222 ( public static void Main() ( Tvne m; m = tvneoftvi/ V): System. Console. wrttaLirie(m. Name); toread'r(ob)ect a In m. GetCustomAt1rIbutes (true)) Console. writet. ine(a); } } [Attri: uteUsage(Attn’bul: eTarvgets. AII)] class vijay : Systemfittribute ( string s1,s2;int i1; public int rnulchi; public override string 'loStrlng() remms1+""+s2+"+lt+"+mu| thl; } public vl1ay(string s , int I) sl-s; i1-i; } public string sonal file 2// E.: ! KrarCSharpcsharpthebasieschap l4.htm 9/29/2007
  9. 9. Attributes. The Reflection API And Conditionals — C9‘! The Basics — Bctal Page 9 of 15 { get { return 52; ) set { 52 value; ) } } [vijay("hI1',10, sonal . by#i1', rnu'-chi 200 )] class yyy ( [vijay("hi2', lC2), sonal = "bye2", rnukhi = 2000)] public void abc() O [vijay("hi3', lC1)0, sc-nal = "bye3‘, mukhi = 2)] public int n; ) Output yyy nu byet 10 2oo Gclcuslonl/ llribulcs takes it boolcan as parameter and rctums an array of objects, The Tostring function of the attribute class get. » called which will decide what string the atuihtttc stands for. a. cs us'ng Sysbem. Runtime. Ini: eropServ'>oes; using System; using Syslaemlteflection; class zzz ( public static void Main() { Twe m; m = tvpeoftm); 5ystem. Console. Writu1Jne{m. Name); ioreach(Method1nfo a in m. GetMethods()) ( object [] b a. GetCustomAttributes(true); foreachmttribute c in b) ( Console. WriteLine{c); ##%N-' [AttrlbuteUsage(AttributeTargets. Ail)] class may 2 System. Attrlbute { string s1,s2;int I1; public int mukhi; public override string To5tring() ( return 51+‘ " + s2+' ' +i1+ ‘ ' + rnukhi; } public vijay(string s , int i) { s1=s; i1=i; ) public string sonal { get { return s2; ) set ( s2 - value; } } Iile: //E: !Krar‘CSharpcshtupthebasicsichup l4.htm 9/29/2007
  10. 10. Attributes. The Reflection API And Conditionals - C# The Basics - Beta2 Page I0 of 15 ) [vi]ey("hl1",10, sonal s 'bye1', mtId1l - 200 )] class yyy ( [vijay("hi2",100, sonal - "lwe2". rnu| tl1i - 2000 )] public void abc() {} [vijay("hi3",1000, sonal - "bye3', n1ukhi - 2 )] public void pqr() {} Output WY m2 bye2 100 2000 hi3 bye’! 1000 2 ‘Die object m looks like Type. As explained earlier, we an: calling a function called GctMethods which nzturns an array of Methodlnfds. a loops through each one. We have two methods and the foreach gets executed twice. Once for ubc and then for pqr. The GctCustumAttributcs also exists in a Methodlnfo class that retums an array of objects representing our attributes. We iterate through each. displaying what the Tostring function returns. As we have only one attribute per function. the second for each gets executed only once. us using Systaem. Runtlme. lntJeropSe~loes; using System; using Sysl: em. Retlection; class zzz ( | {3tl: llic static void Main() Tvve m; In - tvveoflwvi: Sysoem. Console. writeLine(m. Name); foreach(MethodInfo a in m. GetMethods()) { object [] b = a. GetCuslntnAttri: utes(true); foread1(Attri: ulJe c in b) { i ( C l5 Will? ) Gonsole. wrltet. ine(c); } ) } } [Attri: utaeU9ge(AttributeTargets. AII)] class vijay : System. Attnbute < string sl, s2;int it; public int mulchi; | ()ublic override string Tostrlngo retums1+"'+s2+"+i1+"+mukhl; ) ; ()ublic vijary(strlng s , lnt l) st-s; i1-i; } public string sonal { get{ retum s2; ) set ( s2 = vane; } file: //E. :! KrarCSharpcsharpthebasicschap l4.htm 9/29/2007
  11. 11. Attributes. The Reflection API And Conditionals - C# The Basics - Bcta2 Page I l of 15 ) } [vijay("hl1",1o, sonal - "bye1', muld1i - 200 )] class yyy { [vi]ay("hI2',100, sonal - "bye2", multhl - 2000 )] public void abc() {} [vijay('hl3",1000, sonal = "bye3', muld1i = 2 )] public void pq'() (} There is no change at all in the output. A function am be decorated with in many attributes as you like. We would like to filter out ocmiin attributes. 3:9 SyslJem. Runtime. Ini: eropServioes; using System; using Syshemkeflection; class zzz { public static void Malno ( TYPE M; m ' WPGOKYW): System. Consoie. writel. ine(m. Name); foreachmethodlnlo a in m. GetMethods()) { object [] b - a. GetCustomAttri: utes(true); foreacl-i(Attribute c in b) ( if ( c is viiay ) Console. writet. irie(c); } ) l class may 2 Syaemfittrlbute { public override string Tostringo ( tewm i class vijayl : Systienmttrizute { public override string ToSo1'n9() ( return 'vi)ay'; ) ) class yyy ( lvilavln public void abc() {} lviiavlll lvilavilll public void pqrt) {} Output file: //E. :! KrurCSharpcsharpthebasicschap l4.htm 9/29/2007
  12. 12. Attributes. The Reflection API And Conditionals - C1? The Basics - Betal Page I2 of 15 Y! Y VQBY W31 We have two attribute classw vijay and vijayl. The function pqr has been decorated with 2 attributes whereas abc with only one. However we do not see vijayl in the output in the 'c is vijay' makes the if statement true only for the attribute vijay and not vijayl. For the function pqr GetCustomAttn'butes returns an array of size two. but the if statement is true only for one of them. t. he one with the attribute name vijay. This is because of the 'is‘. an usln9 5Vst: em; class zzz ( public static void Maln() ( WY 3 ' DEW WYO: it a is yyy) Console. writet. ine("a yyy’); xxx b - new mt); i‘( b is xxx) Console. WriteUne("b xxx‘); if( b is YW) 0onsole. Wriuet. ine("b yyy"); int d = 10; I (d is yyy) Console. Wrltel. lne("b yyy"); classioot We would like to know the data type of an object at runtime. Cit offers you a key word 'is‘ that lets you check the data type of an object. 3 looks like yyy and 'is‘ results in true. B looks like xxx but is initialized to a new yyy. Thus it doubles up for a yyy and a xxx resulting in the next two is's returning true. D is an int and not a yyy. so the last ‘is’ is false. Attributes Revisited Positional parameters are a must whereas names parameters are optional. Attribute parameters can be a bool. byte. char. short. int. long. float and double. These are the simple types that Cit supports. Other data types are string. enums. objects arrays etc. Attribute usage has a position parameter which specifies the elements where the attribute can be used. The default is All. It also has one named parameter called Allowlvlultiple. us using Systaem. Runtime. lntaeropServioes; using System; class zzz Ftle: IlE: !Krar'lCSharpcsharpthebasicslchapl4.htm 9/29/2007
  13. 13. Attributes. The Reflection API And Conditionals - C# The Basics - Bcta2 Page l3 of 15 ( public static void Maln() { i [Attri: uhetJsage(Attn‘bubeTargets. AII)] class vijay : Systemfittnbute { | {)tblic vijay(string s) } ) class yyy { [v| Jw(’h| ")l[Vt)av("hIl")l public void abc() 0 } Compiler Error a. cs(18.15): error CS0679: Duplicate 'vllay' attribute By default we cannot use the same attribute twice on any entity. Ag using Sysl: em. Rtntime. InherooSenrioes; using System; class zzz { ptblic static void Main() { ) ) [Attrt>utJotJsage(Attt'lbutJeTar9ets. All, AllowMultlple= true)] class may : Syaemmtnbute ( | (3ubllc vljamstrlng s) } } classyw ( [Vilavl'hi")l[Wiav("hi1")l lViiav("hi2') . vilav("h4'3")l ptblic void abc() O ) We get no error as by default the AllowMultiple named parameter has II value of false. If we set its value to true. we are allowed to use multiple attributes on any entity. The above two forms are similar and either one can be used. Attribute permits us to set declarative information for various program entities for use by someone else at run time. Conditionals using Systaemniagnostits; publlc static vold MaIn() ( file: //E. :! KrarCSharpcshatpthebasieschap l4.htm 9/29/2007
  14. 14. Attributes. The Reflection API And Conditionals - C1? The Basics - Betal Page 14 of 15 wv 8 = new wvl); Mb¢(): } } class yyy { [ConditionaI("vijay")] | {>ublic void abe() console. writeUne("abc"); } ) When we run the above program we get no output at all. In other words the function abc does not get called at all. This is inspite of writing a. abc(). us attdefine vljay using SystJem. Dlagriostlt: ; public static vold Maln() ( M a - new mt): aabco; } } class yyy ( [Conditional("vijav')] public void abc() Gonsole. wrtneune("abc"); ) ) Oulnut abc Any line beginning with n 8 is read by the Cl! pre-processor. a program that starts before the C1! compiler stuns. It has words like vdeline which creates a variable or word called vijay. In a programming language. a variable has to have in value. but in the preproeessor scheme of things. it may/ rnaynot have a value. However if we do not give it a value. like in this case. the variable is only set to have been defined or created. Anything in [I brackets is an Attribute class. Earlier we had not created a variable vijay and hence the entire code of ahc was left out of the executable file. Not only that. but all calls to function abc were eliminated from our code. All of this by defining or not defining a variable vijay. This is what we passed as the attribute to Conditional. We can create functions that are omitted during compilation depending upon a preprocessing symbol. When we write code. we add a lot ofeode for debugging purposes. This code ‘us to help the programmer debug code. After a function works. it is error free, we do not require any of this debugging code. One way to eliminate this debugging code is by making the functions conditional. The resulting code is called a ‘Retail build‘ and the debugging version. obviously a ‘Debug build‘. A Retail build is much srnaller in size and obviously much faster. The ldefme has to be at the start of code. Another way of achieving the same result is by eliminating the Sdcline from the code and creating a prepmceasor symbol as an option to the compiler. >csc a. cs Idwliay The compiler option is Id and the colon is part of the syntax. Following the colon is the name of the file: llE. :! KrarCSh: trpcsharpthebasicslchapl4.htm 9/29/2007
  15. 15. Attributes. The Reflection API And Conditionals - Cit The Basics - Beta2 Page 15 of 15 preproccssor symbol. In this it is vijuy. We've discussed prcprocexsors in one of the earlier chapters. us using System; class zzz { public static void Main() ( WV 8 = new wvt); a. abc(); ) } class yyy ( [Obsolete] public void abc() Console. wri: el. ine("abc"); } } Compiler Error a. cs{7.1): warning CS0612: 'yyy. abc()‘ is obsolete Output abc Many at times we create functions in a class which we would not want the user to use. as these functions were useful years ago. but are now obsolete. The only way to warn the user that some time in the future we will no longer support these functions is by marking them with the attribute Obsolete. We see the warning as displayed above but the program runs as normal. file 2// E.: ! KrarCSharpcsharpthebasicschap l4.htm 9/29/2007

×