Megosztás a következőn keresztül:


Választás a névtelen és a rekordtípusok között

A megfelelő típus kiválasztásához figyelembe kell venni a használhatóságot, a teljesítményt és a kompromisszumokat a többi típushoz képest. A névtelen típusok a C# 3.0 óta érhetők el, míg az általános System.Tuple<T1,T2> típusokat a .NET-keretrendszer 4.0-val vezették be. Azóta új lehetőségeket vezetnek be a nyelvi szintű támogatással, például System.ValueTuple<T1,T2> - ami a névből is következik, egy értéktípust biztosít a névtelen típusok rugalmasságával. Ebből a cikkből megtudhatja, hogy mikor érdemes egy típust választani a másikhoz.

Használhatóság és funkcionalitás

A névtelen típusok a C# 3.0-ban jelentek meg a Language-Integrated Query (LINQ) kifejezésekkel. A LINQ használatával a fejlesztők gyakran névtelen típusokká fejlesztik a lekérdezések eredményeit, amelyek a használt objektumok néhány kiválasztott tulajdonságát tárolják. Vegyük az alábbi példát, amely egy objektumtömböt DateTime példányosít, és végigfuttat rajtuk, és egy névtelen típusba vetíti két tulajdonsággal.

var dates = new[]
{
    DateTime.UtcNow.AddHours(-1),
    DateTime.UtcNow,
    DateTime.UtcNow.AddHours(1),
};

foreach (var anonymous in
             dates.Select(
                 date => new { Formatted = $"{date:MMM dd, yyyy hh:mm zzz}", date.Ticks }))
{
    Console.WriteLine($"Ticks: {anonymous.Ticks}, formatted: {anonymous.Formatted}");
}

A névtelen típusok példányosítása az new operátor használatával történik, és a tulajdonságnevek és -típusok a deklarációból következtetnek. Ha két vagy több névtelen objektum inicializálója ugyanabban a szerelvényben olyan tulajdonságok sorozatát adja meg, amelyek azonos sorrendben vannak, és azonos nevűek és típusok, 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.

Az előző C#-kódrészlet egy névtelen típust tervez két tulajdonsággal, hasonlóan a következő fordító által létrehozott C# osztályhoz:

internal sealed class f__AnonymousType0
{
    public string Formatted { get; }
    public long Ticks { get; }

    public f__AnonymousType0(string formatted, long ticks)
    {
        Formatted = formatted;
        Ticks = ticks;
    }
}

További információkért lásd a névtelen típusokat. Ugyanez a funkció létezik a linq-lekérdezésekbe való kivetítéskor a uplokkal is, a tulajdonságokat a csuplok között választhatja ki. Ezek a típusok ugyanúgy haladnak végig a lekérdezésen, mint a névtelen típusok. Most vegye figyelembe a következő példát a System.Tuple<string, long>.

var dates = new[]
{
    DateTime.UtcNow.AddHours(-1),
    DateTime.UtcNow,
    DateTime.UtcNow.AddHours(1),
};

foreach (var tuple in
            dates.Select(
                date => new Tuple<string, long>($"{date:MMM dd, yyyy hh:mm zzz}", date.Ticks)))
{
    Console.WriteLine($"Ticks: {tuple.Item2}, formatted: {tuple.Item1}");
}

A példány számozott System.Tuple<T1,T2>elemtulajdonságokat tesz elérhetővé, például Item1: és Item2. Ezek a tulajdonságnevek megnehezíthetik a tulajdonságértékek szándékának megértését, mivel a tulajdonságnév csak a sorszámot adja meg. Ezenkívül a System.Tuple típusok referenciatípusok class . Ez System.ValueTuple<T1,T2> azonban egy értéktípus struct . A következő C#-kódrészletet használja ValueTuple<string, long> a projektbe. Ennek során konstans szintaxissal rendeli hozzá.

var dates = new[]
{
    DateTime.UtcNow.AddHours(-1),
    DateTime.UtcNow,
    DateTime.UtcNow.AddHours(1),
};

foreach (var (formatted, ticks) in
            dates.Select(
                date => (Formatted: $"{date:MMM dd, yyyy at hh:mm zzz}", date.Ticks)))
{
    Console.WriteLine($"Ticks: {ticks}, formatted: {formatted}");
}

A rekordokról további információt a Tuple-típusok (C#-referencia) vagy a Tuples (Visual Basic) című témakörben talál.

Az előző példák funkcionálisan egyenértékűek, azonban a használhatóságuk és a mögöttes implementációik között kisebb különbségek vannak.

Kompromisszumok

Érdemes lehet mindig a név nélküli típusokat használni ValueTupleTuple, de érdemes megfontolni a kompromisszumokat. A ValueTuple típusok nem módosíthatók, míg Tuple írásvédettek. A névtelen típusok használhatók a kifejezésfákban, míg a csonkok nem. Az alábbi táblázat áttekintést nyújt a főbb különbségekről.

Fő eltérések

Név Hozzáférés-módosító Típus Egyéni tag neve Deconstruction support Kifejezésfa támogatása
Névtelen típusok internal class ✔️ ✔️
Tuple public class ✔️
ValueTuple public struct ✔️ ✔️

Szerializációs

Egy típus kiválasztásakor fontos szempont, hogy szerializálni kell-e. A szerializálás az objektum állapotának megőrzésére vagy átvitelére használható űrlaptá alakításának folyamata. További információ: szerializálás. Ha fontos a szerializálás, hozzon létre vagy classstruct előnyben részesítse a névtelen típusok vagy a tuple típusok helyett.

Teljesítmény

Az ilyen típusok teljesítménye a forgatókönyvtől függ. A fő hatás magában foglalja a kiosztások és a másolás közötti kompromisszumot. A legtöbb forgatókönyvben a hatás kicsi. Ha jelentős hatások léphetnek fel, méréseket kell tenni a döntés tájékoztatása érdekében.

Összegzés

Fejlesztőként a tuples és a névtelen típusok közötti választáshoz több tényezőt is figyelembe kell venni. Általánosságban elmondható, hogy ha nem a kifejezésfákkal dolgozik, és kényelmesen használhatja a tuple szintaxist, akkor válassza kiValueTuple, hogy milyen értéktípust biztosítanak a tulajdonságok elnevezéséhez. Ha kifejezésfákkal dolgozik, és a tulajdonságokat inkább el szeretné nevezni, válasszon névtelen típusokat. Ellenkező esetben használja a következőt Tuple: .

Lásd még