簡體   English   中英

Func委托(C#)中的out參數修飾符

[英]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關鍵字在這里做什么? 有什么需要改變的嗎?

簡短答案

您很少需要擔心泛型類型定義中的inout關鍵字。 使用in / out通用類型參數定義的類通常在使用時會“正常工作”,我敢打賭大多數開發人員永遠不會在自己的代碼中編寫這樣的定義。

更長的答案

要獲得完整的解釋,您應該閱讀代表中的 協方差,協方差方差 我剩下的答案只是一些說明性的示例代碼。

為了簡化說明,我要去解釋inout通過分別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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM