Professional ASP.NET 1.1 [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Professional ASP.NET 1.1 [Electronic resources] - نسخه متنی

Alex Homeret

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید






C#

Like .NET itself, C# has raised a fair amount of discussion, much of it based around raising questions such as "Another language? Why?" and "Isn't it just Java?". To understand why a new language has been introduced, think about what Microsoft is trying to achieve with .NET. Some of the key ideas are:



Cross-language development.



A unified type system.



Extensibility and security.



Greater support for development tools.



These are not the only goals, nor are they specific reasons for creating a new language, but it was clear that to build the .NET Framework the existing languages wouldn't meet these requirements. C++, for example, isn't truly component oriented, and still has many hang-ups from the C language. Java is bound by its ownership by Sun (not to mention lawsuits) and is interpreted, which leads to performance problems. Object-oriented languages such as Smalltalk and Eiffel have the stigma of being considered obscure, and would need performance increases and structural changes.

Therefore, a new language was the simplest answer, but not so new, that it wouldn't feel familiar. You can think of C# as a member of the C/C++ family – a fact that's not surprising, since the majority of development at Microsoft is done in these languages. As such, C# contains the best features of C++, but leaves out all of the bits that aren't required for a language to be part of the framework (such as typedefs, templates, and so on). Leaving out functionality hasn't been a hindrance, rather, it has made the language simpler to use and more efficient. In addition, it's not just a language being pushed on the public – ASP.NET is entirely written in C#.





Note

If you're a Visual Basic or VBScript programmer trying out C# for the first time, there's one really important thing to note: C# is case-sensitive.



Classes


Even though C# is more like C and C++, Visual Basic or VBScript programmers won't have too much trouble with this new language. Classes are defined using the following syntax:


[public | protected | internal | protected internal | private |


abstract | sealed ] class className

{

}


Let's look at the keywords here in more detail:































Keyword


Description


public


The class is publicly accessible.


protected


The class is only accessible from the containing class or types derived from the containing class.


internal


The class is only accessible from this program. Equivalent to

Friend in Visual Basic.


protected internal


The class is only accessible from this program or types derived from the containing class. Equivalent to

Protected Friend in Visual Basic.


private


The class is only accessible from within the containing class.


abstract


This class is an abstract class, and the class members must be implemented by inheriting classes. Equivalent to

MustInherit in Visual Basic.


sealed


No further inheritance is allowed from this class. Equivalent to

NotInheritable in Visual Basic.


For example:


public class Calculator

{

// implementation goes here

}



Methods


In C# there is no direct distinction between a

Sub and a

Function , and members are just implemented as functions (that may or may not return data). The syntax is:

[ public | protected | internal | protected internal | private | static |

virtual | override | abstract | extern ]

[ type | void ] memberName([parameters])

{

}


The various keywords are described as follows:








































Keyword


Description


public


The member is publicly accessible.


protected


The member is only accessible from the containing class or types derived from the containing member.


internal


The member is only accessible from this program. Equivalent to

Friend in Visual Basic.


protected internal


The member is only accessible from this program, or types derived from the containing member. Equivalent to

Protected Friend in Visual Basic.


private


The member is only accessible from within the containing member.


static


The member is shared by all instances of the class, and it exists independently of a class instance. Equivalent to

Shared in Visual Basic.


virtual


The member can be overridden by a sub-class.


override


The member overrides an identically named member from a base class, with the same signature. The base class member must be defined as

virtual ,

abstract or

override .


abstract


This member is an abstract member, and must be implemented by a subclass.


extern


The member is implemented in an external assembly.


For example:


public class calculator

{

public double Add(double op1, double op2)

{

return op1 + op2;

}

}


For a method that does not return a result, we declare the type as

void :


public void updateSomething()

{

}



Properties


Properties in C# are very similar to Visual Basic .NET, and can be implemented as

public member variables or by using the property accessors. For example, the following class uses public variables:

public class calculator
{

public double Op1;

public double Op2;
public double Add()
{
return Op1 + Op2;
}
}


The alternative (and preferred) approach is to use property accessors. For example:


public class calculator

{

private double _op1;

private double _op2;


public double Operand1

{

get

{

return _op1;

}

set

{

_op1 = value;

}

}


public double Operand2

{

get

{

return _op2;

}

set

{

_op2 = value;

}

}


}


Unlike Visual Basic, there are no specific keywords to identify

read-only and

write-only properties. If only the

get accessor is provided, the property is

read-only , and if only the

set accessor is provided, the property is

write-only . Both accessors imply a

read-write property.


Constructors


Rather than using

New for constructors, the C# syntax is to use a method with the same name as the class. For example:


public class person

{

private string _firstName;

private string _lastName;


public person() {}


public person(string firstName, string lastName)

{

_firstName = firstName;

_lastName = lastName;

}

public string FirstName

{

// property accessors here

}


public string LastName

{

// property accessors here

}

}



Destructors


For destructors there is no

Destruct keyword. This functionality is provided by a method with the same name as the class, but with a tilde (

~ ) preceding it. For example:

public class person
{
private string _firstName;
private string _lastName;
public person() {}
public person(string firstName, string lastName) { }

~person()

{

// destructor code here

}
}






Note

Like in Visual Basic .NET, destructors in C# are called by the garbage collector, and are not guaranteed to be executed at the time you destroy the class.



Inheritance


Inheritance in C# looks more like C++, where a colon (

: ) is used to separate the class and the base class. For example:


