开发者

Nullable(of Guid) with Generic Delegate causes weird (hidden) error?

开发者 https://www.devze.com 2023-03-10 10:18 出处:网络
Scroll to the bottom, EDIT 19 onwards.See @Chris\'s comments also for good examples VB: Public Class Class1

Scroll to the bottom, EDIT 19 onwards. See @Chris's comments also for good examples

VB:

Public Class Class1
    Private Delegate Sub AnEventHandler(Of T)(ByVal newValue As T)
    Private Event OnSomething As AnEventHandler(Of Nullable(Of Guid))
End Class

C#:

public class Class1
{
    private delegate void AnEventHandler<T>(T newValue);
    private event AnEventHandler<Nullable<Guid>> OnSomething;
}

With the above VB code in .Net3.5 and .Net 4, Visual Studio 2008 and 2010, regardless of project type, you get the following error:

Type 'Global.System.Guid' is not defined.

You cannot navigate to the error by double clicking, and no line/coloumn numbers are given.

Do not quote from here that: "T" can only be a Class, an interface or a type parameter.

...because that is wrong, as proven below.

To confirm this statement, a couple of facts

Nullable is a structure. Yet, the following compiles:

Public Class Class1
    Private Delegate Sub AnEventHandler(Of T)(ByVal newValue As T)
    Private Event OnSomething As AnEventHandler(Of Nullable(Of Integer))
End Class

You can use Nullable Guids as shown here:

Private Sub StackOverflowTest()
    Dim s As Nullable(Of Guid)
    If s.HasValue Then
        'Do something
    End If
End Sub

That code compiles and works as you might imagine. Even the following code which uses generics and nullable guids works!!

Private Sub StackOve开发者_如何学JAVArflowTest2(Of T)()
    ' do stuff
End Sub

Private Sub StackOverflowTest3()
    StackOverflowTest2(Of Nullable(Of Guid))()
End Sub

However, my particular example listed at the very top, does not work. Why? Clearly, T does work with structures...

EDIT 19ish! =D

  1. Create a VB.Net Console Application
  2. Add the following to "Module1.vb"

    Module Module1

    Sub Main()
        Dim testCase1 As Nullable(Of Integer)
        testCase1 = 2190
        StackOverflowTest1(Of Nullable(Of Integer))(testCase1)
        Dim testCase2 As Nullable(Of Guid)
        testCase2 = Guid.NewGuid
        StackOverflowTest1(Of Nullable(Of Guid))(testCase2)
        Dim testCase3 As Nullable(Of Guid)
        testCase3 = Nothing
        StackOverflowTest1(Of Nullable(Of Guid))(testCase3)
    End Sub
    
    Private Sub StackOverflowTest1(Of T)(ByVal param As T)
        Console.WriteLine(param.ToString)
    End Sub
    

    End Module

Results:

2190

5ef4ed7c-2720-4b37-b8ca-4ac044ec70d0

<<< Nothing here to it just gave carriage return

LAST EDIT (I hope):

It's all gone quiet since Edit 19ish and @Chris reinforcing the issue with a good example (thank you Chris). I'll make the question a little easier (and attempt to tidy up all of the above), can anyone prove this is not an MS bug or similar? It seems to be something under the hood is not correctly wired up for VB.Net with regards to Nullable Structures and Events? However, all other cases using the Nullable Structures does appear to work?


It would appear to be a bug in the code generated behind the scenes by the VB.Net compiler. The following compiles fine, and should be functionally equivalent:

Public Class Class1
    Private Delegate Sub AnEventHandler(Of T)(ByVal newValue As T)
    Private OnSomethingEvent As AnEventHandler(Of Nullable(Of Guid))
    Private Custom Event OnSomething As AnEventHandler(Of Nullable(Of Guid))
        AddHandler(value As AnEventHandler(Of Nullable(Of Guid)))
            Me.OnSomethingEvent = DirectCast(System.Delegate.Combine(Me.OnSomethingEvent, value), AnEventHandler(Of Nullable(Of Guid)))
        End AddHandler

        RemoveHandler(value As AnEventHandler(Of Nullable(Of Guid)))
            Me.OnSomethingEvent = DirectCast(System.Delegate.Remove(Me.OnSomethingEvent, value), AnEventHandler(Of Nullable(Of Guid)))
        End RemoveHandler

        RaiseEvent(newValue As System.Guid?)
            Dim aeh = OnSomethingEvent
            If Not aeh Is Nothing Then
                aeh(newValue)
            End If
        End RaiseEvent
    End Event
End Class

(Hence, also, why you don't get line numbers for the errors - the errors are appearing in code that isn't present in any line you've written)


Unfortunately in VB a type parameter can only be a class, not a structure.

A quick and dirty workaround would be to box the Guid? within an Object.


I'm putting this one down to a bug in the Framework. I've posted a bug report on connect.

I'll not mark my own answer as the answer for another day or two, in case someone else can point out something we've overlooked so far.

Thanks everyone so far for your time!

0

精彩评论

暂无评论...
验证码 换一张
取 消