C#方法的總結(jié)詳解
更新時(shí)間:2013年05月21日 17:36:16 作者:
本篇文章是對(duì)C#方法進(jìn)行了詳細(xì)的總結(jié)與介紹,需要的朋友參考下
C#方法
1:實(shí)例構(gòu)造器和類
2:實(shí)例構(gòu)造器和結(jié)構(gòu)
3:類型構(gòu)造器
4:操作符重載方法
5:轉(zhuǎn)換操作符方法
6:擴(kuò)展方法
7:部分方法
1:實(shí)例構(gòu)造器和類
構(gòu)造器是允許將類型的實(shí)例初始化為良好狀態(tài)的一種特殊方法,創(chuàng)建一個(gè)引用類型的實(shí)例時(shí),先為實(shí)例的數(shù)據(jù)字段分配內(nèi)存,然后初始化對(duì)象的附加字段(類型對(duì)象指針和同步索引),最后調(diào)用構(gòu)造函數(shù)來設(shè)置對(duì)象的初始狀態(tài)。構(gòu)造函數(shù)不能被繼承,所以不能被virtual、new、override、sealed和abstract修飾,若沒有顯示定義任何構(gòu)造函數(shù),編譯器將定義一個(gè)無參的public構(gòu)造函數(shù),但若是抽象類,編譯器將定義一個(gè)無參的protected的構(gòu)造函數(shù)
創(chuàng)建一個(gè)類的實(shí)例并不一定非要調(diào)用構(gòu)造函數(shù)。
1:使用Object的MemberwiseClone()方法。他的作用就是創(chuàng)建當(dāng)前 System.Object 的淺表副本,內(nèi)部工作機(jī)制是分配內(nèi)存,初始化對(duì)象的附加字段(類型對(duì)象指針和同步索引),然后將源對(duì)象的字節(jié)數(shù)據(jù)復(fù)制到新對(duì)象中。從下面的代碼可以看出MemberwiseClone()實(shí)現(xiàn)了對(duì)象復(fù)制,而不是簡單的對(duì)象引用。
class Program
{
public int X;
static void Main(string[] args)
{
Program p = new Program();
p.X = 1;
Program q = (Program)p.MemberwiseClone();
Program z = p;
p.X = 2;
Console.WriteLine("p.X=" + p.X);//輸出:p.X=2
Console.WriteLine("q.X=" + q.X);//輸出:q.X=1
Console.WriteLine("z.X=" + z.X);//輸出:z.X=2
Console.Read();
}
}
2:反序列化。在網(wǎng)絡(luò)編程的時(shí)候,經(jīng)常將一個(gè)對(duì)象序列化成二進(jìn)制,然后傳輸出去,接收端反序列化成原來的對(duì)象,反序列化使用的是類
System.Runtime.Serialization.FormatterServices的方法public static object GetUninitializedObject(Type type)或
public static object GetSafeUninitializedObject(Type type)分配內(nèi)存,而在這兩個(gè)方法內(nèi)部沒有調(diào)用要被反序列化對(duì)象的構(gòu)造函數(shù)。
字段的初始化代碼會(huì)被編譯器自動(dòng)添加到相應(yīng)的構(gòu)造函數(shù)中,非靜態(tài)字段的初始化代碼會(huì)自動(dòng)加到實(shí)例構(gòu)造函數(shù)中,靜態(tài)字段的初始化代碼則添加到靜態(tài)構(gòu)造函數(shù)中,如果你的代碼中有多個(gè)字段被初始化,還有多個(gè)構(gòu)造函數(shù)的話,初始化代碼在每個(gè)構(gòu)造函數(shù)中都會(huì)有一份,這無疑會(huì)讓你的生成文件(如DLL,EXE文件)變大。
證明這一點(diǎn)的代碼如下:
public class SomeType
{
public int x=1,y=2,z=3;
public SomeType() { }
public SomeType(int x, int y)
{
this.x = x;
this.y = y;
}
public SomeType(int x)
{
this.x = x;
}
}
//經(jīng)過IL反編譯,方法SomeType(int x, int y)代碼如下
.method public hidebysig specialname rtspecialname
instance void .ctor(int32 x,
int32 y) cil managed
{
// 代碼大小 45 (0x2d)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldc.i4.1
IL_0002: stfld int32 MyTest.SomeType::x
IL_0007: ldarg.0
IL_0008: ldc.i4.2
IL_0009: stfld int32 MyTest.SomeType::y
IL_000e: ldarg.0
IL_000f: ldc.i4.3
IL_0010: stfld int32 MyTest.SomeType::z
IL_0015: ldarg.0
IL_0016: call instance void [mscorlib]System.Object::.ctor()
IL_001b: nop
IL_001c: nop
IL_001d: ldarg.0
IL_001e: ldarg.1
IL_001f: stfld int32 MyTest.SomeType::x
IL_0024: ldarg.0
IL_0025: ldarg.2
IL_0026: stfld int32 MyTest.SomeType::y
IL_002b: nop
IL_002c: ret
} // end of method SomeType::.ctor
先執(zhí)行了初始化代碼,其他構(gòu)造函數(shù)都包含了初始化代碼,然后在執(zhí)行構(gòu)造函數(shù)中的賦值代碼,要解決這個(gè)代碼膨脹問題,方法很簡單,把初始化代碼寫在無參構(gòu)造函數(shù)中,讓其他構(gòu)造函數(shù)調(diào)用。
2:實(shí)例構(gòu)造器和結(jié)構(gòu)
值類型的工作方式與引用類型截然不同,值類型其實(shí)并不需要定義構(gòu)造函數(shù),地球人根本阻止不了值類型實(shí)例化,編譯器根本不會(huì)生產(chǎn)默認(rèn)無參構(gòu)造函數(shù),如果你顯示聲明無參構(gòu)造函數(shù),編譯根本通過不了,報(bào)錯(cuò)“結(jié)構(gòu)不能包含顯式的無參數(shù)構(gòu)造函數(shù)”。由于值類型存在棧中,根本不需要對(duì)堆中的數(shù)據(jù)進(jìn)行引用,所以我們可以在定義的時(shí)候就直接賦值,(int i=0;string s=”a”;Point p;p.X=2;)他根本不需要new,new當(dāng)然是可以的,調(diào)用構(gòu)造函數(shù)會(huì)初始化所有的字段成相應(yīng)類型的默認(rèn)值,實(shí)例如下:
public struct Point
{
public int x, y;
//public Point() { }//錯(cuò):結(jié)構(gòu)不能包含顯式的無參數(shù)構(gòu)造函數(shù)
//public int z = 4;//錯(cuò):結(jié)構(gòu)中不能有實(shí)例字段初始值設(shè)定項(xiàng)
//public Point(int x) //在控制返回調(diào)用方之前,字段“Point.y”必須被完全賦值,要解決這個(gè)問題就手動(dòng)給y加一個(gè)默認(rèn)值吧,
//你也可以加this=new Point();將所有的字段的值初始化為0或null
//{
// this.x = x;
//}
public void Test()
{
Point p;
p.x = 1;
p.y = 2;
Console.WriteLine(p.x+","+p.y);//輸出1,2
}
}
結(jié)構(gòu)的特點(diǎn):
1:不能顯示定義無參構(gòu)造函數(shù)
2:不能在定義字段的時(shí)候初始化
3:聲明有參構(gòu)造函數(shù)的時(shí)候,要初始化所有的字段
3:類型構(gòu)造器
實(shí)例構(gòu)造器就是靜態(tài)構(gòu)造函數(shù),他的作用是設(shè)置類型的初始化狀態(tài),靜態(tài)構(gòu)造函數(shù)只能有一個(gè),且是無參的,不能有訪問修飾符修飾,默認(rèn)就是private,由編譯器調(diào)用執(zhí)行。實(shí)例如下:
public class SomeType
{
public static int x = 520;
static SomeType()
{
x = 112;
}
}
//用.NET reflector查看源碼,如下
public class SomeType
{
public static int x ;
static SomeType()
{
x = 520;
x = 0x70;
}
public SomeType() { }
}
在定義靜態(tài)字段并初始化,編譯器會(huì)自動(dòng)生成一個(gè)類型構(gòu)造器(靜態(tài)構(gòu)造函數(shù)),并將靜態(tài)字段的初始化代碼插在類型構(gòu)造器的前面,從上面的代碼可以看出,定義時(shí)初始化和在類型構(gòu)造器中初始化只需要一個(gè)即可,還有112的16進(jìn)制為0x70,所以在代碼中看到16進(jìn)制也不用大驚小怪,根本不涉及性能問題,若定義了靜態(tài)字段,但沒有初始化任何一個(gè),編譯器是不會(huì)生成類型構(gòu)造器的。但是靜態(tài)字段還是會(huì)被初始化,其實(shí)不管是靜態(tài)的還是非靜態(tài)的字段都是會(huì)被編譯器自動(dòng)初始化的,int類型的初始化為0;bool:False;string:null,這就是為什么你在實(shí)例化實(shí)體的時(shí)候,有些字段你沒有初始化,卻不會(huì)報(bào)錯(cuò),而且你知道沒有初始化的字符串的值就是null,也就是說編譯器會(huì)幫你初始化你沒有初始化的字段,然而在方法中定義的局部變量是需要自己初始化的,如果你沒有初始化,會(huì)報(bào)一個(gè)錯(cuò)誤“使用了未賦值的局部變量X”。
4:操作符重載方法
要想實(shí)現(xiàn)操作符重載,只需要保證以下兩點(diǎn),其他的話都是浮云:
1:操作符重載方法必須是public和static方法
2:操作符重載方法至少有一個(gè)參數(shù)的類型與當(dāng)前定義這個(gè)方法的類型相同。之所以是要這個(gè)條件是為了使編譯器在合理的時(shí)間內(nèi)找到要綁定的操作方法,實(shí)例如下
public class Complex
{
public int data;
public Complex(int data)
{
this.data = data;
}
public static Complex operator +(Complex c1, Complex c2)
{
return new Complex(c1.data+c2.data);
}
public void Test()
{
Complex c1 = new Complex(1);
Complex c2 = new Complex(2);
Complex c3 = c1 + c2;
Console.WriteLine(c3.data);//輸出3
}
}
5:轉(zhuǎn)換操作符方法
要實(shí)現(xiàn)轉(zhuǎn)換操作符方法,條件和操作符重載方法的條件是一樣的,實(shí)例如下:
public class Rational
{
public Rational(int data)
{
this.data = data;
}
public Rational(char data)
{
this.data = (int)data;
}
//隱式類型轉(zhuǎn)換:int->Rational
public static implicit operator Rational(int data)
{
return new Rational(data);
}
//隱式類型轉(zhuǎn)換:char->Rational
public static implicit operator Rational(char data)
{
return new Rational(data);
}
//顯示類型轉(zhuǎn)換 Rational->int
public static explicit operator int(Rational val)
{
return val.data;
}
//顯示類型轉(zhuǎn)換 Rational->char
public static explicit operator char(Rational val)
{
return Convert.ToChar(val.data);
}
public void Test()
{
Rational r1 = 1;//將int類型隱式轉(zhuǎn)換成Rational
Rational r2 = '2';//將char類型隱式轉(zhuǎn)換成Rational
int i = (int)r1;//將Rational類型顯示轉(zhuǎn)換成int
char c = (char)r2;//將Rational類型顯示轉(zhuǎn)換成char
Console.WriteLine("i=" + i);//輸出:i=1
Console.WriteLine("c=" + c);//輸出:c=2
}
int data;
}
隱式和顯示類型轉(zhuǎn)換的實(shí)現(xiàn)原理就這么簡單,在C++中隱式類型轉(zhuǎn)換根本不需要你寫代碼,只要有相應(yīng)的public構(gòu)造函數(shù)就可以了,如int轉(zhuǎn)換成Rational,只需要有構(gòu)造函數(shù)public Rational(int data)就可以了,如Rational r=1;編譯器會(huì)盡一切努力尋找將int類型轉(zhuǎn)換成Rational的方法,當(dāng)它發(fā)現(xiàn)這個(gè)構(gòu)造函數(shù),他說都不說就幫你進(jìn)行轉(zhuǎn)換了,就因?yàn)檫@樣有時(shí)候非??拥?,你一個(gè)int類型無緣無故的就變成Rational了,而你卻根本不知道怎么回事,有時(shí)候?yàn)榱私鉀Q這個(gè)問題,還得自己定義一個(gè)類(Uint)來封裝int,然后構(gòu)造函數(shù)改成Rational(Uint data),C#就沒有這個(gè)問題,當(dāng)然你要想實(shí)現(xiàn)隱式類型轉(zhuǎn)換就自己寫代碼吧。
6:擴(kuò)展方法
實(shí)現(xiàn)擴(kuò)展方法的條件:
1:定義擴(kuò)展方法的類必須是非泛型靜態(tài)類
2:這個(gè)類必須有自己的作用域,即不能是內(nèi)部類
3:方法必須是public和static
4:方法的第一個(gè)參數(shù)必須用this修飾,第一個(gè)參數(shù)就是你要擴(kuò)展的類型,實(shí)例如下:
public static class StringExtensions
{
public static int ToInt(this string s)
{
return Convert.ToInt32(s);
}
public void Test()
{
string s = "2";
Console.WriteLine(s.ToInt());
}
}
7:部分方法
你懂的
1:實(shí)例構(gòu)造器和類
2:實(shí)例構(gòu)造器和結(jié)構(gòu)
3:類型構(gòu)造器
4:操作符重載方法
5:轉(zhuǎn)換操作符方法
6:擴(kuò)展方法
7:部分方法
1:實(shí)例構(gòu)造器和類
構(gòu)造器是允許將類型的實(shí)例初始化為良好狀態(tài)的一種特殊方法,創(chuàng)建一個(gè)引用類型的實(shí)例時(shí),先為實(shí)例的數(shù)據(jù)字段分配內(nèi)存,然后初始化對(duì)象的附加字段(類型對(duì)象指針和同步索引),最后調(diào)用構(gòu)造函數(shù)來設(shè)置對(duì)象的初始狀態(tài)。構(gòu)造函數(shù)不能被繼承,所以不能被virtual、new、override、sealed和abstract修飾,若沒有顯示定義任何構(gòu)造函數(shù),編譯器將定義一個(gè)無參的public構(gòu)造函數(shù),但若是抽象類,編譯器將定義一個(gè)無參的protected的構(gòu)造函數(shù)
創(chuàng)建一個(gè)類的實(shí)例并不一定非要調(diào)用構(gòu)造函數(shù)。
1:使用Object的MemberwiseClone()方法。他的作用就是創(chuàng)建當(dāng)前 System.Object 的淺表副本,內(nèi)部工作機(jī)制是分配內(nèi)存,初始化對(duì)象的附加字段(類型對(duì)象指針和同步索引),然后將源對(duì)象的字節(jié)數(shù)據(jù)復(fù)制到新對(duì)象中。從下面的代碼可以看出MemberwiseClone()實(shí)現(xiàn)了對(duì)象復(fù)制,而不是簡單的對(duì)象引用。
復(fù)制代碼 代碼如下:
class Program
{
public int X;
static void Main(string[] args)
{
Program p = new Program();
p.X = 1;
Program q = (Program)p.MemberwiseClone();
Program z = p;
p.X = 2;
Console.WriteLine("p.X=" + p.X);//輸出:p.X=2
Console.WriteLine("q.X=" + q.X);//輸出:q.X=1
Console.WriteLine("z.X=" + z.X);//輸出:z.X=2
Console.Read();
}
}
2:反序列化。在網(wǎng)絡(luò)編程的時(shí)候,經(jīng)常將一個(gè)對(duì)象序列化成二進(jìn)制,然后傳輸出去,接收端反序列化成原來的對(duì)象,反序列化使用的是類
System.Runtime.Serialization.FormatterServices的方法public static object GetUninitializedObject(Type type)或
public static object GetSafeUninitializedObject(Type type)分配內(nèi)存,而在這兩個(gè)方法內(nèi)部沒有調(diào)用要被反序列化對(duì)象的構(gòu)造函數(shù)。
字段的初始化代碼會(huì)被編譯器自動(dòng)添加到相應(yīng)的構(gòu)造函數(shù)中,非靜態(tài)字段的初始化代碼會(huì)自動(dòng)加到實(shí)例構(gòu)造函數(shù)中,靜態(tài)字段的初始化代碼則添加到靜態(tài)構(gòu)造函數(shù)中,如果你的代碼中有多個(gè)字段被初始化,還有多個(gè)構(gòu)造函數(shù)的話,初始化代碼在每個(gè)構(gòu)造函數(shù)中都會(huì)有一份,這無疑會(huì)讓你的生成文件(如DLL,EXE文件)變大。
證明這一點(diǎn)的代碼如下:
復(fù)制代碼 代碼如下:
public class SomeType
{
public int x=1,y=2,z=3;
public SomeType() { }
public SomeType(int x, int y)
{
this.x = x;
this.y = y;
}
public SomeType(int x)
{
this.x = x;
}
}
//經(jīng)過IL反編譯,方法SomeType(int x, int y)代碼如下
.method public hidebysig specialname rtspecialname
instance void .ctor(int32 x,
int32 y) cil managed
{
// 代碼大小 45 (0x2d)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldc.i4.1
IL_0002: stfld int32 MyTest.SomeType::x
IL_0007: ldarg.0
IL_0008: ldc.i4.2
IL_0009: stfld int32 MyTest.SomeType::y
IL_000e: ldarg.0
IL_000f: ldc.i4.3
IL_0010: stfld int32 MyTest.SomeType::z
IL_0015: ldarg.0
IL_0016: call instance void [mscorlib]System.Object::.ctor()
IL_001b: nop
IL_001c: nop
IL_001d: ldarg.0
IL_001e: ldarg.1
IL_001f: stfld int32 MyTest.SomeType::x
IL_0024: ldarg.0
IL_0025: ldarg.2
IL_0026: stfld int32 MyTest.SomeType::y
IL_002b: nop
IL_002c: ret
} // end of method SomeType::.ctor
先執(zhí)行了初始化代碼,其他構(gòu)造函數(shù)都包含了初始化代碼,然后在執(zhí)行構(gòu)造函數(shù)中的賦值代碼,要解決這個(gè)代碼膨脹問題,方法很簡單,把初始化代碼寫在無參構(gòu)造函數(shù)中,讓其他構(gòu)造函數(shù)調(diào)用。
2:實(shí)例構(gòu)造器和結(jié)構(gòu)
值類型的工作方式與引用類型截然不同,值類型其實(shí)并不需要定義構(gòu)造函數(shù),地球人根本阻止不了值類型實(shí)例化,編譯器根本不會(huì)生產(chǎn)默認(rèn)無參構(gòu)造函數(shù),如果你顯示聲明無參構(gòu)造函數(shù),編譯根本通過不了,報(bào)錯(cuò)“結(jié)構(gòu)不能包含顯式的無參數(shù)構(gòu)造函數(shù)”。由于值類型存在棧中,根本不需要對(duì)堆中的數(shù)據(jù)進(jìn)行引用,所以我們可以在定義的時(shí)候就直接賦值,(int i=0;string s=”a”;Point p;p.X=2;)他根本不需要new,new當(dāng)然是可以的,調(diào)用構(gòu)造函數(shù)會(huì)初始化所有的字段成相應(yīng)類型的默認(rèn)值,實(shí)例如下:
復(fù)制代碼 代碼如下:
public struct Point
{
public int x, y;
//public Point() { }//錯(cuò):結(jié)構(gòu)不能包含顯式的無參數(shù)構(gòu)造函數(shù)
//public int z = 4;//錯(cuò):結(jié)構(gòu)中不能有實(shí)例字段初始值設(shè)定項(xiàng)
//public Point(int x) //在控制返回調(diào)用方之前,字段“Point.y”必須被完全賦值,要解決這個(gè)問題就手動(dòng)給y加一個(gè)默認(rèn)值吧,
//你也可以加this=new Point();將所有的字段的值初始化為0或null
//{
// this.x = x;
//}
public void Test()
{
Point p;
p.x = 1;
p.y = 2;
Console.WriteLine(p.x+","+p.y);//輸出1,2
}
}
結(jié)構(gòu)的特點(diǎn):
1:不能顯示定義無參構(gòu)造函數(shù)
2:不能在定義字段的時(shí)候初始化
3:聲明有參構(gòu)造函數(shù)的時(shí)候,要初始化所有的字段
3:類型構(gòu)造器
實(shí)例構(gòu)造器就是靜態(tài)構(gòu)造函數(shù),他的作用是設(shè)置類型的初始化狀態(tài),靜態(tài)構(gòu)造函數(shù)只能有一個(gè),且是無參的,不能有訪問修飾符修飾,默認(rèn)就是private,由編譯器調(diào)用執(zhí)行。實(shí)例如下:
復(fù)制代碼 代碼如下:
public class SomeType
{
public static int x = 520;
static SomeType()
{
x = 112;
}
}
//用.NET reflector查看源碼,如下
public class SomeType
{
public static int x ;
static SomeType()
{
x = 520;
x = 0x70;
}
public SomeType() { }
}
在定義靜態(tài)字段并初始化,編譯器會(huì)自動(dòng)生成一個(gè)類型構(gòu)造器(靜態(tài)構(gòu)造函數(shù)),并將靜態(tài)字段的初始化代碼插在類型構(gòu)造器的前面,從上面的代碼可以看出,定義時(shí)初始化和在類型構(gòu)造器中初始化只需要一個(gè)即可,還有112的16進(jìn)制為0x70,所以在代碼中看到16進(jìn)制也不用大驚小怪,根本不涉及性能問題,若定義了靜態(tài)字段,但沒有初始化任何一個(gè),編譯器是不會(huì)生成類型構(gòu)造器的。但是靜態(tài)字段還是會(huì)被初始化,其實(shí)不管是靜態(tài)的還是非靜態(tài)的字段都是會(huì)被編譯器自動(dòng)初始化的,int類型的初始化為0;bool:False;string:null,這就是為什么你在實(shí)例化實(shí)體的時(shí)候,有些字段你沒有初始化,卻不會(huì)報(bào)錯(cuò),而且你知道沒有初始化的字符串的值就是null,也就是說編譯器會(huì)幫你初始化你沒有初始化的字段,然而在方法中定義的局部變量是需要自己初始化的,如果你沒有初始化,會(huì)報(bào)一個(gè)錯(cuò)誤“使用了未賦值的局部變量X”。
4:操作符重載方法
要想實(shí)現(xiàn)操作符重載,只需要保證以下兩點(diǎn),其他的話都是浮云:
1:操作符重載方法必須是public和static方法
2:操作符重載方法至少有一個(gè)參數(shù)的類型與當(dāng)前定義這個(gè)方法的類型相同。之所以是要這個(gè)條件是為了使編譯器在合理的時(shí)間內(nèi)找到要綁定的操作方法,實(shí)例如下
復(fù)制代碼 代碼如下:
public class Complex
{
public int data;
public Complex(int data)
{
this.data = data;
}
public static Complex operator +(Complex c1, Complex c2)
{
return new Complex(c1.data+c2.data);
}
public void Test()
{
Complex c1 = new Complex(1);
Complex c2 = new Complex(2);
Complex c3 = c1 + c2;
Console.WriteLine(c3.data);//輸出3
}
}
5:轉(zhuǎn)換操作符方法
要實(shí)現(xiàn)轉(zhuǎn)換操作符方法,條件和操作符重載方法的條件是一樣的,實(shí)例如下:
復(fù)制代碼 代碼如下:
public class Rational
{
public Rational(int data)
{
this.data = data;
}
public Rational(char data)
{
this.data = (int)data;
}
//隱式類型轉(zhuǎn)換:int->Rational
public static implicit operator Rational(int data)
{
return new Rational(data);
}
//隱式類型轉(zhuǎn)換:char->Rational
public static implicit operator Rational(char data)
{
return new Rational(data);
}
//顯示類型轉(zhuǎn)換 Rational->int
public static explicit operator int(Rational val)
{
return val.data;
}
//顯示類型轉(zhuǎn)換 Rational->char
public static explicit operator char(Rational val)
{
return Convert.ToChar(val.data);
}
public void Test()
{
Rational r1 = 1;//將int類型隱式轉(zhuǎn)換成Rational
Rational r2 = '2';//將char類型隱式轉(zhuǎn)換成Rational
int i = (int)r1;//將Rational類型顯示轉(zhuǎn)換成int
char c = (char)r2;//將Rational類型顯示轉(zhuǎn)換成char
Console.WriteLine("i=" + i);//輸出:i=1
Console.WriteLine("c=" + c);//輸出:c=2
}
int data;
}
隱式和顯示類型轉(zhuǎn)換的實(shí)現(xiàn)原理就這么簡單,在C++中隱式類型轉(zhuǎn)換根本不需要你寫代碼,只要有相應(yīng)的public構(gòu)造函數(shù)就可以了,如int轉(zhuǎn)換成Rational,只需要有構(gòu)造函數(shù)public Rational(int data)就可以了,如Rational r=1;編譯器會(huì)盡一切努力尋找將int類型轉(zhuǎn)換成Rational的方法,當(dāng)它發(fā)現(xiàn)這個(gè)構(gòu)造函數(shù),他說都不說就幫你進(jìn)行轉(zhuǎn)換了,就因?yàn)檫@樣有時(shí)候非??拥?,你一個(gè)int類型無緣無故的就變成Rational了,而你卻根本不知道怎么回事,有時(shí)候?yàn)榱私鉀Q這個(gè)問題,還得自己定義一個(gè)類(Uint)來封裝int,然后構(gòu)造函數(shù)改成Rational(Uint data),C#就沒有這個(gè)問題,當(dāng)然你要想實(shí)現(xiàn)隱式類型轉(zhuǎn)換就自己寫代碼吧。
6:擴(kuò)展方法
實(shí)現(xiàn)擴(kuò)展方法的條件:
1:定義擴(kuò)展方法的類必須是非泛型靜態(tài)類
2:這個(gè)類必須有自己的作用域,即不能是內(nèi)部類
3:方法必須是public和static
4:方法的第一個(gè)參數(shù)必須用this修飾,第一個(gè)參數(shù)就是你要擴(kuò)展的類型,實(shí)例如下:
復(fù)制代碼 代碼如下:
public static class StringExtensions
{
public static int ToInt(this string s)
{
return Convert.ToInt32(s);
}
public void Test()
{
string s = "2";
Console.WriteLine(s.ToInt());
}
}
7:部分方法
你懂的
相關(guān)文章
C#檢測(cè)遠(yuǎn)程計(jì)算機(jī)端口是否打開的方法
這篇文章主要介紹了C#檢測(cè)遠(yuǎn)程計(jì)算機(jī)端口是否打開的方法,實(shí)例分析了C#實(shí)現(xiàn)檢測(cè)遠(yuǎn)程端口開啟的技巧,需要的朋友可以參考下2015-03-03C#實(shí)現(xiàn)簡單學(xué)生信息管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)簡單學(xué)生信息管理系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-06-06C#中實(shí)現(xiàn)Json序列化與反序列化的幾種方式
C#中實(shí)現(xiàn)Json的序列化與反序列化也算是個(gè)老話題,那么在這篇文章中我們將老話重提,本文中將會(huì)學(xué)到如何使用C#,來序列化對(duì)象成為Json格式的數(shù)據(jù),以及如何反序列化Json數(shù)據(jù)到對(duì)象。有需要的朋友們可以參考借鑒,下面來跟著小編一起學(xué)習(xí)學(xué)習(xí)吧。2016-12-12Unity 實(shí)現(xiàn)給物體替換材質(zhì)球
這篇文章主要介紹了Unity 實(shí)現(xiàn)給物體替換材質(zhì)球的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-04-04c#使用簡單工廠模式實(shí)現(xiàn)生成html文件的封裝類分享
這篇文章主要介紹了運(yùn)用了簡單工廠模式實(shí)現(xiàn)頁面靜態(tài)化封裝類,思路比較簡單,大家可根據(jù)自己的思路再擴(kuò)展此類2014-01-01