views:

131

answers:

4

I have the following code block in C#

private void Synchronize<T>(TextSelection selection, DependencyProperty property, Action<T> methodToCall)
{ 
    object value = selection. GetPropertyValue(property) ;
    if ( value != DependencyProperty. UnsetValue) methodToCall((T) value) ;
} 

That I have converted to VB.

Private Sub Synchronize(Of T)(ByVal selection As TextSelection, ByVal [property] As DependencyProperty, ByVal methodToCall As Action(Of T))
    Dim value As Object = selection.GetPropertyValue([property])
    If value IsNot DependencyProperty.UnsetValue Then
        methodToCall(DirectCast(value, T))
    End If
End Sub

The calling method look like:

Synchronize(Of Double)(selection, TextBlock.FontSizeProperty, AddressOf SetFontSize)
Synchronize(Of FontWeight)(selection, TextBlock.FontSizeProperty, AddressOf SetFontWeight)
Synchronize(Of FontStyle)(selection, TextBlock.FontStyleProperty, AddressOf SetFontStyle)
Synchronize(Of FontFamily)(selection, TextBlock.FontFamilyProperty, AddressOf SetFontFamily)
Synchronize(Of TextDecorationCollection)(selection, TextBlock.TextDecorationsProperty, AddressOf SetTextDecoration)

My problem is with the DirectCast call; if my delegate argument can be a simple type (integer, double, etc) or an object. DirectCast doesn't like the simple data types an InvalidCastException is thrown when I try to cast to a double. Does anyone have a suggested solution to this problem? I've also tried TryCast, but it doesn't like my (of T) and says it must be class contstrained.

Thanks all!

Ryan

A: 

Looking at the errors you're seeing, it sounds like you may need to add a constraint on your T handle limit it to a class in order for the TryCast to be used.

I'm not really familiar with VB's TryCast method (or DirectCast, for that matter), but something like this might help [note that (Of T) -> (Of T as Class) ]:

Private Sub Synchronize(Of T as Class)(ByVal selection As TextSelection, ByVal [property] As DependencyProperty, ByVal methodToCall As Action(Of T)) 
    Dim value As Object = selection.GetPropertyValue([property]) 
    If value IsNot DependencyProperty.UnsetValue Then 
        methodToCall(TryCast(value, T)) 
    End If 
End Sub 
Steven
Double and Integer will not satisfy the Class constraint.
Matthieu
A: 

Use CType instead of TryCast/DirectCast. It should work like the casting in C# :

methodToCall(CType(value, T))
Matthieu
+1  A: 

Try CType() instead of DirectCast().

Fantius
Tried it. Bombs out as well. I've tried the three type conversions I'm aware of (CType, TryCast and DirectCast) and none have worked for all cases.
Ryan
I just tested with DirectCast and with CType. The former raised an InvalidCastException. The latter worked fine.
Eyal
A: 

You can put multiple constraints on t

I believe the syntax is something like:

Private Sub Synchronize(Of T as {Class, Integer, Double})
drventure