Las variantes OLE, como las utilizadas en versiones anteriores de Visual Basic y de forma generalizada en COM Automation, pueden almacenar muchos tipos diferentes: tipos básicos como enteros y flotantes, tipos más complicados como cadenas y matrices y hasta IDispatch
implementaciones y punteros en forma de variantes ByRef
.¿Cuál es la implementación recomendada para hashing OLE variantes?
Las variantes también se tipan débilmente: convierten el valor a otro tipo sin previo aviso según el operador que aplique y los tipos actuales de los valores pasados al operador. Por ejemplo, al comparar dos variantes, una que contiene el número entero 1
y otra que contiene la cadena "1"
, para la igualdad devolverá True
.
Así que asumiendo que estoy trabajando con variantes a nivel de datos subyacente (por ejemplo VARIANT
en C++ o TVarData
en Delphi - es decir, la gran unión de diferentes valores posibles), ¿cómo debo hash de variantes constantemente para que obedezcan la derecha ¿reglas?
Reglas:
- variantes que hash de manera desigual debe comparar tan desigual, tanto en la clasificación y la igualdad directa
- variantes que resultan ser iguales tanto para la clasificación y la igualdad directa debe desmenuzar como igual
Está bien si tengo que usar diferentes reglas de clasificación y comparación directa para que el hash se ajuste.
La forma en que estoy trabajando actualmente es que estoy normalizando las variantes de las cadenas (si encajan), y tratándolas como cadenas, de lo contrario estoy trabajando con la variante de datos como si fuera una burbuja opaca, y hashing y comparando sus bytes brutos. Eso tiene algunas limitaciones, por supuesto: los números 1..10
ordenan como [1, 10, 2, ... 9]
etc. Esto es levemente molesto, pero es consistente y es muy poco trabajo. Sin embargo, me pregunto si hay una práctica aceptada para este problema.
VARIANT es en realidad una estructura, que tiene dos datos: valor y tipo. Su reclamo de comparación y conversión parece tomar en consideración solo el valor y no observa el tipo archivado de esa estructura. El enfoque correcto es siempre considerar el tipo archivado también. –
@Franci, creo que te perdiste el punto. Dos variantes pueden comparar igual incluso cuando sus tipos difieren. Si las variantes son iguales, Barry también quiere que sus hash sean iguales. 'Variant (1) = Variant ('1')' ==> 'hash (Variant (1)) = hash (Variant ('1'))'. –
Barry, no creo que tu primera regla sea correcta. Ignora la posibilidad de colisiones hash, donde los hash son iguales pero los valores no son similares en absoluto. –