Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Yapı türü (veya yapı türü), verileri ve ilgili işlevleri kapsülleyebilecek bir değer türüdür. Bir yapı türü tanımlamak için anahtar sözcüğünü struct
kullanırsınız:
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})";
}
ref struct
ve readonly ref struct
türleri hakkında bilgi için başvuru yapısı türleri makalesine bakın.
Yapı türlerinin değer semantiği vardır. Yani, bir yapı türünün değişkeni türün bir örneğini içerir. Varsayılan olarak, değişken değerleri atamada kopyalanır, bir bağımsız değişken yönteme geçirilir ve yöntem sonucu döndürülr. Yapı türü değişkenleri için türün bir örneği kopyalanır. Daha fazla bilgi için bkz . Değer türleri.
Genellikle, çok az davranış sağlayan veya hiç davranış sağlamayan küçük veri merkezli türler tasarlamak için yapı türlerini kullanırsınız. Örneğin, .NET bir sayıyı (hem tamsayı hem de gerçek), Boole değerini, Unicode karakterini, bir zaman örneğini temsil etmek için yapı türlerini kullanır. Bir türün davranışına odaklandıysanız bir sınıf tanımlamayı göz önünde bulundurun. Sınıf türleri başvuru semantiğine sahiptir. Yani, bir sınıf türünün değişkeni, örneğin kendisini değil, türün bir örneğine referans içerir.
Yapı türleri değer semantiğine sahip olduğundan sabit yapı türleri tanımlamanızı öneririz.
readonly
Yapı
Bir yapı türünün sabit olduğunu bildirmek için değiştiriciyi kullanırsınız readonly
. Bir readonly
yapının tüm veri üyeleri aşağıdaki gibi salt okunur olmalıdır:
- Herhangi bir alan bildiriminde
readonly
değiştiriciolmalıdır. - Otomatik olarak uygulananlar da dahil olmak üzere tüm özellikler salt okunur veya
init
yalnızca olmalıdır. Sadece başlatma ayarlayıcıları C# sürüm 9'dan itibaren kullanılabilir.
Bu, bir readonly
yapının hiçbir üyesinin yapının durumunu değiştirmediğini garanti eder. Bu, oluşturucular dışındaki diğer örnek üyelerinin örtük olarak readonly
olduğu anlamına gelir.
Not
Yapıda readonly
, değiştirilebilir başvuru türüne sahip bir veri üyesi kendi durumunu yine de değiştirebilir. Örneğin, bir List<T> örneği değiştiremezsiniz, ancak buna yeni öğeler ekleyebilirsiniz.
Aşağıdaki kod, yalnızca init özellik ayarlayıcılarıyla bir readonly
yapı tanımlar:
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})";
}
readonly
örnek üyeleri
Bir örnek üyesinin readonly
yapı durumunu değiştirmediğini bildirmek için değiştiriciyi de kullanabilirsiniz. Yapı türünün tamamını readonly
olarak bildiremiyorsanız, yapının durumunu değiştirmeyen örnek üyeleri işaretlemek için readonly
değiştiriciyi kullanın.
Bir readonly
örnek üyesi içinde, yapının örnek alanlarına atayamazsınız. Ancak, bir readonly
üye readonly
üye olmayan birini çağırabilir. Böyle bir durumda, derleyici yapı örneğinin bir kopyasını oluşturur ve o kopyada non-readonly
üyeyi çağırır. Sonuç olarak, özgün yapı örneği değiştirilmez.
Genellikle değiştiriciyi readonly
aşağıdaki örnek üyeleri türlerine uygularsınız:
Yöntemler:
public readonly double Sum() { return X + Y; }
Değiştiriciyi
readonly
içinde bildirilen System.Objectyöntemleri geçersiz kılan yöntemlere de uygulayabilirsiniz:public readonly override string ToString() => $"({X}, {Y})";
özellikler ve dizin oluşturucular:
private int counter; public int Counter { readonly get => counter; set => counter = value; }
Değiştiriciyi bir özelliğin
readonly
veya dizin oluşturucunun her iki erişimcisine de uygulamanız gerekiyorsa, özelliğin veya dizin oluşturucunun bildiriminde uygulayın.Not
Derleyici, bir özellik bildiriminde
get
değiştiricisinin varlığına bakmaksızın, otomatik olarak uygulanmış özelliğin bir erişimcisinireadonly
olarak bildirir.readonly
değiştiricisiniinit
erişimcili bir özelliğe veya dizin oluşturucuya uygulayabilirsiniz:public readonly double X { get; init; }
Değiştiriciyi readonly
bir yapı türünün statik alanlarına uygulayabilirsiniz, ancak özellikler veya yöntemler gibi diğer statik üyelere uygulayamayın.
Derleyici, performans iyileştirmeleri için readonly
değiştiricisini kullanabilir. Daha fazla bilgi için Ayırmalardan Kaçınma kısmına bakın.
Yıkıcı olmayan mutasyon
Belirtilen özelliklerin ve alanların değiştirildiği bir yapı türü örneğinin kopyasını oluşturmak için with
ifadesini kullanabilirsiniz. Aşağıdaki örnekte gösterildiği gibi, hangi üyelerin değiştirileceğini ve yeni değerlerini belirtmek için nesne başlatıcı söz dizimini kullanırsınız:
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})";
}
public static void Main()
{
var p1 = new Coords(0, 0);
Console.WriteLine(p1); // output: (0, 0)
var p2 = p1 with { X = 3 };
Console.WriteLine(p2); // output: (3, 0)
var p3 = p1 with { X = 1, Y = 4 };
Console.WriteLine(p3); // output: (1, 4)
}
record
Yapı
Kayıt yapısı türleri tanımlayabilirsiniz. Kayıt türleri, verileri kapsüllemek için yerleşik işlevsellik sağlar. Hem record struct
hem de readonly record struct
türlerini tanımlayabilirsiniz. Kayıt yapısı bir ref struct
olamaz. Daha fazla bilgi ve örnek için bkz . Kayıtlar.
Satır içi diziler
Başlangıç olarak C# 12 ile, "satır içi dizileri" bir türü olarak bildirebilirsiniz.
[System.Runtime.CompilerServices.InlineArray(10)]
public struct CharBuffer
{
private char _firstElement;
}
Satır içi dizi, aynı türdeki N öğelerinin bitişik bloğunu içeren bir yapıdır. Yalnızca güvenli olmayan kodda kullanılabilen sabit arabellek bildiriminin güvenli kod eşdeğeridir. Satır içi dizi, aşağıdaki özelliklere sahip bir struct
dizidir:
- Tek bir alan içerir.
- Yapısı açık bir düzen belirtmez.
Ayrıca, derleyici özniteliğini System.Runtime.CompilerServices.InlineArrayAttribute doğrular:
- Uzunluk sıfırdan (
> 0
) büyük olmalıdır. - Hedef türü bir yapı olmalıdır.
Çoğu durumda, satır içi diziye hem okuma hem de yazma değerleri için bir dizi gibi erişilebilir. Buna ek olarak, aralık ve dizin işleçlerini kullanabilirsiniz.
Satır içi dizinin tek bir alanının türü üzerinde en az kısıtlama vardır. İşaretçi türü olamaz:
[System.Runtime.CompilerServices.InlineArray(10)]
public struct CharBufferWithPointer
{
private unsafe char* _pointerElement; // CS9184
}
Ancak herhangi bir referans türü veya herhangi bir değer türü olabilir.
[System.Runtime.CompilerServices.InlineArray(10)]
public struct CharBufferWithReferenceType
{
private string _referenceElement;
}
Satır içi dizileri neredeyse tüm C# veri yapısıyla kullanabilirsiniz.
Satır içi diziler gelişmiş bir dil özelliğidir. Bunlar, satır içi, bitişik öğe bloğunun diğer alternatif veri yapılarından daha hızlı olduğu yüksek performanslı senaryolara yöneliktir. özellik belirtimindensatır içi diziler hakkında daha fazla bilgi edinebilirsiniz.
Yapı başlatma ve varsayılan değerler
Türündeki bir struct
değişken, doğrudan ilgili struct
için verileri içerir. Bu, varsayılan değerine sahip başlatılmamış bir struct
ile onu oluşturarak ayarlanan değerleri depolayan başlatılmış bir struct
arasında bir ayrım oluşturur. Örneğin, aşağıdaki kodu göz önünde bulundurun:
public readonly struct Measurement
{
public Measurement()
{
Value = double.NaN;
Description = "Undefined";
}
public Measurement(double value, string description)
{
Value = value;
Description = description;
}
public double Value { get; init; }
public string Description { get; init; }
public override string ToString() => $"{Value} ({Description})";
}
public static void Main()
{
var m1 = new Measurement();
Console.WriteLine(m1); // output: NaN (Undefined)
var m2 = default(Measurement);
Console.WriteLine(m2); // output: 0 ()
var ms = new Measurement[2];
Console.WriteLine(string.Join(", ", ms)); // output: 0 (), 0 ()
}
Yukarıdaki örnekte gösterildiği gibi, varsayılan değer ifadesi parametresiz bir oluşturucuyu yoksayar ve yapı türünün varsayılan değerini üretir. Yapı türü dizi örneği de parametresiz bir oluşturucuyu yoksayar ve bir yapı türünün varsayılan değerleriyle doldurulmuş bir dizi oluşturur.
Varsayılan değerleri gördüğünüz en yaygın durum dizilerde veya iç depolamanın değişken blokları içerdiği diğer koleksiyonlardadır. Aşağıdaki örnek, her biri varsayılan değere sahip olan 30 TemperatureRange
yapıdan oluşan bir dizi oluşturur:
// All elements have default values of 0:
TemperatureRange[] lastMonth = new TemperatureRange[30];
türleri doğrudan verilerini depoladığından, bir yapının tüm üye alanları oluşturulduğunda kesinlikle struct
atanmalıdır. Bir yapının
- Herhangi bir alana veya otomatik uygulanan özelliğe alan başlatıcıları ekleyebilirsiniz.
- Oluşturucunun gövdesinde herhangi bir alanı veya otomatik özelliği başlatabilirsiniz.
C# 11 ile başlayarak, bir yapıdaki tüm alanları başlatmazsanız, derleyici bu alanları varsayılan değere başlatan kodu oluşturucuya ekler.
default
değerine atanan bir yapı, 0 bitten oluşan desen olarak başlatılır.
new
ile başlatılan bir yapı 0 bit desenine başlatılır ve ardından herhangi bir alan başlatıcısı ve oluşturucu yürütülür.
public readonly struct Measurement
{
public Measurement(double value)
{
Value = value;
}
public Measurement(double value, string description)
{
Value = value;
Description = description;
}
public Measurement(string description)
{
Description = description;
}
public double Value { get; init; }
public string Description { get; init; } = "Ordinary measurement";
public override string ToString() => $"{Value} ({Description})";
}
public static void Main()
{
var m1 = new Measurement(5);
Console.WriteLine(m1); // output: 5 (Ordinary measurement)
var m2 = new Measurement();
Console.WriteLine(m2); // output: 0 ()
var m3 = default(Measurement);
Console.WriteLine(m3); // output: 0 ()
}
Her struct
, bir parametresiz oluşturucuya sahiptir public
. Parametresiz bir oluşturucu yazarsanız, public olmalıdır. Bir yapı herhangi bir alan başlatıcı bildirirse, açıkça bir oluşturucu bildirmesi gerekir. Bu oluşturucu parametresiz olmamalıdır. Bir yapı bir alan başlatıcı bildirir ancak oluşturucu bildirmezse, derleyici bir hata bildirir. Açıkça bildirilen tüm oluşturucular (parametrelerle veya parametresiz) bu yapı için tüm alan başlatıcılarını yürütür. Alan başlatıcısı veya oluşturucuda ataması olmayan tüm alanlar varsayılan değere ayarlanır. Daha fazla bilgi için Parametresiz yapı oluşturucuları özellik teklifi notu'na bakın.
C# 12 sürümünden başlayarak türler, struct
bildiriminin bir parçası olarak birincil oluşturucu tanımlayabilir. Birincil oluşturucular, yapı için herhangi bir üye bildiriminde struct
gövdesi boyunca kullanılabilecek oluşturucu parametreleri için kısa bir söz dizimi sağlar.
Bir yapı türünün tüm örnek alanları erişilebilir durumdaysa, new
işlecini kullanmadan da örneğini oluşturabilirsiniz. Bu durumda, örneğin ilk kullanımından önce tüm örnek alanlarını başlatmanız gerekir. Aşağıdaki örnek bunun nasıl yapılacağını gösterir:
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)
}
}
Yapı türünün tasarımıyla ilgili sınırlamalar
Yapılar, bir sınıf türünün özelliklerinin çoğuna sahiptir. Bazı özel durumlar vardır:
- Yapı türü başka bir sınıftan veya yapı türünden devralamaz ve bir sınıfın temeli olamaz. Ancak, bir yapı türü arabirimler uygulayabilir.
- Bir yapı türü içinde sonlandırıcı bildiremezsiniz.
- C# 11'in öncesinde, bir yapı türünün oluşturucusunun türün tüm örnek alanlarını başlatması gerekir.
Yapı türündeki değişkenleri referans ile geçirme
Bir yapı türü değişkenini bir yönteme bağımsız değişken olarak geçirdiğinizde veya bir yöntemden yapı türü değeri döndürdüyseniz, yapı türünün tüm örneği kopyalanır. Değere göre geçirme, büyük yapı türlerini içeren yüksek performanslı senaryolarda kodunuzun performansını etkileyebilir. Bir yapı türü değişkeni referans ile geçirerek değer kopyalamayı önleyebilirsiniz.
ref
, out
, in
veya ref readonly
yöntem parametre değiştiricilerini kullanarak bir bağımsız değişkenin başvuruyla geçmesi gerektiğini belirtin. Bir yöntemin sonucunu başvuru ile döndürmek için ref dönüşlerini kullanın. Daha fazla bilgi için Tahsisatlardan kaçınma bölümüne bakın.
struct
kısıtlaması
Ayrıca, tür parametresinin struct
null atanamaz bir değer türü olduğunu belirtmek için kısıtlamada struct
anahtar sözcüğünü de kullanırsınız. Hem yapı türleri hem de numaralandırma türleri struct
kısıtlamayı karşılıyor.
Dönüşümler
Herhangi bir yapı türü için (ref struct
türleri hariç), ve System.ValueType türlerine ve türlerinden System.Object dönüşümleri vardır. Ayrıca, bir yapı türü ile onun uyguladığı herhangi bir arayüz arasında kutulama ve kutu açma dönüştürmeleri de vardır.
C# dili belirtimi
Daha fazla bilgi için C# dil belirtiminin Yapılar bölümüne bakın.
Özellikler hakkında struct
daha fazla bilgi için aşağıdaki özellik teklifi notlarını inceleyin:
- Salt Okunabilir Yapılar
- Salt okunur örnek üyeleri
- Parametresiz yapı oluşturucuları
-
Yapılarda
with
ifadeye izin ver - Kayıt yapıları
- Otomatik varsayılan yapılandırmalar