学习数组类时,碰到typeof()

来源:互联网 发布:java poi怎么用 编辑:程序博客网 时间:2024/05/17 01:17

学习数组类时,碰到typeof(),对其实验引起的一连串知识点、学习小结和思考练习(涉及成员对象变量、成员常量、抽象类Type等知识)
作者:友闻语上 来源:博客园 发布时间:2009-09-20 15:22 阅读:95 次 原文链接 [收藏]

知识点


C#提供了一个名为System.Array的现成数组类,通过这个类提供的属性和方法可以对数组执行多种操作。
由于Array类提供创建、操作、搜索和排序数组的方法,因而在公共语言运行库(CLP)中用作所有数组的基类。但是,只有系统和编译器能从Array类显示派生。用户应该使用由语言
提供的数组构造。如:int[] i=new int[]{1,2,3,4,5,6,7};

Array类和其他类不同,它用CreatInstance方法来创建数组,不提供公共的构造函数。如创建整型数组:Array intVal=Array.CreatInstance(typeof(int),7);
typeof是关键字,用于获取类型的 System.Type 对象。typeof 表达式采用以下形式:
System.Type type = typeof(int);//提供有关类型的信息,将具体类型种类赋值给对象type,typeof()返回的其实就是Type对象(还是叫Type类型?因为Type为抽象类,不能创建实
例,所以这里应该怎么表述才为恰当,在此存留疑问)



由typeof(),拓展出去试验,有了以下小结:


1、抽象类不是不能创建对象的吗,为什么可以用“Type type=typeof(int);”?那岂不是给人感觉将对象赋给了Type类的对象?在此存留疑问。Type类型声明后(用前面的语句) 也可作为类的成员访问,前面的type就可以作为成员访问了。如果定义Type类型成员是静态的,访问也按照静态成员变量来访问。
2、类里可以声明成员对象变量,在构造函数里初始化也可,在声明时候初始化也可,在Main()里也可,也就是说其他类的实例对象也可以作为本地类的成员变量(看上去是这个意思,具体要问清楚。,在此存留疑问)
3、如果整个程序都没有对该静态成员对象变量初始化,字段将保持默认值null
4、WriteLine(),参数内如果是对象,则将指定对象的文本表示形式(后跟当前行结束符)写入标准输出流。如同对象后加了.ToString()
5、typeof是关键字,返回抽象类Type的对象,括号内的一定是类别或类的别名(如把System.Int32 写成int,对别名的说法是自己的理解,在此存留疑问),这样看来,int可以看做是某个类的替代名(有点粗浅,在此存留疑问),long是Int64的替代名,等等
6、System.Int32是结构(存留疑问:类和结构的区别,目前我把它们看成一样的),其中的静态成员方法、常量都必须通过“结构名.方法/常量”来访问,对于非静态成员则需要先声明对象,再由“对象.方法名”来访问
(在类中定义的成员常量感觉上也可叫做静态成员常量,常量和静态变量的区别除了一个是常量一个是变量外,static是不可以用在方法体内声明的,而常量可以,也就是说方法体内声明的可以是局部变量或者局部常量,不能声明静态变量)
7、对象都有GetType()和ToString()两个方法,在不同场合,GetType()的值与ToString()的值未必相同,详见程序。针对type1,GetType()获取当前System.Type;ToSting()是返回当前Type的名称.到底为何不同,在此存留疑问!



