Feature
を汎用にしようとすると、突然コンパイラが言った
演算子 '?'はタイプ 'T'のオペランドには適用できません
これがコードです
public abstract class Feature<T>
{
public T Value
{
get { return GetValue?.Invoke(); } // here is error
set { SetValue?.Invoke(value); }
}
public Func<T> GetValue { get; set; }
public Action<T> SetValue { get; set; }
}
代わりにこのコードを使用することが可能です
get
{
if (GetValue != null)
return GetValue();
return default(T);
}
しかし、私はその素敵なC#6.0ワンライナーを修正する方法を考えています。
すべてがnull
になるわけではないので、T
をnull許容値(別名object
)に絞り込む必要があります。構造体をnullにすることはできず、列挙型にすることもできません。
where
にclass
を追加すると、問題が修正されます。
_public abstract class Feature<T> where T : class
_
では、なぜそれがうまくいかないのですか?
Invoke()
はT
を生成します。 GetValue
がnull
の場合、_?
_演算子はタイプT
の戻り値をnull
に設定しますがこれはできません。たとえば、T
がint
の場合、実際の型が必要なため(T
= int
)、null許容(_int?
_)にすることはできません。 )ではありません。
コードでT
をint
に変更すると、問題が非常に明確にわかります。あなたが尋ねることの最終結果はこれです:
_get
{
int? x = GetValue?.Invoke();
return x.GetValueOrDefault(0);
}
_
これは、null伝搬演算子が行うことではありません。 default(T)
の使用に戻ると、何をすべきかが正確にわかり、「問題のある」null伝播を回避できます。
T
は、参照型またはnull許容型である必要があります
public abstract class Feature<T> where T : class
{
// ...
}
私の知る限り、_?.
_演算子はnull
で機能するようにハードコードされています。つまり、参照型またはnull許容値型では機能しますが、normal値型では機能しません。この問題は、式がdefault(T)
ではなくnull
の場合、演算子がnull
を返す可能性があります。
ここでT
をclass
に制限することで修正できる可能性があります。