zoukankan      html  css  js  c++  java
  • C#学习笔记

    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。
    CLR的类型检查增强了安全性,但也会对性能造成一定的影响。这是因为CLR首先必须判断(obj)引用的对象的实际类型。然后CLR必须遍历继承层次结构,用每个基类型去核对指定的类型(ClassA)。 实际系统开发中,这是一个相当常用的编程模式,于是C#有了操作符as。 as与is做差不多的事情,类型显式强制转换。 as操作符的工作方式与强制类型转换一样,只是它永远不会抛出一个异常——相反,如果对象不能转换,结果就是null。 但as有其不同的地方,简化代码,同时提升性能。 请看示例代码: Object obj
    =new Object(); ClassA a= obj as ClassA; if(a!=null) //在if判断a是否为null { ... } 在这一段代码中,CLR核实obj是否兼容于ClassA类型,如果是,as会返回对同一个对象的一个非null引用; 如果obj不兼容ClassA类型,as操作符会返回null。 因此,as操作符使CLR只检验一次对象的类型。 if语句只是检查a是否为null。这个检查的速度比检验对象的类型快得多。 所以正确做法是检查最终生成的引用是否为null。如果企图直接使用最终生成null的引用,会抛出一个 NullReferenceException异常。 示例代码: Object obj=new Object(); //创建一个object对象. ClassA a =obj as ClassA;//将obj转型为ClassA,此时转型操作会失败,不会抛出异常,但a会被设为null. a.ToString();//访问a会抛出一个NullReferenceException异常。

     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) + "
    ");
            }
            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就像一个装方法的容器,这个容器对方法的添加与删除是里面的私有委托来实现的(这里待会儿可以通过代码理解),
    发布者类Incrementer还有一块触发事件的代码,这段触发事件代码的方法是那个方法容器的引线,只要运行这方法,引线点燃(触发事件的代码开始运行),
    引爆了容器(事件CountedADozen开始运行委托里面装载的方法,比如图中的IncrementDozensCount( )和DoSomething( )),这样就走完了从触发代码到运行所有订阅者代码的流程。
    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+"
    " + "触发事件的对象是" + 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);
            }
  • 相关阅读:
    python从字符串内取两个符号之间的内容
    C# 判读取得字符编码格式
    jquery:字符串(string)转json
    SQL Server 2008 SQL2012 SQL2014 收缩日志 清空删除大日志文件
    WEB 倒计时
    成功配置TOMCAT的LOG4J日志系统,格式:HTML+每天以YYYY-MM-DD.LOG命名的日志文件
    IE Error: '__doPostBack' is undefined 问题解决
    分享:JAVA和C# 3DES加密解密
    好用的linux工具
    python多线程的概念(转载)
  • 原文地址:https://www.cnblogs.com/whwjava/p/9365634.html
Copyright © 2011-2022 走看看