Frage

Ich versuche, herauszufinden Syntax Figur, die Stützen Unboxing einen integralen Typs (kurz / int / long) in seinen intrinsischen Typ, wenn der Typ selbst ist nicht bekannt.

Hier ist ein völlig erfundenes Beispiel, dass das Konzept demonstriert:

 // Just a simple container that returns values as objects
 struct DataStruct
 {
  public short ShortVale;
  public int IntValue;
  public long LongValue;
  public object GetBoxedShortValue() { return ShortVale; }
  public object GetBoxedIntValue() { return IntValue; }
  public object GetBoxedLongValue() { return LongValue; }
 }

 static void Main( string[] args )
 {

  DataStruct data;

  // Initialize data - any value will do
  data.LongValue = data.IntValue = data.ShortVale = 42;

  DataStruct newData;

  // This works if you know the type you are expecting!
  newData.ShortVale = (short)data.GetBoxedShortValue();
  newData.IntValue = (int)data.GetBoxedIntValue();
  newData.LongValue = (long)data.GetBoxedLongValue();

  // But what about when you don't know?
  newData.ShortVale = data.GetBoxedShortValue(); // error
  newData.IntValue = data.GetBoxedIntValue(); // error
  newData.LongValue = data.GetBoxedLongValue(); // error
 }

In jedem Fall ist die Integral-Typen konsistent sind, so sollte es irgendeine Form der Syntax, die sagt, dass „das Objekt enthält eine einfache Art von X, Rückkehr, dass als X (obwohl ich weiß nicht, was X)“ . Denn letztlich die Objekte aus der gleichen Quelle stammen, kann es wirklich nicht ein Mismatch (kurz! = Lang).

Ich entschuldige mich für das erfundene Beispiel, es wie die beste Art und Weise schien die Syntax zu demonstrieren.

Danke.

War es hilfreich?

Lösung

Nun, die object an sich ist die allgemeinste Art der Rahmen kennt. Ob ist ein Box-Wert-Typ (einschließlich primitiven) oder etwas anderes spielt keine Rolle; wenn Sie spezifischere Sie bekommen wurde , um eine Typumwandlung zu tun, wenn Sie in der "lose typisiert" Welt mit object bleiben (oder in C # 4, dynamic).

Beachten Sie jedoch, dass Sie eine Liste von Bedingungen verwenden können, um zu erreichen, was Sie wollen:

object boxedValue = GetBoxedValue();
if (typeof(short) == boxedValue.GetType()) {
  newData.ShortValue = (short)boxedValue;
} else if (typeof(int) == boxedValue.GetType()) {
  newData.IntValue = (int)boxedValue;
} else if (typeof(long) == boxedValue.GetType()) {
  newData.LongValue = (long)boxedValue;
} else {
  // not one of those
}

Edit: Eine generische "Box" kann auch das tun, was Sie wollen:

public class Box<T>: IConvertible where T: struct, IConvertible {
    public static implicit operator T(Box<T> boxed) {
        return boxed.Value;
    }

    public static explicit operator Box<T>(T value) {
        return new Box<T>(value);
    }

    private readonly T value;

    public Box(T value) {
        this.value = value;
    }

    public T Value {
        get {
            return value;
        }
    }

    public override bool Equals(object obj) {
        Box<T> boxed = obj as Box<T>;
        if (boxed != null) {
            return value.Equals(boxed.Value);
        }
        return value.Equals(obj);
    }

    public override int GetHashCode() {
        return value.GetHashCode();
    }

    public override string ToString() {
        return value.ToString();
    }

    bool IConvertible.ToBoolean(IFormatProvider provider) {
        return value.ToBoolean(provider);
    }

    char IConvertible.ToChar(IFormatProvider provider) {
        return value.ToChar(provider);
    }

    sbyte IConvertible.ToSByte(IFormatProvider provider) {
        return value.ToSByte(provider);
    }

    byte IConvertible.ToByte(IFormatProvider provider) {
        return value.ToByte(provider);
    }

    short IConvertible.ToInt16(IFormatProvider provider) {
        return value.ToInt16(provider);
    }

    ushort IConvertible.ToUInt16(IFormatProvider provider) {
        return value.ToUInt16(provider);
    }

    int IConvertible.ToInt32(IFormatProvider provider) {
        return value.ToInt32(provider);
    }

    uint IConvertible.ToUInt32(IFormatProvider provider) {
        return value.ToUInt32(provider);
    }

    long IConvertible.ToInt64(IFormatProvider provider) {
        return value.ToInt64(provider);
    }

    ulong IConvertible.ToUInt64(IFormatProvider provider) {
        return value.ToUInt64(provider);
    }

    float IConvertible.ToSingle(IFormatProvider provider) {
        return value.ToSingle(provider);
    }

    double IConvertible.ToDouble(IFormatProvider provider) {
        return value.ToDouble(provider);
    }

    decimal IConvertible.ToDecimal(IFormatProvider provider) {
        return value.ToDecimal(provider);
    }

    DateTime IConvertible.ToDateTime(IFormatProvider provider) {
        return value.ToDateTime(provider);
    }

    string IConvertible.ToString(IFormatProvider provider) {
        return value.ToString(provider);
    }

    object IConvertible.ToType(Type conversionType, IFormatProvider provider) {
        return value.ToType(conversionType, provider);
    }
}

Dies kann dann statt object verwendet werden; es ist immer noch ein Objektverweis, sondern es auch auf die ursprüngliche Struktur oder Urtyp stark typisiert ist.

Andere Tipps

Ich bin mir nicht ganz sicher, was Sie möchten mit, dies zu erreichen, aber Ihr DataStruct Typ ist errornous.

Ich nehme an, nicht alle ihre Methoden Longvalue zurück.

struct DataStruct
{
    public short ShortVale;
    public int IntValue;
    public long LongValue;
    public object GetBoxedShortValue() { return ShortVale; }
    public object GetBoxedIntValue() { return IntValue; }
    public object GetBoxedLongValue() { return LongValue; }
}

Ansonsten können Sie immer die Convert-Klasse verwenden, um zu versuchen, zwischen verschiedenen Arten zu konvertieren.
Zum Beispiel:

Convert.ToInt32(SomeObject);

Bitte klären Sie Ihren Beitrag (drücken Sie einfach auf die Schaltfläche Bearbeiten und bearbeiten es), wenn Sie etwas anderes gemeint.

übrigens kann von object Umwandlung seiner ziemlich fehleranfällig, da es der Basistyp von allem ist. So kann ein object alles sein, und das bedeutet, dass man nicht immer sicher eine object in einem int oder jede andere Art umwandeln.

Weitere Beispiele:

int value;
try
{
    value = Convert.ToInt32(someObject);
}
catch (FormatException)
{
    // the convertion is unsuccessful
}

Und das ist auch nützlich:

int myValue;
if (!int.TryParse(something, out myValue))
{
    //unsuccessful
}

Ich hoffe, das hilft.

Sie können dynamic zurückkehren, die dann gecastet in einem integrierten Typ sein kann.

Wie bereits von anderen erwähnt, Ihr Beispiel wird nicht funktionieren, weil Sie zurückkommen Longvalue von jeder Methode, so dass Sie hier eine ungültige Cast Exception bekommen (einen Boxed lang nicht gegossen zu kurz sein).

newData.ShortVale = (short)data.GetBoxedShortValue();

Allerdings, C # 4 des dynamic verwenden, dies funktionieren wird (beachten Sie die Korrekturen an Ihre GetBoxed Methoden und dynamic statt object:

// Just a simple container that returns values as objects
struct DataStruct
{
    public short ShortVale;
    public int IntValue;
    public long LongValue;
    public dynamic GetBoxedShortValue() { return ShortValue; }
    public dynamic GetBoxedIntValue() { return IntValue; }
    public dynamic GetBoxedLongValue() { return LongValue; }
}

static void Main( string[] args )
{
    DataStruct data;

    // Initialize data - any value will do
    data.LongValue = data.IntValue = data.ShortVale = 42;

    DataStruct newData;

    newData.ShortVale = (short)data.GetBoxedShortValue();
    newData.IntValue = (int)data.GetBoxedIntValue();
    newData.LongValue = (long)data.GetBoxedLongValue();

    newData.ShortVale = data.GetBoxedShortValue(); // ok
    newData.IntValue = data.GetBoxedIntValue(); // ok
    newData.LongValue = data.GetBoxedLongValue(); // ok
}

Beachten Sie, dass Sie in den letzten drei Fällen keine Würfe nicht brauchen. Beachten Sie aber auch, dass, wenn die Typen nicht align tun, wie in GetBoxedShortValue() { return LongValue; }, die letzten drei Zeilen in einem ungültigen Guss Ausnahmen führen. (Interessanterweise ist die ersten drei werden nicht, sie werden nur Arbeit, aber wenn man dynamic zurück in object ändern, sie ungültig Guss Ausnahmen werfen.)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top