代码改变世界

偶的第一篇译文(下):Data Types in C#

2004-10-17 12:13 FantasySoft 阅读(...) 评论(...) 编辑 收藏

预定义类型
CTS定义了很多能够被C#编译器识别的数据类型,譬如整型,浮点型,字符型和布尔型。我们可以简单的通过为一个对象起个名字的方式去声明一个值类型变量,例如声明了一个布尔类型变量,如下代码所示:

bool b;           //This declares a Boolean b on stack
= false ;      //This assign the value false to b;

另一个示例代码如下:
public class ValueTypes
{
     
public static void Main (string
 [] args)
     
{
          
byte bVar = 111
;
          
int iVar = 786
;
          
float fVar = 110

          Console.WriteLine(
"The Value of bVar is "+
bVar);
          Console.WriteLine(
"The Value of iVar is "+
iVar);
          Console.WriteLine(
"The Value of fVar is "+
fVar);
          Console.ReadLine();
     }

}

当你执行这个程序的时候,所赋的值将会显示出来然后等待你按下回车来结束整个过程。我们可以看到在程序中我们声明了三个值类型变量。其中,第一个是字节型,而字节型实际上代表着CTS中的System.Byte类型,另外两个类型也可以在CTS中找到对应类型。与C和C++类似,你也可以在同一行中声明并且初始化变量。

复杂类型
我们还可以定义另外两种值类型:结构体(Structs)和枚举(Enumeration)。

结构体

结构体是一种特殊类型的类(class),因为结构体是值类型的,而不是引用类型。正如我们所了解到的值类型存在堆栈一样,结构体也存在堆栈上。这样,结构体能够十分有效的被复制和创建(对堆栈进行复制和访问本来就会比对堆进行相应的操作更有效)。

枚举

枚举是用户定义的整数类型。Enum关键字用于声明一个枚举类型。基本上,枚举类型的主要的功能是让我们的代码更加易于维护。变量只能被赋予合法的值,而不会理会值本身的含义。而枚举则会让我们的代码更清楚,因为枚举可以为整数创建一个伪名(deceptive names)。

下面的表格列示了所有值类型和它们在CTS中相应的类型及描述:

Name CTS Type Description
byte System.Byte An 8-bits unsigned Value
sbyte System.SByte An 8-bits signed Value
int System.Int32 A 32-bit signed integer
uint System.UInt32 A 32 bit unsigned integer
short System.Int16 A 16-bit signed value
ushort System.UInt16 A 16-bit unsigned value
long System.Int64 A 64-bit signed value
ulong System.UInt64 A 64-bit unsigned value
float System.Single A single precision 32-bit
double System.Double A double precision 64-bit
decimal System.Decimal A 96-bit decimal value
bool System.Boolean true and false
char System.Char A single 16-bit character

C#支持两种预定义的引用类型,对象和字符串。引用类型在堆中存储引用(这里的引用是指对象本身,而非对象的引用)。堆是另外一个存放引用而不是数据的地方。现在,在.NET中的堆被称为托管堆(Manged Heap),具有更强的可管理性。当你初始化一个进程的时候,运行时环境会保留一个毗邻的地址空间为进程所用。托管堆会维护一个指向堆中某个地址的指针,这个地址就是下一个对象在堆中创建所要分配内存空间的起始地址(此处为意译)。最初,这个指针指向的地址是托管堆的基地址。系统会为所有的引用类型在托管堆中分配内存。当程序创建第一个引用类型的时候,系统会为它在托管堆的基地址分配相应的内存。当应用程序创建下一个对象的时候,垃圾回收器会为这个对象在上一个被创建的对象的后续地址空间中分配内存。只要地址空间是可用的,垃圾回收器就会以这样的方式为新对象分配空间。

在C#中,你必须使用new关键字去初始化一个引用对象,也就是说,我们创建一个引用并且使用new关键字令这个引用指向在堆中的对象,如下所示:

Object myobj;
myobj 
= new Object(); 

以上的代码生成一个引用myobj,并且在堆中将其初始化。引用类型以及它们相应的CTS和描述列示如下:

Name CTS Type Description
Object System.Object This is the root for all other types in CTS.
String System.String Unicode character string

        至此,我们已经了解两种类型的基本概念了,接着就来编写一个包含了这两种数据类型的程序:

using System; 
class
 ReferenceTypes
{
  
public int
 rWidth;
  
public int
 rHeight;
}

struct ValuesTypes
{
  
public int
 iWidth;
  
public int
 iHeight;
}

class Test
{
  
public static void Main(string
 [] args)
  
{
    ValuesTypes objVal1 
= new
 ValuesTypes();

    objVal1.iWidth 
= 10
;
    objVal1.iHeight 
= 10
;
    ValuesTypes objVal2 
=
 objVal1;

    Console.WriteLine(
"Value of Val1 types before changing Val2 width ="+objVal1.iWidth+" and height = "+
objVal1.iHeight);

    objVal2.iWidth 
= 20
;
    objVal2.iHeight 
= 20
;

    Console.WriteLine(
"Value of Val1 types after changing Val2 width ="+objVal1.iWidth+" and height = "+
objVal1.iHeight);

    ReferenceTypes objRef1 
= new
 ReferenceTypes();

    objRef1.rWidth 
= 10
;
    objRef1.rHeight 
= 10
;
    ReferenceTypes objRef2 
=
 objRef1;

    Console.WriteLine(
"Value of Ref1 types before changing Ref2 width ="+objRef1.rWidth+" and height = "+
objRef1.rHeight);

    objRef2.rWidth 
= 20
;
    objRef2.rHeight 
= 20
;

    Console.WriteLine(
"Value of Ref1 types after changing Ref2 width ="+objRef1.rWidth+" and height = "+
objRef1.rHeight);
    Console.ReadLine();
  }

}

        因此,你已经从以上的程序发现,结构体是值类型,它们存储的是数据本身而不是对象的引用,变量间的改动对代码中的ValueTypes不会产生任何的效果。而在另一方面,引用类型则通过引用去修改并显示出被修改过的实际数据。
        我希望你能理解如何在C#中使用数据类型。在这个指南中,我们已经了解到C#和CTS中的基本数据类型,在下一篇文章中将关注数据类型转换。

本篇原文:
C # Predefined Types

CTS defines a number of data types which can be recognized by the C# compiler. C# has fifteen of these predefined types in which thirteen are value and two are reference type.

Built-in Value Types

Built-in value type represents primitives, such as integer, floating point, characters and Boolean types.

To declare a value type we simply give the name of the object itself, like in the following code where we declare a Boolean type:

bool b;           //This declares a Boolean b on stack
b = false ;      //This assign the value false tp b;

As an example consider the following code:

When you execute the program, it will display the assigned values and wait for the carriage return to finish. In this program we have seen that we have declared three value types. The first one is byte which is actually represented as System.Byte in the CTS and so as the all others, like C and C++ you can also declare and initialize the variables into same line and while declaring it.

Complex Type

There are two more types of value types which we can define, these are Structs and Enumeration.

Structs

Struct is a special kind of class that is value type rather than a reference type. As we all know value types are stored on the Stack, structs also are stored on the Stack. In this way they can be copied and created efficiently (Stacks are more efficiently copied and accessed than Heap).

Enumeration

Enumerations are the user defined integer type. Enum keyword is used to declare an enumeration. Basically the main function is that it makes our code easier to maintain. Variables are assigned only legitimate values. The enumerator also makes our code cleaner by creating deceptive names for inetegers.

The following table represents all the value types, and its respective CTS type and description:

Reference Types

C# supports two predefined reference types, object and string. Reference types store references in a Heap. Heap is the second place where references can be store instead of data. In .NET the heap is now more managed and is called the Managed Heap. When you initialize a new process, the runtime reserves a contiguous region of address space for the process. The managed heap maintains a pointer to the address where the next object in the heap will be allocated. Initially this pointer is set to the managed heap's base address. All reference types are allocated on the managed heap. When an the application creates the first reference type, memory is allocated for the type at the base address of the managed heap. When the application creates the next object, the garbage collector allocates memory for it in the address space immediately following the first object. As long as address space is available, the garbage collector continues to allocate space for new objects in this manner.

To instantiate a reference object in C#, you have to use new keyword. In C# we create a reference and then point the reference at an object allocated the heap with the new keyword, like:

Object myobj;
myobj = new Object();

The above code makes a reference and instantiates myobj in Heap. The reference types with their CTS and description are listed below:

Now that we have learned the basic concepts of both the types, we will create a program in which we will see these both data types:

So in the above program you have seen that because structs are the value types and they store the data rather than their reference, no effect took place in the Value types. On the other hand the reference types modifies and shows the modified values as they are showing data from reference.

I hope you understand how to use to data types in C#. In this tutorial we have learned about the basic data types in C# and CTS, the next articles will focus on data type Conversions.

[后记]:总算把一篇文章翻译完了。翻译的过程真的让我深刻认识到“不是金刚钻,别揽瓷器活”就是真理。太痛苦了,每句话乃至每个词都要去斟酌是否有误。即使我这样做了,翻译出来的文字还是让我很不满意。所以,我想说,不用全文翻译工具的而具有技术涵养的翻译者们,你们辛苦了!

PS:短期内都不会再翻译什么文章了,一句话,技术功底还是太薄弱了。