2009-09-15 29 views
5

chciałbym wiedzieć, czy to możliwe, aby zrobić coś takiego:C#: Wprowadzenie wartości za pośrednictwem refleksji

class brand 
{ 
    string name; 
} 

class car 
{ 
    string carname; 
    brand carbrand; 
} 

teraz mam ciąg jak ten oraz instancję obiektu samochodu typu:

car carobject = new car(); 
string brandNameOfCar = DoSomeMagicalReflectionStuff(car, "car.brand.name"); 

Jak wyglądałaby metoda "DoSomeMagicalReflectionStuff"?

I czy to w ogóle możliwe, aby zrobić coś takiego:

car carobject = new car(); 
string brandNameOfCar = DoSomeMagicalReflectionStuff(car, "car.brand.name.ToFormatedString()"); 

Dziękujemy!

+0

Dlaczego po prostu nie użyjesz carobject.carbrand.name? –

+3

Ponieważ jest to tylko głupi przykład iw "prawdziwej aplikacji" chcę uzyskać dostęp do dowolnej jednostki, takiej jak ta –

+0

Chciałbym zrobić "szablon" w ten sposób i potrzebować dostępu do jawnych informacji o obiekcie z ciąg podobny do powyższego. –

Odpowiedz

1

I zazwyczaj nie próbuj podłączyć produktów jestem zaangażowany w, ale jest to idealne problemem do rozwiązania przez Vici Parser (open source parser wyrażenie NET):

var parser = new CSharpParser(); 
var context = new CSharpContext(); 

context["car"] = carobject; 

string brandNameOfCar = 
      parser.Evaluate<string>("car.brand.name.ToFormatedString()", context); 
+0

brzmi dobrze, dziękuję! –

+1

Overkill dla czegoś łatwo zaimplementowanego z bcl .net jeśli pytasz mnie –

+1

@Rune: tak naprawdę nie znasz powodów, dla których on chce czegoś, co ocenia wyrażenia przechowywane w ciągu znaków. Ja osobiście często używam dynamicznego wyrażania do tworzenia bardzo prostych rozwiązań DSL. –

0

typeof (samochód) .GetProperty ("marka", bindingflags.instance | bindingflags.private) .GetValue (carobject, null) tak powinno. Sry za drobne błędy składniowe bit im na moim telefonie

edit: powyższe daje obiekt marki i ty Czy zrobić to samo, aby dostać się do właściwości name

4

Nie testowałem tego, ale tutaj jest coś, co powinno działać:

car c = new car(); 
object val = typeof(car).GetField("carbrand", BindingFlags.Private).GetValue(c); 
string result = (val as brand).ToFormattedString(); 
0

Czy to więcej sensu, aby mieć konstruktora samochodu, który pobiera ciąg jako parametr i robi coś jak następuje:

class brand 
{ 
    public string name; 
} 

class car 
{ 

    public car(string s) 
    { 
     Match match = Regex.Match(s, @"(?<carname>[^\.]+)\.(?<brandname>.+)"); 
     if (match.Success) 
     { 
      this.carname = match.Groups["carname"].Value; 
      this.carbrand = new brand(); 
      this.carbrand.name = match.Groups["brandname"].Value; 
     } else 
     { 
      throw new ArgumentException("Not a valid car"); 
     } 
    } 

    string carname; 
    brand carbrand; 

    public override string ToString() 
    { 
     return carname + "." + carbrand.name; 
    } 
} 

Wit h następujące użycie:

car c = new car("M5.BMW"); 
Console.WriteLine(c.ToString()); 

Można oczywiście podzielić go na metodę Parse and TryParse.

+1

Wow, ktoś powinien zabrać licencję właściciela klawiatury od ciebie! Dlaczego ciąg? po co to parsować? dlaczego nie 2 argumenty? o_O –

+0

Ponieważ pytanie było przekazywane w ciągu znaków, na przykład, jeśli plik był parsowany gdzieś z wielu samochodów. –

+0

Chociaż na twoją korzyść, standardem jest nie mieć konstruktora z takim ciągiem, ale zamiast tego metoda Parse. –

Powiązane problemy