web-dev-qa-db-ja.com

メソッドの戻り値の型をジェネリックにするにはどうすればよいですか?

文字列、bool、int、またはdoubleを返すことができるようにこのメソッドを汎用にする方法はありますか?今のところ、文字列を返していますが、設定値として "true"または "false"を見つけることができれば、例えばboolを返したいと思います。

    public static string ConfigSetting(string settingName)
    {  
         return ConfigurationManager.AppSettings[settingName];
    }
137
MacGyver

あなたはそれをこのように一般的な方法にする必要があります:

public static T ConfigSetting<T>(string settingName)
{  
    return /* code to convert the setting to T... */
}

しかし、呼び出し側は期待する型を指定する必要があります。その場合、関連するすべての型がサポートされていると仮定して、 Convert.ChangeType を使用することもできます。

public static T ConfigSetting<T>(string settingName)
{  
    object value = ConfigurationManager.AppSettings[settingName];
    return (T) Convert.ChangeType(value, typeof(T));
}

私は完全にこれがすべて良い考えだと確信していない、あなたを気に...

300
Jon Skeet

Convert.ChangeType()を使うことができます:

public static T ConfigSetting<T>(string settingName)
{
    return (T)Convert.ChangeType(ConfigurationManager.AppSettings[settingName], typeof(T));
}
25
BrokenGlass

これを行うには多くの方法があります(優先順位別に記載されています。OPの問題に固有のものです)。

  1. オプション1:ストレートアプローチ - 一般的な関数を1つ持つのではなく、期待する型ごとに複数の関数を作成します。

    public static bool ConfigSettingInt(string settingName)
    {  
         return Convert.ToBoolean(ConfigurationManager.AppSettings[settingName]);
    }
    
  2. オプション2:変換の派手な方法を使いたくない場合 - 値をobjectに変換してからジェネリック型に変換します。

    public static T ConfigSetting<T>(string settingName)
    {  
         return (T)(object)ConfigurationManager.AppSettings[settingName];
    }
    

    注 -キャストが無効な場合はエラーになります(あなたの場合)。型キャストについてよくわからない場合は、これを実行することはお勧めしません。代わりにオプション3を選択してください。

  3. オプション3:型安全性を持つ汎用 - 型変換を処理するための汎用関数を作成します。

    public static T ConvertValue<T,U>(U value) where U : IConvertible
    {
        return (T)Convert.ChangeType(value, typeof(T));
    } 
    

    注 - Tは期待される型です。ここでwhere制約に注意してください(Uの型はエラーから保護するためにIConvertibleでなければなりません)。

8
RollerCosta

メソッドの戻り値の型を、呼び出し中にメソッドに渡すGeneric型に変換する必要があります。

    public static T values<T>()
    {
        Random random = new Random();
        int number = random.Next(1, 4);
        return (T)Convert.ChangeType(number, typeof(T));
    }

そのメソッドを介して返される値に対して型を切り捨てることができる型を渡す必要があります。

あなたが渡したジェネリック型に型をキャストできない値を返したい場合は、コードを変更するか、methodの戻り値に対して型をキャストできるようにする必要があります。したがって、このアプローチは推奨されていません。

6
Vinay Chanumolu

以下のコードを試してください。

public T? GetParsedOrDefaultValue<T>(string valueToParse) where T : struct, IComparable
{
 if(string.EmptyOrNull(valueToParse))return null;
  try
  {
     // return parsed value
     return (T) Convert.ChangeType(valueToParse, typeof(T));
  }
  catch(Exception)
  {
   //default as null value
   return null;
  }
 return null;
}
0
Sid

関数を作成し、ジェネリック型としてputパラメータを渡します。

 public static T some_function<T>(T out_put_object /*declare as Output object*/)
    {
        return out_put_object;
    }
0
Prabhakar