Generische, XML-serialisierbare Parameterklasse

Objektdefinitionen

/// <summary>
/// Beispielenumerator
/// </summary> 
public enum ESType
{
    None,
    Static,
    Slope
}
/// <summary>
/// Beispielincludes, diese Typen werden hiermit importiert und können später per XML serialisiert werden
/// muss um die gewünschten Typen erweitert werden
/// </summary> 
[XmlInclude(typeof(GenericDataDescriptor<int>))]
[XmlInclude(typeof(GenericDataDescriptor<int[]>))]
[XmlInclude(typeof(GenericDataDescriptor<uint>))]
[XmlInclude(typeof(GenericDataDescriptor<uint[]>))]
[XmlInclude(typeof(GenericDataDescriptor<float>))]
[XmlInclude(typeof(GenericDataDescriptor<float[]>))]
[XmlInclude(typeof(GenericDataDescriptor<double>))]
[XmlInclude(typeof(GenericDataDescriptor<double[]>))]
[XmlInclude(typeof(GenericDataDescriptor<bool>))]
[XmlInclude(typeof(GenericDataDescriptor<bool[]>))]
[XmlInclude(typeof(GenericDataDescriptor<string>))]
[XmlInclude(typeof(GenericDataDescriptor<string[]>))]
[XmlInclude(typeof(GenericDataDescriptor<byte>))]
[XmlInclude(typeof(GenericDataDescriptor<byte[]>))]
[XmlInclude(typeof(GenericDataDescriptor<List<int>>))]
[XmlInclude(typeof(GenericDataDescriptor<List<uint>>))]
[XmlInclude(typeof(GenericDataDescriptor<List<float>>))]
[XmlInclude(typeof(GenericDataDescriptor<List<double>>))]
[XmlInclude(typeof(GenericDataDescriptor<List<bool>>))]
[XmlInclude(typeof(GenericDataDescriptor<List<string>>))]
[XmlInclude(typeof(GenericDataDescriptor<List<byte>>))]
[XmlInclude(typeof(CBlockParam<ESType>))]
/// <summary>
/// Dummyobjekt für die ParameterListen der Blöcke
/// </summary> 
public class CBlockParamBase
{
    private string _sName = string.Empty;
    private bool _bChangeableByUser = false;
    protected object _oValue = null;

    [XmlAttribute("name")]
    public string Name
    {
        get { return _sName; }
        set { _sName = value; }
    }
    [XmlAttribute("changeable")]
    public bool ChangeableByUser
    {
        get { return _bChangeableByUser; }
        set { _bChangeableByUser = value; }
    }
    [XmlIgnore]
    public object oValue
    {
        get { return _oValue; }
        set { _oValue = value; }
    }
    [XmlIgnore]
    public virtual Type ParamType
    {
        // dummy
        get { return typeof(int); }
    }

    public CBlockParamBase()
    {
    }
}
/// <summary>
/// generisches Parameterobjekt
/// </summary>
/// <typeparam name="T">Wert- oder Referenztyp des Parameters</typeparam>
public class CBlockParam<T> : CBlockParamBase
{
    #region Properties
    [XmlElement("value")]
    public T tValue
    {
        get { return (T)_oValue; }
        set { _oValue = (object)value; }
    }
    [XmlIgnore]
    public override Type ParamType
    {
        get { return typeof(T); }
    }
    #endregion

    public CBlockParam()
    {
        // muss leer bleiben, sonst Fehler beim Laden von XML (deserialize)
    }

    public CBlockParam(string sName, T Value, bool bIsUserCangeable)
    {
        this.Name = sName;
        _oValue = (object)Value;
        this.ChangeableByUser = bIsUserCangeable;
    }
}

Verwendung

// Parameterliste für alle Parameter vom Typ des allg. Interfaces
private List<CBlockParam> ParameterListe = new List<CBlockParam>();

// ein paar Parameterdefinition
CBlockParam<int> Integerwert = new CBlockParam<int>("Parameter integer", 0, true);
CBlockParam<bool> Boolwert = new CBlockParam<bool>("Parameter bool", true, true);
CBlockParam<double> Doublewert = new CBlockParam<double>("Parameter double", 0.0, true);
CBlockParam<string> Stringwert = new CBlockParam<string>("Parameter string", "x1+x2", true);
CBlockParam<ESType> Enumwert = new CBlockParam<ESType>("Parameter enum", ESType.Slope, true);
CBlockParam<List<int>> ListObject = new CBlockParam<List<int>>("Parameter object", new List<int>, false);

// die Parameter der Liste hinzufügen
ParameterListe.Add(Integerwert);
ParameterListe.Add(Boolwert);
ParameterListe.Add(Doublewert);
ParameterListe.Add(Stringwert);
ParameterListe.Add(Enumwert);
ParameterListe.Add(ListObject);

// alle Parameter der Liste ausgeben
foreach (CBlockParamBase bp in ParameterListe)
{
    if (bp.ChangeableByUser)
    {
        Console.WriteLine(bp.Name + ": " + bp.oValue.ToString());
    }
}
                
// Parametertypen unterscheiden
// beispielsweise den ersten Parameter aus der Liste holen
CBlockParamBase bpb = ParameterListe[0] as CBlockParamBase;
// anhand des Typs den TypeCode ermitteln und per TypeCode
// eine Unterscheidung vornehmen, hier beispielhaft für die Typen
// bool, double, string, int, enum, object [List]
switch (Type.GetTypeCode(bpb.ParamType))
{
    case TypeCode.Boolean:
        break;
    case TypeCode.Double:
        break;
    case TypeCode.String:
        break;
    case TypeCode.Int32:
        CBlockParam<int> bpi = bpb as CBlockParam<int>;
        if (bpi != null)
        {
            // int
        }
        else
        {
            // enum
            foreach (string sTypeName in Enum.GetNames(bpb.ParamType))
            {
                Console.WriteLine(sTypeName);
            }
        }
        break;
    case TypeCode.Object:
        // list
        CBlockParam<List<int>> l = bpb as CBlockParam<List<int>>;
        if (l != null)
        {
        }
        break;
    default:
        break;
}

// Beispiele für Wertzuweisungen
// 1. allgemein über object
// 2. speziell über Typ-spezifizierten Wert
Integerwert.oValue = 24;
Integerwert.tValue = 24;
Boolwert.oValue = true;
Boolwert.tValue = true;
Doublewert.oValue = 10.0;
Doublewert.tValue = 10.0;
string sFormel = (string)Stringwert.oValue;
string sFormel = Stringwert.tValue;
ESType eTest = (ESType)Enumwert.oValue;
ESType eTest = Enumwert.tValue;
int b = ListObject.tValue[0];
int b = ((List<int>)ListObject.oValue)[0];