在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
2.const 和 static readonly 区别? 3.extern 是什么意思? 4.abstract 是什么意思? 5.internal 修饰符起什么作用? 6.sealed 修饰符是干什么的? 7.override 和 overload 的区别? 8.什么是索引指示器? 9.new 修饰符是起什么作用? 10.this 关键字的含义? 11.可以使用抽象函数重写基类中的虚函数吗? 12.密封类可以有虚函数吗? 13.如果基类中的虚属性只有一个属性访问器,那么继承类重写该属性后可以有几个属性访问器?如果基类中有 get 和 set 两个呢? 14.abstract 可以和 virtual 一起使用吗?可以和 override 一起使用吗? 15.接口可以包含哪些成员? 16.类和结构的区别? 17.接口的多继承会带来哪些问题? 18.抽象类和接口的区别? 19.别名指示符是什么? 20.如何释放非托管资源? 21.P/Invoke是什么? 22.StringBuilder 和 String 的区别? 23.explicit 和 implicit 的含义? 24.params 有什么用? 25.什么是反射? 以下是我做的一份参考答案(C# 语言范畴之内),如果有不准确、不全面的,欢迎各位朋友指正! 1.静态变量和非静态变量的区别? 答: 静态变量: 静态变量使用 static 修饰符进行声明 在所属类被装载时创建 通过类进行访问 所属类的所有实例的同一静态变量都是同一个值 非静态变量: 不带有 static 修饰符声明的变量称做非静态变量 在类被实例化时创建 通过对象进行访问 同一个类的不同实例的同一非静态变量可以是不同的值 示例: using System; using System.Collections.Generic; using System.Text; namespace Example01 { class Program { class Class1 { public static String staticStr = "Class"; public String notstaticStr = "Obj"; } static void Main(string[] args) { //静态变量通过类进行访问,该类所有实例的同一静态变量都是同一个值 Console.WriteLine("Class1's staticStr: {0}", Class1.staticStr); Class1 tmpObj1 = new Class1(); tmpObj1.notstaticStr = "tmpObj1"; Class1 tmpObj2 = new Class1(); tmpObj2.notstaticStr = "tmpObj2"; //非静态变量通过对象进行访问,不同对象的同一非静态变量可以有不同的值 Console.WriteLine("tmpObj1's notstaticStr: {0}", tmpObj1.notstaticStr); Console.WriteLine("tmpObj2's notstaticStr: {0}", tmpObj2.notstaticStr); Console.ReadLine(); } } }
using System; using System.Collections.Generic; using System.Text; namespace Example02Lib { public class Class1 { public const String strConst = "Const"; public static readonly String strStaticReadonly = "StaticReadonly"; //public const String strConst = "Const Changed"; //public static readonly String strStaticReadonly = "StaticReadonly Changed"; }//5-1-a-s-p-x }
using System; using System.Collections.Generic; using System.Text; using Example02Lib; namespace Example02 { class Program { static void Main(string[] args) { //修改Example02中Class1的strConst初始值后,只编译Example02Lib项目 //然后到资源管理器里把新编译的Example02Lib.dll拷贝Example02.exe所在的目录,执行Example02.exe //切不可在IDE里直接调试运行因为这会重新编译整个解决方案!! //可以看到strConst的输出没有改变,而strStaticReadonly的输出已经改变 //表明Const变量是在编译期初始化并嵌入到客户端程序,而StaticReadonly是在运行时初始化的 Console.WriteLine("strConst : {0}", Class1.strConst); Console.WriteLine("strStaticReadonly : {0}", Class1.strStaticReadonly); Console.ReadLine(); } } }
using System; using System.Collections.Generic; using System.Text; namespace Example02Lib { public class Class1 { //public const String strConst = "Const"; //public static readonly String strStaticReadonly = "StaticReadonly"; public const String strConst = "Const Changed"; public static readonly String strStaticReadonly = "StaticReadonly Changed"; } }
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); } } }
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 = &quot;1234567&quot;; Console.WriteLine(tmpObj.Attribute); //将静态函数OnFunction与tmpObj对象的Event事件进行关联 tmpObj.Event += new EventHandler(OnFunction); tmpObj.Function(&quot;7654321&quot;); Console.ReadLine(); } } }
using System; using System.Collections.Generic; using System.Text; namespace Example05Lib { public class Class1 { internal String strInternal = null; public String strPublic; } }
using System; using System.Collections.Generic; using System.Text; namespace Example06 { class Program { class A { public virtual void F() { Console.WriteLine(&quot;A.F&quot;); } public virtual void G() { Console.WriteLine(&quot;A.G&quot;); } } class B : A { public sealed override void F() { Console.WriteLine(&quot;B.F&quot;); } public override void G() { Console.WriteLine(&quot;B.G&quot;); } } class C : B { public override void G() { Console.WriteLine(&quot;C.G&quot;); } } static void Main(string[] args) { new A().F(); new A().G(); new B().F(); new B().G(); new C().F(); new C().G(); Console.ReadLine(); } } }
using System; using System.Collections.Generic; using System.Text; namespace Example07 { class Program { class BaseClass { public virtual void F() { Console.WriteLine(&quot;BaseClass.F&quot;); } } class DeriveClass : BaseClass { public override void F() { base.F(); Console.WriteLine(&quot;DeriveClass.F&quot;); } public void Add(int Left, int Right) { Console.WriteLine(&quot;Add for Int: {0}&quot;, Left + Right); } public void Add(double Left, double Right) { Console.WriteLine(&quot;Add for int: {0}&quot;, 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(); } } }
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(&quot;X: {0} , Y: {1}&quot;, 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 &quot;Today is cloudy!&quot;; } case 5: { return &quot;Today is thundershower!&quot;; } default: { return &quot;Today is fine!&quot;; } } } } public string this[string Day] { get { string TodayWeather = null; //switch的标准写法 switch (Day) { case &quot;Sunday&quot;: { TodayWeather = &quot;Today is cloudy!&quot;; break; } case &quot;Friday&quot;: { TodayWeather = &quot;Today is thundershower!&quot;; break; } default: { TodayWeather = &quot;Today is fine!&quot;; 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[] { &quot;Sunday&quot;, &quot;Monday&quot;, &quot;Tuesday&quot;, &quot;Wednesday&quot;, &quot;Thursday&quot;, &quot;Friday&quot;, &quot;Staurday&quot;}; 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(); } } }
using System; using System.Collections.Generic; using System.Text; namespace Example09 { class BaseClass { //基类设计者声明了一个PI的公共变量,方便进行运算 public static double PI = 3.1415; } class DervieClass : BaseClass { //继承类发现该变量的值不能满足运算精度,于是可以通过new修饰符显示隐藏基类中的声明 public new static double PI = 3.1415926; } class Program { static void Main(string[] args) { Console.WriteLine(BaseClass.PI); Console.WriteLine(DervieClass.PI); Console.ReadLine(); } } }
using System; using System.Collections.Generic; using System.Text; namespace Example10 { class Class1 { private double c; private string value; public double C { get { return c; } } public Class1(double c) { //限定同名的隐藏成员 this.c = c; } public Class1(Class1 value) { //用对象本身实例化自己没有意义 if (this != value) { c = value.C; } } public override string ToString() { //将对象本身做为参数 return string.Format(&quot;{0} Celsius = {1} Fahrenheit&quot;, c, UnitTransClass.C2F(this)); } //由于好奇,在这做了一个效率测试,想看看到底哪种方式访问成员变量更快,结论:区别不大。。。 public string Test1() { long vTickCount = Environment.TickCount; for (int i = 0; i < 10000000; i++) this.value = i.ToString(); return string.Format(&quot;Have this.: {0} MSEL&quot;, Environment.TickCount - vTickCount); } public string Test2() { long vTickCount = Environment.TickCount; for (int i = 0; i < 10000000; i++) value = i.ToString(); return string.Format(&quot;Don't have this.: {0} MSEL&quot;, Environment.TickCount - vTickCount); } } class UnitTransClass { public static double C2F(Class1 value) { //摄氏到华氏的转换公式 return 1.8 * value.C + 32; } } class Program { static void Main(string[] args) { Class1 tmpObj = new Class1(37.5); Console.WriteLine(tmpObj); Console.WriteLine(tmpObj.Test1()); Console.WriteLine(tmpObj.Test2()); Console.ReadLine(); } } }
class BaseClass
{ public virtual void F() { Console.WriteLine(&quot;BaseClass.F&quot;); } } abstract class DeriveClass : BaseClass { public new abstract void F(); }
class BaseClass { public virtual void F() { Console.WriteLine(&quot;BaseClass.F&quot;); } } sealed class DeriveClass : BaseClass { //基类中的虚函数F被隐式的转化为非虚函数 //密封类中不能再声明新的虚函数G //public virtual void G() //{ // Console.WriteLine(&quot;DeriveClass.G&quot;); //} }
using System; using System.Collections.Generic; using System.Text; namespace Example16 { interface IPoint { double X { get; set; } double Y { get; set; } double Z { get; set; } } //结构也可以从接口继承 struct Point: IPoint { private double x, y, z; //结构也可以增加构造函数 public Point(double X, double Y, double Z) { this.x = X; this.y = Y; this.z = Z; } public double X { get { return x; } set { x = value; } } public double Y { get { return x; } set { x = value; } } public double Z { get { return x; } set { x = value; } } } //在此简化了点状Geometry的设计,实际产品中还包含Project(坐标变换)等复杂操作 class PointGeometry { private Point value; public PointGeometry(double X, double Y, double Z) { value = new Point(X, Y, Z); } public PointGeometry(Point value) { //结构的赋值将分配新的内存 this.value = value; } public double X { get { return value.X; } set { this.value.X = value; } } public double Y { get { return value.Y; } set { this.value.Y = value; } } public double Z { get { return value.Z; } set { this.value.Z = value; } } public static PointGeometry operator +(PointGeometry Left, PointGeometry Rigth) { return new PointGeometry(Left.X + Rigth.X, Left.Y + Rigth.Y, Left.Z + Rigth.Z); } public override string ToString() { return string.Format(&quot;X: {0}, Y: {1}, Z: {2}&quot;, value.X, value.Y, value.Z); } } class Program { static void Main(string[] args) { Point tmpPoint = new Point(1, 2, 3); PointGeometry tmpPG1 = new PointGeometry(tmpPoint); PointGeometry tmpPG2 = new PointGeometry(tmpPoint); tmpPG2.X = 4; tmpPG2.Y = 5; tmpPG2.Z = 6; //由于结构是值类型,tmpPG1 和 tmpPG2 的坐标并不一样 Console.WriteLine(tmpPG1); Console.WriteLine(tmpPG2); //由于类是引用类型,对tmpPG1坐标修改后影响到了tmpPG3 PointGeometry tmpPG3 = tmpPG1; tmpPG1.X = 7; tmpPG1.Y = 8; tmpPG1.Z = 9; Console.WriteLine(tmpPG1); Console.WriteLine(tmpPG3); Console.ReadLine(); } } }
using System; using System.Collections.Generic; using System.Text; namespace Example17 { class Program { //一个完整的接口声明示例 interface IExample { //属性 string P { get; set; } //方法 string F(int Value); //事件 event EventHandler E; //索引指示器 string this[int Index] { get; set; } } interface IA { int Count { get; set;} } interface IB { int Count(); } //IC接口从IA和IB多重继承 interface IC : IA, IB { } class C : IC { private int count = 100; //显式声明实现IA接口中的Count属性 int IA.Count { get { return 100; } set { count = value; } } //显式声明实现IB接口中的Count方法 int IB.Count() { return count * count; } } static void Main(string[] args) { C tmpObj = new C(); //调用时也要显式转换 Console.WriteLine(&quot;Count property: {0}&quot;, ((IA)tmpObj).Count); Console.WriteLine(&quot;Count function: {0}&quot;, ((IB)tmpObj).Count()); Console.ReadLine(); } } }
Class1.cs: using System; using System.Collections.Generic; using System.Text; namespace com.nblogs.reonlyrun.CSharp26QExample.Example19.Lib01 { class Class1 { public override string ToString() { return &quot;com.nblogs.reonlyrun.CSharp26QExample.Example19.Lib01's Class1&quot;; } } }
using System; using System.Collections.Generic; using System.Text; namespace com.nblogs.reonlyrun.CSharp26QExample.Example19.Lib02 { class Class1 { public override string ToString() { return &quot;com.nblogs.reonlyrun.CSharp26QExample.Example19.Lib02's Class1&quot;; } } }
using Lib01Class1 = com.nblogs.reonlyrun.CSharp26QExample.Example19.Lib01.Class1; using Lib02Class2 = com.nblogs.reonlyrun.CSharp26QExample.Example19.Lib02.Class1; namespace Example19 { class Program { static void Main(string[] args) { Lib01Class1 tmpObj1 = new Lib01Class1(); Lib02Class2 tmpObj2 = new Lib02Class2(); Console.WriteLine(tmpObj1); Console.WriteLine(tmpObj2); Console.ReadLine(); } } }
using System; using System.Collections.Generic; using System.Text; namespace Example20 { class Program { class Class1 : IDisposable { //析构函数,编译后变成 protected void Finalize(),GC会在回收对象前会调用调用该方法 ~Class1() { Dispose(false); } //通过实现该接口,客户可以显式地释放对象,而不需要等待GC来释放资源,据说那样会降低效率 void IDisposable.Dispose() { Dispose(true); } //将释放非托管资源设计成一个虚函数,提供在继承类中释放基类的资源的能力 protected virtual void ReleaseUnmanageResources() { //Do something... } //私有函数用以释放非托管资源 private void Dispose(bool disposing) { ReleaseUnmanageResources(); //为true时表示是客户显式调用了释放函数,需通知GC不要再调用对象的Finalize方法 //为false时肯定是GC调用了对象的Finalize方法,所以没有必要再告诉GC你不要调用我的Finalize方法啦 if (disposing) { GC.SuppressFinalize(this); } } } static void Main(string[] args) { //tmpObj1没有手工释放资源,就等着GC来慢慢的释放它吧 Class1 tmpObj1 = new Class1(); //tmpObj2调用了Dispose方法,传说比等着GC来释放它效率要调一些 //个人认为是因为要逐个对象的查看其元数据,以确认是否实现了Dispose方法吧 //当然最重要的是我们可以自己确定释放的时间以节省内存,优化程序运行效率 Class1 tmpObj2 = new Class1(); ((IDisposable)tmpObj2).Dispose(); } } }
using System; using System.Collections.Generic; using System.Text; namespace Example22 { class Program { static void Main(string[] args) { const int cycle = 100000; long vTickCount = Environment.TickCount; String str = null; for (int i = 0; i < cycle; i++) str += i.ToString(); Console.WriteLine(&quot;String: {0} MSEL&quot;, Environment.TickCount - vTickCount); vTickCount = Environment.TickCount; //看到这个变量名我就生气,奇怪为什么大家都使它呢? :) StringBuilder sb = new StringBuilder(); for (int i = 0; i < cycle; i++) sb.Append(i); Console.WriteLine(&quot;StringBuilder: {0} MSEL&quot;, Environment.TickCount - vTickCount); Console.ReadLine(); } } }
using System; using System.Collections.Generic; using System.Text; namespace Example23 { class Program { //本例灵感来源于大话西游经典台词“神仙?妖怪?”--主要是我实在想不出什么好例子了 class Immortal { public string name; public Immortal(string Name) { name = Name; } public static implicit operator Monster(Immortal value) { return new Monster(value.name + &quot;:神仙变妖怪?偷偷下凡即可。。。&quot;); } } class Monster { public string name; public Monster(string Name) { name = Name; } public static explicit operator Immortal(Monster value) { return new Immortal(value.name + &quot;:妖怪想当神仙?再去修炼五百年!&quot;); } } static void Main(string[] args) { Immortal tmpImmortal = new Immortal(&quot;紫霞仙子&quot;); //隐式转换 Monster tmpObj1 = tmpImmortal; Console.WriteLine(tmpObj1.name); Monster tmpMonster = new Monster(&quot;孙悟空&quot;); //显式转换 Immortal tmpObj2 = (Immortal)tmpMonster; Console.WriteLine(tmpObj2.name); Console.ReadLine(); } } }
using System; using System.Collections.Generic; using System.Text; namespace ConsoleApplication1 { class App { //第一个参数必须是整型,但后面的参数个数是可变的。 //而且由于定的是object数组,所有的数据类型都可以做为参数传入 public static void UseParams(int id, params object[] list) { Console.WriteLine(id); for (int i = 0; i < list.Length; i++) { Console.WriteLine(list[i]); } } static void Main() { //可变参数部分传入了三个参数,都是字符串类型 UseParams(1, &quot;a&quot;, &quot;b&quot;, &quot;c&quot;); //可变参数部分传入了四个参数,分别为字符串、整数、浮点数和双精度浮点数数组 UseParams(2, &quot;d&quot;, 100, 33.33, new double[] { 1.1, 2.2 }); Console.ReadLine(); } } }
using System; using System.Collections.Generic; using System.Text; namespace Example25Lib { public class Class1 { private string name; private int age; //如果显式的声明了无参数构造函数,客户端只需要用程序集的CreateInstance即可实例化该类 //在此特意不实现,以便在客户调用端体现构造函数的反射实现 //public Class1() //{ //} public Class1(string Name, int Age) { name = Name; age = Age; } public void ChangeName(string NewName) { name = NewName; } public void ChangeAge(int NewAge) { age = NewAge; } public override string ToString() { return string.Format(&quot;Name: {0}, Age: {1}&quot;, name, age); } } }
using System; using System.Collections.Generic; using System.Text; //注意添加该反射的命名空间 using System.Reflection; namespace Example25 { class Program { static void Main(string[] args) { //加载程序集 Assembly tmpAss = Assembly.LoadFile(AppDomain.CurrentDomain.BaseDirectory + &quot;Example25Lib.dll&quot;); //遍历程序集内所有的类型,并实例化 Type[] tmpTypes = tmpAss.GetTypes(); foreach (Type tmpType in tmpTypes) { //获取第一个类型的构造函数信息 ConstructorInfo[] tmpConsInfos = tmpType.GetConstructors(); foreach (ConstructorInfo tmpConsInfo in tmpConsInfos) { //为构造函数生成调用的参数集合 ParameterInfo[] tmpParamInfos = tmpConsInfo.GetParameters(); object[] tmpParams = new object[tmpParamInfos.Length]; for (int i = 0; i < tmpParamInfos.Length; i++) { tmpParams[i] = tmpAss.CreateInstance(tmpParamInfos[i].ParameterType.FullName); if (tmpParamInfos[i].ParameterType.FullName == &quot;System.String&quot;) { tmpParams[i] = &quot;Clark&quot;; } } //实例化对象 object tmpObj = tmpConsInfo.Invoke(tmpParams); Console.WriteLine(tmpObj); //获取所有方法并执行 foreach (MethodInfo tmpMethod in tmpType.GetMethods()) { //为方法的调用创建参数集合 tmpParamInfos = tmpMethod.GetParameters(); tmpParams = new object[tmpParamInfos.Length]; for (int i = 0; i < tmpParamInfos.Length; i++) { tmpParams[i] = tmpAss.CreateInstance(tmpParamInfos[i].ParameterType.FullName); if (tmpParamInfos[i].ParameterType.FullName == &quot;System.String&quot;) { tmpParams[i] = &quot;Clark Zheng&quot;; } if (tmpParamInfos[i].ParameterType.FullName == &quot;System.Int32&quot;) { tmpParams[i] = 27; } } tmpMethod.Invoke(tmpObj, tmpParams); } //调用完方法后再次打印对象,比较结果 Console.WriteLine(tmpObj); } } Console.ReadLine(); } } }
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论