C# Language
Gjutning
Sök…
Anmärkningar
Gjutning är inte samma sak som Konvertering . Det är möjligt att konvertera strängvärdet "-1"
till ett heltalvärde ( -1
), men detta måste göras genom biblioteksmetoder som Convert.ToInt32()
eller Int32.Parse()
. Det kan inte göras med hjälp av gjutsyntax direkt.
Kasta ett objekt till en bastyp
Följande definitioner:
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";
}
}
Gjutning av ett objekt till ett exempel på bastyp:
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
Explicit casting
Om du vet att ett värde är av en specifik typ kan du uttryckligen kasta det till den typen för att använda det i ett sammanhang där den typen behövs.
object value = -1;
int number = (int) value;
Console.WriteLine(Math.Abs(number));
Om vi försökte överföra value
direkt till Math.Abs()
, skulle vi få ett undantag för Math.Abs()
eftersom Math.Abs()
inte har en överbelastning som tar ett object
som en parameter.
Om value
inte kunde kastas till en int
, skulle den andra raden i detta exempel kasta en InvalidCastException
Safe Explicit Casting ("som" -operatör)
Om du är osäker på om ett värde är den typ du tycker att det är, kan du säkert kasta den med hjälp av as
operatör. Om värdet inte är av den typen kommer det resulterande värdet att vara null
.
object value = "-1";
int? number = value as int?;
if(number != null)
{
Console.WriteLine(Math.Abs(number.Value));
}
Observera att null
har någon typ, så nyckelordet as
ger säkert null
när du kastar null
.
Implicit casting
Ett värde kastas automatiskt till lämplig typ om kompilatorn vet att det alltid kan konverteras till den typen.
int number = -1;
object value = number;
Console.WriteLine(value);
I det här exemplet behövde vi inte använda den typiska uttryckliga gjutsyntaxen eftersom kompilatorn vet att alla int
kan kastas till object
s. Vi kan faktiskt undvika att skapa variabler och skicka -1
direkt som argumentet för Console.WriteLine()
som förväntar sig ett object
.
Console.WriteLine(-1);
Kontrollera kompatibilitet utan gjutning
Om du behöver veta om ett värdetyp utökar eller implementerar en viss typ, men du inte vill kasta den som den typen, kan du använda operatören is
.
if(value is int)
{
Console.WriteLine(value + "is an int");
}
Explicit Numeric Conversions
Explicit casting-operatörer kan användas för att utföra omvandlingar av numeriska typer, även om de inte utökar eller implementerar varandra.
double value = -1.1;
int number = (int) value;
Observera att i fall där destinationstypen har mindre precision än den ursprungliga typen kommer precisionen att gå förlorad. Till exempel blir -1.1
som ett dubbelvärde i exemplet ovan -1
som ett heltal.
Numeriska konverteringar förlitar sig också på kompileringstider, så att de inte fungerar om de numeriska typerna har "boxats" i objekt.
object value = -1.1;
int number = (int) value; // throws InvalidCastException
Konverteringsoperatörer
I C # kan typer definiera anpassade konverteringsoperatörer , som gör att värden kan konverteras till och från andra typer med antingen explicita eller implicita casts. Tänk till exempel på en klass som är avsedd att representera ett JavaScript-uttryck:
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 + ")");
}
}
Om vi ville skapa en JsExpression som representerar en jämförelse av två JavaScript-värden, kan vi göra något liknande:
JsExpression intExpression = new JsExpression("-1");
JsExpression doubleExpression = new JsExpression("-1.0");
Console.WriteLine(intExpression.IsEqualTo(doubleExpression)); // (-1 == -1.0)
Men vi kan lägga till några explicita konverteringsoperatörer till JsExpression
, för att tillåta en enkel konvertering när du använder explicita casting.
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)
Eller så kan vi ändra dessa operatörer till implicit för att göra syntaxen mycket enklare.
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 Gjutning
Anta att du har typer som följande:
interface IThing { }
class Thing : IThing { }
LINQ låter dig skapa en projektion som ändrar den generella kompileringstiden för en IEnumerable<>
via Enumerable.Cast<>()
och Enumerable.OfType<>()
.
IEnumerable<IThing> things = new IThing[] {new Thing()};
IEnumerable<Thing> things2 = things.Cast<Thing>();
IEnumerable<Thing> things3 = things.OfType<Thing>();
När things2
utvärderas kommer metoden Cast<>()
att försöka kasta alla värden i things
till Thing
. Om det stöter på ett värde som inte kan kastas kommer en InvalidCastException
att kastas.
När things3
utvärderas kommer OfType<>()
att göra samma sak, förutom att om den stöter på ett värde som inte kan kastas, kommer det helt enkelt att utelämna det värdet i stället för att kasta ett undantag.
På grund av den generiska typen av dessa metoder kan de inte åberopa konverteringsoperatörer eller utföra numeriska omvandlingar.
double[] doubles = new[]{1,2,3}.Cast<double>().ToArray(); // Throws InvalidCastException
Du kan helt enkelt utföra en roll i en .Select()
som en lösning:
double[] doubles = new[]{1,2,3}.Select(i => (double)i).ToArray();