思考练习
using System;
namespace Temp
{
public class TestClass
{
const int con2 = 777;
private int intVal;
public int intVal2;
public TestClass()
{
intVal = 1717;
intVal2 = 999;
}
public int GetIntVal()
{
return (intVal);
}
}
public class TempClass
{
static int intStatic = 12;
const int con2 = 17;
Array intVal = Array.CreateInstance(typeof(int), 7);

Type type = typeof(long);//也可写成Type type=typeof(Int64);
//TestClass test3=typeof(decimal);
//上面这句是错的,明显typeof()返回的是System.Type类型的一个对象,所以不能赋值给TestClass的对象(不匹配),但又有了疑问,Type类是抽象类,抽象类不是不能创建对象的吗,为什么可以用“Type type=typeof(int);”?那岂不是给人感觉将对象赋给了Type类的对象?在此存留疑问。
TestClass test2;//=new TestClass();//类里可以声明成员对象变量,在构造函数里初始化也可,在声明时候初始化也可,也就是说其他类的实例对象也可以作为本地类的成员变量(看上去是这个意思,具体要问清楚,在此留存疑问)

static Type typeStatic = typeof(double);

static TestClass testStatic;
public TempClass()
{
test2 = new TestClass();
testStatic = new TestClass();//如果整个程序都没有对该静态成员对象变量初始化,字段将保持默认值null
}
public int ConstTest()
{
const int con1 = 77;
return (con1);
}
static void Main()
{
TestClass test1 = new TestClass();
Console.WriteLine("TestClass 的 intVal is {0}", test1.GetIntVal());//以上两句是最常规的对象用法
//Type typeObject = new Type();//这句是错的,因为Type类是抽象类,不能创建实例
TempClass temp1 = new TempClass();
Console.WriteLine("Type type在类中声明后,值 为 {0}", temp1.type);//Type类型也可作为类的成员访问
Console.WriteLine("static Type typeStatic在类中声明后,值 为 {0}", TempClass.typeStatic);//定义Type类型是静态的,访问也按照静态成员变量来访问
Console.WriteLine("static TestClass testStatic 在类中声明后,静态成员对象变量值为:{0}", TempClass.testStatic);//输出Temp.TestClass。WriteLine(),参数内如果是对象,则将指定对象的文本表示形式(后跟当前行结束符)写入标准输出流。如同TempClass.testStatic.ToString()
//temp1.test2=new TestClass();//如果没有对成员对象变量test2初始化,这句话是对的,可以在这里初始化,或者放到构造函数里初始化
Console.WriteLine("temp1.test2内的intVal值是{0}", temp1.test2.GetIntVal());//如果不对成员对象变量进行初始化,这条语句虽然能通过,但程序依然会出错!所有针对成员对象变量一定要初始化
Console.WriteLine("TestClass test2 在类中声明后,值为 {0}", temp1.test2.GetIntVal());
Type type1 = typeof(TempClass);//typeof是关键字,返回抽象类Type的对象,括号内的一定是类别或类的别名(如把System.Int32 写成int,对别名的说法是自己的理解,在此存留疑问)
Type type2 = typeof(int);//这样看来,int可以看做是某个类的替代名(有点粗浅,在此存留疑问)
Int32 iVal1 = 5;//等同于int iVal1=5
int iVal2 = iVal1;
/*
System.Int32是结构(存留疑问:类和结构的区别,目前我把它们看成一样的),其中的静态成员方法、常量都必须通过“结构名.方法/常量”来访问,对于非静态成员则需要先声明对象,再由“对象.方法名”来访问
(在类中定义的成员常量感觉上也可叫做静态成员常量,常量和静态变量的区别除了一个是常量一个是变量外,static是不可以用在方法体内声明的,而常量可以,也就是说方法体内声明的可以是局部变量或者局部常量,不能声明静态变量)

*/
//Console.WriteLine("con2 is {0}",temp1.con2);//一旦在类中定义了成员常量,相当于定义了静态成员常量,不能再由对象访问,而是由“类名.常量”访问
Console.WriteLine("TempClass类中的成员常量con2 值为:{0}", TempClass.con2);//如果是Console.WriteLine("TestClass类中的成员常量con2 值为:{0}",TestClass.con2);那就不可以,因为在TempClass内想直接去访问TempClass的私有成员,那肯定不行
Console.WriteLine("ConstTest is {0}", temp1.ConstTest());//常量在其他的方法体中声明就是局部常量,可以通过各对象访问
const int con1 = 11;
//con1=12;
Console.WriteLine("con1 is {0}", con1);
Console.WriteLine(type1);//输出TempClass
Console.WriteLine(type1.GetType());//输出RuntimeType,GetType()的值与ToString()的值未必相同
Console.WriteLine(type1.ToString());//输出TempClass,感觉Console.WriteLine(type1);默认实际上是去访问Console.WriteLine(type1.ToString());这条语句
/*
针对type1,GetType()获取当前System.Type;ToSting()是返回当前Type的名称.到底为何不同,在此存留疑问!
*/
Console.WriteLine(type2.ToString());//输出System.Int32
Console.WriteLine("WriteLine 指定对象 输出结果是 {0}", temp1);
/*输出TempClass,其实将语句改为Console.WriteLine("WriteLine 指定对象 输出结果是 {0}",temp1.ToString());
或者Console.WriteLine("WriteLine 指定对象 输出结果是 {0}",temp1.GetType());
效果是一样的
在对象temp1中调以上两个方法与type1调用,解释有所不同
GetType()获取当前实例的System.Type();返回表示当前System.Object的System.String,针对这个系类问题要好好琢磨,在此存留疑问

*/
Console.WriteLine("{0} {1}", iVal1, iVal2);
Console.ReadLine();
}
}
}

原创粉丝点击