Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
[gelöst] Art typeof für Namen von Variablen gesucht
mosspower
myCSharp.de - Member

Avatar #avatar-2662.jpg


Dabei seit:
Beiträge: 456
Herkunft: Bamberg

Themenstarter:

[gelöst] Art typeof für Namen von Variablen gesucht

beantworten | zitieren | melden

Hallo "Kollegen",

ist es möglich für Variablennamen einen Ausdruck zu verwenden, so dass beim Refactoring Anpassungen sofort mit durchgeführt werden.

Zum Beispiel kann man das ja bei Klassen so machen ...
String className = typeof(TestClass).FullName;

Gibt es da auch eine Möglichkeit für Variablen? Hintergrund ist der, dass ich für verschiedene Instanzvariablen in einer Interfacemethode zur Serialisierung anmelden möchte. Gegenwärtig habe ich das so gelöst, dass man eine Set und Get-Methode überschreibt und hier den Namen der Variablen (als String) und den Wert (als Object) in ein Dictionary-Objekt packt.

Jetzt dachte ich, dass das einfacher gehen soll und ohne Variablennamen als String. Ich dachte an eine Methode IList<???Identifier??, Object> GetSerializableVariables nur welchen Identifier nehme ich hier.

Gibt es eine andere Möglichkeit, z.B. int, String, double ect. überladen und neuen Typ, z.B. SerializableInt, SerializableString zuweisen und mittels Reflektion werden dann diese Typen nach dem Instanzieren manipuliert?

Wie löst ihr das?

Danke schon mal für etwaige Antworten im Voraus?
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von mosspower am .
private Nachricht | Beiträge des Benutzers
Peter Bucher
myCSharp.de - Experte

Avatar #jVxXe7MDBPAimxdX3em3.jpg


Dabei seit:
Beiträge: 5.940
Herkunft: Zentralschweiz

beantworten | zitieren | melden

Hallo mosspower

Nein das geht nicht.
Wieso dekorierst du deine Eigenschaften nicht einfach mit Attributen?
Dann ist eine Namensänderung egal.


Gruss Peter
--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011

- https://peterbucher.ch/ - Meine persönliche Seite
- https://fpvspots.net/ - Spots für FPV Dronenflüge
private Nachricht | Beiträge des Benutzers
mosspower
myCSharp.de - Member

Avatar #avatar-2662.jpg


Dabei seit:
Beiträge: 456
Herkunft: Bamberg

Themenstarter:

beantworten | zitieren | melden

Hallo Peter Bucher,

das mit den Attributen ist eine super Idee, vielen Dank. Jetzt muss ich nur noch mal gucken ob das mit privaten Instanzvariablen auch geht und dann mittels Reflection bei der Instanzierung die serialisierten Werte setzen.
private Nachricht | Beiträge des Benutzers
mosspower
myCSharp.de - Member

Avatar #avatar-2662.jpg


Dabei seit:
Beiträge: 456
Herkunft: Bamberg

Themenstarter:

beantworten | zitieren | melden

Es geht mit ...


[AttributeUsage(AttributeTargets.Field)]
  class SerializableField : Attribute {
    
  }

braucht man da eigentlich ein eigenes Attribut oder kann man da vordefinierte (welche?) verwenden?
private Nachricht | Beiträge des Benutzers
Peter Bucher
myCSharp.de - Experte

Avatar #jVxXe7MDBPAimxdX3em3.jpg


Dabei seit:
Beiträge: 5.940
Herkunft: Zentralschweiz

beantworten | zitieren | melden

Salute mosspower
Zitat von mosspower
braucht man da eigentlich ein eigenes Attribut oder kann man da vordefinierte (welche?) verwenden?
Ich würde ein eigenes dafür schreiben.
Es gibt zwar schon festgelegte, allerdings werden die vom .NET Framework selber benutzt.


Gruss Peter
--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011

- https://peterbucher.ch/ - Meine persönliche Seite
- https://fpvspots.net/ - Spots für FPV Dronenflüge
private Nachricht | Beiträge des Benutzers
mosspower
myCSharp.de - Member

Avatar #avatar-2662.jpg


Dabei seit:
Beiträge: 456
Herkunft: Bamberg

Themenstarter:

beantworten | zitieren | melden

Hallo Peter Bucher,

vielen Dank nochmal für Deinen Hint. Codeeinsparung > 95 Prozent
private Nachricht | Beiträge des Benutzers
Peter Bucher
myCSharp.de - Experte

Avatar #jVxXe7MDBPAimxdX3em3.jpg


Dabei seit:
Beiträge: 5.940
Herkunft: Zentralschweiz

beantworten | zitieren | melden

Hallo mosspower

Kein Problem.
Wie sieht der Code den jetzt bei dir aus?


Gruss Peter
--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011

- https://peterbucher.ch/ - Meine persönliche Seite
- https://fpvspots.net/ - Spots für FPV Dronenflüge
private Nachricht | Beiträge des Benutzers
mosspower
myCSharp.de - Member

Avatar #avatar-2662.jpg


Dabei seit:
Beiträge: 456
Herkunft: Bamberg

Themenstarter:

beantworten | zitieren | melden

