2016-10-04 17 views
3

nullを返すことができる汎用メソッドを作成しています。汎用パラメータTをC#でNull可能にするには?

例として、私は以下のこのメソッドGetSecondSmallest(List<T>)を作成しました。この関数は、IComparableのすべての項目をループし、可能であれば2番目に小さい項目を返します。このアイテムが存在しない場合はnullを返します。この方法の

public T? GetSecondSmallest<T>(List<T> items) where T : Nullable, IComparable 
{ 
    if (items.Count == 0) return null; 

    T smallest = items[0]; 
    T? secondSmallest = null; 

    // Find second smallest by looping through list 

    return secondSmallest; 
} 

二つの例の使用法は次のようになります。

GetSecondSmallest(new List<int> {4, 2, 3, 1, 6, 8}) // Should return 2 
GetSecondSmallest(new List<MyComparable> {new MyComparable('x')}) // Should return null 

あなたはこのコードをコンパイルしようとするとあなたは問題がここにあるものを見ます:

エラーCS0717 'Nullable':静的クラスは制約として使用できません。

このメソッドは、Tまたはnullのインスタンスを返します。


EDIT:私はすでにthis questionを見てきましたが、これは私の状況では、パラメータも汎用的なので、私の質問に答えていない、とNullableでなければなりません。したがって、その回答は適用されません。

+1

@ j0ey_wh 'INullable'インターフェイスは、データベースで使用するように設計されています。 'Nullable 'が実装しているインタフェースではありません。 –

答えて

1

タプルなどのラッパークラスを使用して、結果の値をラップします。次の例では、2番目に小さい項目がない場合はnullが返されます。それ以外の場合は、2番目に小さい値のタプルが返されます。

public static void Main() 
{ 
    var result1 = GetSecondSmallest(new List<int> 
    { 
    4, 2, 3, 1, 6, 8 
    }); // Should return 2 

    var result2 = GetSecondSmallest(new List<MyComparable> 
    { 
    new MyComparable('x') 
    }); // Should return null 

    Console.WriteLine("result1=" + result1.Item1); 
    Console.WriteLine("result2 == null: " + (result2 == null)); 
} 

public static Tuple<T> GetSecondSmallest<T>(List<T> items)where T : IComparable 
{ 
    return items.Skip(1).Select(v => Tuple.Create(v)).FirstOrDefault(); 
} 
0

変更のNullableに戻り値の型、および非NULL可能パラメータ

簡単な例でメソッドを呼び出します。このよう

static void Main(string[] args) 
{ 
    int? i = GetValueOrNull<int>(null, string.Empty); 
} 


public static Nullable<T> GetValueOrNull<T>(DbDataRecord reader, string columnName) where T : struct 
{ 
    object columnValue = reader[columnName]; 

    if (!(columnValue is DBNull)) 
     return (T)columnValue; 

    return null; 
} 

Nullable type as a generic parameter possible?

UPD

public Nullable<T> GetSecondSmallest<T>(List<T> items) where T : IComparable 
{ 
    if (items.Count == 0) return null; 

    Nullable<T> smallest = items[0]; 
    Nullable<T> secondSmallest = null; 

    // Find second smallest by looping through list 

    return secondSmallest; 
} 
+2

私の2番目の使用例を試しましたか?これは今ではTがnullableでないことが必要なので、このソリューションでは機能しません –

3

null またはオブジェクトを絞り込むことはできません。Tをnullにすることはできません。あなたはTT?の2つの方法を作る必要があります。

public T? GetSecondSmallestAsNullable<T>(List<T> items) where T : struct 
{ 
    return null; 
} 

public T GetSecondSmallestAsClass<T>(List<T> items) where T : class 
{ 
    return null; 
} 
+0

基本的に重複したコードはここでは最高の解決策ですか?より良い方法が必要です –

+1

ジェネリックでnullableをサポートするために.NETフレームワークを書き直しますか? –

+3

もう1つのアプローチは、[オプションタイプ](https://www.google.co.za/webhp?#q = option + type + in + C%23)を呼び出して、述部に一致するものがないことを呼び出し元に示す。これにより、ヌル可能な型のstruct vクラスのジレンマが削除されます。ただし、FPのフレームワークコードを大幅にリファクタリングする必要があります。 – StuartLC

関連する問題