[英]out parameter modifier in Func delegate (C#)
我是C#的初學者,只是有關Func委托的一個問題:
public delegate TResult Func<in T,out TResult>(T arg);
我可以理解,需要放置in
牛逼前關鍵字作為我們不想修改源輸入,但怎么樣out
TResult過嗎? 那不是意味着我們需要修改輸出,但是為什么呢? 有時候我們不是即時生成返回對象,而是說我們有一個委托:
Func<string, bool> nameFilter = str => str[0] == 'S';
因此它檢查字符串以查看其第一個字符是否為'S',然后返回true或false,因此我們動態返回此布爾值,out關鍵字在這里做什么? 有什么需要改變的嗎?
您很少需要擔心泛型類型定義中的in
和out
關鍵字。 使用in
/ out
通用類型參數定義的類通常在使用時會“正常工作”,我敢打賭大多數開發人員永遠不會在自己的代碼中編寫這樣的定義。
要獲得完整的解釋,您應該閱讀代表中的 協方差,協方差和方差 。 我剩下的答案只是一些說明性的示例代碼。
為了簡化說明,我要去解釋in
與out
通過分別Action<T>
和Func<TResult>
代替Func<T,TResult>
這些示例都使用以下兩個類:
class BaseClass {}
class DerivedClass : BaseClass {}
out
在此示例中,我模仿了Func<out TResult>
,但是刪除了out
(協方差)修飾符以演示其效果。 協方差允許我們在任何需要返回BaseType
的函數的地方使用返回 DerivedType
的函數。
class CovarianceExamples
{
// This is similar to System.Func<out TResult>(), but with covariance removed
delegate TResult InvariantFunc<TResult>();
void InvariantFuncExample()
{
// Ignore the values of these variables; it's the types that are important
InvariantFunc<BaseClass> baseFunc = null;
InvariantFunc<DerivedClass> derivedFunc = null;
baseFunc = baseFunc; // Allowed
baseFunc = derivedFunc; // Not allowed; compile error!
}
void CovariantFuncExample()
{
// Ignore the values of these variables; it's the types that are important
Func<BaseClass> baseFunc = null;
Func<DerivedClass> derivedFunc = null;
baseFunc = baseFunc; // Allowed
baseFunc = derivedFunc; // Allowed
}
}
in
在此示例中,我模仿了Action<in T>
,但是刪除了in
(對比度)修飾符以演示其效果。 逆變允許我們在期望接受DerivedType
的動作的任何地方使用接受 BaseType
的動作。
class ContravarianceExamples
{
// This is similar to System.Action<in T>(T), but with contravariance removed
delegate void InvariantAction<T>();
void InvariantActionExample()
{
// Ignore the values of these variables; it's the types that are important
InvariantAction<BaseClass> baseAction = null;
InvariantAction<DerivedClass> derivedAction = null;
baseAction = baseAction; // Allowed
derivedAction = baseAction; // Not allowed; compile error!
}
void ContravariantActionExample()
{
// Ignore the values of these variables; it's the types that are important
Action<BaseClass> baseAction = null;
Action<DerivedClass> derivedAction = null;
baseAction = baseAction; // Allowed
derivedAction = baseAction; // Allowed
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.