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.
Bir sınıfın veya yapının örnekleri bir dizi veya başka bir koleksiyon gibi dizine alınabildiğinde dizin oluşturucuları tanımlarsınız. Dizine alınan değer, açıkça bir tür veya örnek üyesi belirtilmeden ayarlanabilir veya alınabilir. Dizin oluşturucular, özelliklere benzer, ancak erişimcilerinin parametre alması gerekir.
Aşağıdaki örnek, get ve set erişimci yöntemleriyle değerleri atamak ve almak için genel bir sınıf tanımlar.
namespace Indexers;
public class SampleCollection<T>
{
// Declare an array to store the data elements.
private T[] arr = new T[100];
// Define the indexer to allow client code to use [] notation.
public T this[int i]
{
get => arr[i];
set => arr[i] = value;
}
}
Yukarıdaki örnekte okuma/yazma dizin oluşturucu gösterilmektedir. Hem get hem de set erişimcilerini içerir. Aşağıdaki örneklerde gösterildiği gibi salt okunur dizin oluşturucuları gövdeli bir ifade üyesi olarak tanımlayabilirsiniz:
namespace Indexers;
public class ReadOnlySampleCollection<T>(params IEnumerable<T> items)
{
// Declare an array to store the data elements.
private T[] arr = [.. items];
public T this[int i] => arr[i];
}
get anahtar sözcüğü kullanılmaz; => ifade gövdesini tanıtır.
Dizin oluşturucular, bir veya daha fazla bağımsız değişken kullanılarak başvurulan dizine alınmış özellikleri etkinleştirir. Bu argümanlar, bazı değerler koleksiyonuna bir dizin sağlar.
- Dizin oluşturucular, nesnelerin dizilere benzer şekilde dizine alınmasına olanak tanır.
- Erişimci
getbir değer döndürür. Birseterişimci bir değer atar. -
thisanahtar sözcüğü dizin oluşturucuyu tanımlar. -
valueanahtar sözcüğü,seterişimcisinin bağımsız değişkenidir. - Dizin oluşturucular tamsayı dizin değeri gerektirmez; belirli bir arama mekanizmasının nasıl tanımlanacağı size bağlı.
- Dizin oluşturucular aşırı yüklenebilir.
- Dizin oluşturucular, örneğin iki boyutlu bir diziye erişirken bir veya daha fazla resmi parametreye sahip olabilir.
-
partialDizin oluşturucularıpartialtürlerde bildirebilirsiniz.
Özelliklerle çalışmaktan öğrendiğiniz neredeyse her şeyi dizin oluşturuculara uygulayabilirsiniz. Bu kuralın tek özel durumu otomatik olarak uygulanan özelliklerdir. Derleyici her zaman bir dizin oluşturucu için doğru depolamayı oluşturamaz. Her dizin oluşturucunun bağımsız değişken listeleri benzersiz olduğu sürece, bir tür üzerinde birden çok dizin oluşturucu tanımlayabilirsiniz.
Dizin oluşturucuların kullanımları
Türünüzün API'si bazı koleksiyonları modellediğinde dizin oluşturucular tanımlarsınız. Dizin oluşturucunuzun .NET core çerçevesinin parçası olan koleksiyon türlerine doğrudan eşlemesi gerekmez. Dizin oluşturucular, bu soyutlama değerlerinin nasıl depolandığına veya hesaplandığına ilişkin iç ayrıntıları ortaya çıkarmadan türünüzün soyutlaması ile eşleşen API'yi sağlamanıza olanak tanır.
Diziler ve Vektörler
Türünüz bir diziyi veya vektöri modelleyebilir. Kendi dizin oluşturucunuzu oluşturmanın avantajı, bu koleksiyon için depolama alanını gereksinimlerinize uyacak şekilde tanımlayabilmenizdir. Türünüzün aynı anda belleğe yüklenemeyecek kadar büyük geçmiş verileri modellediği bir senaryo düşünün. Kullanımı temel alarak koleksiyonun bölümlerini yüklemeniz ve kaldırmanız gerekir. Aşağıdaki örnek bu davranışı modeller. Kaç veri noktası olduğunu bildirir. İsteğe bağlı olarak verilerin bölümlerini tutmak için sayfalar oluşturur. Daha yeni isteklerin ihtiyaç duyduğu sayfalara yer açmak için sayfaları bellekten kaldırır.
namespace Indexers;
public record Measurements(double HiTemp, double LoTemp, double AirPressure);
public class DataSamples
{
private class Page
{
private readonly List<Measurements> pageData = new ();
private readonly int _startingIndex;
private readonly int _length;
public Page(int startingIndex, int length)
{
_startingIndex = startingIndex;
_length = length;
// This stays as random stuff:
var generator = new Random();
for (int i = 0; i < length; i++)
{
var m = new Measurements(HiTemp: generator.Next(50, 95),
LoTemp: generator.Next(12, 49),
AirPressure: 28.0 + generator.NextDouble() * 4
);
pageData.Add(m);
}
}
public bool HasItem(int index) =>
((index >= _startingIndex) &&
(index < _startingIndex + _length));
public Measurements this[int index]
{
get
{
LastAccess = DateTime.Now;
return pageData[index - _startingIndex];
}
set
{
pageData[index - _startingIndex] = value;
Dirty = true;
LastAccess = DateTime.Now;
}
}
public bool Dirty { get; private set; } = false;
public DateTime LastAccess { get; set; } = DateTime.Now;
}
private readonly int _totalSize;
private readonly List<Page> pagesInMemory = new ();
public DataSamples(int totalSize)
{
this._totalSize = totalSize;
}
public Measurements this[int index]
{
get
{
if (index < 0) throw new IndexOutOfRangeException("Cannot index less than 0");
if (index >= _totalSize) throw new IndexOutOfRangeException("Cannot index past the end of storage");
var page = updateCachedPagesForAccess(index);
return page[index];
}
set
{
if (index < 0) throw new IndexOutOfRangeException("Cannot index less than 0");
if (index >= _totalSize) throw new IndexOutOfRangeException("Cannot index past the end of storage");
var page = updateCachedPagesForAccess(index);
page[index] = value;
}
}
private Page updateCachedPagesForAccess(int index)
{
foreach (var p in pagesInMemory)
{
if (p.HasItem(index))
{
return p;
}
}
var startingIndex = (index / 1000) * 1000;
var newPage = new Page(startingIndex, 1000);
addPageToCache(newPage);
return newPage;
}
private void addPageToCache(Page p)
{
if (pagesInMemory.Count > 4)
{
// remove oldest non-dirty page:
var oldest = pagesInMemory
.Where(page => !page.Dirty)
.OrderBy(page => page.LastAccess)
.FirstOrDefault();
// Note that this may keep more than 5 pages in memory
// if too much is dirty
if (oldest != null)
pagesInMemory.Remove(oldest);
}
pagesInMemory.Add(p);
}
}
Tüm veri kümesini bellek içi bir koleksiyona yüklememek için iyi nedenler olan herhangi bir koleksiyon türünü modellemek için bu tasarım deyimini izleyebilirsiniz. Dikkat edin ki Page sınıfı, genel arabirimin bir parçası olmayan özel bir iç içe sınıftır. Bu ayrıntılar bu sınıfın kullanıcılarından gizlenir.
Sözlükler
Bir diğer yaygın senaryo da bir sözlüğü veya haritayı modellemeniz gerektiği durumdur. Bu senaryo, türünüz değerleri anahtara ve muhtemelen metin anahtarlarına göre depoladığında olur. Bu örnek, komut satırı bağımsız değişkenlerini bu seçenekleri yöneten lambda ifadeleriyle eşleyen bir sözlük oluşturur. Aşağıdaki örnekte iki sınıf gösterilmektedir: bir komut satırı seçeneğini bir temsilciye eşleyen bir ArgsActions sınıfı ve bu seçenekle karşılaştığında her System.Action öğesini yürütmek için ArgsProcessor kullanan bir ArgsActions sınıfı.
namespace Indexers;
public class ArgsProcessor
{
private readonly ArgsActions _actions;
public ArgsProcessor(ArgsActions actions)
{
_actions = actions;
}
public void Process(string[] args)
{
foreach (var arg in args)
{
_actions[arg]?.Invoke();
}
}
}
public class ArgsActions
{
readonly private Dictionary<string, Action> _argsActions = new();
public Action this[string s]
{
get
{
Action? action;
Action defaultAction = () => { };
return _argsActions.TryGetValue(s, out action) ? action : defaultAction;
}
}
public void SetOption(string s, Action a)
{
_argsActions[s] = a;
}
}
Bu örnekte, ArgsAction koleksiyonu, temel alınan koleksiyonla yakından ilişkilidir. , get belirli bir seçeneğin yapılandırılıp yapılandırılmadığını belirler. Öyleyse, bu seçenekle ilişkili Action döndürür. Aksi takdirde, hiçbir şey içermeyen bir Action döndürür. Genel erişimci bir set erişimci içermez. Bunun yerine, tasarım seçenekleri ayarlamak için genel bir yöntem kullanır.
Tarih tabanlı dizin oluşturucular
Tarih tabanlı verilerle çalışırken, DateTime veya DateOnly'yi dizin oluşturucu anahtarları olarak kullanabilirsiniz. Yalnızca tarih bölümüne ihtiyacınız olduğunda ve zamana bağlı komplikasyonlardan kaçınmak istediğinizde kullanın DateOnly . Aşağıdaki örnekte, birincil dizin oluşturucu anahtarı olarak kullanılan DateOnly bir sıcaklık izleme sistemi gösterilmektedir:
using System;
using System.Collections.Generic;
namespace Indexers;
public class DailyTemperatureData
{
private readonly Dictionary<DateOnly, (double High, double Low)> _temperatureData = new();
// Indexer using DateOnly for date-only scenarios
public (double High, double Low) this[DateOnly date]
{
get
{
if (_temperatureData.TryGetValue(date, out var temp))
{
return temp;
}
throw new KeyNotFoundException($"No temperature data available for {date:yyyy-MM-dd}");
}
set
{
_temperatureData[date] = value;
}
}
// Overload using DateTime for convenience, but only uses the date part
public (double High, double Low) this[DateTime dateTime]
{
get => this[DateOnly.FromDateTime(dateTime)];
set => this[DateOnly.FromDateTime(dateTime)] = value;
}
public bool HasDataFor(DateOnly date) => _temperatureData.ContainsKey(date);
public IEnumerable<DateOnly> AvailableDates => _temperatureData.Keys;
}
Bu örnekte hem DateOnly hem de DateTime dizin oluşturucular gösterilmektedir.
DateOnly Dizin oluşturucu birincil arabirim olsa da, DateTime aşırı yükleme yalnızca tarih bölümünü ayıklayarak kolaylık sağlar. Bu yaklaşım, belirli bir günün tüm sıcaklık verilerinin, zaman bileşeninden bağımsız olarak tutarlı bir şekilde değerlendirilmesini sağlar.
Çok Boyutlu Haritalar
Birden çok bağımsız değişken kullanan dizin oluşturucular oluşturabilirsiniz. Ayrıca, bu bağımsız değişkenler aynı türde olacak şekilde kısıtlanmamıştır.
Aşağıdaki örnekte, Mandelbrot kümesi için değerler oluşturan bir sınıf gösterilmektedir. Kümenin arkasındaki matematik hakkında daha fazla bilgi için bu makaleyi okuyun. Dizin oluşturucu X, Y düzleminde bir nokta tanımlamak için iki çift kullanır. Erişimci, get bir noktanın kümede olmadığı belirlenene kadar yineleme sayısını hesaplar. Maksimum yineleme sayısına ulaşıldığında, noktanın kümede olduğu kabul edilir ve sınıfın maxIterations değeri döndürülür. (Mandelbrot kümesi için popüler hale getirilen bilgisayar tarafından oluşturulan görüntüler, bir noktanın kümenin dışında olduğunu belirlemek için gereken yineleme sayısı için renkleri tanımlar.)
namespace Indexers;
public class Mandelbrot(int maxIterations)
{
public int this[double x, double y]
{
get
{
var iterations = 0;
var x0 = x;
var y0 = y;
while ((x * x + y * y < 4) &&
(iterations < maxIterations))
{
(x, y) = (x * x - y * y + x0, 2 * x * y + y0);
iterations++;
}
return iterations;
}
}
}
Mandelbrot Kümesi, gerçek sayı değerleri için her (x,y) koordinatta değerleri tanımlar. Bu, sonsuz sayıda değer içerebilen bir sözlüğü tanımlar. Bu nedenle, kümenin arkasında depolama alanı yoktur. Bunun yerine, kod erişimciyi çağırdığında get bu sınıf her nokta için değeri hesaplar. Altta yatan depolama kullanılmıyor.
Toplama
Sınıfınızda, bu özelliğin tek bir değeri değil, bir değer kümesini temsil ettiği özellik benzeri bir öğeniz olduğu her zaman dizin oluşturucular oluşturursunuz. Bir veya daha fazla bağımsız değişken her bir öğeyi tanımlar. Bu bağımsız değişkenler, kümedeki hangi öğeye başvurulması gerektiğini özgün bir şekilde belirleyebilir. Dizin oluşturucular, bir üyenin sınıfın dışından bir veri öğesi gibi, ancak sınıfın içinde bir yöntem gibi ele alındığı özellikler kavramını genişletir. İndeksleyiciler, parametrelerin bir öğe kümesini temsil eden bir özelliğin içindeki tek bir öğeyi bulmasına olanak tanır.
Dizin oluşturucular için örnek klasöre erişebilirsiniz. İndirme yönergeleri için bkz. Örnekler ve Öğreticiler.
C# Dil Belirtimi
Daha fazla bilgi için bkz. C# Dil BelirtimindeDizin Oluşturucular. Dil belirtimi, C# söz dizimi ve kullanımı için kesin kaynaktır.