2:int,char,结构体是值类型;
3:类,接口,字符串,数组是引用类型;
4:值类型是放在堆栈,引用类型是放在堆中;
5:数据实体化时候最好使用hash-based collections来存放数据 ; 一数据类型和操作符:
class Program { static void Main( string [] args) { int myInt = 7 ; System.Console.WriteLine( " Initialized, myInt: {0} " , myInt); myInt = 5 ; // 这种形式是和myInt=5没有区别的 System.Console.WriteLine( " After assignment, myInt: {0} " , myInt); } }
二: const,static readonly 的区别 用 const 修饰符声明的成员叫常量,是在编译期初始化并嵌入到客户端程序,值类型; 用 static readonly 修饰符声明的成员依然是变量,只不过具有和常量类似的使用方法:通过类进行访问、初始化后不可以修改。但与常量不同的是这种变量是在运行期初始化,所以其类型可以是值类型也可以是引用类型. 注意的是,当static readonly类型变量是引用类型时,在当前类中此变量虽然不能再进行new 操作分配空间,但是可以更改此变量内的field的值 . public class usefulValues { public static readonly int testStart = 5 ; public const int testEnd = 10 ; } public class myTest { public static void Main( string [] args) { for ( int i = usefulValues.testStart; i < usefulValues.testEnd; i ++ ) { Console.WriteLine( " value is {0} " ,i); } Console.ReadLine(); } }
三 值类型和引用类 简单说 值类型的变量包含自身的数据,而引用类型的变量是指向数据的内存块的,并不是直接存放数据 . public class ValueTypes { private string str1 = " 6 " ; public string valueTypes() { return str1; } } public class ReferenceTypes { public string referenceTypes() { ValueTypes vt1 = new ValueTypes(); return vt1.valueTypes().Clone() as string ; } } public class myTest { public static void Main( string [] args) { ReferenceTypes rt = new ReferenceTypes(); ValueTypes vt = new ValueTypes(); Console.WriteLine(rt.referenceTypes()); Console.WriteLine(vt.valueTypes()); Console.ReadLine(); } }
使用值类型和引用类型的巧妙之处 public class content { private MyType _a = new MyType( ); private MyType _b = new MyType( ); } content var = new content(); 如上面的样的情况,你就可以考虑如果是使用值类型,那你只需要分配一段内存,分别存放_a,_b的值就可以..如果你使用引用类型那就要分配三部分内存段,所以设计时要考虑; 在数组合中 MyType [] var = new MyType[ 100 ]; 如果是值类型那就是1的内存段,但如果是引用类型就是101内存段. 接口那通常都是引用类型; 如需要节省内存空间就要使用值类型,而又由于我们常需要使用面向对象的方式来操作数据,这样又不得不使用引用类型,所以需要权衡! 四 通常的数据持久化(Immutable Atomic Value Types) 这里.net有NHibernate.但在这里不谈这个,主要是讨论怎样写的 : public class Address { private string _part1; private string _part2; private string _city; private string _state; private int _zipCode; public string part1 { get { return _part1; } set { _part1 = value; } } public string part2 { get { return _part2; } set { _part2 = value; } } public string City { get { return _city; } set { _city = value; } } public string State { get { return _state; } set { // ValidateState(value); _state = value; } } public int ZipCode { get { return _zipCode; } set { // ValidateZip(value); _zipCode = value; } } public void ModifyAddress() { // Modify: this .City = " Ann Arbor " ; this .ZipCode = 48103 ; this .State = " MI " ; } public void NowAddress() { this .part1 = " 111 S. Main " ; this .City = " Anytown " ; this .State = " IL " ; this .ZipCode = 61111 ; } } public class readonlyAddress { private readonly string _line1; private readonly string _line2; private readonly string _city; private readonly string _state; private readonly int _zipCode; public readonlyAddress( string line1, string line2, string city, string state, int zipCode) { _line1 = line1; _line2 = line2; _city = city; _state = state; _zipCode = zipCode; // ValidateState(state); // ValidateZip(zipCode); } } public class myTest { public static void Main( string [] args) { Address a1 = new Address(); a1.NowAddress(); a1.ModifyAddress(); Console.WriteLine(a1.part1); Console.WriteLine(a1.City); Console.WriteLine(a1.ZipCode); Console.WriteLine(a1.State); Console.ReadLine(); } // 使用只读数据的类使用的Main函数. // public static void Main(string[] args) // { // readonlyAddress ra = new readonlyAddress("111 S. Main", // "", "Anytown", "IL", 61111); // Console.WriteLine(ra); // Console.ReadLine(); // } // ===================================== }
在上面代码中有//ValidateZip(value); 这个是用来做数据验证用的,是为保证存放的数据是一有效数据.如下 public class ValidataMessage { private int _ErrLevel; private string _msg; public string ValidataMessage { get { return (_msg != null ) ? _msg : string .Empty; } set { _msg = value; } } }
比如也可以更复杂一点: public class ListBoxTest { private string [] strings; private int ctr = 0 ; public ListBoxTest( params string [] initialStrings ) { strings = new String[ 256 ]; foreach ( string s in initialStrings ) { strings[ctr ++ ] = s; } } public void Add( string theString ) { if ( ctr >= strings.Length ) { } else strings[ctr ++ ] = theString; } public string this [ int index] { get { if ( index < 0 || index >= strings.Length ) { } return strings[index]; } set { if ( index >= ctr ) { } else strings[index] = value; } } public int GetNumEntries( ) { return ctr; } } public class Tester { static void Main( ) { ListBoxTest lbt = new ListBoxTest( " Hello " , " World " ); lbt.Add( " Proust " ); lbt.Add( " Faulkner " ); lbt.Add( " Mann " ); lbt.Add( " Hugo " ); string subst = " Universe " ; lbt[ 1 ] = subst; for ( int i = 0 ; i < lbt.GetNumEntries( ); i ++ ) { Console.WriteLine( " lbt[{0}]: {1} " , i, lbt[i] ); } } }
总结 先从数据类型开始,又由Const 和 static Readonly的区别引出值类型和引用类型, 并谈到值类型和引用类型在使用内存上的区别,而为什么引用类型占用内存比值类型的大,我 们却还要使用它?这其中的一个主要原因是我们同样想使用面向对象的方式来操作数据,如上 面的代码那做就能将数据实体化,我们也可以大胆的想,Object本来就是一个容器,所以被实体 化的数据可以任意类型,任意数据类型就会和数据的验证有关系,这样就来到在属性中纺织复杂 逻辑的情况出,所以我们常需要写一个专门的方法来验证被实体的数据有效性! -------------------------works guo