public class programmer : person

{

private int _avgHoursSleepPerNight;


public programmer(): base()

{

}


public programmer(string firstName, string lastName):

base(firstName, lastName)

{

}

public programmer(string firstName, string lastName, int hoursSleep):

base(firstName, lastName)

{

_avgHoursSleepPerNight = hoursSleep;

}

public int AvgHoursSleepPerNight

{

get { return _avgHoursSleepPerNight; }

set { _avgHoursSleepPerNight = value; }

}

}


The class definition defines that the class is called

programmer and the base class is called

person :

public class programmer : person
{

Next, you need to provide the constructors. Here specify the same constructors as the base class, and use the same inheritance syntax (

: ) to indicate that this method inherits its implementation from the base class. Any parameters should be passed to the base class constructor:

public programmer(): base()
{
}
public programmer(string firstName, string lastName):
base(firstName, lastName)
{
}

To declare an additional constructor, follow the same rules, invoking the base constructor, but also providing additional functionality:

public programmer(string firstName, string lastName, int hoursSleep):
base(firstName, lastName)
{
_avgHoursSleepPerNight = hoursSleep;
}

Finally, you have the

new property:

   public int AvgHoursSleepPerNight
{
get { return _avgHoursSleepPerNight; }
set { _avgHoursSleepPerNight = value; }
}
}

The

value keyword is implemented automatically by the CLR, providing the property with the supplied value from the calling program.


Interfaces


Interfaces work the same as in Visual Basic .NET, providing an immutable contract to the external world.

To create an interface, use the

interface construct. For example:

public interface IPerson
{
string FirstName(get; set;)
string LastName(get; set;)
string FullName();
}

To derive a class from an interface, use the same method as inheritance:

public class Person : IPerson
{
private string _firstName;
private string _lastName;
public string FirstName()
{
// implementation goes here
}
public string LastName()
{
// implementation goes here
}
public string FullName()
{
return _firstName + " " + _lastName;
}
}

Notice that unlike Visual Basic .NET, only the class needs to specify the interface inheritance.


References


References use the same method as Visual Basic .NET, but with the keyword

using instead of

Imports:


using System;

using MyComponent;


It's also possible to alias references using the following syntax:


using aliasName = Namespace;


If an alias is used, the alias must be included in references to classes that the namespace contains. For example, if you have a namespace called

