scarroot

立志于开发稳定,高性能,容易维护的系统. 追求系统模块化设计,精简与强大的内核框架,可插拔的功能模块

 

重读 c#入门经典 (2)

重读 c#入门经典 (2) [1-13] 基础知识

 

P58:

在switch 中用 return语句,中断当前函数的运行,远胜于中断switch结构的执行.

P59:

const int i=2; (对)

------

const int i;

i=2;

(错)

--------------------------------------------

枚举:http://www.cftea.com/c/2008/02/I2Y6LWL02XCILMWE.asp

http://blog.csdn.net/williamzao/archive/2008/03/02/2139648.aspx

enum Color: long
{
 Red,
 Greeen,
 blue
}

 

[Flags]
public enum WindowStyle
{
    MINIMUM_BUTTON = 1, //十六进制表示为 0x0001
    MAXIMUM_BUTTON = 2,
    CLOSE_BUTTON = 4
}
我们在设置窗口样式时,利用 OR 自由组合:

WindowStyle ws = WindowStyle.MINIMUM_BUTTON | WindowStyle.CLOSE_BUTTON; //表示既有 MINIMUM_BUTTON 也有 CLOSE_BUTTON
这就是为什么标志的值要按 2 的幂排列的原因了,也是为什么标志多于 32 个时不能使用 int 类型的原因了。

通常我们为常用的标志组合提供特殊的枚举值

仍然以上述窗口为例,可知大多数情况下,我们均要显示这三个按钮,所以每次使用时都要用:

WindowStyle ws = WindowStyle.MINIMUM_BUTTON | MAXIMUM_BUTTON | WindowStyle.CLOSE_BUTTON;
实在有些繁琐,我们可以修改枚举为如下:

[Flags]
public enum WindowStyle
{
    MINIMUM_BUTTON = 1,
    MAXIMUM_BUTTON = 2,
    CLOSE_BUTTON = 4,
    ALL_BUTTON = 7
}
增加一个 ALL_BUTTON 为前三个标志的值。使用时直接用 ALL_BUTTON 就可以了

--------------------------

 

P88:

int[] myIntArray = {5,5,8,7,89,4};

---------------

int[] myIntArray = new int[5];

这里使用关键字 new 显式地初始化数组,用一个常量定义其大小,这种方式会给所有的数组元素赋予同一个默认值,对于数值类型来说,其默认值是0;

----------------------------------

 

p92 p93 多维数组,数组的数组.

            int[,] iAry = { {1,2,3},{4,8,9},{5,4,8}};

               //这里不用嵌套
            foreach (int j in iAry)
            {
                Console.WriteLine(j.ToString() + ",");

            }

-----------------

int[][] i;
            i = new int[2][3];

--错

int[][] i={{1,1},{2,2},{1,3}};

--错

初始化数组的数组(锯齿数组)应该这样:

            int[][] i;
            i = new int[2][];
            i[0] = new int[10];
            i[1] = new int[5];

i = new int[2][] { new int[]{1,2,1},new int[]{5,4,4}};

int[][] i = new int[2][] { new int[]{1,2,1},new int[]{5,4,4}};

int[][] i = { new int[]{1,2,1},new int[]{5,4,4}};

------------------------------------------------------

p108:

params 参数必须是形参的最后一个参数.

 

        private void button1_Click(object sender, EventArgs e)
        {
            Doit(1, 2, 3, 3, 4, 4, 23.0,"sf",32);
        }

        public void Doit(params object[] oParam)
        {
            int iSum = 0;
            foreach (object o in oParam)
            {
                if (o is int)
                {
                    iSum += Convert.ToInt32(o);
                }
            }

            Console.WriteLine(iSum.ToString());
        }

 

p109:

out与ref 区别

 

方法参数上的 out 方法参数关键字使方法引用传递到方法的同一个变量。当控制传递回调用方法时,在方法中对参数所做的任何更改都将反映在该变量中。 
当希望方法返回多个值时,声明 out 方法非常有用。使用 out 参数的方法仍然可以返回一个值。一个方法可以有一个以上的 out 参数。 
若要使用 out 参数,必须将参数作为 out 参数显式传递到方法。out 参数的值不会传递到 out 参数。 
不必初始化作为 out 参数传递的变量。然而,必须在方法返回之前为 out 参数赋值。 
属性不是变量,不能作为 out 参数传递。 

        方法参数上的 ref 方法参数关键字使方法引用传递到方法的同一个变量。当控制传递回调用方法时,在方法中对参数所做的任何更改都将反映在该变量中。 
若要使用 ref 参数,必须将参数作为 ref 参数显式传递到方法。ref 参数的值被传递到 ref 参数。 
传递到 ref 参数的参数必须最先初始化。将此方法与 out 参数相比,后者的参数在传递到 out 参数之前不必显式初始化。 
属性不是变量,不能作为 ref 参数传递。 

两者都是按地址传递的,使用后都将改变原来的数值.rel可以把参数的数值传递进函数,但是out是要把参数清空,就是说你无法把一个数值从out传递进去的,out进去后,参数的数值为空,所以你必须初始化一次

rel是有进有出,out是只出不进

 p163 引用类型与值类型比较

http://www.tracefact.net/CSharp-Programming/Type-Fundamentals.aspx

http://www.cnblogs.com/lynnlin/archive/2008/11/18/1335741.html

 

 string 类型精讲

http://www.cnblogs.com/isline/archive/2009/02/04/1383835.html

http://www.cnblogs.com/KissKnife/archive/2008/10/25/1319352.html

String.Intern 方法

返回值

类型:System..::.String
如果 str 的值已经留用,则返回系统的引用;否则返回对带有 str 值的字符串的新引用。

事实上这里涉及到一个所谓的“字符串留用”机制,根据Jeffrey Richter在《框架设计:CLR via C#》中所说,CLR存在一种机制,当它初始化时,它会创建一个内部哈希表,此表中key是字符串,value是对托管堆中的string对象的引用。当定义一个string 时,就会在内部哈希表中检查是否有相匹配的。如果不存在完全相同的字符串,就创建字符串副本,将字符串副本添加到内部哈希表中,并返回这个副本的引用。如果存在完全相同的字符串,就返回对现有字符串的引用。

 深度拷贝与浅度拷贝

http://www.tracefact.net/CSharp-Programming/Type-Fundamentals.aspx

 

 

 p177,p178

构造函数

p180 vs ide 中的符号.

 

 

public
private
internal
protected
abstract :抽象,没有方法体的虚拟
virtual :可以被重写的方法.虚拟


多态:
编绎时多态:重载(overload)
运行时多态:覆写(overrite)(重写)


封装性最有用的方式之一
实现方法--访问限制修饰符
public 无限制,允许任何人来访问
protected internal  = protected + internal
Internal 允许项目或程序内部的类来访问
protected 继承时子类可以对基类有完全访问权
private 只允许同一个类中的成员访问
属性和索引器也用来封装类的细节,并提供公用接口给该类的用户


防止继承
public sealed class XX


只有虚方法和抽象方法才能被覆写
要求: (三相同)
相同的方法名称
相同的参数列表
相同的返回值类型

抽象方法是必须被派生类覆写的方法。
抽象方法是可以看成是没有实现体的虚方法
如果类中包含抽象方法,那么类就必须定义为抽象类,不论是否还包含其它一般方法
publc abstract bool Withdraw(…);

 

 p207:嵌套类的功能主要用于定义对于其包含类来说是私有的类,这样命名空间中的其他代码就不能访问它.

 

 p208:实现接口的类必须包含该接口所有成员的执行代码,且必须匹配指定的签名(包括匹配指定的get和set块),并且必须是公共的.

显式实现接口的话,只能使用接口变量调用方法;非显式的话,还可以通过类的实例对接口定义的方法进行调用(也可以用接口变量)

     public interface IMyInterface
    {
       
void Print();
    }

   
class MyClass : IMyInterface
    {
       
void IMyInterface.Print()//显式实现接口
        {
            Console.WriteLine(
"Print--------------");
        }
    }

调用:

IMyInterface my = new MyClass();
my.Print();

------------------

    public interface IMyInterface
    {
        void Print();
    }
    public class MyClass : IMyInterface
    {
        public void Print()
        {
            Console.WriteLine("Print--------------");
        }
        public string ssss = "";
    }

调用:

            IMyInterface my = new MyClass();
            my.Print();

            MyClass my = new MyClass();
            my.Print();

 

http://www.builder.com.cn/2008/0521/872547.shtml

---------------------------------------------------------


 11章:集合比较转换

哈希函数是一个映象,即:将关键字的集合映射到某个地址集合上,它的设置很灵活,只要这个地址集合的大小不超出允许范围即可。

散列表(也叫哈希表),是根据关键码值直接进行访问的数据结构,也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表.

强类型:

 所谓的强类型对象就是说声明一个对象必须要有一个特定的类型,比如int i = 1; string s ="123";,强类型是对应弱类型而言的,比如javascript就是弱类型,声明一个int变量与声明一个字符串类型都是一样的var i = 1;  var s = "123";

