c# 入门学习

1.在 C# 中,使用 ref 关键字声明引用参数。

说明变量是引用,在调用该方法时,还需要添加ref关键字。

 public void swap(ref int x, ref int y)
 {
 }

swap(ref x, ref y);

2. out 按输出传递参数
return 语句可用于只从函数中返回一个值。但是,可以使用 输出参数 来从函数中返回两个值。输出参数会把方法输出的数据赋给自己,其他方面与引用参数相似。

在方法的输入参数前面加上 out前缀时 ,传递给该方法的变 量可以不初始化.在调用该方法时 ,还 需要使用 out关 键字 ,

public void getValues(out int x, out int y )
{

}

getValues(out x, out y);

3.C# 属性(Property)
属性(Property) 是类(class)、结构(structure)和接口(interface)的命名(named)成员。类或结构中的成员变量或方法称为 域(Field)。
属性(Property)是域(Field)的扩展,且可使用相同的语法来访问。
它们使用 访问器(accessors) 让私有域的值可被读写或操作。
属性(Property)不会确定存储位置。相反,它们具有可读写或计算它们值的 访问器(accessors)。
例如,有一个名为 Student 的类,带有 age、name 和 code 的私有域。
我们不能在类的范围以外直接访问这些域,但是我们可以拥有访问这些私有域的属性.

get访 问器不带任何参数 ,且 必须返回属性声明的类型。也不应为 set  访问器指定任何显式参数
,
但编译器假定它带一个参数 ,其 类型也与属性相同 ,并 表示为 value
也可以把属性声明为 virtual。

   class Student
   {
      private string code = "N.A";

      // 声明类型为 string 的 Code 属性
      public virtual string Code
      {
         get
         {
            return code;
         }
         set
         {
            code = value;
         }
      }
   }
         Student s = new Student();           
         // 设置 student 的 code、name 和 age
         s.Code = "001";

4.静态构造函数

c#一个新特征是也可以给类编写无参数的静态构造函数。这种构造函数只执行一次 ,而 前面
的构造函数是实例构造函数 ,只 要创建类的对象 ,就 会执行它.
编写静态构造函数的一个原因是 ,类 有一些 静态字段 或属性 ,需 要在第1 使用类之前 ,从
部源中初始化这些静态字段和属性.即 初始化静态变量
态构造函数没有访问修饰符 ,其 他 C#代码从来不调用它.
态构造函数不能带任何参数,一个类也只能有一个静态构造函数.
态构造函数只能访问类的 静态成员,不 能访问类的实例成员。
cl ass MyClass
{
  static MyC1ass()
  {
  }
}
5.只读字段readonly
readonly关 键字比 const  灵活得多 ,允 许把一个字段设置为常量 ,但 还需要执行一些计算 ,以
定它的初始值。其规则是可以在构造函数中给只读字段赋值 ,但 不能在其他地方赋值。只读字段还
可以是一个实例字段 ,而 不是静态字段 ,类 的每个实例可以有不同的值
6.结构体和类的区别
a.结构体中声明的字段无法赋予初值,类可以。
b.结构体的 构造函数中,必须为结构体所有字段赋值,类的构造函数无此限制.类的对象是存储在堆空间中,结构存储在栈中.
c.结构体不能显示声明无参数的构造函数, 隐式的无参数的构造函数在结构中无论如何都是存在的.而类一旦我们为这个类写了任意的1个构造函数的时候,这个隐式的构造函数就不会自动生成了。
结构体在无参数的构造函数中为所有的字段赋值,值类型的字段赋值0,给引用类型的字段赋值null。
d.与类不同,结构不能继承其他的结构或类。
e.结构成员不能指定为 abstract、virtual 或 protected。
f.类是 引用 类型,结构是 类型。
struct rectangle
{
   public int nweight;
   public int nheight;
   public rectangle(int weight, int height)
   {
      nweight = weight;
	  nheight = height;
   }   
}

rectangle re = new rectangle();  //调用的就是隐式的无参数的构造函数,
                                 //值类型的字段赋值0,给引用类型的字段赋值null
re.nweight = 1;
re.nheight = 1;

rectangle re = new rectangle(3,5); //调用的就是显式有参数的构造函数

rectangle re2;
int nn = re2.nweight;  //报错,因为此种方式创建结构体对象,没有调用构造函数。需要手动设置 
                         re2.nweight =2;

7.类

有的.net 类都派生自system.object类, 实际上 ,如 果在定义类时没有指定基类 ,编
译器就会 自动假定这个类派生 自 object
唧要求在派生类的函数重写另一个函数时,要 使用 override 键字显式声明。
C++有 一种特殊的语法用于从派生类中调用方法的基类版本:base.
c#支持多接口继承和单一实现继承。不支持多重继承。c++支持多重继承。
多重继承指的是一个类别可以同时从多于一个父类继承行为与特征的功能。与单一继承相对,单一继承指一个类别只可以继承自一个父类。
类是 引用 类型

