聲明的方法是這樣的:
protected abstract void Validate<T>(IEnumerable<T> records)
,並調用它是這樣的:
Validate(records);
編譯器應該能夠推斷泛型方法的類型,沒有必要將其列入明確。如果你真的想包括類型,或者類型推斷由於某種原因失敗(你就會知道這一點,因爲編譯器會抱怨),你可以這樣做:
Validate<LogEventRecord>(records);
那麼你的實現可以使用記錄像這樣:
protected override void Validate<T>(IEnumerable<T> records)
{
//you can use a foreach loop
foreach (T record in records)
{
}
//Or "linq" operators:
bool isValid = records.Any(r => r.IsNotValid);
//Or linq query comprehension syntax:
bool isValid2 = (from r in records
where r.IsNotValid
select r).Any();
}
但現在你知道T
的唯一的事情是,它是一個對象。你不能用類型爲「object」的變量做很多事情,所以這還不是很有用。實際上,我樣本中的後兩個選項現在會失敗,因爲.IsNotValid
屬性可能不存在。相反,你可能想要(也許已經有)一個接口來描述你將使用這個函數的對象:它們可能總是要麼是日誌,要麼是某些公共基類型的記錄。如果是這樣的話,你有兩個選擇。首先是限制你的泛型類型。你這樣做,通過改變你的方法簽名是這樣的:
protected abstract void Validate<T>(IEnumerable<T> records) where T : MyRecordInterface
另一種選擇是,在C#4上有接口(包括IEnumerabe < T>,將讓你避免了需要變化的新支持。這裏所有的通用方法,要充分利用這一點,只是確保你在Visual Studio 2010中使用.NET 4.0或更高版本,並宣佈這樣的方法:
protected abstract void Validate(IEnumerable<MyRecordInterface> records)
你需要.NET 4中,而不是隻是針對早期版本的框架的c#4,因爲您需要IEnumerable的.Net 4版本。它的建立包含了對差異的必要支持。
最後,還有第三個選項。你可以一個delegate
參數添加到您的方法,每個項目在列表轉換爲一個布爾值,像這樣:
protected abstract void Validate<T>(IEnumerable<T> records, Func<T, bool> isValid)
。
protected override void Validate<T>(IEnumerable<T> records, Func<T, bool> isValid)
{
bool recordsAreValid = records.Any(r => !isValid(r));
}
。
Validate(records, l => ((LogEventRecord)l).IsValid);
的IList幾乎總是preferrable列出,和IEnumerable 幾乎總是preferrable到IList中。 –