1conststatic readonly的区别

这个问题虽然很简单,但有时候也能困扰我们一些新来的同学,conststatic readonly的确很像,都在程序中只读,都是一旦初始化则都不再可以改写都是属于语言的静态等等。并且在多数情况下可以混用。
区别
const
1.     编译期间解析的常量
2.     必须在声明就初始化
3.     可用来修饰类中的成员,也可修饰函数体内的局部变量
static readonly
1.     运行期间解析的常量,
2.     既可以在声明时初始化也可以在构造器中初始化
3.     只可以用于修饰类中的成员
例子:
1.      static readonly MyClass myclass = new MyClass();
//必须使用static readonly,因为new需要在运行时确定
//const只能必须在编译时就确定

2. 
static readonly A = B * 20;
   
static readonly B = 10;
//可以使用static readonly,显然可以在运行时确定语句
//也可以使用const
// const A = B * 20;
// const B = 10;
//,编译器会在编译时候,就把B编译为10A编译为200,而不是在运行时再计算B * 20
2.      有一个项目,有一个MyInt的属性,定义如下:
publicclassMYClass
{
publicconstintMyInt = 5;
}
另一个项目中引用该属性
publicclassAnotherClass
{
int I = MYClass.MyInt;
}
编译运行程序, I = 5.这是当然的。
但是如果我们改变MYClass中的MyInt的值,改为6.然后编译MYClass所在的项目,生成dll
再运行程序AnotherClass,发现I还是= 5,而不是6!,为什么?因为在AnotherClass中,I已经被定义为5而不是运行时再去取dll的值,所以说const是编译时就确定了!!!

2、静态变量和非静态变量的区别?
下面的程序在Count类中定义了两个变量,一个是静态变量count,一个是非静态的number,  
  结果为:  
              number=1   count=1  
   
              number=1   count=2  
              number=2   count=2  
   
  不明白既然“number=count;”为什么会有“number=1   count=2;”这组数,number不是应该和count一致吗?  
   
  public   class   Count{  
   
        static   int   count;   //类的实例数  
        int   number;   //类实例的编号  
         
        public   Count(){  
              count=count+1;  
              number=count;  
        }  
         
        public   void   show(){  
              Console.WriteLine("number={0}   count={1}",number,count);  
        }  
  }   
    静态变量是全局的,实例变量是局部的,这样就可以借是你的程序的输出为什么是这样了。  
  首先,实例化a,此时,count=1,   number=1,   当你实例化b的时候,a.number没有变,但是count变了,而b.number=count,所以b.number=2.
static   int   count;    
  在这里,静态字段(变量)count是一个属于“类”的成员。  
  int   number;  
  在这里,实例字段(变量)number是一个属于“实例”的成员。  
   
  Console.WriteLine("number={0}   count={1}",number,count);  
  要知道,上面的一句话是下面的一句话的简写,  
  Console.WriteLine("number={0}   count={1}",this.number,Count.count);  
   
  因此,你的程序实际上有三个变量:a.number   、b.number、   Count.count    
  再补充一句:在默认构造函数里,int类型字段的默认值为0。
当你创建a(Count   a=new   Count();   )时,a实例里的count=1,number=1  
  当你第一次调用a.show()时,显示number=1,count=1  
  当你创建b(Count   b=new   Count();   )时,b实例里的count=2,number=2  
  当你再次调用a.show()时,由于a实例里的number=count并没有再次调用,所以此时count=2,number=1,所以显示number=1,count=2  
  接着你调用b.show(),显示number=2,count=2   


    
  class   TestStaticArea{  
         
        public   static   void   Main(){  
   
              Count   a=new   Count();    
              a.show();    
              Console.WriteLine();  
               
              Count   b=new   Count();    
              a.show();  
              b.show();  
              Console.WriteLine();  
        }  
  }   
3.extern 是什么意思?
extern 修饰符用于声明由程序集外部实现的成员函数
经常用于系统API函数的调用(通过 DllImport )。注意,和DllImport一起使用时要加上 static 修饰符
也可以用于对于同一程序集不同版本组件的调用(用 extern 声明别名)
不能与 abstract 修饰符同时使用
示例:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
 
