2011-12-14 29 views
1

私はデータベースからロードされた情報を保持するために使用している汎用クラスを持っています。書き込み時にすべての型が不明な場合は、値型を汎用オブジェクトのnull可能な列挙型にキャストしますか?

は、私はそのような、引数としてのDataRowを取るオブジェクトの知られている列名を使用したDataRowからデータを抽出する方法を、持っている:ほとんどの場合、私のデフォルトの割り当てなど

Dim loadData As T = CType(myDataRow("myColumnName"), T)) 

作品。

残念なことに、いくつかの恐ろしいデザインの制約のため、一部の列がヌルになることがあります。また、列挙型から取り出すこともできます。

これは<T>Nullable(Of SomeEnumeration)あるとき、私はSomeEnumeration.Zeroに直接0をキャストすることはできませんので、上記のコードは動作しないことを意味します。

<T>Nullable(Of [Enum])かどうかを確認する方法はありますか?あるいは、IntegersNullable(Of [Enum])にキャストできるメソッドを書くための何らかの方法ですか?

私はこれらのうちの1つを書くことができる何かを忘れているように感じるが、私の弱いgoogle-fuは何も上がらない。

EDIT:さて、以下dasblinkenlightの答えのおかげで、私はこのような状況が発生しているときを検出、しかし、私は今行う必要があることは、私がNullable(Of SomeClass)知っているタイプ<T>を取ることです、SomeClassへの型参照を取得することができますタイプNullable(Of SomeClass)の新しいオブジェクトを作成し、それをLoadDataに割り当てます。

私が試したすべてが崩壊します。何か案は?

EDIT 2:

その列挙値の値を取得するための私のソリューションでした:

Dim baseType As Type = Nullable.GetUnderlyingType(GetType(T)) 
loadData = [Enum].Parse(baseType, dataRowIn(Me._dataName)) 

私の問題は、私はbaseTypeを受け入れる任意の関数を見つけることの困難の多くを持っていたということでした実際のタイプとして

[Enum] .Parse acceptedパラメーターとして、baseTypeはdasblinkenlightのコードのために[Enum]タイプであるとわかっていました。このインスタンスではソリューションをコーディングすることができました。それは私の問題に非常に特有の解決策です(すなわち、TNullable(of SomeEnumeration)です)。それにもかかわらず解決策です。

+0

http://stackoverflow.com/a/5199474/284240 –

+0

この他のSO投稿から、これは読んでみる価値があります。http://blogs.msdn.com/b/ericlippert/archive/2009/03/19/ representation-and-identity.aspx –

+0

Dim loadData T = myDataRow.Field(Of T)( "myColumnName")と同様のものを使用しますか? –

答えて

1

私はVBの構文では非常に良好ではないですが、あなたはこの条件が真であるとき、何かが([列挙型]の)空白可能であることを知っている:

GetType(T).IsGenericType AndAlso 
GetType(T).GetGenericTypeDefinition() = GetType(Nullable(Of)) AndAlso 
GetType(T).GetGenericArguments()(0).IsEnum 

編集:

+0

私はDevexpressの "CodeRush Express"アドオンを使用している可能性がありますが、そのコードを貼り付けるとVisual Studioがクラッシュします。 – Frosty840

+0

@ Frosty840修正されたバージョンを試してください。 – dasblinkenlight

+0

私はCodeRush Expressを無効にしていますが、それはやっている "IsGeneric"メソッドのようです。 VBでは存在しないようで、IDEを殺しているかもしれません。ただし、GetType(T).IsGenericTypeはクラッシュすることはありません。 – Frosty840

2
(再び)構文を修正

myDataRow("myColumnName")Objectを返し、そのオブジェクトがNullable(Of SomeEnumeration)になると仮定します。

Sub Main 
    Dim items(2) As Object 
    items(0) = DayOfWeek.Monday 
    items(1) = Nothing 

    Test (items(0)) 
    Test (items(1)) 
End Sub 

Sub Test (value As Object) 
    Dim typedValue = CType(value, DayOfWeek?) 
    Dim notNullValue As DayOfWeek = If(typedValue, DayOfWeek.Sunday) 

    Console.WriteLine ("Nullable = {0:g}, NotNull = {1:g}", typedValue, notNullValue) 
End Sub 

ObjectmyDataRow("myColumnName")戻りを想定すると、そのオブジェクトはあなたが持つことができるNullable(Of Integer)になります。 DayOfWeekからObjectからの型変換はありませんが、DayOfWeekからIntegerから型変換が、しかしがあるので、この作品の理由とNullable(Of DayOfWeek)からObjectからまっすぐキャストが失敗した

Sub Main 
    Dim items(2) As Object 
    items(0) = 1 
    items(1) = Nothing 

    Test (items(0)) 
    Test (items(1)) 
End Sub 

Sub Test (value As Object) 
    Dim intValue = CType(value, Integer?) 
    Dim typedValue = CType(intValue, DayOfWeek?) 
    Dim notNullValue As DayOfWeek = If(typedValue, DayOfWeek.Sunday) 

    Console.WriteLine ("Nullable = {0:g}, NotNull = {1:g}", typedValue, notNullValue) 
End Sub 

があるので、我々は最初にキャストしなければなりません実際のタイプ(Integer)を列挙型に変換します。

あなたはShortからObjectからの型変換がないためShortからIntegerストレートでObjectをキャストしようとすると、同じエラーが発生します。鋳造時にはIntegerに、その後はShortになります。

Dim x As Integer = 5 

' Fails 
CType(x, Short) 

'Works 
CType(CType(x, Integer), Short) 

CType(someInteger, Short)CType(someInteger, DayOfWeek)はなく、実際にそれが明示的な変換を使用して、キャストされていないということで重要な違い。キャストと明示的な変換の両方に同じ構文/キーワードが使用されるだけです。

関連する問題