Anonyma typer

Anonyma typer är ett bekvämt sätt att kapsla in en uppsättning skrivskyddade egenskaper i ett enda objekt utan att uttryckligen behöva definiera en typ först. Typnamnet genereras av kompilatorn och är inte tillgängligt på källkodsnivå. Typen av varje egenskap härleds av kompilatorn.

Du skapar anonyma typer med hjälp av operatorn new tillsammans med en objektinitierare. Mer information om objektinitierare finns i Initierare för objekt och samling.

I följande exempel visas en anonym typ som initieras med två egenskaper med namnet Amount och Message.

var v = new { Amount = 108, Message = "Hello" };

// Rest the mouse pointer over v.Amount and v.Message in the following
// statement to verify that their inferred types are int and string.
Console.WriteLine(v.Amount + v.Message);

Anonyma typer används vanligtvis i -satsen i select ett frågeuttryck för att returnera en delmängd av egenskaperna från varje objekt i källsekvensen. Mer information om frågor finns i LINQ i C#.

Anonyma typer innehåller en eller flera offentliga skrivskyddade egenskaper. Inga andra typer av klassmedlemmar, till exempel metoder eller händelser, är giltiga. Uttrycket som används för att initiera en egenskap får inte vara null, en anonym funktion eller en pekartyp.

Det vanligaste scenariot är att initiera en anonym typ med egenskaper från en annan typ. Anta i följande exempel att det finns en klass med namnet Product. Klassen Product innehåller Color och Price egenskaper, tillsammans med andra egenskaper som du inte är intresserad av. Variabel är products en samling Product objekt. Den anonyma typdeklarationen börjar med nyckelordet new . Deklarationen initierar en ny typ som endast använder två egenskaper från Product. Om du använder anonyma typer returneras en mindre mängd data i frågan.

Om du inte anger medlemsnamn i den anonyma typen ger kompilatorn medlemmarna av anonym typ samma namn som den egenskap som används för att initiera dem. Du anger ett namn för en egenskap som initieras med ett uttryck, som du ser i föregående exempel. I följande exempel är Color namnen på egenskaperna för den anonyma typen och Price.

var productQuery =
    from prod in products
    select new { prod.Color, prod.Price };

foreach (var v in productQuery)
{
    Console.WriteLine("Color={0}, Price={1}", v.Color, v.Price);
}

Dricks

Du kan använda .NET-formatregeln IDE0037 för att framtvinga om härledda eller explicita medlemsnamn är att föredra.

Det går också att definiera ett fält efter objekt av en annan typ: klass, struct eller till och med en annan anonym typ. Det görs med hjälp av variabeln som innehåller det här objektet precis som i följande exempel, där två anonyma typer skapas med redan instansierade användardefinierade typer. I båda fallen är fältet product i den anonyma typen shipment och shipmentWithBonus av typen Product som innehåller standardvärdena för varje fält. Och fältet bonus kommer att vara av anonym typ som skapats av kompilatorn.

var product = new Product();
var bonus = new { note = "You won!" };
var shipment = new { address = "Nowhere St.", product };
var shipmentWithBonus = new { address = "Somewhere St.", product, bonus };

När du använder en anonym typ för att initiera en variabel deklarerar du vanligtvis variabeln som en implicit typ av lokal variabel med hjälp av var. Det går inte att ange typnamnet i variabeldeklarationen eftersom endast kompilatorn har åtkomst till det underliggande namnet på den anonyma typen. Mer information om varfinns i Implicit inskrivna lokala variabler.

Du kan skapa en matris med anonymt inskrivna element genom att kombinera en implicit typad lokal variabel och en implicit typad matris, som du ser i följande exempel.

var anonArray = new[] { new { name = "apple", diam = 4 }, new { name = "grape", diam = 1 }};

Anonyma typer är class typer som härleds direkt från objectoch som inte kan omvandlas till någon typ förutom object. Kompilatorn ger ett namn för varje anonym typ, även om programmet inte kan komma åt den. När det gäller den vanliga språkkörningen skiljer sig en anonym typ inte från någon annan referenstyp.

Om två eller flera anonyma objektinitierare i en sammansättning anger en sekvens med egenskaper som är i samma ordning och som har samma namn och typer behandlar kompilatorn objekten som instanser av samma typ. De delar samma kompilatorgenererade typinformation.

Anonyma typer stöder icke-destruktiv mutation i form av med uttryck. På så sätt kan du skapa en ny instans av en anonym typ där en eller flera egenskaper har nya värden:

var apple = new { Item = "apples", Price = 1.35 };
var onSale = apple with { Price = 0.79 };
Console.WriteLine(apple);
Console.WriteLine(onSale);

Du kan inte deklarera ett fält, en egenskap, en händelse eller returtypen för en metod som en anonym typ. På samma sätt kan du inte deklarera en formell parameter för en metod, egenskap, konstruktor eller indexerare som en anonym typ. Om du vill skicka en anonym typ, eller en samling som innehåller anonyma typer, som ett argument till en metod, kan du deklarera parametern som typ object. Att använda object för anonyma typer motverkar dock syftet med stark skrivning. Om du måste lagra frågeresultat eller skicka dem utanför metodgränsen kan du överväga att använda en vanlig namngiven struct eller klass i stället för en anonym typ.

Equals Eftersom metoderna och GetHashCode för anonyma typer definieras i termer av Equals egenskapernas metoder och GetHashCode är två instanser av samma anonyma typ lika endast om alla deras egenskaper är lika.

Kommentar

Tillgänglighetsnivån för en anonym typ är internal, och därför är två anonyma typer som definierats i olika sammansättningar inte av samma typ. Därför kan instanser av anonyma typer inte vara lika med varandra när de definieras i olika sammansättningar, även om alla deras egenskaper är lika med varandra.

Anonyma typer åsidosätter ToString metoden och sammanfogar namnet och ToString utdata för varje egenskap som omges av klammerparenteser.

var v = new { Title = "Hello", Age = 24 };

Console.WriteLine(v.ToString()); // "{ Title = Hello, Age = 24 }"