最近不知道是抽了什么风,可能是因为一不小心安装了VS2013,然后把默认语言选成了C#的原因。。。
总之是突然玩起了C#。。。
话说,C#是我最早接触到的编程语言之一。(我的第一门编程语言是ActionScript 2.0,最早接触到的是QBASIC,但是只照着源程序打,没有能记下来。)
大概是在高二的时候,为了做一个字符串处理的工作,开始学了C#,不过掌握的仅仅是输入输出,和字符串类的一些方法。
下面打一些代码片段:
Windows编程:
退出程序:Application.Exit();
最小化窗口:this.WindowState = FormWindowState.Minimized;
拖动控制(点击这个部分并拖动,可以起到拖动整个窗口的作用):
1 2 3 4 5 6 7 8 9 10 11 [DllImport("user32.dll" ) ] public static extern bool ReleaseCapture () ; [DllImport("user32.dll" ) ] public static extern bool SendMessage (IntPtr hwdn,int wMsg,int mParam,int lParam ) ; public const int WM_SYSCOMMAND = 0x0112 ;public const int SC_MOVE = 0xF010 ;public const int HTCAPTION = 0x0002 ;private void Form1_MouseDown (object sender, MouseEventArgs e ) { ReleaseCapture(); SendMessage(this .Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0 ); }
给窗口添加阴影效果:
1 2 3 4 5 6 7 8 9 10 11 12 [DllImport("user32.dll" ) ] public static extern int SetClassLong (IntPtr hwnd, int nIndex, int dwNewLong ) ; [DllImport("user32.dll" ) ] public static extern int GetClassLong (IntPtr hwnd, int nIndex ) ; const int CS_DropSHADOW = 0x20000 ; const int GCL_STYLE = (-26 ); public MainPage () { InitializeComponent(); SetClassLong(this .Handle, GCL_STYLE, GetClassLong(this .Handle, GCL_STYLE) CS_DropSHADOW); }
子进程调用外部程序(无前台窗口显示):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 Process proc = new Process(); proc.StartInfo.FileName = ftext[0 ]; proc.StartInfo.Arguments = ftext[1 ]; proc.StartInfo.CreateNoWindow = true ; proc.StartInfo.UseShellExecute = false ; proc.StartInfo.RedirectStandardOutput = true ; this .Cursor = System.Windows.Forms.Cursors.WaitCursor;proc.Start(); using (StreamReader reader = proc.StandardOutput) { string thisline = reader.ReadLine(); while (thisline != null ) { richTextBox1.AppendText(thisline + "n" ); Application.DoEvents(); thisline = reader.ReadLine(); } } proc.WaitForExit(); this .Cursor = Cursors.Default;
注意,当外部程序标准输出过多的时候,可能造成缓冲区写满,此时外部程序会等待主程序读出缓冲区内容,再继续执行。但是主程序必须等待这个外部程序结束后才能继续,造成进程死锁。
解决方法1:将标准输出重定向到另一个文件,然后读那个文件。
解决方法2:(上面程序的解决方案)在proc.WaitForExit();
之前就把标准输出读掉。如果处理比较简单,还可以一边读一边处理。
字符串处理:
返回一个字符串内部包含几个子串:
(假设字符串为S,子串为subS)
1 int c = S.Split(new [] { subS },StringSplitOptions.None).Length - 1 ;
正则表达式匹配:
1 return new Regex("正则表达式字符串" ).Match(S).Success ? "Yes" : "No" ;
某字符的首次出现位置:
1 return Str.IndexOf('N' );
关于如何快速将java源程序转换成C#源程序:
以下是一段Java源程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import java.util.ArrayList; class GetPrime { Integer[] getPrime(int n) { ArrayList<Integer> prime = new ArrayList <>(); boolean [] vis = new boolean [n + 1 ]; for (int i = 2 ; i < n; i++) { if (!vis[i]) prime.add(i); for (int p : prime) { if (i >= n / p) break ; vis[i * p] = true ; if (i % p == 0 ) break ; } } return prime.toArray(new Integer [0 ]); } }
Integer
转换成int
boolean
转换成bool
ArrayList
转换成List
然后还有一些细微修改就好了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 using System; using System.Collections.Generic; class GetPrime { public int [] getPrime (int n ) { List<int > prime = new List<int >(); bool [] vis = new bool [n + 1 ]; for (int i = 2 ; i < n; i++) { if (!vis[i]) prime.Add(i); foreach (int p in prime) { if (i >= n / p) break ; vis[i * p] = true ; if (i % p == 0 ) break ; } } return prime.ToArray(); } }
关于以上程序里面其他细微的修改:在方法函数定义前增加了public
,在第二个List
的<>
加入了变量名。
List
添加方法改为了Add
(只有大小写的变换),for
改成了foreach
,中间的冒号改成了in
。 去掉了ToArray
的参数。(在C#中,ToArray
会自动推断类型,如果在泛型编程中,请这样写c.ToArray<int>();
)
C#和java有着非常多的相似之处,而且据我这几天的使用感觉,C#在很多方面比java更好,而且微软MSDN的文档十分详细(还都是中文)。
嗯,这篇日志先写到这里。
后记:昨天用C#去玩了TopCoder,结果HLL的得了0分。。。。(其实就算不是C#,也会得0分。做出两题,排名前200,结果System Testing全跪。。。第一题是字符串最后一小段没处理好(←没用正则简直哭瞎),第二题是做出了错误的猜想,本来暴力就行的啊。。。)