2

このようなジェネリック関数を作成しようとしています。これは、主にDateTime、int、およびstringの基本型でインスタンス化する予定です。

static T MyParameter<T>(string value, T defaultValue)
{
    return value.StartsWith("$$") ? defaultValue : T.Parse(value);
}

T が "Parse" を持つという保証がないため、これはコンパイルされません。

それを実装する「直接的な」方法はありますか?(つまり、リフレクションやデリゲートが汚い仕事をするのを避けます)。

トリックを行う T への制約が見つかりません。

4

3 に答える 3

6

一般的なケースの parse メソッドを渡すことができます。

static T MyParameter<T>(string value, T defaultValue, Func<string, T> parse)
{
    return value.StartsWith("$$") ? defaultValue : parse(value);
}

ただし、便宜上、使用する予定の最も一般的な型にオーバーロードを提供することをお勧めします。

static int MyParameter(string value, int defaultValue)
{
    return MyParameter(value, defaultValue, int.Parse);
}
static DateTime MyParameter(string value, DateTime defaultValue)
{
    return MyParameter(value, defaultValue, DateTime.Parse);
}
static string MyParameter(string value, string defaultValue)
{
    return MyParameter(value, defaultValue, x => x);
}

これが本当に気に入らない場合は、リフレクションを使用できますが、お勧めしません。

static T MyParameter<T>(string value, T defaultValue)
{
    if (value.StartsWith("$$"))
    {
        return defaultValue 
    }

    var method = typeof(T).GetMethod("Parse", new[] { typeof(string) });
    return (T)method.Invoke(null, new[] { value });
}
于 2013-10-07T20:42:25.410 に答える
2

ジェネリックに Constraint を使用するのはどうですか?

http://msdn.microsoft.com/en-us/library/d5x73970.aspx

したがって、メソッドは次のようになります。

static T MyParameter<T>(string value, T defaultValue) where T : IParseable
{
    return (T)(value.StartsWith("$$") ? defaultValue : defaultValue.Parse(value));
}

もちろん、これは、使用されるすべての型が IParseable を実装する必要があることを意味します。

于 2013-10-07T20:55:58.750 に答える
1

これはそれを行う必要があります:

static T MyParameter<T>(string value, T defaultValue)
{
    return (T) (value.StartsWith("$$") ? defaultValue : Convert.ChangeType(value, typeof (T)));
}
于 2013-10-07T20:50:07.880 に答える