zoukankan      html  css  js  c++  java
  • C#學習基礎方法

    方法
    方法在類中用於執行計算或其它行為的成員.聲明格式:
    method-header
      method-body
    其中方法頭method-header的格式:
    attributes method-modifiers return-type member-name (formal-parameter-list)
    傳遞給方法的參數在方法的形式參數表formal-parameter-list中聲明
    在方法的聲明中,至少應包括方法名稱,修飾符和參數類型,返回值和參數名則不是必須的.
    注意:方法名member-name不應與同一個類中的其它方法同名,也不能與類中的其它成員名稱

    相同.
    修飾符
    方法的修飾符method-modifier可以是:
    new
    public
    protected
    internal
    private
    static
    virtual
    sealed
    override
    abstract
    extern
    對於使用了atstract和extern修飾符的方法,方法的執行體method-body僅僅只有一個簡單

    的分號.其它所有的方法執行體中應包含調用該方法所需要執行的語句.
    返回值
    方法的返回值的類型可以是合法的C#的數據類型.C#在方法的執行部分通過return語句得到

    返回值,如
    using System;
    class Test
    {
      public int max(int x,int y)
      {
        if(x>y)
          return x;
        else
          return y;
      }
    }
    public void Main()
    {
      Console.WriteLine("the max of 6 and 8 is:{0}",max(6,8));
    }
    如果在return後不跟隨任何值,方法返回值是void型的.

    方法中的參數
    C#中方法的參數有四种類型:
    值參數,不含任何修飾符.
    引用型參數,以ref修飾符聲明.
    輸出參數,以out修飾符聲明.
    數組型參數,以params修飾符聲明.
    值參數
    當利用值向方法傳遞參數時,編譯程序給實參的值做一份拷貝,並且將此拷貝傳遞給該方法.

    被調用的方法不會修改內存中實參的值,所以使用值參數時,可以保證實際值是安全的.
    下面的例子可以說明這個問題
    using system;
    class Test
    {
      static void Swap(int x,int y)
      {
        int temp=x;
        x=y;
        y=temp;
      }
      static void Main()
      {
        int i=1,j=2;
        Swap(i,j);
        Console.WriteLine("i={0},j={1}",i,j);
      }
    }
    程序輸出的結果是:
    i=1,j=2
    程序並沒有達到交換的目的.

    引用型參數
    和值參不同的是,引用型參數並不開辟新的內存區域.當利用引用型參數向方法傳遞形參時,

    編譯程序將把實際值在內存中的地址傳遞給方法.
    下面的例子有說明這個
    using System;
    class Test
    {
      static void Swap(ref int x,ref int y)
      {
        int temp=x;
        x=y;
        y=temp;
      }
      static void Main()
      {
        int i=1,j=2;
        Swap(ref i,ref j);
        Console.WriteLine("i={0},j={1}",i,j);
      }
    }
    程序運行的輸出結果是:
    i=2,j=1
    在方法中使用引用型參數,會經常可能多個變量名指向同一處內存地址.見下面的例子:
    using System;
    using System.Collections.Generic;
    using System.Windows.Forms;

    namespace WindowsApplication2
    {
        class A
        {
            public string s="ssss";
            void F(ref string a, ref string b)
            {
                s = "One";
                a = "Two";
                b = "Three";
            }
            public void G()
            {
                F(ref s, ref s);
            }
            public void R()
            {
                Console.WriteLine("S:{0}", s);
            }
        }
        class T
        {
            public static void Main()
            {
                A a=new A();
                a.G();
                a.R();
            }
        }
    }
    程序運行的結果是
    S:Three
    在方法G對F的調用過程中,S的引用被同時傳遞給了a和b.此時,s,a,b同時指向了同一塊內存

    區域.
    輸出參數
    與引用型參數類似,輸出型參數也不開辟新的內存區域,與引用型參數的差別在於,調用方法

    前無需對變量進行初始化.輸出型參數用於傳遞方法返回數據.
    out修飾符後應跟隨與形參的類型相同的類型聲明.在方法返回後,傳遞的變量被認為經過了

    初始化.
    using System;
    class Test
    {
      static void SplitPath(string path,out string dir,out string name)
      {
        int i=path.Length;
        while(i>0)
        {
          char ch=path[i-1];
          if(ch=='\\' || ch=='/' || ch==':') break;
          i--;
        }
        dir=path.Substring(0,i);
        name=path.Substring(i);
      }
      static void Main()
      {
        string dir,name;
        SplitPath("c:\\Window\\System\\hello.txt",out dir,out name);
        Console.WriteLine(dir);
        Console.WriteLine(name);
      }
    }
    程序輸出結果:
    c:\Windwo\System\
    hello.txt
    我們看到,變量dir和name在傳遞給SplitPath之前並未初始化,在調用之後它們則有了明確

    的值.
    數組型參數
    如果形參表中包含了數組型參數,那麼它必須在參數表中位於最後.另外,參數只允許是一維

    數組.比如,string[]和string[][]類型都可以作為數組型參數,而string[,]則不能.最後數

    組型參數不能再有ref和out修飾符.
    using System;
    class Test
    {
      static void F(params int[] args)
      {
        Console.WriteLine("Array contains {0} elements:",args.Length);
        foreach (int i in args) Console.Write("{0},",i);
        Console.WriteLine();
      }
      public static void Main()
      {
        int[] a={1,2,3};
        F(a);
        F(10,20,30,40);
        F();
      }
    }
    程序運行結果:
    Array contains 3 elements:
    1,2,3,
    Array contains 4 elements:
    10,20,30,40,
    Array contains 0 elements:

    靜態和非靜態的方法
    C#的類定義中可以包含兩种方法:靜態的和非靜態的.使用了static修飾符的方法為靜態方

    法,反之則是非靜態的.
    靜態方法是一种特殊的成員方法,它不屬於類的某一個具體的實例.非靜態方法可以訪問類

    中的任何成員,而靜態方法只能訪問類中的靜態成員.
    下面這個列子說明這一點.
    class A
    {
      int x;
      static int y;
      static int F()
      {
        x=1; //錯誤,不允許訪問
        y=2; //正確,允許訪問
      }
    }
    在這個類定議中,靜態方法F()可以訪問類中靜態成員s,但不能訪問非靜態的成員x.這是因

    為,x作為非靜態成員,在類的每個實例中都占有一個存儲(或者說有一個副本),而靜態方法

    是類所共享的,它無法判斷出當前的x屬於那個類的實例.所以不知道應該到內存的哪個地址

    去讀取當前x的值.而y是靜態成員,所有類的實例都公用一個副本,靜態方法F使用它就不存

    什麼問題.
    是不是靜態方法就無法識別類的實例了呢?答案:不是.
    我下面看一下有關windows窗口的例子
    using System;
    class Window
    {
      public string m_caption;  //窗口的標題
      public bool IsActive;     //窗口是否被激活
      public handle m_handle;   //窗口的句柄
      public static int m_total;//當前打開的窗口數目
      public handle Window()
      {
        m_total++;
        return m_handle;
      }
      ~Window()
      {
        m_total--;
      }
      public static string GetWindowCaption(Window w)
      {
        return w.m_caption;
      }
    }
    分析一下上面例子中的代碼,每個窗口都有窗口標題m_caption,窗口句柄m_handle,窗口是

    否激活IsActive三個非靜態的數據成員(窗口句柄是Windows操作系統中保存窗口相關信息

    的一种數據結構,我們在這個例子中簡化了對句柄的使用).系統中總共打開窗口的數目

    m_total作為一個靜態成員.每個窗口調用構造函數創建,這時候m_total的值加1.窗口關閉

    或因為其它行為撤消時,通過析構函數m_total的值減1.我們要注意窗口類的靜態方法

    GetWindowCaption(Window w).這里它通過參數w將對像傳遞給方法執行,這樣它就可以通過

    具體實例中的類的實例指明調用的對像,這時它可以訪問具體實例中的成員,無論是靜態成

    員還是非靜態成員.

    方法的重載
    類中兩個以上的方法(包括隱藏的繼承而來的方法),取的名字相同,只要使用的參數類型或

    者參數個數不同,編譯器便知道在何种情況下應該調用哪個方法,這就叫做方法的重載.
    下面看個例子
    using System;
    class Student
    {
        public string s_name;
        public int s_age;
        public float s_weight;
        public Student(string n, int a, float w)
        {
            s_name = n;
            s_age = a;
            s_weight = w;
        }
        public int max(int x, int y)
        {
            if (x > y) return x;
            else return y;
        }
        public float max(float x, float y)
        {
            if (x > y) return x;
            else return y;
        }
    }
    class test
    {
        public static void Main()
      {
        Student s1=new Student("Mike",21,70);
        Student s2=new Student("John",21,70);
        if (s1.max(s1.s_age, s2.s_age) == s1.s_age)
            Console.WriteLine("{0} age is bigger than {1}.", s1.s_name, s2.s_name);
        else
            Console.WriteLine("{0} age is smaller than {1}.", s1.s_name,

    s2.s_name);
        if (s1.max(s1.s_weight, s2.s_weight) == s1.s_weight)
            Console.WriteLine("{0} age is bigger than {1}.", s1.s_name, s2.s_name);
        else
            Console.WriteLine("{0} age is smaller than {1}.", s1.s_name,

    s2.s_name);
      }
    }
    程序運行的結果:
    Mike age is bigger than John.
    Mike age is bigger than John.

    操作符重載
    C#中,操作符重載總是在類中進行聲明,並且通過調用類的成員方法來實現.操作作重載的聲

    明的格式為:
    type  operator  operator-name  (formal-param-list)
    C#中,下列操作符都是可以重載的
    +  -  !  ~  ++  --  TRUE  FALSE
    *  /  %  |  ^   <<  >>    ==   !=   >   <   >=  <=
    但也有一些操作符是不允許進行重載的,如:
    =,&&,||,?:,NEW,TYPEOF,SIZEOF,IS

    一元操作符重載,一元操作符重載時操作符只作個用於一個對像,此時參數表為空,當前對像

    作為操作符的單操作數.
    下面我們舉一個角色類遊戲中經常遇到的例子.扮演的角色有內力,體力,經驗值,剩餘體力,

    剩餘內力五個屬性,每當經驗值達到一定程度時,角色便會升級,體力,內力上升,剩餘體力和

    內力補滿."升級"我們使用重載操作符"++"來實現.
    using System;
    class Player
    {
        public int neili;
        public int tili;
        public int jingyan;
        public int neili_r;
        public int tili_r;
        public Player()
        {
            neili = 10;
            tili = 50;
            jingyan = 0;
            neili_r = 50;
            tili_r = 50;
        }
        public static Player operator ++(Player p)
        {
            p.neili = p.neili + 50;
            p.tili = p.tili + 100;
            p.neili_r = p.neili;
            p.tili_r = p.tili;
            return p;
        }
        public void Show()
        {
            Console.WriteLine("Tili:{0}", tili);
            Console.WriteLine("Jingyan:{0}", jingyan);
            Console.WriteLine("Neili:{0}", neili);
            Console.WriteLine("Tili_Full:{0}", tili_r);
            Console.WriteLine("Neili_Full:{0}", neili_r);
        }
    }
    class Test
    {
        public static void Main()
        {
            Player man = new Player();
            man.Show();
            man++;
            Console.WriteLine("Now upgrading...");
            man.Show();
        }
    }
    程序輸出結果:
    Tili:50
    Jingyan:0
    Neili:10
    Tili_Full:50
    Neili_Full:50
    Now upgrading...
    Tili:150
    Jingyan:0
    Neili:60
    Tili_Full:150
    Neili_Full:60

    二元操作符重載
    大多數情況下我們使用二元操作符重載.這時參數表中有一個參數,當前對像作為該操作符

    的左操作數,參數作為操作符的右操作數.
    下面是一個二元操作符重載的例子.即笛卡兒坐標相加.
    using System;
    class DKR
    {
        public int x, y, z;
        public DKR(int vx, int vy, int vz)
        {
            x = vx;
            y = vy;
            z = vz;
        }
        public static DKR operator +(DKR d1, DKR d2)
        {
            DKR dkr = new DKR(0, 0, 0);
            dkr.x = d1.x + d2.x;
            dkr.y = d1.y + d2.y;
            dkr.z = d1.z + d2.z;
            return dkr;
        }
    }
    class Test
    {
        public static void Main()
      {
        DKR d1 = new DKR(3,2,1);
        DKR d2 = new DKR(0, 6, 5);
        DKR d3 = d1 + d2;
        Console.WriteLine("The 3d location of d3 is:{0},{1},{2}",d3.x,d3.y,d3.z);
      }
    }
    程序輸出結果:
    The 3d location of d3 is:3,8,6

    申明

    非源创博文中的内容均收集自网上,若有侵权之处,请及时联络,我会在第一时间内删除.再次说声抱歉!!!

    博文欢迎转载,但请给出原文连接。

  • 相关阅读:
    crontab定时任务
    find at tar命令详解
    c#调用c++dll库调用约定问题
    ATL和ActiveX做的控件.dll和.ocx最主要的区别(摘录)
    实现内外网的策略
    探查“ORA-01000:超出最多允许打开的游标数”
    良好编程习惯的重要性
    PCS不能用问题
    msf外网--->>安卓
    github 克隆代码问题
  • 原文地址:https://www.cnblogs.com/Athrun/p/944521.html
Copyright © 2011-2022 走看看