0

Webページのバックエンドは、クエリ文字列で受け取る値に応じて異なるクラスをロードする必要があります。クラスをインスタンス化できるように、他のすべての必要なパラメーターが存在することを確認する方法が必要です。

簡略化した例を次に示します。

2つのクラス、CarおよびCycle両方がから継承しVehicleます。

Public Class Car
    Inherits Vehicle

    Private Const _wheels as Int = 4
    Private _transmission as string
    Private _mpg as int

    Public Sub New(Byval transmission as string, Byval mpg as int)
        _transmission = transmission
        _mpg = mpg
    End Sub
End Class

Public Class Cycle
    Inherits Vehicle

    Private Const _wheels as Int = 2
    Private _gears as Int

    Public Sub New(ByVal gears as Int)
        _gears = gears                
    End Sub
End Class

これは私のクエリ文字列です:?type = car&transmission =automatic

だから私はタイプが何であるかを知っていますが、クラスをインスタンス化できるようにするために必要なmpgの詳細が提供されていません。

これを行う「手動」の方法は、クエリ文字列を解析して次のように記述することです。

if not string.isNullOrEmpty(transmission) and not string.isNullOrEmpty(mpg) then
    dim c as new Car(transmission, mpg)
end if

しかし、パラメータがたくさんある場合、これは厄介になる可能性があります。また、クラスオブジェクトを編集する場合は、保守が難しくなります。

クラスに必要な各パラメーターの名前を取得し、それがクエリ文字列に存在するかどうかを確認したいと思います。ただし、クラスをインスタンス化する前に、明らかにこれを行う必要があります。それが可能かどうかはわかりません。

これはこれを行うための賢い方法ですか?存在を確認するために必要なすべてのパラメーターを単に書き出すよりも賢い方法はありますか?

この質問のコードはvb.netで記述されていますが、C#で回答について話し合うことができてうれしいです。

4

2 に答える 2

2
var queryParams = HttpUtility.ParseQueryString("?type=car&transmission=automatic");

Type type = typeof(Car);

bool canCreate = type.GetConstructors()
                .Any(c => c.GetParameters().All(p => queryParams[p.Name] != null));

クエリ文字列から車両オブジェクトを動的に作成することもできます。

var queryParams = HttpUtility.ParseQueryString("?type=car&transmission=automatic&mpg=12");

Dictionary<string, Type> types = new Dictionary<string, Type>()
{
    {"car",typeof(Car)},
    {"cycle",typeof(Cycle)}

};

Type vehicleType = types[queryParams["type"]];

var cInfo = vehicleType.GetConstructors()
        .FirstOrDefault(c => c.GetParameters().All(p => queryParams[p.Name] != null));

if (cInfo != null)
{
    var cParams=  cInfo.GetParameters()
                        .Select(p => Convert.ChangeType(queryParams[p.Name], p.ParameterType))
                        .ToArray();

    object vehicle = Activator.CreateInstance(vehicleType, cParams);
}
于 2012-10-11T14:55:03.863 に答える
1

たぶん、Activatorオブジェクトを使ってみることができますか?このようなもの(C#):

(T)Activator.CreateInstance(typeof(T), p1, p2); 

ここで、Tはあなたのタイプ(車など)です。

次に、クラスパラメータをオプションにしますが、ctorでnullをテストし、次の場合は例外をスローします。

Public Sub New(Optional Byval transmission as string, Optional Byval mpg as int)    

if string.isNullOrEmpty(transmission) then
    throw exception ....
end if
    _transmission = transmission                 
    _mpg = mpg             
End Sub 

最後に、例外を処理して次に進みます。ただのアイデア...

于 2012-10-11T15:10:42.940 に答える