Come rendere un tipo wrapper sicuro attorno ai valori Variant
-
22-07-2019 - |
Domanda
Sto lavorando con un OPC Server che archivia i tag di dati come tipi di varianti, descritto da System.Runtime.InteropServices.VarEnum . Questi tipi includono i seguenti, VT_BSTR (stringa), VT_I2 (breve) e VT_I4 (lungo).
Tutti questi valori sono memorizzati dal server come oggetti e quindi devo lanciare il valore corretto quando li recupero.
So di poter fare qualcosa del tipo:
object tagValue = (object)"testing"; //this would be returned from a function rather than created this way!!
var typedVariant = new TypedVariant<string>(tagValue);
string actualString = typedVariant.Value;
Dove TypedVariant è una classe generica qualcosa del genere:
class TypedVariant<T> where T : class, struct
{
public TypedVariant(object variant)
{
Value = variant as T;
}
public T Value { private set; get; }
public static implicit operator TypedVariant<T> (T m)
{
// code to convert from TypedVariant<T> to T
return new TypedVariant<T>(m);
}
public static implicit operator T (TypedVariant<T> m)
{
// code to convert from T to TypedVariant<T>
return m.Value;
}
}
Ma c'è un modo in cui posso fare tutto in fase di esecuzione, ovvero qualcosa di simile al seguente:
TypedVariant<> typedVariant = TypedVariant.Create(VarEnum.VT_BSTR, tagValue);
//typedVariant should now be of type TypedVariant<string>
Ovviamente questo codice non verrà compilato, ma può essere fatto in questo modo?
Aggiornamento: secondo il suggerimento di @Konamiman, ho modificato la classe per consentire il casting implicito. Quindi ora puoi scrivere questo codice ed è tutto typesafe, quindi non puoi memorizzare la variante in un tipo diverso da quello con cui è stata creata.
object objectStr = (object)"testing"; //created this way just for testing
TypedVariant<string> typedVariant = (string)objectStr;
string actualString = typedVariant;
Soluzione
Penso che il wrapper TypedVariant
sia una buona idea, potresti estenderlo per sovrascrivere l'operatore di conversione implicita da / al tipo di wrapping e quindi potresti usarlo in modo più trasparente, ad esempio come:
var typedVariant = (string)tagValue;
string actualString = typedVariant;