C#本身是一种强类型的语言。
所以这类语言中,所有建立的对象都要声明类型

强类型,就是对变量指定数据类型。

c#中所变量都是指定类型的,所以大家都说 all 。

 -----------------------------------------

索引:

http://www.goalercn.com/article.php?id=1620

定义索引指示器时,可以带有多个参数,每个参数的类型可以不同。添加的参数由逗号隔开,同方法中的的参数表一样。索引指示器的合法的参数类型包括:整型,枚举类型和字符串。另外,索引指示器也可以被重载

public object this[int param1, ..., int paramN]
{
get
{
// process and return some class data
}
set
{
// process and assign some class data
}
}

----------------------------------------

 迭代器Iterators

 

迭代器是 C# 2.0 中的新功能。迭代器是方法、get 访问器或运算符,它使您能够在结构中支持 foreach 迭代,而不必实现整个 IEnumerable 接口。您只需提供一个迭代器,即可遍历类中的数据结构。当编译器检测到迭代器时,它将自动生成 IEnumerableIEnumerable<T> 接口的 CurrentMoveNextDispose 方法。

迭代器概述

  • 迭代器是可以返回相同类型的值的有序序列的一段代码。

  • 迭代器可用作方法、运算符或 get 访问器的代码体。

  • 迭代器代码使用 yield return 语句依次返回每个元素。yield break 将终止迭代。有关更多信息,请参见 yield

  • 可以在类中实现多个迭代器。每个迭代器都必须像任何类成员一样有唯一的名称,并且可以在 foreach 语句中被客户端代码调用,如下所示:foreach(int x in SampleClass.Iterator2){}

  • 迭代器的返回类型必须为 IEnumerableIEnumeratorIEnumerable<T> 或 IEnumerator<T>。

yield 关键字用于指定返回的值。到达 yield return 语句时,会保存当前位置。下次调用迭代器时将从此位置重新开始执行。

迭代器对集合类特别有用,它提供一种简单的方法来迭代不常用的数据结构(如二进制树)。

 

示例

在本示例中,DaysOfTheWeek 类是将一周中的各天作为字符串进行存储的简单集合类。foreach 循环每迭代一次,都返回集合中的下一个字符串。

public class DaysOfTheWeek : System.Collections.IEnumerable
{
string[] m_Days = { "Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat" };
public System.Collections.IEnumerator GetEnumerator()
{
for (int i = 0; i < m_Days.Length; i++)
{
yield return m_Days[i];
}
}
}
class TestDaysOfTheWeek
{
static void Main()
{
// Create an instance of the collection class
DaysOfTheWeek week = new DaysOfTheWeek();
// Iterate with foreach
foreach (string day in week)
{
System.Console.Write(day + " ");
}
}
}

输出

Sun Mon Tue Wed Thr Fri Sat
-----------------------------
is 运算符
<operand> is <type>
这个表达式的结果如下:
.如果<type>是一个类类型,而<operand>也是该类型,或者它继承了该类型,或者它封箱到该类型中,则结果为true;
.如果<type>是一个接口类型,而<operand>也是该类型,或者它是实现该接口的类型,则结果为true;
.如果<type>是一个值类型,而<operand>也是该类型,或者它被拆箱到该类型中,则结果为true;
 
 ----------------
运算符重载,
必须为static,注意书写格式,有些必须一起重载,如true/false.

        public static C1 operator +(C1 a, C1 b)
        {
            C1 t = new C1();
            t.TestTest = a.TestTest + b.TestTest;
            return t;
        }

        public static bool operator true(C1 p)
        {
            return p.TestTest >= 0;
        }

        public static bool operator false(C1 p)
        {
            return p.TestTest < 0;
        }

--------------------------

IComparable

(obj.CompareTo(object o))

,IComparer

(obj.Compare(object x,object y)

http://space.itpub.net/12639172/viewspace-483585

----------------------------------------

 显式转换:explicit

隐式转换:implicit

http://www.cnblogs.com/jonney/archive/2007/04/17/716645.html

--------------------------

p267

as 运算符:适用于:

<operand> as <type>

1,<operand>的类型是<type>类型.

2,<operand>可以隐式转换为<type>类型.

3,<operand>可以封箱到类型<type>中.

如果不能从<operand>转换为<type>,则表达式的结果就是null.

 

 

 

posted on 2009-02-16 11:59  scarroot  阅读(328)  评论(0编辑  收藏  举报

导航