Chapter 1: .Net 2.0 Framework 基础之 使用值类型

这是系列文章,是读"MS Press - MCTS Self-Paced Training Kit"的笔记,并把主要部分翻译成中文。
作者地址:http://www.cnblogs.com/nevernet (转载请保留)

使用值类型

     

通常有三种值类型:

  • .Net 框架内建的类型

  • 用户自定义类型

  • 枚举类型

上述每个类型都继承于 System.Value . 后续部分将显示如何使用这些不同的类型.

 

内建的值类型

所有的数值类型都是值类型.


Table 1-1: Built-in Value Types

Type (Visual Basic/C# alias)

Bytes

Range

Use for

System.SByte (SByte/sbyte)

1

-128 to 127

Signed byte values

System.Byte (Byte/byte)

1

0 to 255

Unsigned bytes

System.Int16 (Short/short)

2

-32768 to 32767

Interoperation and other specialized uses

System.Int32 (Integer/int)

4

-2147483648 to 2147483647

Whole numbers and counters

System.UInt32 (UInteger/uint)

4

0 to 4294967295

Positive whole numbers and counters

System.Int64 (Long/long)

8

-9223372036854775808 to 9223372036854775807

Large whole numbers

System.Single (Single/float)

4

-3.402823E+38 to 3.402823E+38

Floating point numbers

System.Double (Double/double)

8

-1.79769313486232E+308 to 1.79769313486232E+308

Precise or large floating point numbers

System.Decimal (Decimal/decimal)

16

-79228162514264337593543950335 to 79228162514264337593543950335

Financial and scientific calculations requiring great precision

  Best Practices—Optimizing performance with built-in types 

The runtime optimizes the performance of 32-bit integer types (Int32 and UInt32), so use those types for counters and other frequently accessed integral variables. For floating-point operations, Double is the most efficient type because those operations are optimized by hardware.

 

以下是最常用的类型,(C#或者VB对以下类型做了别名)

Table 1-2: Other Value Types

Type (Visual Basic/C# alias)

Bytes

Range

Use for

System.Char (Char/char)

2

N/A

Single Unicode characters

System.Boolean (Boolean/bool)

4

N/A

True/False values

System.IntPtr (none)

Platform-dependent

N/A

Pointer to a memory address

System.DateTime (Date/date)

8

1/1/0001 12:00:00 AM to 12/31/9999 11:59:59 PM

Moments in time

在.Net里面有近300个值类型

我们经常使用ToString方法来显示function或者objects的simple values。ToString is overridden from the fundamental System.Object type.

  The Object base class 

In the .NET Framework, all types are derived from System.Object. That relationship helps establish the common type system used throughout the Framework.

怎样定义值类型?

  Keyword differences in Visual Basic and C# 
Code

  Variable capitalizations in Visual Basic and C#  注意C#区分大小写,但是VB不区分


定义nullable
' VB
Dim b As Nullable(Of Boolean) = Nothing

// C#
Nullable<bool> b = null;

// Shorthand notation, only for C#
bool? b = null;

  NET 2.0 

The Nullable type is new in .NET 2.0.

Declaring a variable as nullable enables the HasValue and Value members. Use HasValue to detect whether or not a value has been set:

' VB
If b.HasValue Then Console.WriteLine("b is {0}.", b.Value) _
Else Console.WriteLine("b is not set.")

// C#
if (b.HasValue)Console.WriteLine("b is {0}.", b.Value);
else Console.WriteLine("b is not set.");

如何创建自定义值类型

' VB - Requires reference to System.Drawing
' Create point
Dim p As New System.Drawing.Point(20, 30)

' Move point diagonally
p.Offset(-1, -1)
Console.WriteLine("Point X {0}, Y {1}", p.X, p.Y)

// C# - Requires reference to System.Drawing
// Create point
System.Drawing.Point p = new System.Drawing.Point(20, 30);

// Move point diagonally
p.Offset(-1, -1);
Console.WriteLine("Point X {0}, Y {1}", p.X, p.Y);

通过Structure 关键字,可以创建自定义struct

' VB
Structure Cycle
' Private fields
Dim _val, _min, _max As Integer

' Constructor
Public Sub New(ByVal min As Integer, ByVal max As Integer)
_val = min : _min = min : _max = max
End Sub

' Public members
Public Property Value() As Integer
Get
Return _val
End Get
Set(ByVal value As Integer)
' Ensure new setting is between _min and _max.
If value > _max Then _val = _min _
Else If value < _min Then _val = _max _
Else _val = value
End Set
End Property

Public Overrides Function ToString() As String
Return Value.ToString
End Function

Public Function ToInteger() As Integer
Return Value
End Function

' Operators (new in 2.0)
Public Shared Operator +(ByVal arg1 As Cycle, _
ByVal arg2 As Integer) As Cycle
arg1.Value += arg2
Return arg1
End Operator

Public Shared Operator -(ByVal arg1 As Cycle, _
ByVal arg2 As Integer) As Cycle
arg1.Value -= arg2
Return arg1
End Operator
End Structure

// C#
struct Cycle
{
// Private fields
int _val, _min, _max;

// Constructor
public Cycle(int min, int max)
{
_val = min;
_min = min;
_max = max;
}

public int Value
{
get { return _val; }
set
{
if (value > _max)
_val = _min;
else
{
if (value < _min)
_val = _max;
else
_val = value;
}
}
}

public override string ToString()
{
return Value.ToString();
}

public int ToInteger()
{
return Value;
}

// Operators (new in .NET 2.0)
public static Cycle operator +(Cycle arg1, int arg2)
{
arg1.Value += arg2;
return arg1;
}

public static Cycle operator -(Cycle arg1, int arg2)
{
arg1.Value -= arg2;
return arg1;
}
}

  .NET 2.0 

The Operator keyword is new in .NET 2.0.


如何创建枚举类型

' VB
Enum Titles As Integer
Mr
Ms
Mrs
Dr
End Enum

// C#
enum Titles : int { Mr, Ms, Mrs, Dr };

在创建Titles 类型的实例后,你就可以把值赋给一个变量了,如下:

' VB
Dim t As Titles = Titles.Dr
Console.WriteLine("{0}.", t) ' Displays "Dr."

// C#
Titles t = Titles.Dr;
Console.WriteLine("{0}.", t); // Displays "Dr."

定义和使用值类型

下面是练习:

  1. 用Visual Studio, 创建console application 项目. 命名为:CreateStruct.

  2. Create a new structure named Person, as the following code demonstrates:

    ' VB
    Structure Person
    End Structure

    // C#
    struct Person
    {
    }
  3. Within the Person structure, define three public members:

    • firstName (a String)

    • lastName (a String)

    • age (an Integer)

    The following code demonstrates this:

    ' VB
    Public firstName As String
    Public lastName As String
    Public age As Integer

    // C#
    public string firstName;
    public string lastName;
    public int age;
  4. Create a constructor that defines all three member variables, as the following code demonstrates:

    ' VB
    Public Sub New(ByVal _firstName As String, ByVal _lastName As String, ByVal _age As
    Integer)
    firstName = _firstName
    lastName = _lastName
    age = _age
    End Sub

    // C#
    public Person(string _firstName, string _lastName, int _age)
    {
    firstName = _firstName;
    lastName = _lastName;
    age = _age;
    }
  5. Override the ToString method to display the person's first name, last name, and age. The following code demonstrates this:

    ' VB
    Public Overloads Overrides Function ToString() As String
    Return firstName + " " + lastName + ", age " + age.ToString
    End Function

    // C#
    public override string ToString()
    {
    return firstName + " " + lastName + ", age " + age;
    }
  6. Within the Main method of the console application, write code to create an instance of the structure and pass the instance to the Console.WriteLine method, as the following code demonstrates:

    ' VB
    Dim p As Person = New Person("Tony", "Allen", 32)
    Console.WriteLine(p)

    // C#
    Person p = new Person("Tony", "Allen", 32);
    Console.WriteLine(p);
  7. Run the console application to verify that it works correctly.

Image from book
 
Exercise 2: Add an Enumeration to a Structure
Image from book

In this exercise, you will extend the structure you created in Exercise 1 by adding an enumeration.

  1. Open the project you created in Exercise 1.

  2. Declare a new enumeration in the Person structure. Name the enumeration Genders, and specify two possible values: Male and Female. The following code sample demonstrates this:

    ' VB
    Enum Genders
    Male
    Female
    End Enum

    // C#
    public enum Genders : int { Male, Female };
  3. Add a public member of type Genders, and modify the Person constructor to accept an instance of Gender. The following code demonstrates this:

    ' VB
    Public firstName As String
    Public lastName As String
    Public age As Integer
    Public gender As Genders

    Public Sub New(ByVal _firstName As String, ByVal _lastName As String, _
    ByVal _age As Integer, ByVal _gender As Genders)
    firstName = _firstName
    lastName = _lastName
    age = _age
    gender = _gender
    End Sub

    // C#
    public string firstName;
    public string lastName;
    public int age;
    public Genders gender;

    public Person(string _firstName, string _lastName, int _age, Genders _gender)
    {
    firstName = _firstName;
    lastName = _lastName;
    age = _age;
    gender = _gender;
    }

  4. Modify the Person.ToString method to also display the gender, as the following code sample demonstrates:

    ' VB
    Public Overloads Overrides Function ToString() As String
    Return firstName + " " + lastName + " (" + gender.ToString() + "), age " +
    age.ToString
    End Function

    // C#
    public override string ToString()
    {
    return firstName + " " + lastName + " (" + gender + "), age " + age;
    }
  5. Modify your Main code to properly construct an instance of the Person class, as the following code sample demonstrates:

    ' VB
    Sub Main()
    Dim p As Person = New Person("Tony", "Allen", 32, Person.Genders.Male)
    Console.WriteLine(p)
    End Sub

    // C#
    static void Main(string[] args)
    {
    Person p = new Person("Tony", "Allen", 32, Person.Genders.Male);
    Console.WriteLine(p.ToString());
    }
  6. Run the console application to verify that it works correctly.

Image from book
 

Lesson Summary

  • The .NET Framework includes a large number of built-in types that you can use directly or use to build your own custom types.

  • Value types directly contain their data, offering excellent performance. However, value types are limited to types that store very small pieces of data. In the .NET Framework, all value types are 16 bytes or shorter.

  • You can create user-defined types that store multiple values and methods. In object-oriented development environments, a large portion of your application logic will be stored in user-defined types.

  • Enumerations improve code readability by providing symbols for a set of values.

Lesson Review

You can use the following questions to test your knowledge of the information in Lesson 1, "Using Value Types." The questions are also available on the companion CD if you prefer to review them in electronic form.

  Answers 

Answers to these questions and explanations of why each answer choice is right or wrong are located in the "Answers" section at the end of the book.

1. 

Which of the following are value types? (Choose all that apply.)

  1. Decimal

  2. String

  3. System.Drawing.Point

  4. Integer

Image from book

2. 

You pass a value-type variable into a procedure as an argument. The procedure changes the variable; however, when the procedure returns, the variable has not changed. What happened? (Choose one.)

  1. The variable was not initialized before it was passed in.

  2. Passing a value type into a procedure creates a copy of the data.

  3. The variable was redeclared within the procedure level.

  4. The procedure handled the variable as a reference.

Image from book

3. 

Which is the correct declaration for a nullable integer?

  1. ' VB
    Dim i As Nullable<Of Integer> = Nothing

    // C#
    Nullable(int) i = null;
  2. ' VB
    Dim i As Nullable(Of Integer) = Nothing

    // C#
    Nullable<int> i = null;

  3. ' VB
    Dim i As Integer = Nothing

    // C#
    int i = null;
  4. ' VB
    Dim i As Integer(Nullable) = Nothing

    // C#
    int<Nullable> i = null;

Image from book

4. 

You need to create a simple class or structure that contains only value types. You must create the class or structure so that it runs as efficiently as possible. You must be able to pass the class or structure to a procedure without concern that the procedure will modify it. Which of the following should you create?

  1. A reference class

  2. A reference structure

  3. A value class

  4. A value structure

Image from book

Answers

1. 

Correct Answers: A, C, and D

  1. Correct: Decimal is a value type.

  2. Incorrect: String is a reference type. (这里好像有一个错误,string也该是值类型)

  3. Correct: System.Drawing.Point is a value type.

  4. Correct: Integer is a value type.

2. 

Correct Answer: B

  1. Incorrect: First, value types must be initialized before being passed to a procedure unless they are specifically declared as nullable. Second, passing a null value would not affect the behavior of a value type.

  2. Correct: Procedures work with a copy of variables when you pass a value type. Therefore, any modifications that were made to the copy would not affect the original value.

  3. Incorrect: The variable might have been redeclared, but it would not affect the value of the variable.

  4. Incorrect: If the variable had been a reference, the original value would have been modified.

3. 

Correct Answer: B

  1. Incorrect: The Visual Basic sample uses angle brackets rather than parentheses. The C# sample uses parentheses rather than angle brackets.

  2. Correct: This is the proper way to declare and assign a nullable integer. In C#, you could also use the following: int? i = null;

  3. Incorrect: You must use the Nullable generic to declare an integer as nullable. By default, integers are not nullable.

  4. Incorrect: This is not the correct syntax for using the Nullable generic.

4. 

Correct Answer: D

  1. Incorrect: You could create a reference class; however, it could be modified when passed to a procedure.

  2. Incorrect: You cannot create a reference structure.

  3. Incorrect: You could create a value class; however, structures tend to be more efficient.

  4. Correct: Value structures are typically the most efficient.

 

posted @ 2008-09-16 18:55  无尽思绪  阅读(457)  评论(0编辑  收藏  举报