在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
1.parse()与try parse() int.Parse()是一种类容转换;表示将数字内容的字符串转为int类型。 如果字符串为空,则抛出ArgumentNullException异常; 如果字符串内容不是数字,则抛出FormatException异常; 如果字符串内容所表示数字超出int类型可表示的范围,则抛出OverflowException异常; int.TryParse 与 int.Parse 又较为类似,但它不会产生异常,转换成功返回 true,转换失败返回 false。最后一个参数为输出值,即结果会赋值给这个参数,如果转换失败,输赋值为 0 int.TryParse(n1.Text, out P_int_Number) 其中第一个参数代表被转换的参数,第二个参数为转换后的参数 int类型,成功返回True,失败返回False。 2.is 与 as 在C#语言中进行类型转换的操作符is和as。is和as都是强制类型转换,但这两者有什么相同之处和不同之处呢?在使用is和as需要注意哪些事项?下面我们从简单的代码示例去探讨这个简单的问题。
is检查一个对象是否兼容于指定的类型,并返回一个Boolean值:true或者fasle。注意,is操作符永远不会抛出异常,请看以下示例:
ClassA
{
....
}
Object o=new Object();
Boolean b1=(o is Object); //b1为true.
Boolean b2=(o is ClassA) ; b2为false.
如果对象引用是null,is操作符总是返回false,因为没有可检查的其类型的对象。
is 操作符通常像下面这样使用:
if(obj is ClassA)
{
ClassA a=(ClassA) obj;
...
}
在这一段代码中,CLR实际会检查两次对象类型。is操作符首先核实obj是否兼容于ClassA 类型。如果是,那么在if语句内部执行类型转换时,CLR再次核实obj是否引用一个ClassA。
3.Dictionary/HashTable/ArrayList HashTable/ArrayList属于System.Collections; Dictionary属于System.Collections.Generic; 其中Dictionary有泛型Dictionary<T,T>,可以直接通过键来获取值 Dictionary<string, string> d = new Dictionary<string, string>(); d.Add("Name", "张三"); d.Add("Rules", "红牌"); string str = d["Name"]; 遍历方式: Dictionary<string, int> list = new Dictionary<string, int>(); list.Add("d", 1); //3.0以上版本 foreach (var item in list) { Console.WriteLine(item.Key + item.Value); } //KeyValuePair<T,K> foreach (KeyValuePair<string, int> kv in list) { Console.WriteLine(kv.Key + kv.Value); } //通过键的集合取 foreach (string key in list.Keys) { Console.WriteLine(key + list[key]); } //直接取值 foreach (int val in list.Values) { Console.WriteLine(val); } //非要采用for的方法也可 List<string> test = new List<string>(list.Keys); for (int i = 0; i < list.Count; i++) { Console.WriteLine(test[i] + list[test[i]]); } Dictionary多层嵌套可以实现类似DataTable的访问方式 Dictionary<int, Dictionary<string, int>> list = new Dictionary<int, Dictionary<string, int>>(); Dictionary<string, int> son = new Dictionary<string, int>(); son.Add("年龄", 20); list.Add(1,son); int result = list[1]["年龄"] = 50; dt.Rows[0]["姓名"] = "乐乐"; ArrayList无泛型,储存的是object,访问时需要强转 ArrayList ar = new ArrayList(); ar.Add(1); ar.Add("123"); int t = (int)ar[0]; string ss = (string)ar[1]; HashTable四中遍历方式 Hashtable ht=new Hashtable(); ht.Add("1", "1111"); ht.Add("2", "2222"); ht.Add("3", "3333"); ht.Add("4", "4444"); //遍历方法一:遍历哈希表中的键 foreach(string key in ht.Keys) { //Console.WriteLine(string.Format("{0}-{1}"), key, ht[key]); Console.WriteLine(string.Format("{0}-{1}", key, ht[key])); } //遍历方法二:遍历哈希表中的值 foreach(string value in ht.Values) { Console.WriteLine(value); } //遍历方法三:遍历哈希表中的键值 foreach(DictionaryEntry de in ht) { Console.WriteLine(string.Format("{0}-{1}", de.Key, de.Value)); } //遍历方法四:遍历哈希表中的键值 IDictionaryEnumerator myEnumerator = ht.GetEnumerator(); bool flag = myEnumerator.MoveNext(); while (flag) { Console.WriteLine(myEnumerator.Key + "-" + myEnumerator.Value); // Console.WriteLine(ht[myEnumerator.Key]);//ht[myEnumerator.Key]== myEnumerator.Value=true; flag = myEnumerator.MoveNext(); } 4.方法调用问题 静态方法可以以ClassName.StaticMethod() 或者在当前类内StaticMethod()方式调用、其他方法内直接调用(包括主方法) public static void Test() { Console.WriteLine("静态方法测试"); } public void Test2() { Console.WriteLine("普通方法测试"); Test(); } public void Test3() { Test2(); } 普通方法无法在静态方法(包括主方法)内调用,可由Object.Method()方式调用,或者在当前类内另一个普通方法内直接调用,如上例。 5.DataTable的Clone()、Copy() Clone():复制表结构、约束 Copy();复制表结构、数据,注意行状态也会被复制! 6.Delegate 委托 当有大量的、相似的方法且这些方法代码量很多,要用来调用时,我们可以考虑使用委托,将方法封装好作为一个参数进行传递或调用: namespace Delegate { public delegate int Expressin(int a, int b); class Program { static int Add(int a, int b) { return a+b; } static int Divide(int a, int b) { return a / b; } static int Subtract(int a, int b) { return a - b; } static int Multiply(int a, int b) { return a * b; } static int GetAdd(int a,int b) { return a + b; } static void Calculate(Expressin ex, int a , int b) { Console.WriteLine(ex(a , b) + "\n"); } static void Main(string[] args) { int a = 10; int b = 5; Expressin ex1 = new Expressin(Multiply); Calculate(ex1, a , b); Expressin ex2 = new Expressin(Add); Calculate(ex2, a, b); Console.ReadKey(); } } } 在上例中,我们虽然调用了同一个Calculate()方法,但因为传入的委托实例不同,而间接的调用了不同的方法 同时委托的多播可以很方便的调用多个方法,多播可以理解为一个委托绑定多个方法: delegate int NumberChanger(int n); namespace DelegateAppl { class TestDelegate { static int num = 10; public static int AddNum(int p) { num += p; return num; } public static int MultNum(int q) { num *= q; return num; } public static int getNum() { return num; } static void Main(string[] args) { // 创建委托实例 NumberChanger nc; NumberChanger nc1 = new NumberChanger(AddNum); NumberChanger nc2 = new NumberChanger(MultNum); nc = nc1; nc += nc2; // 调用多播 nc(5); Console.WriteLine("Value of Num: {0}", getNum()); Console.ReadKey(); } } } 注意,多播也可以 += -=方法名,这在接下来的事件中会有应用: NumberChanger n = new NumberChanger(); n += AddNum; 委托链执行顺序及返回值问题:委托内的方法按照绑定顺序依次执行,如果委托有返回值,则只会返回最后执行的的方法的返回值! 7.Event 事件 事件与委托相似,可以看做一种特殊的委托,与委托不同的是,事件无法直接调用且只能在发布类内间接调用 声明方式: public delegate EventHandler(); public event EventHandler TestEvent;
正如上图所示,发布者类Incrementer里面的事件CountedADozen就像一个装方法的容器,这个容器对方法的添加与删除是里面的私有委托来实现的(这里待会儿可以通过代码理解), namespace Event { public delegate void Handler(); class Incrementer //事件发布者 { public event Handler CountedADozen; //事件 public void DoCount() //触发事件的方法,“起爆器” { for (int i = 1; i<50; i++) { //委托不为空就代表已经绑定了方法,i%12 ==0是触发条件,会触发四次 if (i % 12 ==0 && CountedADozen !=null) { CountedADozen(); //事件(委托)调用 } } } } class Dozens //订阅类,绑定出触发事件后执行的方法 { public Dozens(Incrementer incrementer) { incrementer.CountedADozen += IncrementDozensCount;//执行方法绑定 } void IncrementDozensCount() //事件触发后要执行的方法 { Console.WriteLine("Dozens"); } } class SomeOtherClass //订阅类 { public SomeOtherClass(Incrementer incrementer) { incrementer.CountedADozen += DoSomething; } public void DoSomething() { Console.WriteLine("SomeOherClass"); } } class Program { static void Main() { Incrementer incrementer = new Incrementer(); Dozens dozensCounter = new Dozens(incrementer); SomeOtherClass other = new SomeOtherClass(incrementer); incrementer.DoCount(); Console.ReadKey(); } } } namespace EventArg { public class TestEventArgs : EventArgs //自定义EventArgs { public string parameters; public TestEventArgs(string par) { parameters = par; } } public class Test //事件发布类 { public delegate string TestHandler(object sender, TestEventArgs tea); //带参数,带返回值的的委托 public event TestHandler TestEvent;//事件 public string OntestEvent(TestEventArgs tea)//触发事件方法 { if(TestEvent != null) { return TestEvent(this, tea); //this指的是调用OntestEvent方法的Test实例化对象 } return null; } } class Program //事件触发测试 { public static string model_TestEvent(object sender, TestEventArgs tea)//事件触发后执行的方法 { return "传入的参数是:" + tea.parameters+"\n" + "触发事件的对象是" + sender.ToString(); } static void Main(string[] args) { Test model = new Test(); model.TestEvent += model_TestEvent;//注册事件 TestEventArgs tea = new TestEventArgs("test"); //事件传入参数 string result = model.OntestEvent(tea); //执行触发事件方法 Console.WriteLine(result); Console.ReadKey(); } } }
8.@符号的使用 1.限定字符串 用 @ 符号加在字符串前面表示其中的转义字符“不”被处理。 如果我们写一个文件的路径,例如"D:/文本文件"路径下的text.txt文件,不加@符号的话写法如下: string fileName = "D://文本文件//text.txt"; 如果使用@符号就会比较简单: string fileName = @"D:/文本文件/text.txt"; 2.让字符串跨行 有时候一个字符串写在一行中会很长(比如SQL语句),不使用@符号,一种写法是这样的: string strSQL = "SELECT * FROM HumanResources.Employee AS e" + " INNER JOIN Person.Contact AS c" + " ON e.ContactID = c.ContactID" + " ORDER BY c.LastName"; 加上@符号后就可以直接换行了: string strSQL = @"SELECT * FROM HumanResources.Employee AS e INNER JOIN Person.Contact AS c ON e.ContactID = c.ContactID ORDER BY c.LastName"; 3.在标识符中的用法 C#是不允许关键字作为标识符(类名、变量名、方法名、表空间名等)使用的,但如果加上@之后就可以了,例如: namespace @namespace... { class @class... { public static void @static(int @int)... { if (@int > 0)... { System.Console.WriteLine("Positive Integer"); } else if (@int == 0)... { System.Console.WriteLine("Zero"); } else... { System.Console.WriteLine("Negative Integer"); } } } }
10.Linq、lambda以及静态类的扩展方法 静态成员、静态方法、静态类、实例成员及区别需要特别注意的是,Linq的语法分为查询语法与方法与法,其中方法语法的Select()/Where()方法来自于System.Linq.Enumerable类中定义的扩展方法: int[] a = {1,2,3,4,5,6}; var result = a.Where(p => p%2 ==0).ToArray(); 和上例使用的方法来源不同,容易混淆! 11.使用句柄关闭指定窗体(可关闭模态化窗口)
/* 配置计时器 */ _timer = new System.Timers.Timer(3000); _timer.Enabled = true; _timer.AutoReset = false; _timer.Elapsed += _timer_Elapsed; /// <summary> /// 寻找指定窗口 /// </summary> /// <param name="lpClassName">窗体类名</param> /// <param name="lpWindowName">窗体名称</param> /// <returns></returns> [DllImport("user32.dll", EntryPoint = "FindWindow")] private extern static IntPtr FindWindow(string lpClassName, string lpWindowName); /// <summary> /// 关闭窗体的方法 /// </summary> public const int WmClose = 0x10; [DllImport("user32.dll", EntryPoint = "SendMessageA")] public static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam); /// <summary> /// 响应_timer的Elapsed事件 /// </summary> private void _timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { /* 计时器定时结束后,关闭模拟效果窗体 */ IntPtr mn = FindWindow(null, "模拟效果"); SendMessage(mn, WmClose, 0, 0); }
|
请发表评论