Introducción
Revisando el artículo de
Octavio Hernández
sobre los nuevos tipos anulables
de la próxima versión de VB 9.0 (Orcas) que publicará próximamente en la
revista
dotNetManía,
(que
dicho sea de paso, así como quién no quiere la cosa, si resides en España y
quieres conseguirla
al mejor precio, pues
usa mi oferta de suscripción), me decidí a
crear tipos de datos
en Visual Basic 2005 que
simulen los tipos anulables, al menos como será en la próxima versión de
Visual Basic (VB 9.0 / Orcas) y como lo son actualmente en C#.
Por si no sabes de que va esto de los tipos anulables:
En realidad la explicación la he puesto aparte,
pulsa aquí
para verla.
Ahí mismo tendrás ejemplos para Visual Basic y para C# 2005, en este último
con un ejemplo de
los nuevos tipos anulables, en particular de int?.
Crear un nuevo tipo de datos con sobrecarga de operadores y conversiones
personalizadas
No vamos a ver todos los tipos definidos en la DLL (elGuille.NumericNullable),
solo
veremos el
tipo IntegerNullable con el que nos haremos una idea de cómo están
definidos los demás
tipos,
que son:
Tipo definido en
elGuille.NumericNullable |
Tipo usado
internamente |
SByteNullable |
Nullable(Of SByte) |
ByteNullable |
Nullable(Of Byte) |
ShortNullable |
Nullable(Of Short) |
UShortNullable |
Nullable(Of UShort) |
IntegerNullable |
Nullable(Of Integer) |
UIntegerNullable |
Nullable(Of UInteger) |
LongNullable |
Nullable(Of Long) |
ULongNullable |
Nullable(Of ULong) |
DecimalNullable |
Nullable(Of Decimal) |
SingleNullable |
Nullable(Of Single) |
DoubleNullable |
Nullable(Of Double) |
Todos los tipos tienen una serie de métodos y propiedades, que son:
Miembros de la clase |
Descripción |
New(v) |
Constructor con parámetros.
Recibe el valor a asignar. |
Métodos y propiedades
compartidas |
Null |
Propiedad compartida de solo
lectura para obtener un
valor nulo (Nothing o null). En C# si queremos asignar
un valor nulo a uno
de estos tipos debemos hacerlo así:
IntegerNullable i1 = IntegerNullable.Null;
Que sería el equivalente a:
int? i1 = null; |
Not(v) |
Método compartido para usar como
el operador Not de
VB.
Si hacemos esto: n = Not 5, n valdrá -6. |
Pow(v1, v2) |
Eleva v1 a la potencia indicada
por v2.
Este método compartido es el equivalente al operador ^ de VB. |
Métodos y propiedades
de instancia |
ToString() |
Propiedad reemplazada.
Devuelve el valor en formato cadena.
Si el valor que contiene es nulo, devuelve la palabra "Nothing". |
Value |
Propiedad de solo lectura que
devuelve el valor o
Nothing si no tiene nada asignado. |
HasValue |
Propiedad de solo lectura que
devuelve un valor
verdadero o falso según tenga un valor o no. |
GetValueOrDefault() |
Devuelve el valor que contiene o
cero (el valor por
defecto del tipo interno) si el contenido es nulo. |
GetValueOrDefault(defaultValue) |
Devuelve el valor que contiene o
el valor indicado en
el argumento si el contenido es nulo. |
Pow(n) |
Eleva el valor de la instancia
actual al valor
indicado por v. |
Sobrecargas |
Están
todos los operadores sobrecargados excepto Like, (ver nota). |
Los siguientes
operadores aritméticos
están sobrecargados:
suma (+), resta (-), multiplicación (*), división (/), división
entera (\),
exponenciación (^),
desplazamiento de bits (<< y >>) |
Nota:
En la DLL distribuida a fecha del 14 de Abril (v1.0.0.1) no
están implementados
todas las sobrecargas de todos los operadores, pero si los
más usados.
Las únicas clases que los tienen todos son: IntegerNullable
y DoubleNullable.
En futuras actualizaciones incluiré todas las sobrecargas.
|
Los operadores lógicos
o a nivel de bits:
And, Or, Xor y Not.
También AndAlso y OrElse. |
Los 6 operadores de
comparaciones: >, <,
>=, <=, = y <> |
El operador de
concatenación (&),
(para unir los tipos como si fueran cadenas). |
Los operadores unarios
+ y - |
Se pueden usar en
expresiones boolean, ya
que True y False están sobrecargados, por tanto,
podemos hacer algo como:
If i1 Then ... o
If i1 = False Then ...
Esto en realidad es lo mismo que si usáramos HasValue:
If i1.HasValue Then ... o
If i1.HasValue = False Then ... |
Conversiones |
Se permiten
conversiones implícitas entre
tipos que están "por debajo", siguiendo el mismo
criterio que en los tipos numéricos, con el valor añadido de que podemos
convertir de
LongNUllable a ULongNullable, (y lo mismo con el resto de tipos con y sin
signo), algo que con
los tipos normales no podemos hacer.
El orden de "privilegios", (empezando por el de menos), es:
SByte, Byte, Short,
UShort, Integer,
UInteger, Long, ULong, Decimal, Single y Double.
Esto quiere decir que cualquier tipo se puede convertir
implícitamente (sin
necesidad de usar
CType) a Double, pero, por ejemplo, a Short solo se podrán convertir
implícitamente los dos
tipos que están "por debajo": Byte y SByte. |
El resto de
conversiones hay que hacerlas
de forma explícita usando CType( valor, TIPO )
Ver ejemplo. |
Por ejemplo, para convertir un valor ShortNullable a ByteNullable debemos
hacerlo así:
Dim s1 As ShortNullable = 125
Dim sb1 As SByteNullable = -105
Dim b1 As ByteNullable = 200
' A ShortNullable podemos asignar directamente valores de tipos "menores"
s1 = sb1
s1 = b1
' Pero al revés hay que hacer la conversión explícita
b1 = CType(s1, ByteNullable)
De todas formas, el propio IDE de Visual Basic te recomienda esa
conversión si ve que no se
puede
hacer la asignación directamente, tal como vemos en la figura 1:
Figura 1: El IDE de VB2005 se encarga de convertir los tipos
Nota:
Estos tipos también se pueden usar en C#, el único inconveniente es que si
queremos asignar un
valor null debemos usar la propiedad compartida (estática) Null
que está definida
en cada tipo.
Un par de clases (estructuras) de la librería NumericNullable
Ahora vamos a ver cómo están definidos los tipos
IntegerNullable y
DecimalNullable, para que
veas todo lo referente a las conversiones y como en ciertos tipos no tenemos
que hacerlas todas.
También te muestro
un par de ejemplos
de cómo se pueden usar estas clases en
Visual Basic y
en C#.
En los proyectos de prueba de cada lenguaje hay más ejemplos.
Pues espero que te sea de utilidad, que es de lo que siempre se trata.
Nos vemos.
Guillermo
El ZIP con la DLL compilada y los ejemplos de VB y C#:
pruebaAnulable_pub.zip - 81.4 KB
(MD5
checksum:
B9BC648081CE5C5A88F9208C740167C0)
El ZIP con el código completo de la DLL:
NumericNullable_src.zip - 50.1 KB
(MD5
checksum:
5E6E911405449F10EB507AD5C9919447)
Private Sub operadoresLogicos()
Dim i1 As IntegerNullable = 15
Dim i2 As IntegerNullable = 25
Console.WriteLine()
Console.WriteLine("Usando AndAlso en dos tipos IntegerNullable")
Console.WriteLine("===========================================")
Console.WriteLine("i1= {0}, i2= {1}", i1, i2)
If i1 AndAlso i2 Then
Console.WriteLine("If i1 AndAlso i2 Then := True")
Else
Console.WriteLine("If i1 AndAlso i2 Then := False")
End If
Console.WriteLine()
Console.WriteLine("Después de hacer: i1 = Nothing")
i1 = Nothing
Console.WriteLine("i1= {0}, i2= {1}", i1, i2)
If i1 AndAlso i2 Then
Console.WriteLine("If i1 AndAlso i2 Then := True")
Else
Console.WriteLine("If i1 AndAlso i2 Then := False")
End If
Console.WriteLine()
Console.WriteLine("Usando Not")
i1 = Not i2
Console.WriteLine("Después de hacer: i1 = Not i2")
Console.WriteLine("i1= {0}, i2= {1}", i1, i2)
Console.WriteLine()
i1 = Nothing ' o IntegerNullable.Null
Console.WriteLine("i1= {0}", i1)
' Esto en realidad asignará -1 que es lo mismo que Not 0
i1 = Not i1
Console.WriteLine("Después de hacer: i1 = Not i1")
Console.WriteLine("i1= {0}", i1)
Console.WriteLine()
Console.WriteLine("Usando Mod")
Console.WriteLine("Después de hacer i1 = i2 Mod 5, (i2 = {0})", i2)
i1 = i2 Mod 5
Console.WriteLine("i1= {0}", i1)
Console.WriteLine("Después de hacer i1 = i2 Mod 3, (i2 = {0})", i2)
i1 = i2 Mod 3
Console.WriteLine("i1= {0}", i1)
Console.WriteLine("Después de hacer i1 = i2 Mod 2, (i2 = {0})", i2)
i1 = i2 Mod 2
Console.WriteLine("i1= {0}", i1)
Console.WriteLine()
Console.WriteLine("Con valores de tipo Integer")
Dim n1 As Integer
Dim n2 As Integer = 25
Console.WriteLine("Después de hacer n1 = n2 Mod 5, (n2 = {0})", n2)
n1 = n2 Mod 5
Console.WriteLine("n1= {0}", n1)
Console.WriteLine("Después de hacer n1 = n2 Mod 3, (n2 = {0})", n2)
n1 = n2 Mod 3
Console.WriteLine("n1= {0}", n1)
Console.WriteLine("Después de hacer n1 = n2 Mod 2, (n2 = {0})", n2)
n1 = n2 Mod 2
Console.WriteLine("n1= {0}", n1)
Console.WriteLine()
Console.WriteLine("Usando ^")
i1 = i2 ^ 2
Console.WriteLine("Después de hacer: i1 = i2 ^ 2")
Console.WriteLine("i1= {0}, i2= {1}", i1, i2)
'
Dim i3 As IntegerNullable
Dim ui3 As UIntegerNullable
i1 = 10
i3 = i1 ^ i2
Console.WriteLine("Después de hacer: i3 = i1 ^ i2")
Console.WriteLine("i1= {0}, i2= {1}, i3= {2}", i1, i2, i3)
ui3 = i1 ^ i2
Console.WriteLine("Después de hacer: ui3 = i1 ^ i2")
Console.WriteLine("i1= {0}, i2= {1}, ui3= {2}", i1, i2, ui3)
Console.WriteLine()
Console.WriteLine("Usando ^ (con Integer)")
n1 = CInt(n2 ^ 2)
Console.WriteLine("Después de hacer: n1 = CInt(n2 ^ 2)")
Console.WriteLine("n1= {0}, n2= {1}", n1, n2)
Console.WriteLine()
Console.WriteLine("Usando <<")
'i2 = Nothing
i1 = i2 << 2
Console.WriteLine("Después de hacer: i1 = i2 << 2")
Console.WriteLine("i1= {0}, i2= {1}", i1, i2)
Console.WriteLine()
Console.WriteLine("Usando >>")
i1 = i2 >> 2
Console.WriteLine("Después de hacer: i1 = i2 >> 2")
Console.WriteLine("i1= {0}, i2= {1}", i1, i2)
Console.WriteLine()
n1 = n2 << 2
Console.WriteLine("Después de hacer: n1 = n2 << 2")
Console.WriteLine("n1= {0} n2= {1}", n1, n2)
n1 = n2 >> 2
Console.WriteLine("Después de hacer: n1 = n2 >> 2")
Console.WriteLine("n1= {0} n2= {1}", n1, n2)
Console.WriteLine()
Console.WriteLine("Concatenación")
Dim str As String
str = i1 & i2
Console.WriteLine("i1= {0} i2= {1}", i1, i2)
Console.WriteLine("Dim str As String = i1 & i2")
Console.WriteLine(str)
i1 = Nothing
str = i1 & i2
Console.WriteLine("i1= {0} i2= {1}", i1, i2)
Console.WriteLine("Dim str As String = i1 & i2")
Console.WriteLine(str)
'
' Esta se puede hacer independientemente de que
' sobrecarguemos &
str = "El valor de n2 = " & n2
Console.WriteLine("str = 'El valor de n2 = ' & i2")
Console.WriteLine(str)
Console.WriteLine()
i1 = -i2
Console.WriteLine("Después de hacer: i1 = -i2")
Console.WriteLine("i1= {0} i2= {1}", i1, i2)
Console.WriteLine()
Console.WriteLine("Divisiones")
i1 = i2 / 2.5
Console.WriteLine("Después de hacer: i1 = i2 / 2.5")
Console.WriteLine("i1= {0} i2= {1}", i1, i2)
i1 = i2 / 3
Console.WriteLine("Después de hacer: i1 = i2 / 3")
Console.WriteLine("i1= {0} i2= {1}", i1, i2)
Console.WriteLine()
Dim d1 As DoubleNullable
Dim d2 As DoubleNullable = 25.0
' Esta llama a la sobrecarga de DoubleNullable
d1 = d2 / 2.5
Console.WriteLine("Después de hacer: d1 = d2 / 2.5")
Console.WriteLine("d1= {0} d2= {1}", d1, d2)
d1 = d2 / 2.0
Console.WriteLine("Después de hacer: d1 = d2 / 2.0")
Console.WriteLine("d1= {0} d2= {1}", d1, d2)
Console.WriteLine()
' Esta llama a la sobrecarga de IntegerNullable
d1 = i2 / 2.5
Console.WriteLine("Después de hacer: d1 = i2 / 2.5")
Console.WriteLine("d1= {0} i2= {1}", d1, i2)
' Esta llama a la sobrecarga de IntegerNullable
d1 = i2 / 2
Console.WriteLine("Después de hacer: d1 = i2 / 2")
Console.WriteLine("d1= {0} i2= {1}", d1, i2)
Console.WriteLine()
i1 = CType(d2 ^ 2, IntegerNullable)
Console.WriteLine("Después de hacer: i1 = CType(d2 ^ 2, IntegerNullable)")
Console.WriteLine("i1= {0}, d2= {1}", i1, d2)
d1 = d2 ^ 2.5
Console.WriteLine("Después de hacer: d1 = d2 ^ 2.5")
Console.WriteLine("d1= {0}, d2= {1}", d1, d2)
Console.WriteLine("Con valores Double")
Dim nd1 As Double
Dim nd2 As Double = 25
nd1 = nd2 ^ 2.5
Console.WriteLine("Después de hacer: nd1 = nd2 ^ 2.5")
Console.WriteLine("nd1= {0}, nd2= {1}", nd1, nd2)
Console.WriteLine()
End Sub
En C# hay cosas que no se pueden usar y otras habrá que hacerlo mediante
métodos expresamente
creados por el propio .NET para los casos en los que C# no soporta esa
característica, como es
el caso de la concatenación (&) o la exponenciación (^), lo mismo ocurre con
otros operadores,
por ejemplo Not que equivale a !, en C# solo opera con valores bool y
devuelve también un valor
bool, pero en mis clases está implementado como para devolver un valor
entero, por ejemplo, i =
5, Not i será -6.
Para solventar los casos de Not y ^ he creado dos métodos estáticos
(compartidos) para que tenga
esa misma funcionalidad:
Pow(n1, n2) para elevar el valor de n1 a la potencia indicada por n2,
también se puede usar como
res = n1.Pow(n2)
Not(n1) hace lo mismo que Not n1 de Visual Basic.
private static void operadoresLogicos()
{
IntegerNullable i1 = 15;
IntegerNullable i2 = 25;
Console.WriteLine();
Console.WriteLine("Usando AndAlso en dos tipos IntegerNullable");
Console.WriteLine("===========================================");
Console.WriteLine("i1= {0}, i2= {1}", i1, i2);
if (i1 && i2)
{
Console.WriteLine("If i1 AndAlso i2 Then := True");
}
else
{
Console.WriteLine("If i1 AndAlso i2 Then := False");
}
Console.WriteLine();
Console.WriteLine("Después de hacer: i1 = Nothing");
i1 = IntegerNullable.Null; // null;
Console.WriteLine("i1= {0}, i2= {1}", i1, i2);
if (i1 && i2)
{
Console.WriteLine("If i1 AndAlso i2 Then := True");
}
else
{
Console.WriteLine("If i1 AndAlso i2 Then := False");
}
Console.WriteLine();
Console.WriteLine("Usando Not");
bool b1 = ! Convert.ToBoolean(i2);
Console.WriteLine( _
"Después de hacer: bool b1 = Not i2, en C#: bool b1 = ! Convert.ToBoolean(i2);");
Console.WriteLine("b1= {0}, i2= {1}", b1, i2);
Console.WriteLine();
i1 = IntegerNullable.Null;
Console.WriteLine("i1= {0}", i1);
// Esto en realidad asignará -1 que es lo mismo que Not 0
b1 = ! Convert.ToBoolean(i1);
Console.WriteLine("Después de hacer: b1 = Not i1, en C#: b1 = ! Convert.ToBoolean(i1);");
Console.WriteLine("b1= {0}", b1);
Console.WriteLine();
Console.WriteLine("Usando Mod");
Console.WriteLine("Después de hacer i1 = i2 Mod 5, (i2 = {0})", i2);
i1 = i2 % 5;
Console.WriteLine("i1= {0}", i1);
Console.WriteLine("Después de hacer i1 = i2 Mod 3, (i2 = {0})", i2);
i1 = i2 % 3;
Console.WriteLine("i1= {0}", i1);
Console.WriteLine("Después de hacer i1 = i2 Mod 2, (i2 = {0})", i2);
i1 = i2 % 2;
Console.WriteLine("i1= {0}", i1);
Console.WriteLine();
Console.WriteLine("Con valores de tipo Integer");
int n1;
int n2 = 25;
Console.WriteLine("Después de hacer n1 = n2 Mod 5, (n2 = {0})", n2);
n1 = n2 % 5;
Console.WriteLine("n1= {0}", n1);
Console.WriteLine("Después de hacer n1 = n2 Mod 3, (n2 = {0})", n2);
n1 = n2 % 3;
Console.WriteLine("n1= {0}", n1);
Console.WriteLine("Después de hacer n1 = n2 Mod 2, (n2 = {0})", n2);
n1 = n2 % 2;
Console.WriteLine("n1= {0}", n1);
Console.WriteLine();
Console.WriteLine("Usando ^");
i1 = i2 ^ 2;
Console.WriteLine("Después de hacer: i1 = i2 ^ 2");
Console.WriteLine("i1= {0}, i2= {1}", i1, i2);
//
IntegerNullable i3;
UIntegerNullable ui3;
i1 = 10;
i3 = i1 ^ i2;
Console.WriteLine("Después de hacer: i3 = i1 ^ i2");
Console.WriteLine("i1= {0}, i2= {1}, i3= {2}", i1, i2, i3);
ui3 = i1 ^ i2;
Console.WriteLine("Después de hacer: ui3 = i1 ^ i2");
Console.WriteLine("i1= {0}, i2= {1}, ui3= {2}", i1, i2, ui3);
Console.WriteLine();
Console.WriteLine("Usando ^ (con Integer)");
n1 = Convert.ToInt32(n2 ^ 2);
Console.WriteLine("Después de hacer: n1 = CInt(n2 ^ 2)");
Console.WriteLine("n1= {0}, n2= {1}", n1, n2);
Console.WriteLine();
Console.WriteLine("Usando <<");
//i2 = Nothing
i1 = i2 << 2;
Console.WriteLine("Después de hacer: i1 = i2 << 2");
Console.WriteLine("i1= {0}, i2= {1}", i1, i2);
Console.WriteLine();
Console.WriteLine("Usando >>");
i1 = i2 >> 2;
Console.WriteLine("Después de hacer: i1 = i2 >> 2");
Console.WriteLine("i1= {0}, i2= {1}", i1, i2);
Console.WriteLine();
n1 = n2 << 2;
Console.WriteLine("Después de hacer: n1 = n2 << 2");
Console.WriteLine("n1= {0} n2= {1}", n1, n2);
n1 = n2 >> 2;
Console.WriteLine("Después de hacer: n1 = n2 >> 2");
Console.WriteLine("n1= {0} n2= {1}", n1, n2);
Console.WriteLine();
Console.WriteLine("Concatenación");
string str;
str = IntegerNullable.op_Concatenate(i1, i2);
Console.WriteLine("i1= {0} i2= {1}", i1, i2);
Console.WriteLine("Dim str As String = i1 & i2");
Console.WriteLine(str);
i1 = IntegerNullable.Null;
str = IntegerNullable.op_Concatenate(i1, i2);
Console.WriteLine("i1= {0} i2= {1}", i1, i2);
Console.WriteLine("Dim str As String = i1 & i2");
Console.WriteLine(str);
//
// Esta se puede hacer independientemente de que
// sobrecarguemos &
str = "El valor de n2 = " + n2;
Console.WriteLine("str = 'El valor de n2 = ' & i2");
Console.WriteLine(str);
Console.WriteLine();
i1 = -i2;
Console.WriteLine("Después de hacer: i1 = -i2");
Console.WriteLine("i1= {0} i2= {1}", i1, i2);
Console.WriteLine();
Console.WriteLine("Divisiones");
i1 = i2 / 2.5;
Console.WriteLine("Después de hacer: i1 = i2 / 2.5");
Console.WriteLine("i1= {0} i2= {1}", i1, i2);
i1 = i2 / 3;
Console.WriteLine("Después de hacer: i1 = i2 / 3");
Console.WriteLine("i1= {0} i2= {1}", i1, i2);
Console.WriteLine();
DoubleNullable d1;
DoubleNullable d2 = 25.0;
// Esta llama a la sobrecarga de DoubleNullable
d1 = d2 / 2.5;
Console.WriteLine("Después de hacer: d1 = d2 / 2.5");
Console.WriteLine("d1= {0} d2= {1}", d1, d2);
d1 = d2 / 2.0;
Console.WriteLine("Después de hacer: d1 = d2 / 2.0");
Console.WriteLine("d1= {0} d2= {1}", d1, d2);
Console.WriteLine();
// Esta llama a la sobrecarga de IntegerNullable
d1 = i2 / 2.5;
Console.WriteLine("Después de hacer: d1 = i2 / 2.5");
Console.WriteLine("d1= {0} i2= {1}", d1, i2);
// Esta llama a la sobrecarga de IntegerNullable
d1 = i2 / 2;
Console.WriteLine("Después de hacer: d1 = i2 / 2");
Console.WriteLine("d1= {0} i2= {1}", d1, i2);
Console.WriteLine();
i1 = IntegerNullable.op_Exponent((IntegerNullable)d2, 2);
Console.WriteLine("Después de hacer: i1 = CType(d2 ^ 2, IntegerNullable)");
Console.WriteLine("i1= {0}, d2= {1}", i1, d2);
d1 = DoubleNullable.op_Exponent(d2, 2.5);
Console.WriteLine("Después de hacer: d1 = d2 ^ 2.5");
Console.WriteLine("d1= {0}, d2= {1}", d1, d2);
Console.WriteLine();
}
'------------------------------------------------------------------------------
' IntegerNullable (11/Abr/06)
' Estructura para simular el tipo Integer? de VB 9.0 o int? de C# 2.0
'
' Ejemplo de tipos anulables para Visual Basic 2005
' Inicialmente como complemento del artículo de Octavio Hernández
' para dotNetManía.
'
' ©Guillermo 'guille' Som, 2006
'------------------------------------------------------------------------------
Imports Microsoft.VisualBasic
Imports System
''' <summary>
''' Estructura del tipo Nullable(Of Integer)
''' Con sobrecargas para facilitar el trabajo con este tipo de números.
''' Así se podrá usar como Integer? de VB 9.0
''' </summary>
''' <remarks></remarks>
Public Structure IntegerNullable
''' <summary>
''' Campo del tipo Nullable(Of Integer)
''' </summary>
''' <remarks>Este campo es el que realmente contiene el valor.</remarks>
Private valor As Nullable(Of Integer)
''' <summary>
''' Propiedad compartida de solo lectura para asignar un valor nulo
''' </summary>
''' <value></value>
''' <returns>Nothing (null)</returns>
''' <remarks>
''' Es por si se usa en C#, ya que no podremos asignarle directamente un valor null.
''' </remarks>
Public Shared ReadOnly Property Null() As IntegerNullable
Get
Return Nothing
End Get
End Property
''' <summary>
''' El constructor parametrizado para crear un valor indicando un valor entero
''' </summary>
''' <param name="v"></param>
''' <remarks></remarks>
Public Sub New(ByVal v As Integer)
valor = v
End Sub
''' <summary>
''' Conversión implícita de Integer a IntegerNullable
''' </summary>
''' <param name="v"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Widening Operator CType(ByVal v As Integer) As IntegerNullable
Return New IntegerNullable(v)
End Operator
''' <summary>
''' Conversión implícita de IntegerNullable a Integer
''' </summary>
''' <param name="v"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Widening Operator CType(ByVal v As IntegerNullable) As Integer
Return v.GetValueOrDefault()
End Operator
''' <summary>
''' Convertir los demás tipos a DoubleNullable sin pérdida de información
''' </summary>
''' <param name="v"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Widening Operator CType(ByVal v As SByteNullable) As IntegerNullable
Return v.Value
End Operator
Public Shared Widening Operator CType(ByVal v As ByteNullable) As IntegerNullable
Return v.Value
End Operator
Public Shared Widening Operator CType(ByVal v As ShortNullable) As IntegerNullable
Return v.Value
End Operator
Public Shared Widening Operator CType(ByVal v As UShortNullable) As IntegerNullable
Return v.Value
End Operator
'
' Conversiones explícitas
'
Public Shared Narrowing Operator CType(ByVal v As IntegerNullable) As ByteNullable
Return CByte(v.Value)
End Operator
Public Shared Narrowing Operator CType(ByVal v As IntegerNullable) As SByteNullable
Return CSByte(v.Value)
End Operator
Public Shared Narrowing Operator CType(ByVal v As IntegerNullable) As ShortNullable
Return CShort(v.Value)
End Operator
Public Shared Narrowing Operator CType(ByVal v As IntegerNullable) As UShortNullable
Return CUShort(v.Value)
End Operator
'
' Operadores aritméticos
'
''' <summary>
''' Los operadores aritméticos
''' </summary>
''' <param name="v1"></param>
''' <param name="v2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator +(ByVal v1 As IntegerNullable, _
ByVal v2 As IntegerNullable) As IntegerNullable
If v1.HasValue = False OrElse v2.HasValue = False Then
Return Nothing
End If
Return New IntegerNullable(v1.Value + v2.Value)
End Operator
Public Shared Operator -(ByVal v1 As IntegerNullable, _
ByVal v2 As IntegerNullable) As IntegerNullable
If v1.HasValue = False OrElse v2.HasValue = False Then
Return Nothing
End If
Return New IntegerNullable(v1.Value - v2.Value)
End Operator
Public Shared Operator *(ByVal v1 As IntegerNullable, _
ByVal v2 As IntegerNullable) As IntegerNullable
If v1.HasValue = False OrElse v2.HasValue = False Then
Return Nothing
End If
Return New IntegerNullable(v1.Value * v2.Value)
End Operator
Public Shared Operator \(ByVal v1 As IntegerNullable, _
ByVal v2 As IntegerNullable) As IntegerNullable
If v1.HasValue = False OrElse v2.HasValue = False Then
Return Nothing
End If
Return New IntegerNullable(v1.Value \ v2.Value)
End Operator
Public Shared Operator /(ByVal v1 As IntegerNullable, _
ByVal v2 As DoubleNullable) As IntegerNullable
If v1.HasValue = False OrElse v2.HasValue = False Then
Return Nothing
End If
Return CType(v1.Value / v2.Value, IntegerNullable)
End Operator
Public Shared Operator ^(ByVal v1 As IntegerNullable, _
ByVal v2 As IntegerNullable) As IntegerNullable
If v1.HasValue = False OrElse v2.HasValue = False Then
Return Nothing
End If
Return CType((v1.Value ^ v2.Value), IntegerNullable)
End Operator
''' <summary>
''' Elevar un valor a una potencia, equivalente al operador ^ de Visual Basic.
''' </summary>
''' <param name="v1"></param>
''' <param name="v2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function Pow(ByVal v1 As IntegerNullable, _
ByVal v2 As IntegerNullable) As IntegerNullable
If v1.HasValue = False OrElse v2.HasValue = False Then
Return Nothing
End If
Return CType(v1.Value ^ v2.Value, IntegerNullable)
End Function
''' <summary>
''' Método de instancia para elevar el valor actual a una potencia.
''' </summary>
''' <param name="v"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Function Pow(ByVal v As IntegerNullable) As IntegerNullable
If Me.HasValue = False OrElse v.HasValue = False Then
Return Nothing
End If
Return CType(Me.Value ^ v.Value, IntegerNullable)
End Function
''' <summary>
''' Sobrecarga de Mod
''' </summary>
''' <param name="v1"></param>
''' <param name="v2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator Mod(ByVal v1 As IntegerNullable, _
ByVal v2 As IntegerNullable) As IntegerNullable
Return v1.Value Mod v2.Value
End Operator
''' <summary>
''' Desplazamiento de bits
''' </summary>
''' <param name="v1"></param>
''' <param name="v2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator <<(ByVal v1 As IntegerNullable, _
ByVal v2 As Integer) As IntegerNullable
If v1.HasValue = False Then
Return Nothing
End If
Return v1.Value << v2
End Operator
Public Shared Operator >>(ByVal v1 As IntegerNullable, _
ByVal v2 As Integer) As IntegerNullable
If v1.HasValue = False Then
Return Nothing
End If
Return v1.Value >> v2
End Operator
''' <summary>
''' Sobrecarga del operador de concatenación
''' </summary>
''' <param name="v1"></param>
''' <param name="v2"></param>
''' <returns></returns>
''' <remarks>
''' Esto solo es necesario para concatenar dos valores de este tipo
''' </remarks>
Public Shared Operator &(ByVal v1 As IntegerNullable, ByVal v2 As IntegerNullable) As String
Return v1.valor.ToString & v2.valor.ToString
End Operator
'
' Operadores de comparaciones
'
'''' <summary>
'''' Los operadores lógicos
'''' </summary>
''' <param name="v1"></param>
''' <param name="v2"></param>
'''' <returns></returns>
'''' <remarks></remarks>
Public Shared Operator =(ByVal v1 As IntegerNullable, ByVal v2 As IntegerNullable) As Boolean
If v1.HasValue = False OrElse v2.HasValue = False Then
Return True
End If
Return CType(v2, IntegerNullable).GetValueOrDefault() = v1.GetValueOrDefault()
End Operator
Public Shared Operator <>(ByVal v1 As IntegerNullable, ByVal v2 As IntegerNullable) As Boolean
If v1.HasValue = False OrElse v2.HasValue = False Then
Return False
End If
Return CType(v2, IntegerNullable).GetValueOrDefault() <> v1.GetValueOrDefault()
End Operator
Public Shared Operator <(ByVal v1 As IntegerNullable, ByVal v2 As IntegerNullable) As Boolean
If v1.HasValue = False OrElse v2.HasValue = False Then
Return False
End If
Return v1.GetValueOrDefault() < CType(v2, IntegerNullable).GetValueOrDefault()
End Operator
Public Shared Operator >(ByVal v1 As IntegerNullable, ByVal v2 As IntegerNullable) As Boolean
If v1.HasValue = False OrElse v2.HasValue = False Then
Return False
End If
Return v1.GetValueOrDefault() > CType(v2, IntegerNullable).GetValueOrDefault()
End Operator
Public Shared Operator <=(ByVal v1 As IntegerNullable, ByVal v2 As IntegerNullable) As Boolean
If v1.HasValue = False OrElse v2.HasValue = False Then
Return False
End If
Return v1.GetValueOrDefault() <= CType(v2, IntegerNullable).GetValueOrDefault()
End Operator
Public Shared Operator >=(ByVal v1 As IntegerNullable, ByVal v2 As IntegerNullable) As Boolean
If v1.HasValue = False OrElse v2.HasValue = False Then
Return False
End If
Return v1.GetValueOrDefault() >= CType(v2, IntegerNullable).GetValueOrDefault()
End Operator
'
' Operadores de manejos de bits (lógicos)
'
''' <summary>
''' Sobrecarga de And y AndAlso, ya que tenemos definido IsFalse
''' </summary>
''' <param name="v1"></param>
''' <param name="v2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator And(ByVal v1 As IntegerNullable, _
ByVal v2 As IntegerNullable) As IntegerNullable
'Return New IntegerNullable(v1.Value And v2.Value)
Return v1.Value And v2.Value
End Operator
''' <summary>
''' Sobrecarga de Or y OrElse, ya que tenemos definido IsTrue
''' </summary>
''' <param name="v1"></param>
''' <param name="v2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator Or(ByVal v1 As IntegerNullable, _
ByVal v2 As IntegerNullable) As IntegerNullable
'Return New IntegerNullable(v1.Value Or v2.Value)
Return v1.Value Or v2.Value
End Operator
''' <summary>
''' Sobrecarga de Xor
''' </summary>
''' <param name="v1"></param>
''' <param name="v2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator Xor(ByVal v1 As IntegerNullable, _
ByVal v2 As IntegerNullable) As IntegerNullable
'Return New IntegerNullable(v1.Value Xor v2.Value)
Return v1.Value Xor v2.Value
End Operator
''' <summary>
''' Sobrecarga del operador Not, actúa directamente con el valor interno
''' </summary>
''' <param name="v"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator Not(ByVal v As IntegerNullable) As IntegerNullable
'Return New IntegerNullable(Not v.Value)
Return Not v.Value
End Operator
''' <summary>
''' Método compartido equivalente al operador Not de Visual Basic.
''' <summary>
''' <param name="v"></param>
''' <returns><returns>
''' <remarks><remarks>
Public Shared Function [Not](ByVal v As IntegerNullable) As IntegerNullable
Return Not v.Value
End Function
'
' Operadores unarios (+ y -)
'
Public Shared Operator +(ByVal v As IntegerNullable) As IntegerNullable
Return +v.Value
End Operator
Public Shared Operator -(ByVal v As IntegerNullable) As IntegerNullable
Return -v.Value
End Operator
''' <summary>
''' Operadores para valores boolean (True y False)
''' </summary>
''' <param name="v"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator IsTrue(ByVal v As IntegerNullable) As Boolean
If v.HasValue Then
Return True
Else
Return False
End If
End Operator
Public Shared Operator IsFalse(ByVal v As IntegerNullable) As Boolean
If v.HasValue Then
Return False
Else
Return True
End If
End Operator
'
' Métodos de instancia
'
''' <summary>
''' Devuelve el valor que contiene o el valor por defecto
''' </summary>
''' <param name="defaultValue"></param>
''' <returns></returns>
''' <remarks>
''' Si el valor contenido es nulo, devolverá el predeterminado de Integer: cero
''' </remarks>
Public Function GetValueOrDefault(ByVal defaultValue As Integer) As Integer
Return valor.GetValueOrDefault(defaultValue)
End Function
Public Function GetValueOrDefault() As Integer
Return valor.GetValueOrDefault()
End Function
''' <summary>
''' Comprueba si tiene algún valor
''' </summary>
''' <value></value>
''' <returns>True si tiene un valor o False si es nulo</returns>
''' <remarks></remarks>
Public ReadOnly Property HasValue() As Boolean
Get
Return valor.HasValue
End Get
End Property
''' <summary>
''' Devuelve el valor interno
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property Value() As Integer
Get
If valor.HasValue = False Then
Return Nothing
End If
Return valor.Value
End Get
End Property
''' <summary>
''' Sobrecarga del método ToString algo que SIEMPRE deberíamos hacer.
''' </summary>
''' <returns>
''' Devuelve una cadena con el valor o la palabra Nothing si contiene un valor nulo
''' </returns>
''' <remarks></remarks>
Public Overrides Function ToString() As String
If valor.HasValue = False Then
Return "Nothing"
End If
Return valor.GetValueOrDefault().ToString()
End Function
End Structure
'------------------------------------------------------------------------------
' DoubleNullable (12/Abr/06)
' Estructura para simular el tipo Double? de VB 9.0 o double? de C# 2.0
'
' ©Guillermo 'guille' Som, 2006
'------------------------------------------------------------------------------
Imports Microsoft.VisualBasic
Imports System
''' <summary>
''' Estructura del tipo Nullable(Of Double)
''' Con sobrecargas para facilitar el trabajo con este tipo de números.
''' Así se podrá usar como Double? de VB 9.0
''' </summary>
''' <remarks></remarks>
Public Structure DoubleNullable
''' <summary>
''' Campo del tipo Nullable(Of Double)
''' </summary>
''' <remarks>Este campo es el que realmente contiene el valor.</remarks>
Private valor As Nullable(Of Double)
''' <summary>
''' Propiedad compartida de solo lectura para asignar un valor nulo
''' </summary>
''' <value></value>
''' <returns>Nothing (null)</returns>
''' <remarks>
''' Es por si se usa en C#, ya que no podremos asignarle directamente un valor null.
''' </remarks>
Public Shared ReadOnly Property Null() As DoubleNullable
Get
Return Nothing
End Get
End Property
''' <summary>
''' El constructor parametrizado para crear un valor indicando un valor entero
''' </summary>
''' <param name="v"></param>
''' <remarks></remarks>
Public Sub New(ByVal v As Double)
valor = v
End Sub
'
' Las conversiones
'
''' <summary>
''' Conversión implícita de Double a DoubleNullable
''' </summary>
''' <param name="v"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Widening Operator CType(ByVal v As Double) As DoubleNullable
Return New DoubleNullable(v)
End Operator
''' <summary>
''' Conversión implícita de DoubleNullable a Double
''' </summary>
''' <param name="v"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Widening Operator CType(ByVal v As DoubleNullable) As Double
Return v.GetValueOrDefault()
End Operator
''' <summary>
''' Convertir los demás tipos a DoubleNullable sin pérdida de información
''' </summary>
''' <param name="v"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Widening Operator CType(ByVal v As SByteNullable) As DoubleNullable
Return v.Value
End Operator
Public Shared Widening Operator CType(ByVal v As ByteNullable) As DoubleNullable
Return v.Value
End Operator
Public Shared Widening Operator CType(ByVal v As ShortNullable) As DoubleNullable
Return v.Value
End Operator
Public Shared Widening Operator CType(ByVal v As UShortNullable) As DoubleNullable
Return v.Value
End Operator
Public Shared Widening Operator CType(ByVal v As IntegerNullable) As DoubleNullable
Return v.Value
End Operator
Public Shared Widening Operator CType(ByVal v As UIntegerNullable) As DoubleNullable
Return v.Value
End Operator
Public Shared Widening Operator CType(ByVal v As LongNullable) As DoubleNullable
Return v.Value
End Operator
Public Shared Widening Operator CType(ByVal v As ULongNullable) As DoubleNullable
Return v.Value
End Operator
Public Shared Widening Operator CType(ByVal v As DecimalNullable) As DoubleNullable
Return v.Value
End Operator
Public Shared Widening Operator CType(ByVal v As SingleNullable) As DoubleNullable
Return v.Value
End Operator
'
' Conversiones explícitas desde DoubleNullable al resto de tipos de esta DLL
'
Public Shared Narrowing Operator CType(ByVal v As DoubleNullable) As ByteNullable
Return CByte(v.Value)
End Operator
Public Shared Narrowing Operator CType(ByVal v As DoubleNullable) As SByteNullable
Return CSByte(v.Value)
End Operator
Public Shared Narrowing Operator CType(ByVal v As DoubleNullable) As ShortNullable
Return CShort(v.Value)
End Operator
Public Shared Narrowing Operator CType(ByVal v As DoubleNullable) As UShortNullable
Return CUShort(v.Value)
End Operator
Public Shared Narrowing Operator CType(ByVal v As DoubleNullable) As IntegerNullable
Return CInt(v.Value)
End Operator
Public Shared Narrowing Operator CType(ByVal v As DoubleNullable) As UIntegerNullable
Return CUInt(v.Value)
End Operator
Public Shared Narrowing Operator CType(ByVal v As DoubleNullable) As LongNullable
Return CLng(v.Value)
End Operator
Public Shared Narrowing Operator CType(ByVal v As DoubleNullable) As ULongNullable
Return CULng(v.Value)
End Operator
Public Shared Narrowing Operator CType(ByVal v As DoubleNullable) As DecimalNullable
Return CDec(v.Value)
End Operator
Public Shared Narrowing Operator CType(ByVal v As DoubleNullable) As SingleNullable
Return CSng(v.Value)
End Operator
'
' Los operadores aritméticos
'
''' <summary>
''' Los operadores aritméticos
''' </summary>
''' <param name="v1"></param>
''' <param name="v2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator +(ByVal v1 As DoubleNullable, _
ByVal v2 As DoubleNullable) As DoubleNullable
If v1.HasValue = False OrElse v2.HasValue = False Then
Return Nothing
End If
Return New DoubleNullable(v1.Value + v2.Value)
End Operator
Public Shared Operator -(ByVal v1 As DoubleNullable, _
ByVal v2 As DoubleNullable) As DoubleNullable
If v1.HasValue = False OrElse v2.HasValue = False Then
Return Nothing
End If
Return New DoubleNullable(v1.Value - v2.Value)
End Operator
Public Shared Operator *(ByVal v1 As DoubleNullable, _
ByVal v2 As DoubleNullable) As DoubleNullable
If v1.HasValue = False OrElse v2.HasValue = False Then
Return Nothing
End If
Return New DoubleNullable(v1.Value * v2.Value)
End Operator
Public Shared Operator \(ByVal v1 As DoubleNullable, _
ByVal v2 As DoubleNullable) As DoubleNullable
If v1.HasValue = False OrElse v2.HasValue = False Then
Return Nothing
End If
Return New DoubleNullable(CLng(v1.Value) \ CLng(v2.Value))
End Operator
Public Shared Operator /(ByVal v1 As DoubleNullable, _
ByVal v2 As DoubleNullable) As DoubleNullable
If v1.HasValue = False OrElse v2.HasValue = False Then
Return Nothing
End If
Return v1.Value / v2.Value
End Operator
Public Shared Operator ^(ByVal v1 As DoubleNullable, _
ByVal v2 As DoubleNullable) As DoubleNullable
If v1.HasValue = False OrElse v2.HasValue = False Then
Return Nothing
End If
Return v1.Value ^ v2.Value
End Operator
''' <summary>
''' Elevar un valor a una potencia, equivalente al operador ^ de Visual Basic.
''' </summary>
''' <param name="v1"></param>
''' <param name="v2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function Pow(ByVal v1 As DoubleNullable, _
ByVal v2 As DoubleNullable) As DoubleNullable
If v1.HasValue = False OrElse v2.HasValue = False Then
Return Nothing
End If
Return v1.Value ^ v2.Value
End Function
''' <summary>
''' Método de instancia para elevar el valor actual a una potencia.
''' </summary>
''' <param name="v"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Function Pow(ByVal v As DoubleNullable) As DoubleNullable
If Me.HasValue = False OrElse v.HasValue = False Then
Return Nothing
End If
Return Me.Value ^ v.Value
End
''' <summary>
''' Sobrecarga de Mod
''' </summary>
''' <param name="v1"></param>
''' <param name="v2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator Mod(ByVal v1 As DoubleNullable, _
ByVal v2 As DoubleNullable) As DoubleNullable
Return v1.Value Mod v2.Value
End Operator
''' <summary>
''' Desplazamiento de bits
''' </summary>
''' <param name="v1"></param>
''' <param name="v2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator <<(ByVal v1 As DoubleNullable, ByVal v2 As Integer) As DoubleNullable
If v1.HasValue = False Then
Return Nothing
End If
Return CLng(v1.Value) << v2
End Operator
Public Shared Operator >>(ByVal v1 As DoubleNullable, ByVal v2 As Integer) As DoubleNullable
If v1.HasValue = False Then
Return Nothing
End If
Return CLng(v1.Value) >> v2
End Operator
''' <summary>
''' Sobrecarga del operador de concatenación
''' </summary>
''' <param name="v1"></param>
''' <param name="v2"></param>
''' <returns></returns>
''' <remarks>
''' Esto solo es necesario para concatenar dos valores de este tipo
''' </remarks>
Public Shared Operator &(ByVal v1 As DoubleNullable, ByVal v2 As DoubleNullable) As String
Return v1.valor.ToString & v2.valor.ToString
End Operator
''' <summary>
''' Los operadores lógicos
''' </summary>
''' <param name="v1"></param>
''' <param name="v2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator =(ByVal v1 As DoubleNullable, ByVal v2 As DoubleNullable) As Boolean
If v1.HasValue = False OrElse v2.HasValue = False Then
Return True
End If
Return CType(v2, DoubleNullable).GetValueOrDefault() = v1.GetValueOrDefault()
End Operator
Public Shared Operator <>(ByVal v1 As DoubleNullable, ByVal v2 As DoubleNullable) As Boolean
If v1.HasValue = False OrElse v2.HasValue = False Then
Return False
End If
Return CType(v2, DoubleNullable).GetValueOrDefault() <> v1.GetValueOrDefault()
End Operator
Public Shared Operator <(ByVal v1 As DoubleNullable, ByVal v2 As DoubleNullable) As Boolean
If v1.HasValue = False OrElse v2.HasValue = False Then
Return False
End If
Return v1.GetValueOrDefault() < CType(v2, DoubleNullable).GetValueOrDefault()
End Operator
Public Shared Operator >(ByVal v1 As DoubleNullable, ByVal v2 As DoubleNullable) As Boolean
If v1.HasValue = False OrElse v2.HasValue = False Then
Return False
End If
Return v1.GetValueOrDefault() > CType(v2, DoubleNullable).GetValueOrDefault()
End Operator
Public Shared Operator <=(ByVal v1 As DoubleNullable, ByVal v2 As DoubleNullable) As Boolean
If v1.HasValue = False OrElse v2.HasValue = False Then
Return False
End If
Return v1.GetValueOrDefault() <= CType(v2, IntegerNullable).GetValueOrDefault()
End Operator
Public Shared Operator >=(ByVal v1 As DoubleNullable, ByVal v2 As DoubleNullable) As Boolean
If v1.HasValue = False OrElse v2.HasValue = False Then
Return False
End If
Return v1.GetValueOrDefault() >= CType(v2, IntegerNullable).GetValueOrDefault()
End Operator
'
' Operadores de manejos de bits (lógicos)
'
''' <summary>
''' Sobrecarga de And y AndAlso, ya que tenemos definido IsFalse
''' </summary>
''' <param name="v1"></param>
''' <param name="v2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator And(ByVal v1 As DoubleNullable, _
ByVal v2 As DoubleNullable) As LongNullable
'Return New IntegerNullable(v1.Value And v2.Value)
Return CLng(v1.Value) And CLng(v2.Value)
End Operator
''' <summary>
''' Sobrecarga de Or y OrElse, ya que tenemos definido IsTrue
''' </summary>
''' <param name="v1"></param>
''' <param name="v2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator Or(ByVal v1 As DoubleNullable, _
ByVal v2 As DoubleNullable) As LongNullable
'Return New IntegerNullable(v1.Value Or v2.Value)
Return CLng(v1.Value) Or CLng(v2.Value)
End Operator
''' <summary>
''' Sobrecarga de Xor
''' </summary>
''' <param name="v1"></param>
''' <param name="v2"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator Xor(ByVal v1 As DoubleNullable, _
ByVal v2 As DoubleNullable) As LongNullable
'Return New IntegerNullable(v1.Value Xor v2.Value)
Return CLng(v1.Value) Xor CLng(v2.Value)
End Operator
''' <summary>
''' Sobrecarga del operador Not, actúa directamente con el valor interno
''' </summary>
''' <param name="v"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator Not(ByVal v As DoubleNullable) As LongNullable
'Return New IntegerNullable(Not v.Value)
Return Not CLng(v.Value)
End Operator
''' <summary>
''' Método compartido equivalente al operador Not de Visual Basic.
''' </summary>
''' <param name="v">Valor de tipo DoubleNullable</param>"
''' <returns>Devuelve un valor de tipo LongNullable</returns>
''' <remarks></remarks>
Public Shared Function [Not](ByVal v As DoubleNullable) As LongNullable
Return Not CLng(v.Value)
End Function
'
' Operadores unarios (+ y -)
'
Public Shared Operator +(ByVal v As DoubleNullable) As DoubleNullable
Return +v.Value
End Operator
Public Shared Operator -(ByVal v As DoubleNullable) As DoubleNullable
Return -v.Value
End Operator
''' <summary>
''' Operadores para valores boolean (True y False)
''' </summary>
''' <param name="v"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Operator IsTrue(ByVal v As DoubleNullable) As Boolean
If v.HasValue Then
Return True
Else
Return False
End If
End Operator
Public Shared Operator IsFalse(ByVal v As DoubleNullable) As Boolean
If v.HasValue Then
Return False
Else
Return True
End If
End Operator
'
' Métodos de instancia
'
''' <summary>
''' Devuelve el valor que contiene o el valor por defecto
''' </summary>
''' <param name="defaultValue"></param>
''' <returns></returns>
''' <remarks>
''' Si el valor contenido es nulo, devolverá el predeterminado de Double: cero
''' </remarks>
Public Function GetValueOrDefault(ByVal defaultValue As Double) As Double
Return valor.GetValueOrDefault(defaultValue)
End Function
Public Function GetValueOrDefault() As Double
Return valor.GetValueOrDefault()
End Function
''' <summary>
''' Comprueba si tiene algún valor
''' </summary>
''' <value></value>
''' <returns>True si tiene un valor o False si es nulo</returns>
''' <remarks></remarks>
Public ReadOnly Property HasValue() As Boolean
Get
Return valor.HasValue
End Get
End Property
''' <summary>
''' Devuelve el valor interno
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property Value() As Double
Get
If valor.HasValue = False Then
Return Nothing
End If
Return valor.Value
End Get
End Property
''' <summary>
''' Sobrecarga del método ToString algo que SIEMPRE deberíamos hacer.
''' </summary>
''' <returns>
''' Devuelve una cadena con el valor o la palabra Nothing si contiene un valor nulo
''' </returns>
''' <remarks></remarks>
Public Overrides Function ToString() As String
If valor.HasValue = False Then
Return "Nothing"
End If
Return valor.GetValueOrDefault().ToString()
End Function
End Structure