Névtelen típusok

A névtelen típusokkal kényelmesen ágyazhat be írásvédett tulajdonságokat egyetlen objektumba anélkül, hogy először explicit módon kellene definiálnia egy típust. A típusnevet a fordító hozza létre, és nem érhető el a forráskód szintjén. A fordító az egyes tulajdonságok típusára következtet.

Névtelen típusokat hozhat létre az operátor és egy new objektum inicializáló együttes használatával. Az objektum-inicializálókkal kapcsolatos további információkért lásd: Objektum- és gyűjtemény inicializálók.

Az alábbi példa egy névtelen típust mutat be, amely két névvel ellátott Amount tulajdonsággal Messagevan inicializálva.

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

A lekérdezési kifejezés záradékában select általában névtelen típusokat használnak a forrásütemezésben lévő egyes objektumok tulajdonságainak egy részhalmazának visszaadására. További információ a lekérdezésekről: LINQ in C#.

A névtelen típusok egy vagy több nyilvános írásvédett tulajdonságot tartalmaznak. Más típusú osztálytagok, például metódusok vagy események nem érvényesek. A tulajdonság inicializálásához használt kifejezés nem lehet nullnévtelen függvény vagy mutatótípus.

A leggyakoribb forgatókönyv egy névtelen típus inicializálása egy másik típus tulajdonságaival. Az alábbi példában tegyük fel, hogy létezik egy osztály, amely neve Product. Az osztály Product tartalmazza Color és Price tartalmazza a tulajdonságokat, valamint azokat a tulajdonságokat, amelyek nem érdeklik. A változó products objektumok gyűjteménye Product . A névtelen típusdeklaráció a new kulcsszóval kezdődik. A deklaráció inicializál egy új típust, amely csak két tulajdonságot használ.Product A névtelen típusok használata kisebb mennyiségű adatot ad vissza a lekérdezésben.

Ha nem ad meg tagneveket névtelen típusban, a fordító ugyanazt a nevet adja a névtelen típustagoknak, mint az inicializálásukhoz használt tulajdonság. Egy kifejezéssel inicializálandó tulajdonság nevét adja meg, ahogy az előző példában is látható. Az alábbi példában a névtelen típus tulajdonságainak nevei a következők Color : és 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);
}

Tipp.

A .NET stílusszabály IDE0037 használatával kikényszerítheti, hogy a kikövetkesített vagy explicit tagnevek legyenek-e előnyben részesítve.

Egy mező definiálható egy másik típusú objektum alapján is: osztály, struktúra vagy akár egy másik névtelen típus. A művelet az objektumot tartalmazó változóval történik, ugyanúgy, mint az alábbi példában, ahol két névtelen típus jön létre a már példányosított, felhasználó által definiált típusok használatával. Mindkét esetben a product névtelen típusú shipment mező, amely shipmentWithBonusProduct az egyes mezők alapértelmezett értékeit tartalmazza. A bonus mező névtelen típusú lesz, amelyet a fordító hoz létre.

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 };

Ha egy változó inicializálásához névtelen típust használ, a változót implicit módon beírt helyi változóként deklarálja var használatával. A típusnév nem adható meg a változó deklarációjában, mert csak a fordító rendelkezik hozzáféréssel a névtelen típus mögöttes nevéhez. További információ: varImplicit módon beírt helyi változók.

Névtelenül beírt elemekből álló tömböt úgy hozhat létre, hogy egy implicit módon beírt helyi változót és egy implicit módon beírt tömböt kombinál az alábbi példában látható módon.

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

A névtelen típusok olyan típusok, amelyek közvetlenül a forrásból származnakclass, és amelyek nem vethetők át semmilyen típusra, kivéveobject.object A fordító minden névtelen típushoz megad egy nevet, bár az alkalmazás nem fér hozzá. A közös nyelvi futtatókörnyezet szempontjából a névtelen típus nem különbözik a többi referenciatípustól.

Ha egy szerelvény két vagy több névtelen objektum-inicializálója azonos sorrendben, azonos nevű és típusú tulajdonságok sorozatát adja meg, a fordító az objektumokat azonos típusú példányokként kezeli. Ugyanazokkal a fordító által generált típusinformációkat osztják meg.

A névtelen típusok kifejezésekkel támogatják a roncsolásmentes mutációt. Ez lehetővé teszi egy névtelen típusú új példány létrehozását, amelyben egy vagy több tulajdonság új értékekkel rendelkezik:

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

Nem deklarálhat egy mezőt, tulajdonságot, eseményt vagy metódus visszatérési típusát névtelen típusként. Hasonlóképpen nem deklarálhatja egy metódus, tulajdonság, konstruktor vagy indexelő formális paraméterét névtelen típusként. Ha névtelen típust vagy névtelen típusokat tartalmazó gyűjteményt szeretne átadni egy metódus argumentumaként, a paramétert típusként objectdeklarálhatja. A névtelen típusok használata object azonban nem célja az erős gépelésnek. Ha a lekérdezési eredményeket el kell tárolnia, vagy át kell adnia őket a metódushatáron kívül, fontolja meg egy névvel ellátott struktúra vagy osztály használatát névtelen típus helyett.

Mivel a Equals névtelen típusok és GetHashCode metódusok a tulajdonságok és GetHashCode metódusok szempontjából vannak definiálvaEquals, két azonos névtelen típusú példány csak akkor egyenlő, ha az összes tulajdonságuk egyenlő.

Feljegyzés

A névtelen típus akadálymentességi szintje az internal, ezért a különböző szerelvényekben definiált két névtelen típus nem azonos típusú. Ezért a névtelen típusok példányai nem lehetnek egyenlők egymással, ha különböző szerelvényekben vannak definiálva, még akkor sem, ha minden tulajdonságuk egyenlő.

A névtelen típusok felülírják a ToString metódust, összefűzve a kapcsos zárójelekkel körülvett összes tulajdonság nevét és ToString kimenetét.

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

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