MyComponent containing a class called

MyClass , and import the namespace like this:


using foo = MyComponent;


You can't then access the class like this:


MyClass comp = MyClass


You have to use the following syntax:


foo.MyClass comp = foo.MyClass



Exception Handling


The

try …

catch …

finally combo is another way of performing exception handling in C#, using the following syntax:


try

{

// code block to try

}

[catch[(type exception)]

{

// code block to run if the exception matches the type above

}]

catch[(type exception)]

{

// code block to run if the exception matches the type above

}

finally

{

' code that always runs, whether or not

' an exception was caught

}


For example:


try

{

// connect to a database and

// retrieve some data

// ... code left out for clarity ...

}

catch(SQLException exSQL)

{

ErrorLabel.Text = "SQL Error: " + exSQL.ToString();

}

catch(Exception ex)

{

ErrorLabel.Text = "Other error: " + ex.ToString();

}

finally

{

FinishedLabel.Text = "Finished";

}


The

throw statement can be used to raise errors, even when in

try …

catch blocks. For example:


try

{

// some code here

}

catch(SQLException exSQL)

{

if (some expression)

throw(exSQL);

}



XML Documentation


One great feature that C# has over Visual Basic is the ability to include inline documentation. This is done by placing a set of XML tags at various places in code, and then adding a compiler directive to pull out the comments. For example:

using System;
namespace peopleCS
{

///<remarks>

///The <c>programmer</c>class defines the salient

///attributes of every fine programmer.

///<seealso cref="person">Inherits from person</seealso>

///</remarks>
public class programmer : person
{
private int _avgHoursSleepPerNight;

///<summary>Default constructor</summary>
public programmer(): base()
{ }

///<summary>Constructor using first and last names</summary>


///<param name="firstName">The first name of the programmer</param>


///<param name="lastName">The last name of the programmer</param>


///<seealso cref="string"/>


public programmer(string firstName, string lastName):

base(firstName, lastName)

{ }


///<summary>Constructor using first and last names and


///the hours of sleep</summary>


///<param name="firstName">The first name of the programmer</param>


///<param name="lastName">The last name of the programmer</param>


///<param name="hoursSleep">The average number of hours of sleep</param>


///<seealso cref="string"/>


///<seealso cref="int"/>
public programmer(string firstName, string lastName, int hoursSleep):
base(firstName, lastName)
{
_avgHoursSleepPerNight = hoursSleep;
}

///<value>Defines the average number of hours of sleep.</value>
public int AvgHoursSleepPerNight
{
get { return _avgHoursSleepPerNight; }
set { _avgHoursSleepPerNight = value; }
}
}
}






Note

The XML tags are placed after three

/// characters – not to be confused with two, as used by comments.


The tags are as follows:


























































Tag


Description


c


Text that indicates inline code.


code


Multiple lines of code, such as a sample.


example


Description of a code sample.


exception


Indicates an exception class. Additionally, the attribute

cref can be used to reference another type (such as the exception type). This reference is checked against the imported libraries.


include


Allows XML documentation to be retrieved from another file.


list


Indicates a list of items. The

type attribute can be one of:

bullet , for bulleted lists

number , for numbered lists

table , for a table

You can use a

listheader element to define headings, and an

item element to define the items in the list. Each of these can contain two elements:

item for the item being listed, and

description .


para


Allows paragraph definitions within other tags.


param


Describes the parameter of a method. The name attribute should match the name of the parameter.


paramref


Used to indicate references for parameters.


permission


Describes the permissions required to access the member. The

cref can be used to reference another type (such as the security permission type). This reference is checked against the imported libraries.


remarks


Overview information about the class or type.


returns


The return value of a method.


see


The attribute

cref is used to reference another type (such as a related member). This reference is checked against the imported libraries.


seealso


The attribute

