C#编程解惑

1、类中静态构造函数的说明

  • 静态构造函数只能执行一次;
  • 静态构造函数不能有访问修饰符;
  • 静态构造函数先于其他构造函数,首先被执行;
  • 静态构造函数必须无参数;

2、静态构造函数直接实用类调用的时候就会被调用;当然创建实例的时候也会调用;

  class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(MyTest.str);
            Console.ReadLine();
        }
    }

    public class MyTest
    {
        public static string str = "123";
        static MyTest()
        {
            Console.WriteLine("hehe");
        }
    }

  

3、子类构造函数和父类构造函数的执行顺序问题,代码如下,eg:

 1  class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             new B();
 6             Console.ReadLine();
 7         }
 8     }
 9 
10     class A
11     {
12         public A()
13         {
14             PrintFields();
15         }
16         public virtual void PrintFields() { }
17     }
18     class B : A
19     {
20         private int x = 1;
21         private int y;
22         public B()
23         {
24             y = -1;
25         }
26 
27         public override void PrintFields()
28         {
29             Console.WriteLine("x={0},y={1}", x, y);
30         }
31     }

结果是x=1,y=0,下面讲解一下,当我们创建B类对象的时候,我们先会给B分配一块内存空间,并且初始化其中的字段,把x,y分别初始化。然后就调用B的无参构造函数,由于是继承自类A,所以这里先调用A类中的构造函数,在调用B类中的构造函数,执行A类中的构造函数就会执行B中重写的PrintFields方法,然后输出字符,接着在调用B中的构造函数为y赋值,把y赋值为-1,但是这个时候语句已经输出了,所以y=-1不会显示出来。所以结果就是x=1,y=0;如果在B类的构造函数中添加一句如下代码:

1 Console.WriteLine("x={0},y={1}", x, y);

那么构造函数中的输出结果就会变成x=1,y=-1了。

 

4、if(a=="")、if(a==String.Empty)、if(a.Length==0)三者之间的性能比较

if(a.Length==0)最快。

那么为什么if(a.Length==0)最快呢? 

因为整数判断等于最快,没有经过实例化等复杂的过程。

 

5、页面之间传值有一个这个方法,Server.Transfer,这个方法性能比Response.Redirect的性能好一些。Response.Redirect请求两次,而Server.Transfer只请求一次;Response.Redirect面向的是任何网址都可以,而Server.Transfer只面对本站中的文件;Response.Redirect跳转页面的时候会改变地址栏地址而Server.Transfer不会改变地址栏地址。下面讲解一下如何使用Server.Transfer,eg:

Index主页,点击button按钮的时候跳转到其他页面

public string Name { get { return TextBox1.Text; } }//在页面添加属性方便以后页面访问此属性
protected void Button1_Click(object sender, EventArgs e)
{
    Server.Transfer("about.aspx");
}

About页面

 protected void Page_Load(object sender, EventArgs e) { _Default df = (_Default)Context.Handler; Response.Write(df.Name); } 

 

6、一个静态类中只能有静态方法、属性、索引器等,不能有实例方法,也不可以有virtual、abstract等方法,因为静态类就是一个工具类,所以不能有上面的那些东西。

 

7、泛型约束条件可以有多个,class约束代表引用约束、struct代表值类型约束、new ()代表的是有一个无参构造函数的约束。代码如下,eg:

a、简单情况约束

1  interface IMyInterface<T> where T:struct,IComparable//struct 是值类型约束不是结构体,class、 struct类型约束要放在所有约束的最前面,class约束是引用类型约束

 b、有多个类型参数,有多个约束的情况,eg:

1  interface IMyInterface<T, U>
2         where T : class, IComparable
3         where U : struct,ICollection<int>
4 {
5 
6 }

其中T参数必须是引用类型的同时T类型的参数必须实现IComparable接口,U类型参数必须是值类型,并且必须实现ICollections<int> 这个泛型接口。

c、类型约束中的第二个参数是受第一个参数约束的情况,eg:

1 interface IMyInterface<T, U>
2         where T:IComparable
3         where U : T,new ()
4 {
5 
6 }

U类型参数必须继承自T类型,并且U类型必须有一个默认的构造函数。

8、Trim函数的特殊使用,Trim函数除了有去空格的作用还可以替换原有字符串中的特定字符,代码如下,eg:

1 string str = "yesbyesseyaseyys";
2 string result = str.Trim('y', 'e', 's');//这行代码就是把str中的开头和结尾包含yes的所有字母都递归替换掉,直到没有遇到这个字符为止。
3 Console.WriteLine(result);
4 Console.ReadLine();

运行结果:“byesseya”

 

9、IEnumerable接口的数据和List集合数据

IEnumerable接口的数据只能通过foreach遍历而不能通过for来循环遍历;所以IEnumerable接口的数据也没法修改。但是list集合数据却可以。

 

10、以前比较两个对象通常会实现下面两个接口,代码如下,eg:

 1     class Person :IComparer
 2     {
 3         public int Age { get; set; }
 4         public string Name { get; set; }
 5 
 6         public int Compare(object x, object y)
 7         {
 8             throw new NotImplementedException();
 9         }
10     }
11 
12     class Anminal :IComparable
13     {
14         public int Age { get; set; }
15         public string Name { get; set; }
16         public int CompareTo(object obj)
17         {
18             throw new NotImplementedException();
19         }
20     }

我们可以看到其中的方法都是object类型,几乎每一次计算的时候都得进行类型转换。这个时候我们就可以使用泛型接口了,具体代码如下,eg:

实现IComparable接口

 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             Person person1 = new Person();
 6             person1.Age = 20;
 7             Person person2 = new Person();
 8             person2.Age = 30;
 9             Person person3 = new Person();
10             person3.Age = 15;
11             List<Person> list = new List<Person>();
12             list.Add(person1);
13             list.Add(person2);
14             list.Add(person3);
15             foreach (var A in list)
16             {
17                 Console.WriteLine(A.Age);
18             }
19             list.Sort();
20             foreach (var A in list)
21             {
22                 Console.WriteLine(A.Age);
23             }
24             Console.ReadLine();
25         }
26     }
27     class Person : IComparable<Person>
28     {
29         public int Age { get; set; }
30         public string Name { get; set; }
31 
32         public int CompareTo(Person other)
33         {
34             return this.Age - other.Age;
35         }
36     }

实现IComparer接口

 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             Person person1 = new Person();
 6             person1.Age = 20;
 7             Person person2 = new Person();
 8             person2.Age = 30;
 9             Person person3 = new Person();
10             person3.Age = 15;
11             List<Person> list = new List<Person>();
12             list.Add(person1);
13             list.Add(person2);
14             list.Add(person3);
15             foreach (var A in list)
16             {
17                 Console.WriteLine(A.Age);
18             }
19             list.Sort(new Person());//此处参数为实现了IComparer接口的对象(也可以传递person1、person2、person3等对象)。
20             foreach (var A in list)
21             {
22                 Console.WriteLine(A.Age);
23             }
24             Console.ReadLine();
25         }
26     }
27     class Person :IComparer<Person>
28     {
29         public int Age { get; set; }
30         public string Name { get; set; }
31 
32         public int Compare(Person x, Person y)
33         {
34             return x.Age - y.Age;
35         }
36     }

 

11、委托Action委托和Action<>是不同的两中,Action是无参无返回值的而,Action<>是有参数无返回值的委托。代码如下,eg:

1 Action action = new Action(() => { Console.WriteLine("234"); });
2 Action<int> action1 = new Action<int>(x => { Console.WriteLine("234"); });

 

12、Predicate表示的是一个参数一个bool返回值,代码如下,eg:

Predicate<int> pre = new Predicate<int>(x => x == 3);

 

13、Func中的参数列表是最后一个参数是返回类型,其他都是输入参数,我们最多可以输入16个参数,具体代码如下,eg:

Func<int, string, string> func = new Func<int, string, string>((x, y) => x.ToString() + y);

上面代码最后一个string 是返回值类型,前两个int 和string 是输入参数。

 

14、Func<>和Action<>最多只能有16个输入参数。如果还是不能满足需求的话,就需要自己写了,通过上面的代码我们知道了以后基本上我们都可以不用写委托了,因为上面的三种委托已经够我们使用了。

15、老长时间没有使用WinForm的用户自定义控件,WinForm的用户自定义控件和WebForm的用户自定义控件使用上有点区别,WebForm创建完了用户自定义控件之后就可以拖拽到页面上使用而WinForm必须是先创建用户自定义控件,然后编译程序,才会在工具箱位置生成相对应的自定义控件,这个时候我们才可以去拖拽到页面上去使用。

posted @ 2015-04-24 09:50  我的___爱  阅读(173)  评论(0)    收藏  举报