namespace Example03
{
    class Program
    {
        //注意DllImport是一个Attribute Property,在System.Runtime.InteropServices命名空间中定义
        //extern与DllImport一起使用时必须再加上一个static修饰符
        [DllImport("User32.dll")]
        public static extern int MessageBox(int Handle, string Message, string Caption, int Type);
 
        static int Main()
        {
            string myString;
            Console.Write("Enter your message: ");
            myString = Console.ReadLine();
            return MessageBox(0, myString, "My Message Box", 0);
        }
    }
}
结果:
 4.abstract 是什么意思?
答:
abstract 修饰符可以用于类、方法、属性、事件和索引指示器(indexer),表示其为抽象成员
abstract 不可以和 static 、virtual 、override 一起使用
声明为 abstract 成员可以不包括实现代码,但只有类中还有未实现的抽象成员,该类就不可以被实例化,通常用于强制继承类必须实现某一成员
示例:
using System;
using System.Collections.Generic;
using System.Text;
 
namespace Example04
{
    #region 基类,抽象类
    public abstract class BaseClass
    {
        //抽象属性,同时具有get和set访问器表示继承类必须将该属性实现为可读写
        public abstract String Attribute
        {
            get;
            set;
        }
 
        //抽象方法,传入一个字符串参数无返回值
        public abstract void Function(String value);
 
        //抽象事件,类型为系统预定义的代理(delegate):EventHandler
        public abstract event EventHandler Event;
 
        //抽象索引指示器,只具有get访问器表示继承类必须将该索引指示器实现为只读
        public abstract Char this[int Index]
        {
            get;
        }
    }
    #endregion
 
    #region 继承类
    public class DeriveClass : BaseClass
    {
        private String attribute;
 
        public override String Attribute
        {
            get
            {
                return attribute;
            }
            set
            {
                attribute = value;
            }
        }
        public override void Function(String value)
        {
            attribute = value;
            if (Event != null)
            {
                Event(this, new EventArgs());
            }
        }
        public override event EventHandler Event;
        public override Char this[int Index]
        {
            get
            {
                return attribute[Index];
            }
        }
    }
    #endregion
 
    class Program
    {
        static void OnFunction(object sender, EventArgs e)
        {
            for (int i = 0; i < ((DeriveClass)sender).Attribute.Length; i++)
            {
                Console.WriteLine(((DeriveClass)sender)[i]);
            }
        }
        static void Main(string[] args)
        {
            DeriveClass tmpObj = new DeriveClass();
 
            tmpObj.Attribute = "1234567";
            Console.WriteLine(tmpObj.Attribute);
 
            //将静态函数OnFunction与tmpObj对象的Event事件进行关联
            tmpObj.Event += new EventHandler(OnFunction);
 
            tmpObj.Function("7654321");
 
            Console.ReadLine();
        }
    }
}
结果:
1234567
7
6
5
4
3
2
1

5.internal 修饰符起什么作用?
答:
internal 修饰符可以用于类型或成员,使用该修饰符声明的类型或成员只能在同一程集内访问
接口的成员不能使用 internal 修饰符
示例
Example05Lib 项目的 Class1
using System;
using System.Collections.Generic;
using System.Text;
 
namespace Example05Lib
{
    public class Class1
    {
        internal String strInternal = null;
        public String strPublic;
    }
}
结果
Example05Lib 项目的 Class2 类可以访问到 Class1 的 strInternal 成员
 
Example05 项目的 Program 类无法访问到 Class1 的 strInternal 成员 

6、override 和 overload 的区别?
答:
override 表示重写,用于继承类对基类中虚成员的实现
overload 表示重载,用于同一个类中同名方法不同参数(包括类型不同或个数不同)的实现
示例:
using System;
using System.Collections.Generic;
using System.Text;
 
namespace Example07
{
    class Program
    {
        class BaseClass
        {
            public virtual void F()
            {
                Console.WriteLine("BaseClass.F");
            }
        }
        class DeriveClass : BaseClass
        {
            public override void F()
            {
                base.F();
                Console.WriteLine("DeriveClass.F");
            }
            public void Add(int Left, int Right)
            {
                Console.WriteLine("Add for Int: {0}", Left + Right);
            }
            public void Add(double Left, double Right)
            {
                Console.WriteLine("Add for int: {0}", Left + Right);
            }
        }
        static void Main(string[] args)
        {
            DeriveClass tmpObj = new DeriveClass();
            tmpObj.F();
            tmpObj.Add(1, 2);
            tmpObj.Add(1.1, 2.2);
 
            Console.ReadLine();
        }
    }
}
结果:
BaseClass.F
DeriveClass.F
Add for Int: 3
Add for int: 3.3

8.什么是索引指示器?
答:
实现索引指示器(indexer)的类可以象数组那样使用其实例后的对象,但与数组不同的是索引指示器的参数类型不仅限于int
简单来说,其本质就是一个含参数属性
示例:

using System;
using System.Collections.Generic;
using System.Text;
 
namespace Example08
{
    public class Point
    {
        private double x, y;
        public Point(double X, double Y)
        {
            x = X;
            y = Y;
        }
        //重写ToString方法方便输出
        public override string ToString()
        {
            return String.Format("X: {0} , Y: {1}", x, y);
        }
    }
    public class Points
    {
        Point[] points;
        public Points(Point[] Points)
        {
            points = Points;
        }
        public int PointNumber
        {
            get
            {
                return points.Length;
            }
        }   
        //实现索引访问器
        public Point this[int Index]
        {
            get
            {
                return points[Index];
            }
        }
    }
 
    //感谢watson hua(
http://huazhihao.cnblogs.com/)的指点
    //索引指示器的实质是含参属性,参数并不只限于int
    class WeatherOfWeek
    {
        public string this[int Index]
        {
            get
            {
                //注意case段使用return直接返回所以不需要break
                switch (Index)
                {
                    case 0:
                        {
                            return "Today is cloudy!";
                        }
                    case 5:
                        {
                            return "Today is thundershower!";
                        }
                    default:
                        {
                            return "Today is fine!";
                        }
                }
            }
        }
        public string this[string Day]
        {
            get
            {
                string TodayWeather = null;
                //switch的标准写法
                switch (Day)
                {
                    case "Sunday":
                        {
                            TodayWeather = "Today is cloudy!";
                            break;
                        }
                    case "Friday":
                        {
                            TodayWeather = "Today is thundershower!";
                            break;
                        }
                    default:
                        {
                            TodayWeather = "Today is fine!";
                            break;
                        }
                }
                return TodayWeather;
            }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Point[] tmpPoints = new Point[10];
            for (int i = 0; i < tmpPoints.Length; i++)
            {
                tmpPoints[i] = new Point(i, Math.Sin(i));
            }
 
            Points tmpObj = new Points(tmpPoints);
            for (int i = 0; i < tmpObj.PointNumber; i++)
            {
                Console.WriteLine(tmpObj[i]);
            }
 
 
            string[] Week = new string[] { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Staurday"};
            WeatherOfWeek tmpWeatherOfWeek = new WeatherOfWeek();
            for (int i = 0; i < 6; i++)
            {
                Console.WriteLine(tmpWeatherOfWeek[i]);
            }
            foreach (string tmpDay in Week)
            {
                Console.WriteLine(tmpWeatherOfWeek[tmpDay]);
            }
 
            Console.ReadLine();
        }
    }
}
结果:
X: 0 , Y: 0
X: 1 , Y: 0.841470984807897
X: 2 , Y: 0.909297426825682
X: 3 , Y: 0.141120008059867
X: 4 , Y: -0.756802495307928
X: 5 , Y: -0.958924274663138
X: 6 , Y: -0.279415498198926
X: 7 , Y: 0.656986598718789
X: 8 , Y: 0.989358246623382
X: 9 , Y: 0.412118485241757
Today is cloudy!
Today is fine!
Today is fine!
Today is fine!
Today is fine!
Today is thundershower!
Today is cloudy!
Today is fine!
Today is fine!
Today is fine!
Today is fine!
Today is thundershower!
Today is fine!
大家有什么问题可以在我的群里来交流:9196338
posted on 2008-10-31 16:30  Ready  阅读(805)  评论(2)    收藏  举报