In realtà, avrei dovuto chiedere: come posso fare questo e rimanere CLS compatibile? Perché l'unico modo che posso pensare di fare questo è il seguente, ma l'utilizzo di __makeref
, FieldInfo.SetValueDirect
o solo System.TypedReference
in generale invalida la conformità CLS.Posso impostare un valore su una struttura attraverso il riflesso senza box?
// code illustrating the issue:
TestFields fields = new TestFields { MaxValue = 1234 }; // test struct with one field
FieldInfo info = fields.GetType().GetField("MaxValue"); // get the FieldInfo
// actual magic, no boxing, not CLS compliant:
TypedReference reference = __makeref(fields);
info.SetValueDirect(reference, 4096);
La controparte compliant di SetValueDirect
è SetValue
, ma ci vuole un oggetto come l'obiettivo, da qui la mia struct sarà inscatolato, rendendo l'impostazione di un valore su una copia, non la variabile originale me.
Una controparte generica per SetValue
non esiste per quanto ne so. C'è un altro modo di impostare il campo di un (riferimento a una) struttura attraverso la riflessione?
Forse non capisco CLSCompliancy, pensavo che significava che non si potevano _use_ le funzioni non conformi. Se questo è permesso, rende le cose molto più semplici. – Abel
@Abel: CLS Compliant indica che i membri pubblici fanno riferimento solo ai tipi conformi a CLS. Non dice nulla su ciò che è contenuto nei tuoi membri. – Gabe
Oops, la mia modifica di commento è andata persa. Sì, ho notato, è chiaro dai [primi tre elenchi puntati su MSDN su CLS Compliance] (http://msdn.microsoft.com/en-us/library/bhc3fa7f.aspx). Tuttavia mi sembra terribilmente strano che io abbia bisogno di una [parola chiave non documentata __makeref] (http://www.codeproject.com/Articles/38695/UnCommon-C-keywords-A-Look#makref) per farlo funzionare. – Abel