Csharp杂记

1. Csharp Note

所有的csharp文件以.cs为后缀.

  • struct 声明:

struct 声明时,必须加成员的访问方式,public或其它

public struct Book
{
    public decimal price;
    public string title;
    public string author;
}
  • struct与class与C++有区别

struct结构是一种值类型。创建结构时,为其分配结构的变量保存结构的实际数据。将结构分配给新变量时,会复制该变量。因此,新变量和原始变量包含相同数据的两个单独副本。对一个副本所做的更改不会影响另一个副本

class类是引用类型。创建类的对象时,为其分配对象的变量仅保留对该内存的引用。将对象引用分配给新变量时,新变量引用原始对象。通过一个变量进行的更改会反映在另一个变量中,因为它们都引用相同的数据。

struct中的函数,不用加static,可用作结构的全局函数.

  • 数组声明

数组声明与C++不同,数组是引用类型(隐式)

`<type>` [] name;
`<type>` [,] name;//二维数组
`<type>` [,,] name;//三维数组
`<type>` [][] name;//鑡齿维数组,数组的数组
  • 函数

函数传递值时引用用ref,调用时也必须加上ref

输出参数out:必须视为未赋值的.调用时也必须加上out

函数在类中声明,静态方法中只能调用静态成员或者方法,不能调用非静态方法或者非静态成员,非静态方法要被实例化才能被静态方法调用.如在Main函数中调用一个类.

函数重载,ref与out等也是函数签名的一部分,使用哪个函数看调用的签名类型.

  • 静态类

一个静态类是基本相同的非静态类,但有一个区别:静态类不能被实例化。换句话说,您不能使用new运算符来创建类类型的变量。因为没有实例变量,所以可以使用类名本身访问静态类的成员。如console.write()方法.

  • 委托delegate

委托delegate是一种可以把引用存储为函数的类型.与函数类似,但是不带实现,有delegate关键字.可以声明委托变量,使用时可以将委托变量当成一个代理函数.

public delegate void GreetingDelegate(string name);
 
class Program
{
    private static void EnglishGreeting(string name)
    {
        Console.WriteLine("Good Morning, " + name);
    }
 
    private static void ChineseGreeting(string name)
    {
        Console.WriteLine("早上好, " + name);
    }
 
    private static void GreetPeople(string name, GreetingDelegate MakeGreeting)
    {
        MakeGreeting(name);
    }
 
    static void Main(string[] args)
    {
        GreetPeople("Liker", EnglishGreeting);
        GreetPeople("李志中", ChineseGreeting);
        Console.ReadLine();
    }
}
  • 类与对象OOP

类是实例的模板,实例是类的对象.

使用new来生成实例:coffe my = new coffe();

静态构造函数:一个类只有有一个静态初始化函数,该构造函数不能有访问修饰符,且不能有任何参数.

//使用完成自动调用Dispose()接口
using(coffe my = new coffe())
{
}

string与object是引用类型,类是引用类型

类声明,默认为internal,即只有本项目才能访问,当声明为public时,其它项目可以访问.只能有一个基类.内部类可以继承于公共类,反之则不行,访问权限不能高于基类. 可以继承自多个接口.继承顺序是先基类,后接口.

//类型比较
myclass.GetType()==typeof(MyClass)
{
}

类成员

字段:readonly修饰时,只能在初始化或构造函数中赋值.static和const修饰的成员都是静态的,只能通过类来访问,但是两个修饰符不能同时使用.

方法:重写基类方法,必须加override修饰.override 后加 sealed ,则派生类不能对此方法进行修改.如果类方法不是虛方法,派生类可用new关键字声明要隐藏基类方法.

访问基类成员或当前类,可以使用basethis关键字.

public class Base
{
	public virtual void DoSome(){}
	public void DoSome2(){}
}
public class MyClass:Base
{
	(new)public override sealed void DoSome(){}
	new public void DoSome2(){}//隐藏基类方法
}

属性: 用来定义或访问类的私有字段,可以定义访问级别,就像方法一样,也叫get set 块.定义时不用加分号(区别于字段).

private int myInt;
public int MyVoice
{
	public get
	{
		return myInt;
	}
	protect set
	{
		myInt = value; //value是属性的值
	}
}

//自动属性
public int MyVoice
{
	get;
	set;
}

类和方法可以使用partial修饰符,定义一部分类或方法,但是部分方法只能是私有的,且不能有返回值,如out,但是可以用ref.

public partial class MyClass
{

}

类方法如果只有定义,没有实现,编译器在编译时会完全删除该定义.这样可以提高性能.

  • 接口与实现

不能使用访问修饰符,不能定义字段,不能有实现代码,不能用static\virtual\sealed\abstract来定义;

可以定义属性.可以在实现中增加virtual\abstract来修饰.

显式实现接口:类中加接口名称 public Interface.DoSomething(){}

隐式实现接口:继承实现接口的基类,或方法前不加接口名称.

若接口中属性的get/set方法,只定义了一个,则实现类中增加另一个,只能用访问权限更低的修饰符增加,如protect,private等.

  • 浅复制与深复制

System.Object的方法MemberwiseClone(),只是复制值,没有考虑引用成员. 如果想要深复制,需要实现ICloneable()接口,用标准方式进行.

  • 集合类

比数组更好用,不用管理大小

接口IList,IDictionary,相当于vector,map

ArrayList;对基中的对象,必须进行类型转换,才能使用对象的方法.

数组中的对象,可以直接调用基类方法,派生类方法需要类型转换.

自定义集合类,可以从system.collections.collectionbase类继承.这样的集合项不用类型转化,也可以用.

索引符,看起来比较怪,而且这个集合类没有C++的STL好用,起码不用类型转换.

  • 泛型

c++泛型是在编译时动态生成.csharp是在运行时动态生成.

空值类型:像C++的空指针.

//下面二者等价
System.Nullable<int> nuallInt;
int? nuallInt;

List<T>
Dictionary<T>

排序与搜索
int m(A,B);//Comparison<T> s = new Comparison<T>(T.m)
Bool m(A);//Predicate<T> s = new Predicate<T>(T.m)

//创建泛型,where约束类型
public class myclall<T,T2> where T:Myeolclass
{
	private T a = default(T);//default可以执行多种操作,引用或值类型.
//泛型比较只能用==和!=
}

创建泛型,where约束类型,有struct,class,interface,baseclass,new等,new()约束必须为最后一个.它约束类必须有一个无参构造函数.

  • 运算符重载

必须是静态函数

有时需要重载system.Equals(object o)和GetHashCode()函数,后者得到实例唯一的标识(int值)

as运算符:

<intsance> as <type>

可用于类型转换,转换失败返回NULL

  • 异常

从标准异常继承,可以建立自己的异常.

  • 事件

Timer的定时事件:

Timer myTimer = new Timer(100);
myTimer.Elapsed += new ElapsedEventHandler(WriteChar);

static void WriteChar(object source,ElapsedEventArgs e)
{
}

定义事件:

先定义委托,再定义事件.定义事件用event关键字.也可以直接使用.net定义好的委托:EventHandler,也可以使用其名委托.

public class Connect
{
	public event EventHandler MessageArrived;
	...
}

对象初始化器:

<classname> <var> = new <classname>
{
	<fild> = <value>,
	<fild> = <value>,
};
  • 安装与部署

可以使用clickonce或安装程序部署.

参考:

  1. my coding.net
  2. https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/index
  3. C#调用的C++库的使用(三种方式)
  4. https://blog.csdn.net/love_kevin/article/details/88043565