cref is used to reference another type (such as a related member), to be documented in the See Also section. This reference is checked against the imported libraries.


summary


Description of a member or type.


value


Description of a property.


In Visual Studio, these tags can be processed to form HTML pages that become part of the project documentation. Outside Visual Studio, you can produce an XML file for the comments by using the

/doc compiler switch (more on these in The .NET Language Compilers section), which produces the file as follows:


<?xml version="1.0"?>

<doc>


<assembly>

<name>PeopleCS</name>

</assembly>


<members>


<member name="T:peopleCS.programmer">

<remarks>

The <c>programmer</c>class defines the salient

attributes of every fine programmer.

<seealso cref="T:peopleCS.person">Inherits from person</seealso>

</remarks>

</member>


<member name="M:peopleCS.programmer.#ctor">

<summary>Default constructor</summary>

</member>


<member name="M:peopleCS.programmer.#ctor(System.String,System.String)">

<summary>Constructor using first and last names</summary>

<param name="firstName">The first name of the programmer</param>

<param name="lastName">The last name of the programmer</param>

<seealso cref="T:System.String"/>

</member>


<member name="M:peopleCS.programmer.#ctor(System.String,

System.String,System.Int32)">

<summary>Constructor using first and last

names and the hours of sleep</summary>

<param name="firstName">The first name of the programmer</param>

<param name="lastName">The last name of the programmer</param>

<param name="hoursSleep">The average number of hours of sleep</param>

<seealso cref="T:System.String"/>

<seealso cref="T:System.Int32"/>

</member>


<member name="P:peopleCS.programmer.AvgHoursSleepPerNight">

<value>Defines the average number of hours of sleep.</value>

</member>


</members>


</doc>


The compiler automatically includes the namespace and builds tags for the member names. The members are given a fully qualified name starting with one of the following prefixes:































Prefix


Description


N


Namespace


T


Type:

Class ,

Interface ,

Struct ,

Enum , or

Delegate


F


Field


P


Property (including indexers)


M


Method (including constructors)


E


Event


!


Error string if links cannot be resolved


You could then use an XSLT stylesheet, or XML processing code to style this into your own documentation. You could also add your own XML elements to the class descriptions, and these would be extracted along with the predefined elements.


Unsafe Code


Although C# is part of the managed code environment, Microsoft has realized that sometimes developers need total control, such as when performance is an issue, when dealing with binary structures, or for some advanced COM support. Under these circumstances, you are able to use C# code in an unsafe manner, using pointers, unsafe casts, and so on.

As an ASP.NET developer it's unlikely you'll ever need this, but knowing it's available gives you the flexibility to choose, should the need arise.


Operator Overloading


C# is the only one of the supplied languages that supports operator overloading. This works in the same way as method overloading, except for operators. The reason for this is to allow the standard operators to be used on objects such as classes.

The classic example given is a class for handling complex numbers, which have a real and imaginary part (stored as integers). Imagine a class that has two properties for these two parts, and a constructor that takes two arguments to match the properties:


CNumber c1 = new CNumber(12, 4);

CNumber c2 = new CNumber(5, 6);


When performing addition on complex numbers, you must add the real part and imaginary part independently of each other, and might consider creating this method:


public CNumber Add(CNumber c1, CNumber c2)

{

return new CNumber(c1.real + c2.real, c1.imag + c2.imag);

}


You could then call this by:


CNumber c3 = CNumber.Add(c1, c2);


There's nothing wrong with that per se, but it would be far better to use:


CNumber c3 = c1 + c2;


To achieve this, you would have to overload the

+ operator:


public static CNumber operator +(CNumber c1, CNumber c2);

{

return new CNumber(c1.real + c2.real, c1.imag + c2.imag);

}


This provides a much more intuitive way of developing, and is especially useful when building class libraries for other developers.





Note

For more details on C#, see Professional C#, ISBN 0-7645-4398-9, from Wrox Press.


/ 244