Hi,

I am creating a 'generic input dialog': InputDialog(Of T). The idea is that I can create new instances of this dialog for different values of T. For example, I can create an InputDialog(Of String) and it displays a textbox. I create an InputDialog(Of Boolean) and it displays two radiobuttons (I could use a Checkbox, irrelevant). I create an InputDialog(Of Date) and it shows a DateTimePicker.

I do this by simply checking the type of T at run-time. In this way it is not really generic, as the dialog still has to know which type T is (which is usually not the case), but the generic is in the fact that the T can be multiple types that require a TextBox. For example, InputDialog(Of String), (Of Integer), (Of Single), (Of Double), etc, all simply display a TextBox (and it is validated later), so I still want to use generics as much as possible.


Anyway, the result of the dialog is of course a property of type T. This property needs to return the value in the textbox, converted from string to T, OR the value in the DateTimePicker, converted from Date to T, OR the checked property of the 'Yes' radiobutton, converted from Boolean to T.

In order to convert from any object to T I googled and found this code:
vb.net Code:
  1. Imports System.ComponentModel
  2.  
  3. Public Class GenericTypeConverter
  4.  
  5.     Public Shared Function FromObject(Of T)(ByVal value As Object) As T
  6.         Dim tc As TypeConverter = TypeDescriptor.GetConverter(GetType(T))
  7.         Return CType(tc.ConvertFrom(value), T)
  8.     End Function
  9.  
  10. End Class

I have to use this, I cannot simply CType a string to T since a String cannot be converted to any type T.


So, my Result property looks like this at the moment:
vb.net Code:
  1. Public ReadOnly Property Result() As T
  2.         Get
  3.             If GetType(T) Is GetType(Boolean) Then
  4.                 Return GenericTypeConverter.FromObject(Of T)(rbYes.Checked)
  5.             ElseIf GetType(T) Is GetType(Date) Then
  6.                 Return GenericTypeConverter.FromObject(Of T)(CType(datePicker.Value, Date))
  7.             Else
  8.                 Return GenericTypeConverter.FromString(Of T)(txtAnswer.Text.Trim)
  9.             End If
  10.         End Get
  11.     End Property

This actually works for Strings, Integers, Doubles, Singles, etc. I pass it the String in the textbox and it converts it to 'T' (note: T is then a String, Integer or Double!) just fine.

So, it can convert a String to a String, Integer or Double without any problems (I am validating the text before using the Result property so it will always be a valid integer, double, etc).

However, it does not work for a Boolean, nor for a DateTime. When I try that, it says "BooleanConverter cannot convert from System.Boolean" or "DateTimeConverter cannot convert from DateTime".


I realize it is a bit of a strange thing, since the object already IS a Boolean or a Date(Time) so no conversion should be done at all, but this doesn't work in design-time because I need to return the objects as type T.
I know that T will be Boolean when the value to be converted is a Boolean, and that T will be DateTime when the value to be converted is a DateTime, but the designer does not accept a simple CType. As I said, it does not accept this:
Code:
Return CType(rbYes.Checked, T)
because 'Boolean cannot be converted to T'.


However, I did find a way to make it work, but it seems like a complete hack... I can assign the boolean to an Object and then convert that using CType:
Code:
Dim obj As Object
obj = rbYes.Checked
Return CType(obj, T)
This works, it's accepted during design-time, and it works during run-time, but it seems very wrong... Is there no better way to handle this??

Thanks!