Yapı türleri (C# Başvurusu)Structure types (C# reference)

Yapı türü (veya Yapı türü), verileri ve ilgili işlevleri kapsüllemek için bir değer türüdür .A structure type (or struct type) is a value type that can encapsulate data and related functionality. structYapı türünü tanımlamak için anahtar sözcüğünü kullanırsınız:You use the struct keyword to define a structure type:

public struct Coords
{
    public Coords(double x, double y)
    {
        X = x;
        Y = y;
    }

    public double X { get; }
    public double Y { get; }

    public override string ToString() => $"({X}, {Y})";
}

Yapı türlerinde değer semantiğivardır.Structure types have value semantics. Diğer bir deyişle, yapı türünün bir değişkeni türünün bir örneğini içerir.That is, a variable of a structure type contains an instance of the type. Varsayılan olarak, değişken değerleri atamaya kopyalanır, bir yönteme bağımsız değişken geçirme ve bir yöntem sonucu döndürüyor.By default, variable values are copied on assignment, passing an argument to a method, and returning a method result. Yapı türü değişkeni söz konusu olduğunda, türün bir örneği kopyalanır.In the case of a structure-type variable, an instance of the type is copied. Daha fazla bilgi için bkz. değer türleri.For more information, see Value types.

Genellikle, çok az davranış sağlayan küçük veri merkezli türler tasarlamak için yapı türlerini kullanırsınız.Typically, you use structure types to design small data-centric types that provide little or no behavior. Örneğin, .NET bir sayıyı (hem tamsayı hem de gerçek), bir Boole değerini, bir Unicode karakteri, bir zaman örneğinitemsil etmek için yapı türlerini kullanır.For example, .NET uses structure types to represent a number (both integer and real), a Boolean value, a Unicode character, a time instance. Bir türün davranışına odaklandıysanız bir sınıftanımlamayı düşünün.If you're focused on the behavior of a type, consider defining a class. Sınıf türlerinde başvuru semantiğivardır.Class types have reference semantics. Diğer bir deyişle, bir sınıf türünün değişkeni, örneğin kendisi değil, türün bir örneğine bir başvuru içerir.That is, a variable of a class type contains a reference to an instance of the type, not the instance itself.

Yapı türlerinde değer semantiklerine sahip olduğundan, değişmez yapı türlerini tanımlamanızı öneririz.Because structure types have value semantics, we recommend you to define immutable structure types.

readonly sýnýreadonly struct

C# 7,2 ' den başlayarak, readonly bir yapı türünün sabit olduğunu bildirmek için değiştiricisini kullanın:Beginning with C# 7.2, you use the readonly modifier to declare that a structure type is immutable:

public readonly struct Coords
{
    public Coords(double x, double y)
    {
        X = x;
        Y = y;
    }

    public double X { get; init; }
    public double Y { get; init; }

    public override string ToString() => $"({X}, {Y})";
}

Bir yapının tüm veri üyeleri readonly aşağıdaki şekilde salt okunabilir olmalıdır:All data members of a readonly struct must be read-only as follows:

  • Herhangi bir alan bildirimi readonly değiştiriciye sahip olmalıdırAny field declaration must have the readonly modifier
  • Otomatik olarak uygulanan özellikler dahil olmak üzere herhangi bir özellik salt okunabilir olmalıdır.Any property, including auto-implemented ones, must be read-only. C# 9,0 ve üzeri sürümlerde bir özelliğin init erişimcisiolabilir.In C# 9.0 and later, a property may have an init accessor.

Bu, yapının hiçbir üyesinin readonly yapının durumunu değiştirdiğine garanti eder.That guarantees that no member of a readonly struct modifies the state of the struct. C# 8,0 ve üzeri sürümlerde, oluşturucular hariç diğer örnek üyelerinin örtülü olarak olduğu anlamına gelir readonly .In C# 8.0 and later, that means that other instance members except constructors are implicitly readonly.

Not

Bir readonly yapıda, kesilebilir başvuru türünün veri üyesi yine de kendi durumunu mukuz edebilir.In a readonly struct, a data member of a mutable reference type still can mutate its own state. Örneğin, bir List<T> örneği değiştiremezsiniz, ancak buna yeni öğeler ekleyebilirsiniz.For example, you can't replace a List<T> instance, but you can add new elements to it.

readonly örnek üyelerireadonly instance members

C# 8,0 ' den başlayarak, readonly bir örnek üyesinin bir yapının durumunu değiştirmediğini bildirmek için değiştiricisini de kullanabilirsiniz.Beginning with C# 8.0, you can also use the readonly modifier to declare that an instance member doesn't modify the state of a struct. Tüm yapı türünü olarak bildiremezseniz readonly , readonly yapının durumunu değiştirmeyin örnek üyelerini işaretlemek için değiştiricisini kullanın.If you can't declare the whole structure type as readonly, use the readonly modifier to mark the instance members that don't modify the state of the struct.

Bir readonly örnek üyesi içinde, yapının örnek alanlarına atayamazsınız.Within a readonly instance member, you can't assign to structure's instance fields. Ancak bir readonly üye üye olmayan bir öğesi çağırabilir readonly .However, a readonly member can call a non-readonly member. Bu durumda, derleyici yapı örneğinin bir kopyasını oluşturur ve bu kopyada üye olmayan ' i çağırır readonly .In that case the compiler creates a copy of the structure instance and calls the non-readonly member on that copy. Sonuç olarak, özgün yapı örneği değiştirilmez.As a result, the original structure instance is not modified.

Genellikle, readonly değiştiricisini aşağıdaki örnek üye türlerine uygularsınız:Typically, you apply the readonly modifier to the following kinds of instance members:

  • Yöntemmethods:

    public readonly double Sum()
    {
        return X + Y;
    }
    

    Ayrıca, readonly içinde belirtilen yöntemleri geçersiz kılan yöntemlere değiştiricisini uygulayabilirsiniz System.Object :You can also apply the readonly modifier to methods that override methods declared in System.Object:

    public readonly override string ToString() => $"({X}, {Y})";
    
  • Özellikler ve Dizin oluşturucular:properties and indexers:

    private int counter;
    public int Counter
    {
        readonly get => counter;
        set => counter = value;
    }
    

    readonlyDeğiştirici ' i bir özelliğin veya dizin oluşturucunun her ikisine de uygulamanız gerekiyorsa, bunu özelliğin veya dizin oluşturucunun bildiriminde uygulayın.If you need to apply the readonly modifier to both accessors of a property or indexer, apply it in the declaration of the property or indexer.

    Not

    Derleyici, get auto-implemented property readonly readonly bir özellik bildiriminde değiştiricinin varlığından bağımsız olarak otomatik uygulanan bir özelliğin erişimcisini bildirir.The compiler declares a get accessor of an auto-implemented property as readonly, regardless of presence of the readonly modifier in a property declaration.

    C# 9,0 ve üzeri sürümlerde, readonly değiştiriciyi bir özelliğe veya dizin oluşturucusuna uygulayabilirsiniz init :In C# 9.0 and later, you may apply the readonly modifier to a property or indexer with an init accessor:

    public readonly double X { get; init; }
    

readonlyBir yapı türünün statik üyelerine değiştiricisini uygulayamazsınız.You can't apply the readonly modifier to static members of a structure type.

Derleyici, readonly performans iyileştirmeleri için değiştiriciyi kullanabilir.The compiler may make use of the readonly modifier for performance optimizations. Daha fazla bilgi için bkz. yazma güvenli ve verimli C# kodu.For more information, see Write safe and efficient C# code.

Yapı türünün tasarımıyla ilgili sınırlamalarLimitations with the design of a structure type

Bir yapı türü tasarlarken, aşağıdaki özel durumlarla birlikte bir sınıf türüyle aynı olanaklara sahip olursunuz:When you design a structure type, you have the same capabilities as with a class type, with the following exceptions:

  • Parametresiz bir Oluşturucu bildiremezsiniz.You can't declare a parameterless constructor. Her yapı türü zaten türün varsayılan değerini üreten örtük parametresiz bir oluşturucu sağlar.Every structure type already provides an implicit parameterless constructor that produces the default value of the type.

  • Bildiriminde bir örnek alanı veya özelliği başlatamıyor.You can't initialize an instance field or property at its declaration. Ancak, bir statik veya const alanı veya bildiriminde statik bir özellik başlatabilirsiniz.However, you can initialize a static or const field or a static property at its declaration.

  • Yapı türünde bir Oluşturucu, türün tüm örnek alanlarını başlatmalıdır.A constructor of a structure type must initialize all instance fields of the type.

  • Yapı türü, diğer sınıf veya yapı türünden devralınabilir ve bir sınıfın temeli olamaz.A structure type can't inherit from other class or structure type and it can't be the base of a class. Ancak, bir yapı türü arabirimleruygulayabilir.However, a structure type can implement interfaces.

  • Bir yapı türü içinde sonlandırıcıyı bildiremezsiniz.You can't declare a finalizer within a structure type.

Yapı türünü örneklemeInstantiation of a structure type

C# dilinde, kullanılmadan önce, belirtilen bir değişkeni başlatmalısınız.In C#, you must initialize a declared variable before it can be used. Bir yapı türü değişkeni olamaz null ( null yapılabilir değer türündebir değişken değilse), karşılık gelen türün bir örneğini örneklemelisiniz.Because a structure-type variable can't be null (unless it's a variable of a nullable value type), you must instantiate an instance of the corresponding type. Bunu yapmak için birkaç yol vardır.There are several ways to do that.

Genellikle, işleçle uygun bir oluşturucuyu çağırarak bir yapı türü örnekleyebilirsiniz new .Typically, you instantiate a structure type by calling an appropriate constructor with the new operator. Her yapı türünün en az bir Oluşturucusu vardır.Every structure type has at least one constructor. Bu, türün varsayılan değerini üreten örtük parametresiz bir Oluşturucu.That's an implicit parameterless constructor, which produces the default value of the type. Bir türün varsayılan değerini oluşturmak için varsayılan değer ifadesini de kullanabilirsiniz.You can also use a default value expression to produce the default value of a type.

Bir yapı türünün tüm örnek alanlarına erişilebiliyorsa, işleci olmadan da örneğini oluşturabilirsiniz new .If all instance fields of a structure type are accessible, you can also instantiate it without the new operator. Bu durumda, örneğin ilk kullanmadan önce tüm örnek alanlarını başlatmalısınız.In that case you must initialize all instance fields before the first use of the instance. Aşağıdaki örnek bunun nasıl yapılacağını göstermektedir:The following example shows how to do that:

public static class StructWithoutNew
{
    public struct Coords
    {
        public double x;
        public double y;
    }

    public static void Main()
    {
        Coords p;
        p.x = 3;
        p.y = 4;
        Console.WriteLine($"({p.x}, {p.y})");  // output: (3, 4)
    }
}

Yerleşik değer türlerisöz konusu olduğunda, türü bir değer belirtmek için karşılık gelen değişmez değerleri kullanın.In the case of the built-in value types, use the corresponding literals to specify a value of the type.

Başvuruya göre yapı türü değişkenleri geçirmePassing structure-type variables by reference

Bir yapı türü değişkenini bir bağımsız değişken olarak bir yönteme geçirdiğinizde veya bir yöntemden yapı türü değer döndürmeniz durumunda, bir yapı türünün tüm örneği kopyalanır.When you pass a structure-type variable to a method as an argument or return a structure-type value from a method, the whole instance of a structure type is copied. Bu, büyük yapı türlerini içeren yüksek performanslı senaryolarda kodunuzun performansını etkileyebilir.That can affect the performance of your code in high-performance scenarios that involve large structure types. Bir yapı türü değişkenini başvuruya göre geçirerek değer kopyalamaya engel olabilirsiniz.You can avoid value copying by passing a structure-type variable by reference. ref out in Bir bağımsız değişkenin başvuruya göre geçirilmesi gerektiğini göstermek için, veya yöntem parametre değiştiricilerini kullanın.Use the ref, out, or in method parameter modifiers to indicate that an argument must be passed by reference. Başvuruya göre bir yöntem sonucu döndürmek için ref dönüşleri kullanın.Use ref returns to return a method result by reference. Daha fazla bilgi için bkz. yazma güvenli ve verimli C# kodu.For more information, see Write safe and efficient C# code.

ref sýnýref struct

C# 7,2 ' den başlayarak, ref bir yapı türünün bildiriminde değiştiricisini kullanabilirsiniz.Beginning with C# 7.2, you can use the ref modifier in the declaration of a structure type. refYapı türünün örnekleri yığında ayrılır ve yönetilen yığına atlayabilir.Instances of a ref struct type are allocated on the stack and can't escape to the managed heap. Derleyicinin yapı türlerinin kullanımını şu şekilde sınırladığından emin olmak için ref :To ensure that, the compiler limits the usage of ref struct types as follows:

  • refStruct bir dizinin öğe türü olamaz.A ref struct can't be the element type of an array.
  • Bir ref struct, bir sınıfın veya struct olmayan bir alanın tanımlı bir türü olamaz ref .A ref struct can't be a declared type of a field of a class or a non-ref struct.
  • Bir ref struct arabirimleri uygulayamaz.A ref struct can't implement interfaces.
  • Bir ref struct veya olarak kutulanabilir System.ValueType System.Object .A ref struct can't be boxed to System.ValueType or System.Object.
  • refStruct bir tür bağımsız değişkeni olamaz.A ref struct can't be a type argument.
  • Bir ref struct değişkeni bir lambda ifadesi veya yerel bir işlevtarafından yakalanamaz.A ref struct variable can't be captured by a lambda expression or a local function.
  • Bir ref struct değişkeni bir async yöntemde kullanılamaz.A ref struct variable can't be used in an async method. Ancak, ref Yapı değişkenlerini, örneğin veya döndüren zaman uyumlu yöntemlerle kullanabilirsiniz Task Task<TResult> .However, you can use ref struct variables in synchronous methods, for example, in those that return Task or Task<TResult>.
  • Bir ref struct değişkeni yineleyicileriçinde kullanılamaz.A ref struct variable can't be used in iterators.

Genellikle, ref Yapı türlerinin veri üyelerini de içeren bir türe ihtiyacınız olduğunda bir struct türü tanımlarsınız ref :Typically, you define a ref struct type when you need a type that also includes data members of ref struct types:

public ref struct CustomRef
{
    public bool IsValid;
    public Span<int> Inputs;
    public Span<int> Outputs;
}

Bir yapıyı olarak bildirmek için, ref readonly readonly ref tür bildiriminde ve değiştiricilerini birleştirin (değiştiricinin readonly değiştiricisinden önce gelmesi gerekir ref ):To declare a ref struct as readonly, combine the readonly and ref modifiers in the type declaration (the readonly modifier must come before the ref modifier):

public readonly ref struct ConversionRequest
{
    public ConversionRequest(double rate, ReadOnlySpan<double> values)
    {
        Rate = rate;
        Values = values;
    }

    public double Rate { get; }
    public ReadOnlySpan<double> Values { get; }
}

.NET ' te, bir ref struct örnekleri ve ' dir System.Span<T> System.ReadOnlySpan<T> .In .NET, examples of a ref struct are System.Span<T> and System.ReadOnlySpan<T>.

DönüşümlerConversions

Herhangi bir yapı türü için ( ref Yapı türleri hariç), ve türlerinden ve türlerine bir paketleme ve kutudan çıkarma dönüştürmeleri mevcuttur System.ValueType System.Object .For any structure type (except ref struct types), there exist boxing and unboxing conversions to and from the System.ValueType and System.Object types. Ayrıca, yapı türü ve uyguladığı herhangi bir arabirim arasında kutulama ve kutudan çıkarma dönüştürmeleri de mevcuttur.There exist also boxing and unboxing conversions between a structure type and any interface that it implements.

C# dili belirtimiC# language specification

Daha fazla bilgi için C# dil belirtiminin yapılar bölümüne bakın.For more information, see the Structs section of the C# language specification.

C# 7,2 ve üzeri sürümlerde sunulan özellikler hakkında daha fazla bilgi için aşağıdaki özellik teklifi notlarına bakın:For more information about features introduced in C# 7.2 and later, see the following feature proposal notes:

Ayrıca bkz.See also