Generic Class: Passing Data Type to Placeholder

  • Thread starter Thread starter Etienne-Louis Nicolet
  • Start date Start date
E

Etienne-Louis Nicolet

I have a generic class defined as follows:

Public Class SqlArgument(Of TDataType)

Private _values as List(Of TDataType)

Public Property Values() As List(Of TDataType)
Get
Return _values
End Get
Set(ByVal pValues As List(Of TDataType))
_values = pValues
End Set

Public Sub New()
Me.Values = New List(Of TDataType)
End Sub

....

End Class


Given the DataType property of a (strongly typed) DataTable I'd like to
create a new instance of SqlArgument with the data type of the appropriate
table column. I thought about something like

Sub TestArgument(pColumn as System.Data.DataColumn)
...
Dim s As new SqlArgument(Of pColumn.DataType)
...
End Sub

but obviously this does not work. Can anybody give me a hint on how to do
this?

Many thanks for your suggestions,
Etienne
 
Given the DataType property of a (strongly typed) DataTable I'd like to
create a new instance of SqlArgument with the data type of the appropriate
table column. I thought about something like

Sub TestArgument(pColumn as System.Data.DataColumn)
...
Dim s As new SqlArgument(Of pColumn.DataType)
...
End Sub

but obviously this does not work. Can anybody give me a hint on how to do
this?

You have to go the Reflection route if you want to do this. You can
instantiate the right generic type using Type.MakeGenericType and then
an object from that type with Activator.CreateInstance. But know that
once you've started using Reflection, it's hard to do something
without it, and the code quickly gets pretty ugly.

What are you actually going to do with the s variable once you've
created the instance?


Mattias
 
Mattias Sjögren said:
You have to go the Reflection route if you want to do this. You can
instantiate the right generic type using Type.MakeGenericType and then
an object from that type with Activator.CreateInstance. But know that
once you've started using Reflection, it's hard to do something
without it, and the code quickly gets pretty ugly.

What are you actually going to do with the s variable once you've
created the instance?


Mattias

Thank you Mattias, I will have to go deeper into Reflection to fully
understand the matter, but I'm pretty sure that this was the hint I needed.

Basically I'm creating a set of classes that build dynamic SQL WHERE
clauses, having one or more expressions in the form of

[ColumnName] [ComparisonOperator] [Value(s)], where

- ComparisonOperator can by any valid SQL operator (=, <>, <=, ... [NOT]
LIKE, [NOT] BETWEEN, [NOT] IN, ...)
- Value(s): Depending on the ComparisonOperator, one, two or multiple values
have to be provided. In any case, the data type is given by the table
column. The values have then to be converted to a literal in order to form
the where clause. My generic class would represent the collection of values
to append to the expression after the Comparison Operator.

- The expressions would then be concatenated in the form of

WHERE [expression1] AND [expression2] AND ...

As I understand the SqlClient classes are somehow limited when it comes to
build complex statements including IN-operations.

Kind regards,
Etienne
 
Can I just say: look at LINQ-to-SQL; that is exactly what it does for
you. You might be able to save a lot of effort...

Marc
 
Dear Marc,

I bought a book on LINQ yesterday and will have a look at it. Thanks for the
tip!

Kind regards,
Etienne
 
Mattias Sjögren said:
You have to go the Reflection route if you want to do this. You can
instantiate the right generic type using Type.MakeGenericType and then
an object from that type with Activator.CreateInstance. But know that
once you've started using Reflection, it's hard to do something
without it, and the code quickly gets pretty ugly.

What are you actually going to do with the s variable once you've
created the instance?


Mattias

Dear Mattias,

I tried to figure out how to use Reflection as recommended. I think i got
the first part:

Sub TestArgument(pColumn as System.Data.DataColumn)
Dim generic As System.Type = GetType(SqlArgument(Of ))
Dim typeArgs() As Type = {pColumn.DataType}
Dim constructed As Type = generic.MakeGenericType(typeArgs)
....
End Sub
However, I did not get along with the VB help on Activator.CreateInstance.
Would you mind giving me a hint how the code should look like?

Many thanks & kind regards,
Etienne
 
Back
Top