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();


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow