C#-二十五问总结

/***********************************************
 * 静态变量
 *        在所属类装载时被创建;
 *        通过类(注意,是类,不是类的对象)进行访问;
 *        自始自终只存在一个值.
**********************************************
*/

namespace  重要小知识点  // 静态变量
{
    
class Program
    
{
        
static int staNum = 0//静态成员
        public int pubNum = 10//类成员
        static void Main(string[] args)
        
{
            Program p 
= new Program();
            p.pubNum 
= 100//使用对象 访问类成员
            Program.staNum = 999;  //使用类名 访问静态成员
        }

    }

}





/***********************************************
 * const 和 static readonly
 * const 是在编译期间初始化
 * static readonly 是在运行期间初始化
 * 实验见 "C#基础概念二十五问"
**********************************************
*/

namespace  重要小知识点  // const 和 static readonly
{
    
class Program
    
{
        
public const int conNum = 100;
        
public static readonly int srNum = 10000;

        
static void Main(string[] args)
        
{
            Console.WriteLine(Program.conNum);    
//调用方法一样
            Console.WriteLine(Program.srNum);    //调用方法一样    
        }

    }

}




/***********************************************
 * abstract
 *        此修饰可以用于类、方法、属性、事件和索引指示器.
 * 下面一段程序中需要注意的
 *        抽象类中定义了一个Attribute,但它并不需要知道这是谁的属性;
 *        事件的定义方法,事件的响应函数,怎样触发一个事件;
 *        索引,可以对"对象"进行索引,也可以针对"成员"进行索引.
**********************************************
*/

namespace  重要小知识点  // abstract
{
    
class Program
    
{
        
public abstract class AMedia //抽象类
        {
            
public abstract string Attribute //属性
            {
                
get;
                
set;
            }

            
public abstract event EventHandler Play; //事件 注意写法
            public abstract void Response();
            
public abstract string this[int Index] //索引 注意写法
            {
                
get;
            }

        }

        
public class Mp3 : AMedia
        
{
            
//注意父抽象类,里面虽然有 Attribute属性,但却不需要定义 attribute变量
            private string attribute;
            
public override string Attribute //属性
            {
                
get
                
{
                    
return attribute;
                }

                
set
                
{
                    attribute 
= value;
                }

            }

            
public override event EventHandler Play; //事件
            public override void Response()
            
{
                
if (Play != null)
                
{
                    Play(
thisnew EventArgs());
                }

            }

            
public override string this[int Index] //索引
            {
                
get
                
{
                    
switch (Index)
                    
{
                        
case 1:
                            
return "one";
                        
case 2:
                            
return "two";
                        
case 3:
                            
return "three";
                        
default:
                            
return "rand";
                    }

                }

            }

        }

        
static void OnPlay(object sender, EventArgs e)
        
{
            Console.WriteLine(
" Mp3 is playing...");
        }

        
static void Main(string[] args)
        
{
            Mp3 mp3 
= new Mp3();
            mp3.Attribute 
= " HelloWorld!"//使用属性
            Console.WriteLine(mp3.Attribute);

            mp3.Play 
+= new EventHandler(OnPlay); //与响应函数关联
            mp3.Response();//触发事件

            
int i = 0;
            
for (i = 0; i < 4; i++)
            
{
                Console.WriteLine(mp3[i]); 
//索引(针对 对象)
            }

            
for (i = 0; i < mp3.Attribute.Length; i++)
            
{
                Console.WriteLine(mp3.Attribute[i]); 
//索引(针对 属性)
            }

        }

    }

}





/***********************************************
 * sealed 密封
 *    1)    用于类时,该类不能再被继承;(不能和abstract同用)
 *    2)    用于方法和属性时,该方法和属性不能被继承,必须和override
 *        连用,使用sealed修饰的方法肯定是基类中的    虚成员.
**********************************************
*/

namespace  重要小知识点  // sealed
{
    
class Program
    
{
        
static void Main(string[] args)
        
{
            A a 
= new A();
            a.ShowMe();
            B b 
= new B();
            b.ShowMe();
        }

    }

    
sealed class SealSelf //此类无法再被继承
    { }

    
class A
    
{
        
public virtual void ShowMe()
        
{
            Console.WriteLine(
"I am A.");
        }

    }

    
class B : A
    
{
        
//密封的肯定是基类中的虚成员
        public sealed override void ShowMe() //密封
        {
            Console.WriteLine(
"I am B.");
        }

    }

    
class C : B
    
{
    }

}




