2012-11-09 7 views
9

Próbuję użyć odbicia (ostatecznie nieznanego w czasie kompilacji) object, które obejmują struct. Dotarłem aż do TypedReference.MakeTypedReference, ale uderzyłem w ścianę.Pola dostępu obiektu Struct w obiekcie z odbiciem

Oto moja klasa i Struct

public class MyObject 
{ 
    public int Id; 
    public Money Amount; 
} 

public struct Money 
{ 
    public int Vaule; 
    public string Code; 
} 

A oto jak próbuję ustawić „kod” z „ilość” w MyObject użyciu odbicia. Jak wspomniałem powyżej, szukam rozwiązania, które nie wie o tych typach w czasie kompilacji (byłoby to zbyt łatwe!)

Oto kod, który mam do tej pory (użyłem [0], [1], aby kod prostsze)

var obj = new MyObject() { Id = 1 }; 
obj.Amount.Vaule = 10; 
obj.Amount.Code = "ABC"; 

FieldInfo[] objFields = obj.GetType().GetFields(); 
FieldInfo[] moneyFields = objFields[1].GetValue(obj).GetType().GetFields(); 

List<FieldInfo> fields = new List<FieldInfo>() { objFields[1] }; 
fields.AddRange(moneyFields); 

TypedReference typeRef = TypedReference.MakeTypedReference( 
          objFields[1].GetValue(obj), fields.ToArray()); 

moneyFields[1].SetValueDirect(typeRef, "XXX"); 

TypedReference.MakeTypedReference wdmuchuje się z; "FieldInfo nie pasuje do typu docelowego." Podobnie jeśli przekażę tylko objFields[1]. I jeśli przejdę tylko moneyFields otrzymam "TypedReferences nie może być przedefiniowany jako prymitywy."

Dlaczego? Powiedzmy Tworzę Losowe urządzeń testowych i chcą wypełnić pola klasy z danych losowych :)

+0

Czy mówisz, że podczas kompilacji nie wiesz, czy używasz MyObject lub Money, więc musi wykryć, który obiekt jest używany i odczytać/zapisać właściwość odpowiednio? – series0ne

+0

Co powiecie na temat korzystania z AutoFixture i wydostawania się z branży maszyn Rube Goldberg? (Mimo, że wrt 'struct', zobacz http://stackoverflow.com/questions/12930963/creating-a-struct-with-autofixture-throws-no-public-constructor-error) (nie napotkasz żadnej potrzeby' MakeTypedReference 'profesjonalnie i muszę powiedzieć coś tak, jakbym rzeczywiście oglądał strumień tweetów na raz, sry!) –

+0

@RubenBartelink -" dlaczego "było po prostu dla odniesienia. Zrobiłabym "użyj AutoFixture, jeśli to właśnie robiłem. –

Odpowiedz

13

Szczerze mówiąc, nie ma potrzeby w ogóle dla TypedReference tutaj - tylko box struct powinny działać prawidłowo:

var amountField = obj.GetType().GetField("Amount"); 
    object money = amountField.GetValue(obj); 
    var codeField = money.GetType().GetField("Code"); 
    codeField.SetValue(money, "XXX"); 
    amountField.SetValue(obj, money); 

Jednak! Poinformuję cię o kilku rzeczach:

  • Pola publiczne zamiast nieruchomości zazwyczaj nie są dobrym pomysłem; że często gryźć później
  • zmienny konstrukcjom (tj strukturach, które można zmienić po utworzeniu) są prawie nigdy dobrym pomysłem, a ugryzie nawet częściej, i gryzą mocniej
  • łącząc zmienny konstrukcjom i pól publiczne związki to, ale bardzo trudno jest zmienić później
+1

Dzięki Marc. Bardzo doceniane. –

+5

@ Po prostu zwróć uwagę na punkty ... nie jest to świetny pomysł –

Powiązane problemy