none
Konstantenbezeichner ausgeben constants expression RRS feed

  • Frage

  • Hallo Community,

    ich habe hier ein Problem für welches ich momentan noch keine Lösung gefunden habe und deshalb Eure Hilfe benötige!

    Und zwar habe ich eine Konstante z.B:

    const int WAHR = 1;

    jetzt würde ich gerne den Bezeichner WAHR in die Console ausgegeben jemand ne Idee?

    mit:

    Console.WriteLine(WAHR); wird nur der Wert ausgegeben = 1
    Console.WriteLine(WAHR.ToString()) wird nur der String vom Wert ausgegeben also auch = 1

    wie kann ich nur die Bezeichnung WAHR in die Console ausgeben?

    Mfg Stefan

    Freitag, 8. November 2013 14:47

Antworten

  • Ja, mit Reflection geht es, ist aber meistens Sinnlos (Leistung verschwendend und die Unterscheidung zwischen verschiedenen Konstanten ist schwierig).
                var StaticFields = typeof(Program).GetFields(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
                foreach (var field in StaticFields)
                    if ((field.Attributes & FieldAttributes.Literal) != 0)
                        Console.WriteLine(field.Name);
    Dieser Code gibt alle statischen Felder der Program-Klasse aus (Public un Privat). Konstanten haben noch das Attribut Literal wodurch man sie von einfachen statischen Felder unterscheiden kann..


    Koopakiller [kuːpakɪllɐ] (Tom Lambert)
    Webseite | Code Beispiele | Facebook | Twitter | Snippets   C# ↔ VB.NET Konverter
    Markiert bitte beantwortende Posts als Antwort und bewertet Beiträge. Danke.

    Freitag, 8. November 2013 15:23
    Moderator
  • "Eindeutig" wird es nie! Es braucht blos eine Zeile geändert zu werden und schon geht mein Reflection-Code schief. Mehr oder weniger eindeutig sind Angaben wie "System.Math.Sin".
    Wie gesagt nimm einen String oder ein Enum. So machst du dir keine Arbeit und es ist sicher.

    PS: Enum-Werte sind auch eine Art Konstanten.


    Koopakiller [kuːpakɪllɐ] (Tom Lambert)
    Webseite | Code Beispiele | Facebook | Twitter | Snippets   C# ↔ VB.NET Konverter
    Markiert bitte beantwortende Posts als Antwort und bewertet Beiträge. Danke.

    Freitag, 8. November 2013 19:30
    Moderator
  • Ja es soll halt eindeutig sein und net einfach nur ein String.

    Ob Du nun den Namen "WAHR" der Konstante "WAHR" als String oder als über drei Ecken ewrmittelten String aus dem Namen der Konstanten ermittelst, spielt keine Rolle. Es ist auch IMHO ziemlich unsinnig, das so zu machen.

    Ich würd auch sagen, nimm entweder Enum oder gleich den Namen als String.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Freitag, 8. November 2013 19:50
    Moderator

Alle Antworten

  • Hallo,
    der bezeichner WAHR ist nur zur Designzeit (wärend du den Code schreibst) verfügbar. Zur Laufzeit kommst du also nicht mehr an den Namen der Variablen/Konstanten heran.

    Du kannst aber auf eine Enumeration setzen:

    enum MyEnum : int
    {
      WAHR = 1,
      FALSCH = 0,
    }

    Du kannst dann einfach den Wert ausgeben:

    Console.WriteLine(MyEnum.WAHR);
    Console.WriteLine(MyEnum.WAHR.ToString());

    Beide Zeilen machen das selbe. Die Ableitung von int beim enum (kursiv) ist Optional. Wenn du aber beispielsweise von long ableitest, dann kannst du größere Werte nutzen.

    Um an den Wert heran zu kommen musst du das Feld casten:

    Console.WriteLine((int)MyEnum.WAHR);
    So bekommst du wieder die Zahl.



    Koopakiller [kuːpakɪllɐ] (Tom Lambert)
    Webseite | Code Beispiele | Facebook | Twitter | Snippets   C# ↔ VB.NET Konverter
    Markiert bitte beantwortende Posts als Antwort und bewertet Beiträge. Danke.

    Freitag, 8. November 2013 14:54
    Moderator
  • Hi,

    danke für deine Antwort ja bei Enum ist es klar aber ich habe halt nur einfache Konstanten und keine Enum.

    Muss irgendwie mit reflection gehen.

    Freitag, 8. November 2013 15:08
  • Ja, mit Reflection geht es, ist aber meistens Sinnlos (Leistung verschwendend und die Unterscheidung zwischen verschiedenen Konstanten ist schwierig).
                var StaticFields = typeof(Program).GetFields(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
                foreach (var field in StaticFields)
                    if ((field.Attributes & FieldAttributes.Literal) != 0)
                        Console.WriteLine(field.Name);
    Dieser Code gibt alle statischen Felder der Program-Klasse aus (Public un Privat). Konstanten haben noch das Attribut Literal wodurch man sie von einfachen statischen Felder unterscheiden kann..


    Koopakiller [kuːpakɪllɐ] (Tom Lambert)
    Webseite | Code Beispiele | Facebook | Twitter | Snippets   C# ↔ VB.NET Konverter
    Markiert bitte beantwortende Posts als Antwort und bewertet Beiträge. Danke.

    Freitag, 8. November 2013 15:23
    Moderator
  • Jup cool you make my Day!

    Aber ich möchte ja nicht alle Bezeichner meiner Konstanten einer Klasse ausgeben.

    Sondern nur den Bezeichner einer bestimmten Konstante dieser Klasse!

    Die Konstante ist mir auch bekannt und ich kenne Bezeichner und Wert!

    Kannst Du vielleicht nochmal überlegen wie sich das realisieren lassen könnten?

    Freitag, 8. November 2013 16:23
  • Wenn du den Wert kennst, dann kanst du diesen noch mittels GetValue abprüfen.

    if (field.IsLiteral && (int)field.GetValueDirect(new TypedReference()) == 1)

    (Für das Literal-Attrobut gibt es auch eine Eigenschaft)

    Wenn du mit Bezeichner den Namen der Konstanten meinst, dann macht die Frage keinen richtigen Sinn mehr:

    Console.WriteLine("WAHR");

    Den Typ kannst du auch noch abfragen:

    if(... && field.FieldType == typeof(int))

    Ansonsten kannst du die Konstante noch mit einem Attribut versehen und das abfragen:

    if(...  && field.IsDefined(typeof(CLSCompliantAttribute))

    (CLSCompliant ist das Attribut des Feldes)

    Meine Meinung zum Thema Reflection bei solchen Dingen kennst du...und eindeutig ist es nie, da du die Klasse jederzeit mit weiteren Konstanten versehen kannst, die genauso gefunden würden. Du musst also am Ende das 1. gefundene Element nutzen, dein gewolltes Element könnte aber auch später kommen.


    Koopakiller [kuːpakɪllɐ] (Tom Lambert)
    Webseite | Code Beispiele | Facebook | Twitter | Snippets   C# ↔ VB.NET Konverter
    Markiert bitte beantwortende Posts als Antwort und bewertet Beiträge. Danke.

    Freitag, 8. November 2013 16:37
    Moderator
  • Hi,

    Sondern nur den Bezeichner einer bestimmten Konstante dieser Klasse!

    Die Konstante ist mir auch bekannt und ich kenne Bezeichner und Wert!

    und warum willst Du dann per Code den Namen der Konstanten ermitteln und ausgeben, wenn Du den Namen der Konstanten schon kennst und im Code, der den Namen ermitteln müsste, sowieso angeben musst?

      String name = HoleNameDerKonstanten( "NameDerKonstanten" )

    Klar könnte man sowas machen aber welchen Sinn soll das haben?


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Freitag, 8. November 2013 18:12
    Moderator
  • Ja es soll halt eindeutig sein und net einfach nur ein String. Ich möchte halt bei der Ausgabe nicht den Wert der Konstante ausgeben sondern den Namen wie bei eim Enum auch. Da gehts ja zum Glück einfach aber ich hab halt nur Konstanten als Ausgabsbasis.
    Freitag, 8. November 2013 18:45
  • "Eindeutig" wird es nie! Es braucht blos eine Zeile geändert zu werden und schon geht mein Reflection-Code schief. Mehr oder weniger eindeutig sind Angaben wie "System.Math.Sin".
    Wie gesagt nimm einen String oder ein Enum. So machst du dir keine Arbeit und es ist sicher.

    PS: Enum-Werte sind auch eine Art Konstanten.


    Koopakiller [kuːpakɪllɐ] (Tom Lambert)
    Webseite | Code Beispiele | Facebook | Twitter | Snippets   C# ↔ VB.NET Konverter
    Markiert bitte beantwortende Posts als Antwort und bewertet Beiträge. Danke.

    Freitag, 8. November 2013 19:30
    Moderator
  • Ja es soll halt eindeutig sein und net einfach nur ein String.

    Ob Du nun den Namen "WAHR" der Konstante "WAHR" als String oder als über drei Ecken ewrmittelten String aus dem Namen der Konstanten ermittelst, spielt keine Rolle. Es ist auch IMHO ziemlich unsinnig, das so zu machen.

    Ich würd auch sagen, nimm entweder Enum oder gleich den Namen als String.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Freitag, 8. November 2013 19:50
    Moderator