C# Language
Casting
Suche…
Bemerkungen
Casting ist nicht dasselbe wie das Konvertieren . Es ist möglich, den Zeichenfolgewert "-1"
in einen ganzzahligen Wert ( -1
) umzuwandeln. Dies muss jedoch über Bibliotheksmethoden wie Convert.ToInt32()
oder Int32.Parse()
. Es kann nicht direkt mit der Casting-Syntax ausgeführt werden.
Umwandeln eines Objekts in einen Basistyp
Angesichts der folgenden Definitionen:
public interface IMyInterface1
{
string GetName();
}
public interface IMyInterface2
{
string GetName();
}
public class MyClass : IMyInterface1, IMyInterface2
{
string IMyInterface1.GetName()
{
return "IMyInterface1";
}
string IMyInterface2.GetName()
{
return "IMyInterface2";
}
}
Umwandeln eines Objekts in ein Basistyp-Beispiel:
MyClass obj = new MyClass();
IMyInterface1 myClass1 = (IMyInterface1)obj;
IMyInterface2 myClass2 = (IMyInterface2)obj;
Console.WriteLine("I am : {0}", myClass1.GetName());
Console.WriteLine("I am : {0}", myClass2.GetName());
// Outputs :
// I am : IMyInterface1
// I am : IMyInterface2
Explizite Besetzung
Wenn Sie wissen, dass ein Wert von einem bestimmten Typ ist, können Sie ihn explizit in diesen Typ umwandeln, um ihn in einem Kontext zu verwenden, in dem dieser Typ benötigt wird.
object value = -1;
int number = (int) value;
Console.WriteLine(Math.Abs(number));
Wenn Sie versuchen, den value
direkt an Math.Abs()
, erhalten Sie eine Ausnahmebedingung zur Kompilierungszeit, da Math.Abs()
keine Überladung hat, die ein object
als Parameter übernimmt.
Wenn der value
nicht in ein int
, würde die zweite Zeile in diesem Beispiel eine InvalidCastException
Sicheres explizites Casting (`as`-Operator)
Wenn Sie nicht sicher sind, ob ein Wert von dem Typ ist, von dem Sie glauben, dass Sie ihn mit dem Operator as
sicher umsetzen können Wenn der Wert nicht von diesem Typ ist, ist der resultierende Wert null
.
object value = "-1";
int? number = value as int?;
if(number != null)
{
Console.WriteLine(Math.Abs(number.Value));
}
Beachten Sie, dass null
keine Art haben, so dass das as
Schlüsselwort wird sicher ergeben null
, wenn Giessharzsystemen null
Wert.
Implizite Besetzung
Ein Wert wird automatisch in den entsprechenden Typ umgewandelt, wenn der Compiler weiß, dass er immer in diesen Typ konvertiert werden kann.
int number = -1;
object value = number;
Console.WriteLine(value);
In diesem Beispiel mussten wir nicht die typische explizite Umwandlungssyntax verwenden, da der Compiler weiß, dass alle int
in object
s umgewandelt werden können. Tatsächlich könnten wir das Erstellen von Variablen vermeiden und -1
direkt als Argument von Console.WriteLine()
, das ein object
erwartet.
Console.WriteLine(-1);
Kompatibilität ohne Abguss prüfen
Wenn Sie wissen möchten, ob der Typ eines Werts einen bestimmten Typ erweitert oder implementiert, Sie ihn jedoch nicht als diesen Typ umwandeln möchten, können Sie den Operator is
.
if(value is int)
{
Console.WriteLine(value + "is an int");
}
Explizite numerische Konvertierungen
Explizite Casting-Operatoren können verwendet werden, um Konvertierungen numerischer Typen durchzuführen, auch wenn sie sich nicht erweitern oder implementieren.
double value = -1.1;
int number = (int) value;
Beachten Sie, dass in Fällen, in denen der Zieltyp eine geringere Genauigkeit als der Originaltyp hat, die Genauigkeit verloren geht. Zum Beispiel wird -1.1
als Doppelwert im obigen Beispiel zu -1
als ganzzahliger Wert.
Außerdem sind numerische Konvertierungen von Kompilierzeittypen abhängig. Sie funktionieren daher nicht, wenn die numerischen Typen in Objekten "eingebettet" wurden.
object value = -1.1;
int number = (int) value; // throws InvalidCastException
Konvertierungsoperatoren
In C # können Typen benutzerdefinierte Konvertierungsoperatoren definieren, mit denen Werte in explizite oder implizite Umwandlungen in andere Typen konvertiert werden können. Stellen Sie sich beispielsweise eine Klasse vor, die einen JavaScript-Ausdruck darstellen soll:
public class JsExpression
{
private readonly string expression;
public JsExpression(string rawExpression)
{
this.expression = rawExpression;
}
public override string ToString()
{
return this.expression;
}
public JsExpression IsEqualTo(JsExpression other)
{
return new JsExpression("(" + this + " == " + other + ")");
}
}
Wenn Sie eine JsExpression erstellen möchten, die einen Vergleich von zwei JavaScript-Werten darstellt, können Sie Folgendes tun:
JsExpression intExpression = new JsExpression("-1");
JsExpression doubleExpression = new JsExpression("-1.0");
Console.WriteLine(intExpression.IsEqualTo(doubleExpression)); // (-1 == -1.0)
Wir können jedoch einige explizite Konvertierungsoperatoren zu JsExpression
hinzufügen, um bei der expliziten Umwandlung eine einfache Konvertierung zu ermöglichen.
public static explicit operator JsExpression(int value)
{
return new JsExpression(value.ToString());
}
public static explicit operator JsExpression(double value)
{
return new JsExpression(value.ToString());
}
// Usage:
JsExpression intExpression = (JsExpression)(-1);
JsExpression doubleExpression = (JsExpression)(-1.0);
Console.WriteLine(intExpression.IsEqualTo(doubleExpression)); // (-1 == -1.0)
Oder wir können diese Operatoren implizit ändern, um die Syntax viel einfacher zu machen.
public static implicit operator JsExpression(int value)
{
return new JsExpression(value.ToString());
}
public static implicit operator JsExpression(double value)
{
return new JsExpression(value.ToString());
}
// Usage:
JsExpression intExpression = -1;
Console.WriteLine(intExpression.IsEqualTo(-1.0)); // (-1 == -1.0)
LINQ Casting-Vorgänge
Angenommen, Sie haben Typen wie die folgenden:
interface IThing { }
class Thing : IThing { }
Mit LINQ können Sie eine Projektion erstellen, die den generischen Typ der Kompilierzeit eines IEnumerable<>
über die Enumerable.Cast<>()
und Enumerable.OfType<>()
.
IEnumerable<IThing> things = new IThing[] {new Thing()};
IEnumerable<Thing> things2 = things.Cast<Thing>();
IEnumerable<Thing> things3 = things.OfType<Thing>();
Wenn things2
ausgewertet wird, versucht die Cast<>()
Methode, alle Werte in things
in Thing
s zu things2
. Wenn ein Wert gefunden wird, der nicht umgewandelt werden kann, wird eine InvalidCastException
ausgelöst.
Bei der things3
führt die OfType<>()
Methode dasselbe aus, mit der Ausnahme, dass ein Wert, der nicht umgewandelt werden kann, einfach weggelassen wird, anstatt eine Ausnahme OfType<>()
.
Aufgrund des generischen Typs dieser Methoden können sie keine Konvertierungsoperatoren aufrufen oder numerische Konvertierungen durchführen.
double[] doubles = new[]{1,2,3}.Cast<double>().ToArray(); // Throws InvalidCastException
Sie können einfach einen Cast in einem .Select()
als Workaround ausführen:
double[] doubles = new[]{1,2,3}.Select(i => (double)i).ToArray();