1、set和get方法:
可以使得protected/private 类成员变量与外界沟通,但是增加了一个屏障。
2、virtual和abstract的区别:
共同点:实现抽象/虚拟方法,可以被子类修改,因为要被修改所以必须public;
不同点:virtual是多态,必须有实现;abstract是抽象,被继承类不能有实现,且类修饰词也必须包含abstract.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace testcsclass
{
public abstract class Basecam
{
protected int index;
protected string name;
public abstract bool Open();
public virtual string Name
{
get
{
return name;
}
}
public virtual int Index
{
get
{
return index;
}
set
{
if (value > 100)
index = value;
else
index = 90;
}
}
}
public class Idtest : Basecam
{
public override bool Open()
{
return true;
}
}
public class Ietest : Basecam
{
public override bool Open()
{
return true;
}
public override int Index
{
get
{
return 2;
}
set
{
index = value;
}
}
public void prt()
{
Console.WriteLine("xxxxx");
}
}
class Program
{
static void Main(string[] args)
{
Ietest test = new Ietest();
Console.WriteLine("{0}---{1}.", test.Index, test.Name);
test.Index = 2;
Console.WriteLine("{0}---{1}.", test.Index, test.Name);
Dictionary<int, Basecam> CameraDic = new Dictionary<int, Basecam>(); ;
CameraDic.Add(0, test);
Console.WriteLine("{0}", CameraDic[0].Index);
Idtest d = new Idtest();
d.Index = 20;
CameraDic.Add(1, d);
Console.WriteLine("{0}", CameraDic[1].Index);
Ietest b = (Ietest)CameraDic[0];
b.prt();
}
}
}
3、函数类型(C#实现C++函数参数,函数指针)
使用delegate
4、匿名函数
namespace Test
{
public delegate void Function1(int a,out string b);
public class Test
{
public Function1 function1= (int a,out string b)=>{
b=a.ToString();
};
}
}
5、string、char和unsigned char
C#有char这个变量类型,但因为正常不操作指针,所以需要相互转。
//string -> char []
string ss = "abcdefg";
char[] cc = ss.ToCharArray();
//char [] ->string
string s = new string(cc);
unsigned char在C++中等价于byte,C#使用的类型名称就是它,由于string牵涉到字符编码,所以需要反编码。
//正常都是UTF8编码
byte[] bb = Encoding.UTF8.GetBytes(ss);
string s = Encoding.UTF8.GetString(bb);
6.C#调用C++ dll
要会玩Marshal,这个可以参看
c#与opencv Mat交互总结_陶醉鱼的博客-优快云博客https://blog.youkuaiyun.com/jerry_yu_1/article/details/107379082总体的思路就是使用指针和内存块的思想,结合C# 的safe 指针 IntPtr,会比较简单点。缺点是会复制内存,这个还要深入学习一下;
7.C++调用C# dll
要会玩gcnew和^ 这个后续补上例子
8. Event Mutex 都有对应的类
这里上一个锁定程式只启动一个的范例:
static void Main()
{
bool runone;
System.Threading.Mutex run = new System.Threading.Mutex(true, "xinbiao_a_test", out runone);
if (runone)
{
run.ReleaseMutex();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
else
{
MessageBox.Show("已经运行了一个实例了。");
}
}
9.GC 以及 析构函数
C#有个毛病,它自动GC,但是反应不是实时的,也就是说,例如:
public class Test
{
public Socket socket;
public Test()
{
//socket.createandconnect();
}
~Test()
{
socket.close();
}
}
public class TestA
{
static public void test()
{
while(true)
{
Test test;
//test.createandconnect();
}
}
可能你会发现有很多socket没有释放...这个时候就需要动用继承类IDisposable,这里上一个ImageGrabEvent的例子:
public class ImgGrabEvent:EventArgs,IDisposable
{
public Bitmap bitmap;
//public IntPtr data;
public int width;
public int height;
public int step;
public int index;
public System.Drawing.Imaging.PixelFormat format;
public ImgGrabEvent(ref Bitmap bitmap,int i)
{
this.index = i;
this.bitmap = bitmap;
//this.data = this.bitmap.GetHbitmap();
this.width = this.bitmap.Width;
this.height = this.bitmap.Height;
this.format = this.bitmap.PixelFormat;
}
public ImgGrabEvent(int width,int height,int step, System.Drawing.Imaging.PixelFormat format,IntPtr data)
{
this.width = width;
this.height = height;
this.format = format;
this.step = step;
//this.data = data;
bitmap =new Bitmap(width, height, step, format, data);
}
private bool disposed;
~ImgGrabEvent()
{
//必须为false
Dispose(false);
}
public void Dispose()
{
//必须为true
Dispose(true);
//通知垃圾回收器不再调用终结器
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposed)
{
return;
}
//告诉自己已经被释放
disposed = true;
}
}
10.C++模板编程和C#泛型编程
还是有很大区别的,C++不会检测模板类型的子操作符/元素是否存在,因为真正的检测是在编译阶段,对于C++模板编程可以简单的理解为是用利用编译器这个代码翻译器,将模板代码翻译成最终代码,或者简单来讲就是模板编程是一种代码半自动生成器,所以对于如下例子:
#include <iostream>
using namespace std;
template<class T> class A
{
public:
T add(T &a, T&b)
{
return a + b;
}
};
class B
{
public:
void *ptr;
};
int main()
{
A<string>a;
string s1 = "a";
string s2 = "b";
cout<<a.add(s1 ,s2).data()<<endl;
A<B> ab;
B b1;
B b2;
ab.add(b1, b2);
}
IDLE不会提示语法错误,而是在编译的时候提示class B不存在运算符+操作。
但是对于C#,对于没有约束的情况下,单独写一个+运算符,对于已有对运算符支持的类型都是不能编译通过的,例如,对于如下例子:
internal class TestA<T>
{
public T add(T a,T b)
{
return a + b;
}
}
TestA<int> testa;
testa.add(1,2);
直接提示 a+b非法。
持续更新中....