在C#中实例化一个对象时,需要经历下面这几步:

声明引用;
使用new关键字创建类的对象并对其初始化;(分配内存空间)
将引用指向类的对象。
若没有使用new关键字创建类的实例,则仅仅创建引用,指向的对象为null。

注意:c#的函数中new的的对象不需要手动delete。因为.NET有专门的垃圾收集器。

A a = new A();(1)
B b = null;(2)   声明引用b,并指向null。
C c;(3)    声明的引用c不指向任何对象

     class CWorkbase 
    {
        public virtual void add()
        { 
        }
    }


    class CWorkchild : CWorkbase
    {
        public override void add()
        {
            int a = 1;
            base.add();
        }

    }

抽象类和抽象函数

c#允许把类和函数声明为 abstract 抽象类不能实例化 ,而 抽象函数不能直接实现 ,必 须在非抽
象的派生类中重写。显然 ,抽 象函数本身也是虚拟的 (尽 管也不需要提供 vitrual 键字 ,实 际上 ,如
果提供了该关键字 ,就 会产生一个语法错误 。如果类包含抽象函数,则 该类也是抽象的 ,也 必须声
明为抽象的。
    abstract class Shape
   {
       abstract public int area();
   }
   class Rectangle:  Shape
   {
      private int length;
      private int width;
      public Rectangle( int a=0, int b=0)
      {
         length = a;
         width = b;
      }
      public override int area ()
      {
         Console.WriteLine("Rectangle 类的面积:");
         return (width * length);
      }
   }

在c++中,抽象函数称为纯虚函数。抽象类没有关键字abstract.

密封类和密封方法
c#允许把类和方法声明为 seaIed 对于类,这表示不能继承该类。对于方法,表示不能重写该方法。
要在方法或属性上使用 sealed关键字 ,必 须先从基类上把它声明为要重写的方法或属性。如果
基类上不希望有重写的方法或属性 ,就 不要把它声明为virtual。
    sealed class CWorkbase1
    {
        
    }

    class CWorkbase 
    {
        public virtual void add1()
        {
            int a = 2;
        }

    }


    class CWorkchild : CWorkbase
    {
        public sealed override void add1()
        {
            int a = 3;
        }

    }

8.接口

接口定义了所有类继承接口时应遵循的语法合同。接口定义了语法合同 "是什么" 部分,派生类定义了语法合同 "怎么做" 部分。
接口使用 interface 关键字声明,它与类的声明类似。接口声明默认是 public 的。
不能实例化接口。接口既不能有构造函数,也不能有字段(应该是成员变量吧)
接口成员总是公有的,不能声明为虚拟或静态。

一个接口可以继承其他接口,接口也可以让类来继承。如果一个接口继承其他接口,那么实现类或结构就需要实现所有接口的成员。
不允许提供接口中任何成员的实现方式(即只声明,不实现,实现在继承的类中实现)

using System;
interface IParentInterface
{
    void ParentInterfaceMethod();
}

interface IMyInterface : IParentInterface
{
    void MethodToImplement();
}

class InterfaceImplementer : IMyInterface
{
    static void Main()
    {
        InterfaceImplementer iImp = new InterfaceImplementer();
        iImp.MethodToImplement();
        iImp.ParentInterfaceMethod();
    }

    public void MethodToImplement()
    {
        Console.WriteLine("MethodToImplement() called.");
    }

    public void ParentInterfaceMethod()
    {
        Console.WriteLine("ParentInterfaceMethod() called.");
    }
}

9.泛型

c#泛型和c++的模板相似。

泛型类:

class BaseNode { }
class BaseNodeGeneric { }
 
// concrete type
class NodeConcrete : BaseNode { }
 
//closed constructed type
class NodeClosed : BaseNodeGeneric { }
 
//open constructed type
class NodeOpen : BaseNodeGeneric { }

泛型方法

泛型方法是通过类型参数声明的方法。

static void Swap(ref T lhs, ref T rhs)
{
    T temp;
    temp = lhs;
    lhs = rhs;
    rhs = temp;
}

泛型接口

interface IMonth { }

interface IJanuary : IMonth { }  //No error
interface IFebruary : IMonth { }  //No error
interface IMarch : IMonth { }    //No error
                                     r

泛型委托

10.数组

int[] arr  = new int[3];

Array:

Array 类是 C# 中所有数组的基类。Array类是一个抽象类,所以不能使用构造函数来创建数组.

可以通过调用Array.CreateInstance动态创建一个数组实例。该方法可以在运行时指定元素类型、维数,以及通过指定数组下界来实现非零开始的数组。
GetValueSetValue方法可用于访问动态创建的数组元素(访问普通数组元素亦可)

            Array a = Array.CreateInstance(typeof(string), 2);
            a.SetValue("hi", 0);                             //  → a[0] = "hi";
            a.SetValue("there", 1);                          //  → a[1] = "there";
            string s = (string)a.GetValue(0);               //  → s = a[0];

其他用途是:调用Array 类的方法,如

int[] list = { 34, 72, 13, 44, 25, 30, 10 };
Array.Sort(list);
Array.Reverse(list);

数组的遍历:foreach

       int ncout = 0;
       int[] arr = { 34, 72, 13, 44, 25, 30, 10 };
       foreach(var nvalue in arr)
       {
           ncout += nvalue;
       }

元组

数组合并了相同类型的对象 ,而 元组合并了不同类型的对象.

元组用静态Tuple类的静态create法创建

 Tuple tt = Tuple.Create(1, "hello");

11.运算符

is运算符

is运算符可以检查对象是否与特定的类型兼容。“兼容 ”表示对象或者该类型,或 者派生自该类
型. 
as运算符
as运 算符用于执行 引用类型的显式类型转换 。如果要转换的类型与指定的类型兼容 ,转 换就会
成功进行 ;如 果类型不兼容 ,as运 算符就会返回 null值
     class CWorkbase 
    {

    }

    class CWorkchild : CWorkbase
    {
        public int a;
    }
      
      CWorkchild ch = new CWorkchild();
            ch.a = 2;
            if (ch is CWorkbase)
            { 
                 int asa = 1;
            }

            CWorkbase base11 = ch as CWorkbase;
            if (base11 != null)
            {
                int ss = 1;
            }

12.键盘鼠标事件

都可以通过可视化的方式设置,先自定义后触发事件的函数,然后在可视化属性中设置。

键盘

C#中描述"KeyDown"、"KeyUp"的事件的Delegate是"KeyEventHandler"。而描述"KeyPress"所用的Delegate是"KeyPressEventHandler"。这二个Delegate都被封装在命名空间"Syetem.Windows.Froms"中。为"KeyDown"、"KeyUp"的事件提供数据的类是"KeyEventArgs"。而为"KeyPress"事件提供数据的类是"KeyPressEventArgs"。同样这二者也被封装在命名空间"Syetem.Windows.Froms"中。

一般来说,在键盘按下某个按键,事件处理步骤为:keydown-> keypress -> keyup .若按下的是控制键,则触发的事件过程为keydown -> keyup.

button1. KeyUp += new Syetem.Windows.Froms. KeyEventHandler(button1_KUp);
private void button1_KUp ( object sender , Syetem.Windows.Froms. KeyEventArgs e )
{
此处加入响应此事件的代码
}


button1. KeyPress += new Syetem.Windows.Froms. KeyPressEventArgs(button1_KPress);
private void button1_KPress ( object sender , Syetem.Windows.Froms. KeyPressEventArgs e )
{
此处加入响应此事件的代码
}

鼠标:

将鼠标指针移向控件时会触发MouseEnter事件,在控件上移动鼠标会不断触发mosemove事件,鼠标指针停驻在控件上不动会触发mousehover事件,在控件上单击鼠标按键或者滚动鼠标滚轮会触发mousedown和mousewheel事件,放开鼠标时会触发mouseup事件,离开控件时则触发mouseleave事件。

单击控件,所触发的事件如下:

1.mousedown事件

2.click

3.mouseclick

4.mouseup

在C#中是通过不同的Delegate来描述上述事件,其中描述"MouseHover"、"MouseLeave"、"MouseEnter"事件的Delegate是"EventHandler",而描述后面的三个事件的Delegate是"MouseEventHandler"来描述。这二个Delegate分别被封装在不同的命名空间,其中"EventHandler"被封装在"System"命名空间;"MouseEventHandler"被封装在"Syetem.Windows.Froms"命名空间中的。在为"MouseHover"、"MouseLeave"、"MouseEnter"事件通过数据的类是"EventArgs",他也被封装在"System"命名空间中;而为后面的三个事件提供数据的类是"MouseEventArgs",他却被封装在"Syetem.Windows.Froms"命名空间。

button1.MouseLeave += new Syetem.EvenHandler(button1_MLeave); 
private void button1_MLeave ( object sender , System.EventArgs e )
{
此处加入响应此事件的代码
}


button1.MouseMove += new System.Windows.Forms.MouseEventHandler(button1_MMove);
private void button1_MMove ( object sender , System.Windows.Forms. MouseEventArgs e )
{
此处加入响应此事件的代码
}

你可能感兴趣的:(c#,c#,学习,开发语言)