前往
大廳
主題

in 參數修飾詞 (C# 7.2以上支援)

Yang | 2022-07-25 13:35:10 | 巴幣 0 | 人氣 257

參考微軟MSDN的介紹
in關鍵字會使引數以傳址方式傳遞,但可確保不會修改引數。

開始嘗試在輸入參數加上in,因為少了建立新的記憶體區塊以及複製資料的動作,推測能減少程式的記憶體使用以及優化效能,也能避免不小心改錯參數的風險

C# 7.2以上專案支援,測試中

in 參數的限制
您不可為下列幾種方法使用 in、ref 和 out 關鍵字:
使用 async 修飾詞定義的 async 方法。
迭代器方法,其包括 yield return 或 yield break 陳述式。
擴充方法的第一個引數不能有 in 修飾詞,除非該引數是結構。
擴充方法的第一個引數,也就是該引數是泛型型別 (即使該型別限制為結構時也一樣 )

除了MSDN上寫的限制,另外發現在自定義的特性(Attribute)上使用會有問題

//將log加入AppLog動態資料集(_appLogCollection),顯示在DataGrid上
void AppendLog(in LogLevel level, in string msg, [CallerLineNumber] in int lineNumber = 0, [CallerMemberName] in string memberName = "")
{
    AppLog log = new AppLog()
    {
        Level = level.Name.ToUpper(),
        ThreadID = Thread.CurrentThread.ManagedThreadId,
        Message = msg,
        CallerLineNumber = lineNumber,
        CallerMemberName = memberName,
    };

    _appLogCollection.Add(log);
}

[Serializable]
public class NotifyPropertyChanged : INotifyPropertyChanged
{
    /// <summary>
    /// 事件通知指定欄位有資料變更
    /// </summary>
    [field: NonSerialized()]
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(in PropertyChangedEventArgs e)
    {
        PropertyChanged?.Invoke(this, e);
    }

    /// <summary>
    ///
    /// </summary>
    /// <param name="propertyName">欄位名稱</param>
    protected virtual void OnPropertyChanged([CallerMemberName] in string propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    /// <summary>
    /// 有一個欄位可能有資料異動
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="field">舊資料</param>
    /// <param name="value">新資料</param>
    /// <param name="propertyName">欄位名稱</param>
    /// <returns>是否有異動</returns>
    protected virtual bool OnPropertyChanged<T>(ref T field, in T value, [CallerMemberName] in string propertyName = "")
    {
        if (EqualityComparer<T>.Default.Equals(field, value))
        {
            return false;
        }

        field = value;
        OnPropertyChanged(propertyName);

        return true;
    }

    /// <summary>
    /// 有多個欄位可能有資料異動
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="field">舊資料</param>
    /// <param name="value">新資料</param>
    /// <param name="propertyName">第一個欄位名稱</param>
    /// <param name="otherNames">其它欄位名稱</param>
    /// <returns>是否有異動</returns>
    protected virtual bool OnPropertiesChanged<T>(ref T field, in T value, in string propertyName, params string[] otherNames)
    {
        if (EqualityComparer<T>.Default.Equals(field, value))
        {
            return false;
        }

        field = value;
        OnPropertyChanged(propertyName);

        foreach (string name in otherNames)
        {
            OnPropertyChanged(name);
        }

        return true;
    }
}
送禮物贊助創作者 !
0
留言

創作回應

更多創作