2015-09-15 13 views
21

タイプのオペランドに適用することはできないと、突然演算子 '?' 「T」<code>Feature</code>ジェネリックをしようとして

オペレータ言っコンパイラ「?」タイプのオペランドに適用することはできませんここでは「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ワンライナー。

+1

これは本当に面白いです。私はそれがバグかもしれないと思う。 'T:class'を使って示唆する答えは、' Func 'が' T'ではなくヌルであるかどうかをチェックしているという事実を見逃しています。それが動作すれば、 'GetValue?.Invoke()'構文もうまくいくはずです。 次のように書くことができます: 'return GetValue?.Invoke()??デフォルト(T) ' – kjbartel

+0

@kjbartel:'? 'が原因です。式が 'null'で、' default(T) 'ではなく' null'を返します。 – Joey

+1

Func はnullです。 – kjbartel

答えて

26

でなければなりません。構造体はヌルにすることはできませんし、どちらも列挙できません。

public abstract class Feature<T> where T : class 

はなぜそれだけでは動作しません:

classwhere問題が解決しない追加?

Invoke()TGetValuenullの場合、?演算子は、Tの戻り値をnullに設定します。これはできません。例えば、Tintの場合、実際に必要なタイプ(T = int)がないため、nullable(int?)にすることはできません。

コードでTintに変更すると、問題が非常にはっきりとわかります。

get 
{ 
    int? x = GetValue?.Invoke(); 
    return x.GetValueOrDefault(0); 
} 

これはヌル伝播演算子があなたのために行うものではありません。 default(T)の使用に戻すと、何をすべきか正確に分かり、「問題のある」ヌル伝播を回避できます。

+0

'T:class'節を追加すると別の問題が発生しますか、別の質問をするか、それとも簡単ですか?私は 'public class FeatureBool:Feature {}'を持っていて、今はこう言っています* "タイプ 'T'は、ジェネリックタイプまたはメソッド 'Feature 'でパラメータ 'T'として使用するためには、 。 'class'よりも良い選択肢があるかどうかは分かりません(' object'を使うことはできません)、あるいは 'FeatureBool'自体で何かするべきでしょうか? – Sinatr

+4

私は、C#コンパイラがこれを許可しておらず、この作業をするためにオプション#2が必要であるということを受け入れるだけです。すべてが1つのライナーである必要はありません、そうですか? –

+1

作動エラーは、 '条件付きアクセス式のタイプ 'T'をヌル可能タイプに持ち上げることができません。 '。?'演算子は子の戻り値の型を 'Nullable <>'にラップします。コンパイラは 'Nullable 'を処理できますが、 'Nullable 'は処理できません。なぜなら、 'Action .Invoke'のエラーがないからです。 –

4

私の知る限り?.オペレータは、nullで動作するようにハードコードされていることである、それは参照型またはNULL可能値型のために動作しますが、ない通常値の型を知っているよう。問題は、の代わりにnullの式がnullの場合、演算子がnullを返す可能性があります。

ここではTclassに制限して修正することができます。

+0

@PanagiotisKanavos: 'Nullable 'は、コンパイラによってNullableとして扱われますが、それは[値型]です(http://referencesource.microsoft.com/#mscorlib/system/nullable.cs,ffebe438fd9cbf0e)。 – Joey

+0

はまず参照元をチェックしてください。 –

8

Tはない、すべてがnullすることができますので、あなたは(object別名)NULL可能なものであることをTを絞り込むする必要が参照型またはNULL可能タイプ

public abstract class Feature<T> where T : class 
{ 
    // ... 
} 
関連する問題