Naja, ich benutze das Attribute ...


 [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
  class SerializableField : Attribute {
    
  }

und im Code dann benutze ich die halt mit Attributes ... z.B. ...


  [SerializableField]
    private int blub = 0;

    [SerializableField]
    private String bla = String.Empty;

    private Decimal nonSerializable = 0.0m;

Wird die Applikation runtergefahren, dann werden alle mit Attribut geflagten Fields und Properties mittels Reflektion serialisiert, beim Start werden dann die Werte gesetzt (wenn vorhanden), nach Instanzierung mittels Reflektion.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von mosspower am .
private Nachricht | Beiträge des Benutzers
marsgk
myCSharp.de - Member



Dabei seit:
Beiträge: 1.439
Herkunft: Linz, Austria

beantworten | zitieren | melden

Warum verwendest du nicht die Attribute Serializable und NonSerialized und die Standardserialisierung von .Net?
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo mosspower,

an die Namen von Feldern kommst du quasi genauso einfach wie an den Namen der Klasse. Stichwort: MemberInfo, FieldInfo.

herbivore
private Nachricht | Beiträge des Benutzers
mosspower
myCSharp.de - Member

Avatar #avatar-2662.jpg


Dabei seit:
Beiträge: 456
Herkunft: Bamberg

Themenstarter:

beantworten | zitieren | melden

Hallo herbivore,

da hast Du recht, nur ist hier das Problem, dass ich einen String brauche um Operationen anzustellen, z.B. wenn Field name ist bla (wobei bla ein String ist, der soz. ein Verweis auf die Variable ist), dann mache das ... usw. ... das braucht man bei Klassen nicht (hier kann man ja Klassentypen vergleichen, bzw. abfragen). Die einzige Lösung, die mir eingefallen wäre (ohne die Attribute, die sind die beste Lösung) wäre gewesen, dass ich allen relevanten Variablen ein Postfix-Flag anhänge, z.B.

private int myTestVariable_ser;

.. dann hätti ich mit FieldInfos nur die mit dem Postfix serialisiert.

Gruß
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von mosspower am .
private Nachricht | Beiträge des Benutzers
mosspower
myCSharp.de - Member

Avatar #avatar-2662.jpg


Dabei seit:
Beiträge: 456
Herkunft: Bamberg

Themenstarter:

beantworten | zitieren | melden

Zitat von marsgk
Warum verwendest du nicht die Attribute Serializable und NonSerialized und die Standardserialisierung von .Net?

Weil man das Attribute nicht bei Felder verwenden kann. Ich möchte nicht das ganze Objekt serialisieren, da es sehr viele und sehr große sind. Es geht hier um Teilservices innerhalb eines Services (also zig Threads), die z.B. Imports, Counter, Fehler, Warnings etc. hochzählen und diese möchte ich nicht verlieren, wenn ich den Service runterfahre. Denn dann würde ich ja z.B. wieder bei 0 anfangen wenn aber z.B. schon X Dateien importiert worden sind an diesem Tag.
private Nachricht | Beiträge des Benutzers
kleines_eichhoernchen
myCSharp.de - Member

Avatar #avatar-2079.jpg


Dabei seit:
Beiträge: 3.971
Herkunft: Ursprünglich Vogtland, jetzt Much

beantworten | zitieren | melden

Felder werden mitserialisiert. Beim XmlSerializer allerdings nur public Felder. Binäre und Soap-Formatierung verwenden beispielsweise nur Felder zur Serialisierung, egal ob public oder private.

Wenn du dir eine benutzerdefinierte Serialisierung einer Klasse wünschst, dann implementier das Interface IXmlSerializable oder ISerializable.
Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...
private Nachricht | Beiträge des Benutzers
mosspower
myCSharp.de - Member

Avatar #avatar-2662.jpg


Dabei seit:
Beiträge: 456
Herkunft: Bamberg

Themenstarter:

beantworten | zitieren | melden

Hallo kleines_eichhoernchen,

ja, das hätte ich machen können, nur ist mir das im Moment zuviel Overhead, da es idR zwei bis drei Instanzvariablen sind (normaler Typ, also String oder int). Ich habe ja gegenwärtig schon eine lauffähige Lösung, ist auch so eine Art Anpassung an das Objekt, aber das erschien mir zu aufwändig, irgendwie wie mit Kanonen auf Spatzen schießen. Ich denke, dass die Lösung mit Attributes eine saubere (nicht die sauberste) und schnellste Lösung ist.
private Nachricht | Beiträge des Benutzers
JunkyXL
myCSharp.de - Experte

Avatar #avatar-3234.gif


Dabei seit:
Beiträge: 1.665
Herkunft: Ein paar Bytes südlich von string

beantworten | zitieren | melden

Noch ein kleiner Hinweis:
Setze 'Attribute' hinter dem Attribut-Klassennamen. Damit folgst der Namenskonvention für Attribute.
private Nachricht | Beiträge des Benutzers
marsgk
myCSharp.de - Member



Dabei seit:
Beiträge: 1.439
Herkunft: Linz, Austria

beantworten | zitieren | melden

Zitat von mosspower
Zitat von marsgk
Warum verwendest du nicht die Attribute Serializable und NonSerialized und die Standardserialisierung von .Net?

Weil man das Attribute nicht bei Felder verwenden kann...

Das NonSerialized Attribute kann man doch gerade nur bei Feldern verwenden!?
private Nachricht | Beiträge des Benutzers
mosspower
myCSharp.de - Member

Avatar #avatar-2662.jpg


Dabei seit:
Beiträge: 456
Herkunft: Bamberg

Themenstarter:

beantworten | zitieren | melden

Hier ist noch der Code .. habe ich in meine Serializable-Utilityklasse gepackt ...


using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using Util;
using System.Runtime.Serialization;
using System.Reflection;

namespace Util {
  /// <summary>
  /// Handles serialization issues
  /// </summary>
  public class SerializationUtil {
    private static readonly String PREFIX_SERIALIZABLE_VALUES_FIELD = "F_";
    private static readonly String PREFIX_SERIALIZABLE_VALUES_PROPERTY = "P_";
    private static readonly BindingFlags SERIALIZABLE_VALUES_BINDINGFLAGS = 
      BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static;

    /// <summary>
    /// Sets all fields and properties which are flagged with the 
    /// <see cref="Util.SerializableValue"/> attribute on the passed instance
    /// </summary>
    /// <param name="instance">The instance</param>
    /// <param name="serializedValues"></param>
    public static void SetSerializableValues(Object instance, Dictionary<String, Object> serializedValues) {
      try {
        // Check instance
        if(instance == null) {
          throw new ArgumentException("Parameter instance was passed null");
        }

        // Check serialized values
        if(serializedValues == null) {
          throw new ArgumentException("Parameter serializedValues was passed null");
        }

        foreach(String key in serializedValues.Keys) {
          String removePrefix = String.Empty;

          if(key.StartsWith(SerializationUtil.PREFIX_SERIALIZABLE_VALUES_FIELD)) {
            String fieldName = StringUtil.ReplaceEmpty(key, 
              SerializationUtil.PREFIX_SERIALIZABLE_VALUES_FIELD);

            // Get field info
            FieldInfo fieldInfo = instance.GetType().GetField(fieldName,
              SerializationUtil.SERIALIZABLE_VALUES_BINDINGFLAGS | BindingFlags.GetField);

            // Set value
            fieldInfo.SetValue(instance, serializedValues[key]);
          }
          else if(key.StartsWith(SerializationUtil.PREFIX_SERIALIZABLE_VALUES_PROPERTY)) {
            String fieldName = StringUtil.ReplaceEmpty(key,
            SerializationUtil.PREFIX_SERIALIZABLE_VALUES_PROPERTY);

            // Get property info
            PropertyInfo propertyInfo = instance.GetType().GetProperty(fieldName,
              SerializationUtil.SERIALIZABLE_VALUES_BINDINGFLAGS | BindingFlags.GetProperty);

            // Set value
            propertyInfo.SetValue(instance, serializedValues[key], null);
          }
        }
      }
      catch {
        throw;
      }
    }

    /// <summary>
    /// Gets all instance field and property values for the passed instance
    /// which has been flagged with the attribute <see cref="Util.SerializableValue"/>
    /// </summary>
    /// <param name="instance">The instance</param>
    /// <returns>Dict</returns>
    public static Dictionary<String, Object> GetSerializableValues(Object instance) {
      Dictionary<String, Object> serializableValues = null;

      try {
        if(instance != null) {
          // Get all field infos
          FieldInfo[] fieldInfos = instance.GetType().GetFields(
            SerializationUtil.SERIALIZABLE_VALUES_BINDINGFLAGS | BindingFlags.GetField);

          if(fieldInfos != null) {
            foreach(FieldInfo fieldInfo in fieldInfos) {
              Object[] customAttributes = fieldInfo.GetCustomAttributes(true);

              if(customAttributes != null) {
                foreach(Object customAttribute in customAttributes) {
                  if(customAttribute.GetType().Equals(typeof(SerializableValue))) {
                    // Add to dictionary
                    if(serializableValues == null) {
                      serializableValues = new Dictionary<String, Object>();
                    }

                    serializableValues.Add(SerializationUtil.PREFIX_SERIALIZABLE_VALUES_FIELD +
                      fieldInfo.Name, fieldInfo.GetValue(instance));
                  }
                }
              }
            }
          }

          // Get all property infos
          PropertyInfo[] propertyInfos = instance.GetType().GetProperties(
            SerializationUtil.SERIALIZABLE_VALUES_BINDINGFLAGS | BindingFlags.GetProperty);

          if(propertyInfos != null) {
            foreach(PropertyInfo propertyInfo in propertyInfos) {
              Object[] customAttributes = propertyInfo.GetCustomAttributes(true);

              if(customAttributes != null) {
                foreach(Object customAttribute in customAttributes) {
                  if(customAttribute.GetType().Equals(typeof(SerializableValue))) {
                    // Add to dictionary
                    if(serializableValues == null) {
                      serializableValues = new Dictionary<String, Object>();
                    }

                    serializableValues.Add(SerializationUtil.PREFIX_SERIALIZABLE_VALUES_PROPERTY +
                      propertyInfo.Name, propertyInfo.GetValue(instance, null));
                  }
                }
              }
            }
          }
        }
      }
      catch {
        throw;
      }

      return serializableValues;
    }
  }
}

private Nachricht | Beiträge des Benutzers