15

次のヘルパーメソッドがあります。

public static T CreateRequest<T>()
    where T : Request, new()
{
    T request = new T();
    // ...
    // Assign default values, etc.
    // ...
    return request;
}

別のヘルパーの別のメソッドの内部からこのメソッドを使用したい:

public T Map<F, T>(F value, T toValue)
    where T : new()
    where F : new()
{
    if (typeof(T).BaseType.FullName == "MyNamespace.Request")
    {
        toValue = MyExtensions.CreateRequest<T>();
    }
    else
    {
        toValue = new T();
    }
}

しかし、その後、エラーが発生します:

型 'T' は、ジェネリック型またはメソッド 'MyExtensions.CreateRequest()' で型パラメーター 'T' として使用できません。'T' から 'MyNamespace.Request' へのボックス変換や型パラメーターの変換はありません。

CreateRequest が問題なく使用できるように、タイプ「T」をキャストする方法はありますか?

編集:

私は2つのことができることを知っています:

  • CreateRequest の制約を緩めるか、
  • マップの制約を強化します。

しかし、CreateRequest では Request クラスのユーザー プロパティを使用するため、最初のことはできません。また、Map 関数で他の型 (Request から継承されない) を使用するため、2 番目のことはできません。

4

2 に答える 2

9

このシナリオでは、 の一般的な制限を緩める必要がありますCreateRequest

public static T CreateRequest<T>()
    where T : new()
{
    if(!typeof(Request).IsAssignableFrom(typeof(T)))
        throw new ArgumentException();

    var result = new T();
    Request request = (Request)(object)result;
   // ...
   // Assign default values, etc.
   // ...
   return result ;
}

このパラメーターのコンパイル時の検証が失われるため、苦痛になる可能性があります。

または、CreateRequest他の場所でメソッドを使用する場合は、このシナリオ専用の非ジェネリック オーバーロードを作成します。

public static object CreateRequest(Type requestType)
 {
    if(!typeof(Request).IsAssignableFrom(requestType))
        throw new ArgumentException();

    var result = Activator.CreateInstance(requestType);
    Request request = (Request)result;
   // ...
   // Assign default values, etc.
   // ...
   return result ;
}
于 2012-08-06T06:55:27.217 に答える
5

TタイプがメソッドRequest内にあることを宣言しました。CreateRequest一方、Mapメソッドでは、そのような制約はありません。の宣言を次のように変更してみてくださいMap

public T Map<F, T>(F value, T toValue)
where T : Request, new()
where F : new()
于 2012-08-06T06:48:28.870 に答える