2011-01-09 13 views
2

In VB.NET habe ich eine Klasse, die eine Reihe von Nummern implementiert, rufen Sie NumericRange(Of T). Intern speichert NumericRangeT als Nullable, T?. Ich habe eine andere Klasse, die diese Klasse als NumericRange(Of UInt16) umschließt. Nennen Sie diese Klasse MyNumRange (ich bin hier zu einfach).Wie verwende ich Nullable mit numerischen Typen in Konstruktoren richtig?

So In MyNumRange, ich habe ein paar Konstrukteurs definiert:

Public Sub New(ByVal num1 As UInt16?, ByVal num2 As UInt16?) 
    ' Code 
End Sub 

Public Sub New(ByVal num As UInt16, ByVal flag As Boolean) 
    ' Code 
End Sub 

Public Sub New(ByVal num As UInt16) 
    ' Code 
End Sub 

In einigem Code außerhalb von MyNumRange, ich versuche, einen offenen Bereich zu instanziiert. Das heißt, ein Bereichswert, bei dem einer der Operanden fehlt, um ein Größer-als-oder-gleich-Szenario darzustellen. Wenn New MyNumRange(32000, Nothing)aufgerufen wird, muss gleichgesetzt werden (nach Aufruf der MyNumRange überschriebenen ToString Methode) zu 32000 ~ (beachten Sie das nachgestellte Leerzeichen und nehmen Sie an, ~ ist das Trennzeichen).

Ausgenommen, Aufruf New MyNumRange(32000, Nothing) springt nicht zum Konstruktor mit einer Signatur von New(UInt16?, UInt16?), sondern zu New(UInt16?, Boolean) statt. Dies bewirkt, dass NumericRange die Nummer 32000 als einen einzelnen spezifischen Wert verarbeitet, nicht den offenen Bereich.

Meine Frage ist, wie kann ich die Konstrukteure verwenden, wie ich sie oben so definiert haben, dass ich einen Nothing Wert auf das zweite Argument der New(UInt16?, UInt16?) Konstruktor übergeben kann, wird es in Nothing übersetzt und num2.HasValue, wenn aufgerufen von innerhalb des Konstruktors, würde melden False?

Muss ich überdenken, wie ich meine Konstruktoren eingerichtet habe?

Antwort

2

Der Standardkonstruktor von Nullable<T> kann verwendet werden. Wenn es als new Nullable<UInt16>() aufgerufen wird, wird es als Nullwert ohne Wert fungieren. In VB-Bedingungen sollten Sie New Nullable(of UInt16)() tun können.

+0

Das funktioniert. Es ist nicht intuitiv, aber es funktioniert. Ich kann keinen anderen Weg finden, meine Konstruktoren aufzuschreiben und zu überladen, um die Anzahl der Möglichkeiten, wie mein Objekt/meine Klasse initialisiert werden kann, richtig zu artikulieren. Aber deshalb habe ich auch eine FromString-Funktion. – Kumba

1

DirectCast(Nothing, UInt16?) geben Ihnen den Wert, den Sie passieren in wollen, aber so tun, erzeugt einen Compiler-Fehler:

Overload resolution failed because no accessible 'New' can be called without a narrowing conversion: 
    'Public Sub New(num As UShort, flag As Boolean)': Argument matching parameter 'num' narrows from 'Short' to 'UShort'. 
    'Public Sub New(num As UShort, flag As Boolean)': Argument matching parameter 'flag' narrows from 'UShort?' to 'Boolean'. 
    'Public Sub New(num1 As UShort?, num2 As UShort?)': Argument matching parameter 'num1' narrows from 'Short' to 'UShort?'. 

aber es funktioniert gut, wenn Sie den Ball in einem explizit typisierte Wert verwenden:

Dim num1 As UInt16? = 32000S 
Dim r = New MyNumRange(num1, DirectCast(Nothing, UInt16?)) 
+0

Dies funktioniert auch, und ist nicht so intuitiv von der Art, wie VB Dinge tut. Ich werde beide Methoden in der XML-Dokumentation für diese Konstruktoren beachten müssen. Vielen Dank! – Kumba