C# Language
Gieten
Zoeken…
Opmerkingen
Casten is niet hetzelfde als Converteren . Het is mogelijk om de tekenreekswaarde "-1"
te converteren naar een geheel getal ( -1
), maar dit moet worden gedaan via bibliotheekmethoden zoals Convert.ToInt32()
of Int32.Parse()
. Het kan niet worden gedaan met behulp van casting syntax direct.
Cast een object naar een basistype
Gegeven de volgende definities:
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";
}
}
Een object casten naar een voorbeeld van een basistype:
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
Expliciete casting
Als u weet dat een waarde van een specifiek type is, kunt u deze expliciet naar dat type casten om deze in een context te gebruiken waar dat type nodig is.
object value = -1;
int number = (int) value;
Console.WriteLine(Math.Abs(number));
Als we zouden proberen value
rechtstreeks aan Math.Abs()
, zouden we een compilatie-uitzondering krijgen omdat Math.Abs()
geen overbelasting heeft die een object
als parameter neemt.
Als de value
niet naar een int
kon worden gegoten, zou de tweede regel in dit voorbeeld een InvalidCastException
Veilig expliciet casten (operator 'als')
Als u niet zeker weet of een waarde van het type is dat u denkt te hebben, kunt u deze veilig casten met de operator as
. Als de waarde niet van dat type is, is de resulterende waarde null
.
object value = "-1";
int? number = value as int?;
if(number != null)
{
Console.WriteLine(Math.Abs(number.Value));
}
Merk op dat null
waarden geen type hebben, dus het sleutelwoord as
levert veilig null
bij het casten van een null
waarde.
Impliciet casten
Een waarde wordt automatisch naar het juiste type gegoten als de compiler weet dat deze altijd naar dat type kan worden geconverteerd.
int number = -1;
object value = number;
Console.WriteLine(value);
In dit voorbeeld hoefden we de typische expliciete casting-syntaxis niet te gebruiken, omdat de compiler weet dat alle int
's naar object
s kunnen worden gecast. We zouden zelfs kunnen voorkomen dat we variabelen creëren en -1
rechtstreeks doorgeven als het argument van Console.WriteLine()
dat een object
verwacht.
Console.WriteLine(-1);
Compatibiliteit controleren zonder casten
Als u wilt weten of het type van een waarde een bepaald type uitbreidt of implementeert, maar u het eigenlijk niet als dat type wilt casten, kunt u de operator is
gebruiken.
if(value is int)
{
Console.WriteLine(value + "is an int");
}
Expliciete numerieke conversies
Expliciete castingoperators kunnen worden gebruikt om conversies van numerieke typen uit te voeren, hoewel ze elkaar niet uitbreiden of implementeren.
double value = -1.1;
int number = (int) value;
Merk op dat in gevallen waarin het type bestemming minder precisie heeft dan het oorspronkelijke type, de precisie verloren gaat. -1.1
als dubbele waarde in het bovenstaande voorbeeld wordt bijvoorbeeld -1
als een geheel getal.
Numerieke conversies zijn ook afhankelijk van compilatie-tijdtypen, dus ze werken niet als de numerieke typen in objecten zijn "omkaderd".
object value = -1.1;
int number = (int) value; // throws InvalidCastException
Conversie-exploitanten
In C # kunnen typen aangepaste conversie-operators definiëren, waarmee waarden naar en van andere typen kunnen worden geconverteerd met behulp van expliciete of impliciete casts. Overweeg bijvoorbeeld een klasse die bedoeld is om een JavaScript-expressie te vertegenwoordigen:
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 + ")");
}
}
Als we een JsExpression wilden maken die een vergelijking van twee JavaScript-waarden vertegenwoordigt, zouden we zoiets kunnen doen:
JsExpression intExpression = new JsExpression("-1");
JsExpression doubleExpression = new JsExpression("-1.0");
Console.WriteLine(intExpression.IsEqualTo(doubleExpression)); // (-1 == -1.0)
Maar we kunnen enkele expliciete conversie-operatoren toevoegen aan JsExpression
, om een eenvoudige conversie toe te staan wanneer expliciet casten wordt gebruikt.
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)
Of we kunnen deze operatoren veranderen in impliciet om de syntax veel eenvoudiger te maken.
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-activiteiten
Stel dat u typen als de volgende hebt:
interface IThing { }
class Thing : IThing { }
Met LINQ kunt u een projectie maken die het compilatie-generieke type van een IEnumerable<>
Enumerable.Cast<>()
via de Enumerable.Cast<>()
en Enumerable.OfType<>()
.
IEnumerable<IThing> things = new IThing[] {new Thing()};
IEnumerable<Thing> things2 = things.Cast<Thing>();
IEnumerable<Thing> things3 = things.OfType<Thing>();
Wanneer things2
wordt geëvalueerd, zal de methode Cast<>()
proberen alle waarden in things
in Thing
s te casten. Als het een waarde tegenkomt die niet kan worden gecast, wordt een InvalidCastException
gegenereerd.
Wanneer things3
wordt geëvalueerd, doet de OfType<>()
hetzelfde, behalve dat als het een waarde tegenkomt die niet kan worden gecast, deze waarde gewoon wordt weggelaten in plaats van een uitzondering te genereren.
Vanwege het generieke type van deze methoden kunnen ze geen conversie-operators oproepen of numerieke conversies uitvoeren.
double[] doubles = new[]{1,2,3}.Cast<double>().ToArray(); // Throws InvalidCastException
U kunt eenvoudig een cast uitvoeren in een .Select()
als tijdelijke oplossing:
double[] doubles = new[]{1,2,3}.Select(i => (double)i).ToArray();