亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

具有可為空引用類型的輸出參數

具有可為空引用類型的輸出參數

C#
搖曳的薔薇 2022-06-12 16:36:58
我已經為我Option的一些項目實現了一個類型,如下所示:public abstract Option<T> {}public class None<T> : Option<T>public class Some<T> : Option<T> {    public T Value { get; }    public Some(T value)    {        Value = value;    }}為了找出一個選項是否包含一個值,我使用了這個利用模式匹配的擴展方法:public static bool TryGetValue<T>(this Option<T> option, out T value){    if (option is Some<T> some)    {        value = some.Value;        return true;    }    value = default;    return false;}我現在收到以下警告return default;無法將 null 文字轉換為不可為 null 的引用或不受約束的類型參數我不可能將泛型參數限制T為classor struct。例如,如果我將泛型參數限制為 ,則class無法生成Option<int?>實例,因為Nullable<int>類型是 astruct本身。通過后綴將 out 參數聲明為可為空也不?是看起來的解決方案。對我來說,在這個階段,類型系統有些破損或沒有徹底考慮過。Nullable 應該是 aclass或者需要有一個通用參數限制,例如:public static bool TryGetValue<T>(this Option<T> option, out T value)     where T : nullable [...]是否有另一種可能適合此問題的方法?我錯過了什么?
查看完整描述

2 回答

?
ITMISS

TA貢獻1871條經驗 獲得超8個贊

使用MaybeNullWhenAttribute或NotNullWhenAttribute。我推薦MaybeNullWhen,因為它甚至適用于不受結構或引用類型約束的類型參數。


public static bool TryGetValue<T>(this Option<T> option, [MaybeNullWhen(false)] out T value)

{

    if (option is Some<T> some)

    {

        value = some.Value;

        return true;

    }


    value = default;

    return false;

}

用法:


if(option.TryGetValue(out var value))

{

    value.SomeMethod(); // no warning - value is known to be non-null here

}

value.SomeMethod(); // warning - value may be null here.

該屬性在 .Net 標準 2.1/.new core 3.0 之前不可用,但如果它不可用,您可以自己手動定義它。確保它是內部的,否則如果另一個庫也將它定義為公共并且有人從這兩個庫繼承它會導致沖突:


namespace System.Diagnostics.CodeAnalysis

{

    /// <summary>Specifies that when a method returns <see cref="ReturnValue"/>, the parameter may be null even if the corresponding type disallows it.</summary>

    [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]

    internal sealed class MaybeNullWhenAttribute : Attribute

    {

        /// <summary>Initializes the attribute with the specified return value condition.</summary>

        /// <param name="returnValue">

        /// The return value condition. If the method returns this value, the associated parameter may be null.

        /// </param>

        public MaybeNullWhenAttribute(bool returnValue) => ReturnValue = returnValue;


        /// <summary>Gets the return value condition.</summary>

        public bool ReturnValue { get; }

    }

(取自https://github.com/dotnet/runtime/blob/6077cf01f951a711a26a8d5970b211b6031b5158/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/NullableAttributes.cs#L45-L60)


查看完整回答
反對 回復 2022-06-12
?
侃侃爾雅

TA貢獻1801條經驗 獲得超16個贊

到目前為止,使用 C# 8.0 還沒有完全通用的解決方案。

[NotNullWhen()]屬性是向前邁出的一步,但隨后我們將遇到以下情況:

可空類型參數必須已知為值類型或不可空引用類型。考慮添加“類”、“結構”或類型約束。

我想說這是現在可以為空的一個主要痛點。我希望它會在 8.1 或其他東西中得到解決......

相關討論 - https://github.com/dotnet/cshaplang/issues/2194 -允許泛型方法指定 T?不限于 class 或 struct。

where作為一種解決方法,可以制作具有所需約束的多個擴展方法副本以涵蓋所有可能的類型。

由于問題#1628已修復,現在可以在單個擴展類中包含所有重載。但它仍然需要為每個獨立的通用輸出參數增加一倍的擴展方法數量。哎呀!


查看完整回答
反對 回復 2022-06-12
  • 2 回答
  • 0 關注
  • 243 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號