/***********************************************
 * 索引指示器
 *        可以像数组那样使用其实例后的对象,但与数组不同的是
 * 索引指示器的参数类型不仅限于int.
**********************************************
*/

namespace  重要小知识点
{
    
class Program
    
{
        
private string secret;
        
static void Main(string[] args)
        
{
            Program pro 
= new Program();
            pro.Secret 
= "ILOVEU";
            
for (int i = 0; i < pro.Secret.Length; i++//对类成员的索引操作
            {
                Console.WriteLine(pro.Secret[i]);
            }

        }

        
public string this[int Index] //不仅限于int,可以是string Index等等
        {
            
get
            
{
                
return secret;
            }

        }

        
public string Secret
        
{
            
get
            
{
                
return secret;
            }

            
set
            
{
                secret 
= value;
            }

        }

    }

}



/***********************************************
 * this
 * 关注该程序是如何测试效率的!
 * Environment.TickCount
**********************************************
*/

namespace  重要小知识点
{
    
class Program
    
{
        
private string value;
        
static void Main(string[] args)
        
{
            Program pro 
= new Program();
            Console.WriteLine(pro.Test1());
            Console.WriteLine(pro.Test2());
        }

        
public string Test1()
        
{
            
long vTickCnt = Environment.TickCount;
            
for (int i = 0; i < 10000000; i++)
            
{
                
this.value = i.ToString(); //使用this调用成员
            }

            
return string.Format("Have this.:: {0} MSEL", Environment.TickCount - vTickCnt);
        }

        
public string Test2()
        
{
            
long vTickCnt = Environment.TickCount;
            
for (int i = 0; i < 10000000; i++)
            
{
                value 
= i.ToString(); //不使用this调用成员
            }

            
return string.Format("Have this.:: {0} MSEL", Environment.TickCount - vTickCnt);
        }

    }

}



/***********************************************
 * 可以使用抽象函数重写基类中的虚函数吗?
 * 答:可以.   需要使用 new 修饰符显式声明.
 * new:隐藏了基类中该函数的实现.
 * override:重新了基类中的函数.
**********************************************
*/

namespace  重要小知识点
{
    
class Program
    
{
        
static void Main(string[] args)
        
{
        }

    }

    
class Base
    
{
        
public virtual void Show()
        
{
            Console.WriteLine(
"I am Base...");
        }

    }

    
abstract class Son : Base
    
{
        
public new abstract void Show();
    }

}



/***********************************************
 * 密封类可以有虚函数吗?
 * 答:可以.   但基类中的虚函数隐式转换成非虚函数.
**********************************************
*/

namespace  重要小知识点
{
    
class Program
    
{
        
static void Main(string[] args)
        
{
        }

    }

    
class Base
    
{
        
public virtual void Show()
        
{
            Console.WriteLine(
"I am Base...");
        }

    }

    
sealed class Son : Base
    
{
        
// Base中的虚函数Show()已隐式转换为非虚函数了.
        
//Son类不能自己再定义虚函数!
    }

}




/***********************************************
 * 类和结构的区别
 *       类是引用类型,在堆上分配,类的实例进行赋值其实只是复
 * 制了引用;
 *       结构是值类型,在栈上分配,结构的赋值操作将产生一个新
 * 对象.
 * 
 * 堆和栈
 *     堆:需要手动释放. 如类,如new
 *     栈:系统自动释放. 如函数里的变量
**********************************************
*/

namespace  重要小知识点
{
    
class Program
    
{
        
static void Main(string[] args)
        
{
            OwnClass oc 
= new OwnClass("Hello");
            OwnStruct os 
= new OwnStruct("Hello");
        }

    }

    
class OwnClass
    
{
        
private string secret;
        
public OwnClass(string str)
        
{
            
//注意,这里的赋值操作. str 是一个引用类型,
            
//所以不要再分配内存空间.
            this.secret = str;
        }

    }

    
struct OwnStruct
    
{
        
private string secret;
        
//结构也可以有构造函数,但必须是有参数的构造函数.
        public OwnStruct(string str)
        
{
            
//注意,这里的赋值操作. str 并非是一个引用类型,
            
//所以得为它再分配内存空间.
            this.secret = str;
        }

    }

}




/***********************************************
 * 接口的多继承会带来哪些问题?
 * 答:如果两个或多个父接口中存在同名成员,就产生二义性.
 *     此时,最好使用显式声明.
**********************************************
*/

namespace  重要小知识点
{
    
class Program : Video, Audio
    
{
        
void Video.Play() //显式声明
        {
            Console.WriteLine(
"Video is working...");
        }

        
void Audio.Play() //显式声明
        {
            Console.WriteLine(
"Audio is working...");
        }

        
static void Main(string[] args)
        
{
            Program pro 
= new Program();
            
//注意如何调用
            Video v = (Video)pro; //显示转换
            v.Play();
            Audio a 
= (Audio)pro; //显示转换
            a.Play();
        }

    }

    
interface Video
    
{
        
void Play();
    }

    
interface Audio
    
{
        
void Play();
    }

}




/***********************************************
 * 抽象类和接口的区别:
 *     抽象类可以包含 定义 和 实现;
 *     接口只可以包含 定义.
 * 
 *        抽象类是从一系列对象中抽象出来的概念,因此反映事物
 * 的内部共性;
 *        接口是为了满足外部调用而定义的一个功能约定,因此反
 * 映的是事物的外部特性.
 * 
 *        分析对象,提炼内部共性形成抽象类,用以表示对象本质,
 * 即"是什么";
 *        为外部提供调用或功能需要扩充时优先使用接口.
**********************************************
*/

namespace  重要小知识点
{
    
class Program
    
{
        
static void Main(string[] args)
        
{
        }

    }

    
abstract class Base
    
{
        
public abstract void Show();
        
public void Hide() //抽象类可以有已实现的成员
        {
            Console.WriteLine(
"have hided...");
        }

    }

    
class Son : Base
    
{
        
public override void Show()
        
{
            Console.WriteLine(
"I am Base's son...");
        }

    }

}



/***********************************************
 * using 别名指示符
 *     包含其它文件,为某个类型起个别名;
 *     只在一个单元文件内起作用.
**********************************************
*/

namespace  重要小知识点
{
    
class Program
    
{
        
static void Main(string[] args)
        
{
            T1.Test1 t1 
= new T1.Test1(); //T1 是 Test1.cs 的别名
            t1.Show();
            T2.Test2 t2 
= new T2.Test2();
            t2.Show();
        }

    }

}




/***********************************************
 * StringBuilder和String的区别
 * String虽然是引用类型,但在赋值时却会产生新的对象;
 * StringBuilder则不会,所以在处理大量字符串时,它是首选.
**********************************************
*/

namespace  重要小知识点
{
    
class Program
    
{
        
static void Main(string[] args)
        
{
            Program pro 
= new Program();
            pro.Test1();
            pro.Test2();
        }

        
public void Test1()
        
{
            
long vTickCnt = Environment.TickCount;
            
string str = null;
            
for (int i = 0; i < 20000; i++)
            
{
                str 
+= i.ToString();
            }

            Console.WriteLine(
"string 字符串相加需要 {0} 毫秒", Environment.TickCount - vTickCnt);
        }

        
public void Test2()
        
{
            
long vTickCnt = Environment.TickCount;
            StringBuilder sb 
= new StringBuilder();
            
for (int i = 0; i < 20000; i++)
            
{
                sb.Append(i);
            }

            Console.WriteLine(
"StringBuilder 字符串相加需要 {0} 毫秒", Environment.TickCount - vTickCnt);
        }

    }

}





/***********************************************
 * params
 *        该关键字用在方法的参数列表中,为该方法参数提供了可
 * 变的能力.它只能出现一次,且只能定义在所有参数最后.
**********************************************
*/

namespace  重要小知识点
{
    
class Program
    
{
        
//params 定义的参数后面不可以再定义其它参数
        public static void UseParams(string str, params object[] list)
        
{
            Console.WriteLine(str);
            
for (int i = 0; i < list.Length; i++)
            
{
                Console.WriteLine(list[i]);
            }

        }

        
static void Main(string[] args)
        
{
            String[] str 
= new string[] "I""LOVE""YOU" };
            Program.UseParams(
"Hello", str);
        }

    }

}
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值