[英]Why am I allowed to pass in more parameters than I defined for the method?
我正在嘗試學習一個使用C#的名為Xamarin的移動開發框架,我也是一個初學者。 當我遇到以下代碼時,我正在關注一個教程:
public static class PhonewordTranslator
{
public static string ToNumber(string raw)
{
if (string.IsNullOrWhiteSpace(raw))
{
return "";
}
else
{
raw = raw.ToUpper();
}
var newNumber = new StringBuilder();
foreach (var c in raw)
{
if (" -0123456789".Contains(c))
{
newNumber.Append(c);
}
else
{
var result = TranslateToNumber(c);
if (result != null)
{
newNumber.Append(result);
}
}
}
return newNumber.ToString();
}
static bool Contains (this string keyString, char c)
{
return keyString.IndexOf(c) >= 0;
}
static int? TranslateToNumber(char c)
{
if ("ABC".Contains(c))
return 2;
else if ("DEF".Contains(c))
return 3;
else if ("GHI".Contains(c))
return 4;
else if ("JKL".Contains(c))
return 5;
else if ("MNO".Contains(c))
return 6;
else if ("PQRS".Contains(c))
return 7;
else if ("TUV".Contains(c))
return 8;
else if ("WXYZ".Contains(c))
return 9;
return null;
}
為什么我允許將一個參數傳遞給Contains()方法,即使它顯然具有兩個參數也是如此。 這樣做的目的是什么?
在您的代碼中, Contains
方法定義為Extension Method
。
那么什么是擴展方法
擴展方法使您可以將方法“添加”到現有類型,而無需創建新的派生類型,重新編譯或修改原始類型。 擴展方法是一種特殊的靜態方法,但是它們的調用就像是擴展類型上的實例方法一樣。
以及它們如何工作?
擴展方法定義為靜態方法,但使用實例方法語法調用。 它們的第一個參數指定方法將對哪種類型進行操作,並且此參數之前帶有this修飾符。
在您的代碼中,您將使用實例方法語法調用擴展方法。 但是,編譯器生成的中間語言(IL)將您的代碼轉換為對靜態方法的調用。
讓我們通過一個例子來理解這一點。
眾所周知,如果我們通過調用ToString
方法將null
object
轉換為string
,那么它將拋出NullReferenceException
。 雖然我可以調用Convert.ToString()
方法,該方法不會為null
值引發異常。 但是,如果我想像語法一樣堅持使用ToString
方法,該怎么辦? 因此,在需要將任何object
轉換為string
值的object
上調用ToString
方法之前,首先需要檢查null
,然后將其轉換為string
值。 但這很耗時,我必須為此編寫代碼。
為了克服這個問題,我創建了一個名為ToStringNullSafe
的ExtensionMethod
。 首先要檢查object
null
值。 如果null
則將其轉換為Empty String
否則將object
值轉換為string
值。
這是我的擴展方法的定義
public static string ToStringNullSafe(this object obj)
{
return (obj ?? string.Empty).ToString();
}
這就是調用語法
DataRow dr = dataTable.Rows[0];
string firstName = dr["firstName"].ToStringNullSafe();
創建ExtensionMethod
需要考慮的一件事是ExtentionMethod
名稱應與.Net
框架中提供的方法不同。 就像我們有ToString
方法進行string
轉換一樣。 因此,我無法使用此名稱創建擴展方法。
如果我使用.Net
框架方法名稱作為擴展名創建擴展方法,那么不會出現編譯器錯誤,但是不會調用您創建的ExtensionMethod
。 假設如果我通過將擴展名定義為ToString
創建擴展方法,則編譯器將不會調用我的擴展方法。 它將調用.Net
框架提供的ToString
方法。
在Visual Studio中, ExtensionMethos
的Down Arrow
標志出現
擴展方法可以放在單獨的類中,例如我有一個擴展方法可以將DataTable
轉換為單獨類中的string[][] array
。
namespace myProject.Common
{
public static class ExtensionMethods
{
public static object ToStringArray(this DataTable dt, params string[] columns)
{
//AsEnumerable is also a Extension Method provided by .Net framework.
return dt.AsEnumerable().Select(x => columns.Select(c => x[c].ToStringNullSafe()).ToArray()).ToArray();
}
}
public static string ToStringNullSafe(this object obj)
{
return (obj ?? string.Empty).ToString();
}
}
要在我的項目中使用此ExtensionMethod
,我必須先添加using語句
using myProject.Common;
然后我可以按以下方式調用此方法:
var dataTableData = dataTable.ToStringArray("firstName", "LastName", "Age", "Email");
調用擴展方法的另一種語法是:
var dataTableData = ExtensionMethods.ToStringArray(dataTable,"firstName", "LastName", "Age", "Email");
進一步閱讀:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.