You are on page 1of 2343

Contents

C# belgeleri
Başlarken
Genel Bakış
C# Diline ve.NET Framework’e Giriş
Öğreticiler
Genel Bakış
C# ile programlamaya giriş
İlk dersinizi seçme
Merhaba dünya
C# numaraları
Dal ve döngüler
Liste koleksiyonları
Yerel ortamınızda çalışma
Ortamınızı ayarlama
C# numaraları
Dal ve döngüler
Liste koleksiyonları
Sınıflara giriş
C# 6’yı keşfetme
Dize ilişkilendirmeyi keşfetme - etkileşimli
Dize ilişkilendirmeyi keşfetme - ortamınızda
Dize ilişkilendirmeye yönelik gelişmiş senaryolar
Arabirimleri varsayılan arabirim metotları ile güvenli bir şekilde güncelleştirme
Varsayılan arabirim metotlarıyla mixin işlevi oluşturma
Dizin ve aralıkları keşfetme
Boş değer atanabilir başvuru türleri ile çalışma
Bir uygulamayı boş değer atanabilir başvuru türlerine yükseltme
Asenkron akışlar oluşturma ve kullanma
Desen eşleştirme kullanarak veri yeteneklerini geliştirme
Konsol Uygulaması
REST İstemcisi
C# ve .NET içinde devralma
LINQ ile Çalışma
Öznitelikleri Kullanma
C# Turu
Giriş
Program Yapısı
Türler ve Değişkenler
İfadeler
Deyimler
Sınıflar ve nesneler
Yapılar
Diziler
Arabirimler
Numaralandırmalar
Temsilciler
Öznitelikler
C# yenilikleri
C# 8.0
C# 7.3
C# 7.2
C# 7.1
C# 7.0
C# 6
C# Sürüm Geçmişi
Dil ile çerçeve arasındaki ilişkiler
Sürüm ve güncelleştirme konusunda dikkat edilmesi gerekenler
C# Kavramları
C# Tür sistemi
Boş değer atanabilir başvuru türleri
Null atanabilen API’leri öznitelikleri ve kısıtlamaları kullanarak açıklama
Ad Alanları
Temel Türler
Sınıflar
Yapılar
Demetler
Demetleri ve diğer türleri ayrıştırma
Arabirimler
Yöntemler
Lambda İfadeleri
Özellikler
Dizin Oluşturucular
Atılanlar
Genel Türler
Yineleyiciler
Temsilciler ve olaylar
Temsilcilere Giriş
System.Delegate ve temsilci anahtar sözcüğü
Kesin Tür Belirtilmiş Temsilciler
Temsilciler için Ortak Desenler
Olaylara giriş
Standart .NET olay desenleri
Güncelleştirilmiş .NET Olay Deseni
Temsilcileri ve Olayları Ayırt Etme
Dil ile Tümleşik Sorgu (LINQ)
LINQ’e Genel Bakış
Sorgu ifadesi temelleri
C# üzerinde LINQ
C# içinde LINQ sorguları yazma
Nesneler koleksiyonunu sorgulama
Yöntemden sorgu döndürme
Bellekte sorgunun sonuçlarını depolama
Sorgu sonuçlarını gruplandırma
İç içe geçmiş grup oluşturma
Gruplandırma işleminde alt sorgu gerçekleştirme
Sonuçları bitişik anahtarlara göre gruplama
Çalışma zamanında koşul filtrelerini dinamik olarak belirtme
İç birleşimler gerçekleştirme
Gruplanmış birleşimler gerçekleştirme
Sol dış birleşimler gerçekleştirme
Join yan tümcesinin sonuçlarını sıralama
Bileşik anahtarlar kullanarak birleştirme
Özel birleştirme işlemleri gerçekleştirme
Sorgu ifadelerinde boş değerler işleme
Sorgu ifadelerinde özel durumları işleme
Zaman uyumsuz programlama
Desen Eşleştirme
Güvenli, verimli kod yazma
İfade Ağaçları
İfade ağaçlarına giriş
İfade Ağaçları Açıklaması
İfade Ağaçlarını Destekleyen Çerçeve Türleri
İfade Yürütme
İfade Yorumlama
İfade Derleme
İfade Çevirme
Özet
Native ile birlikte çalışma
Kodunuzu belgeleme
Sürüm Oluşturma
C# Kullanımı Hakkındaki Konular
Konu dizini
`String.Split` kullanarak dizeleri ayrıştırma
Dizeleri birleştirme
Bir dizeyi DateTime olarak dönüştürme
Dizeleri arama
Dize içeriklerini değiştirme
Dizeleri karşılaştırma
Desen eşleştirme, is ve as işleçleri kullanarak güvenli bir şekilde tür dönüştürme
.NET Compiler Platform SDK’sı (Roslyn API’leri)
.NET Compiler Platform SDK’sına (Roslyn API’leri) genel bakış
Derleyici API modelini anlama
Söz dizimi ile çalışma
Semantik ile çalışma
Bir çalışma alanı ile çalışma
Söz dizimi görselleştiricisi ile kod bulma
Hızlı Başlangıçlar
Söz dizimi analizi
Anlam analizi
Söz Dizimi Dönüşümü
Öğreticiler
İlk çözümleyicinizi oluşturma ve kod düzeltmesi uygulama
C# Programlama Kılavuzu
Genel Bakış
C# Programı İçinde
C# Programı içinde neler var?
Hello World -- İlk Programınız
C# Programının Genel Yapısı
Tanımlayıcı adları
C# Kodlama Kuralları
Ana() ve Komut Satırı Bağımsız Değişkenleri
Genel Bakış
Komut Satırı Bağımsız Değişkenleri
Nasıl yapılır: Komut Satırı Bağımsız Değişkenlerini Görüntüleme
Ana() Dönüş Değerleri
Programlama Kavramları
Genel Bakış
Async ve await ile Zaman Uyumsuz Programlama
Genel Bakış
Zaman uyumsuz görev programlama modeli
İzlenecek yol: Async ve await kullanarak Web'e erişme
Task.WhenAll kullanarak zaman uyumsuz izlenecek yolu genişletme
Async ve await kullanarak birden çok web isteğini paralel hale getirme
Zaman Uyumsuz Dönüş Türleri
Zaman Uyumsuz Programlarda Denetim Akışı
Görevleri iptal etme ve tamamlanan görevleri işleme
Genel Bakış
Zaman Uyumsuz bir Görevi veya Görev Listesini İptal Etme
Zaman Uyumsuz Görevleri Belirli Bir Süre Sonunda İptal Etme
Bir Görev Tamamlandıktan Sonra Geri Kalan Zaman Uyumsuz Görevleri İptal
Etme
Birden Çok Zaman Uyumsuz Görev Başlatma ve Görevleri Tamamlandıkça İşleme
Zaman Uyumsuz Uygulamalarda Yeniden Girişi İşleme
Dosya Erişimi için Async Kullanma
Öznitelikler
Genel Bakış
Özel Öznitelikler Oluşturma
AttributeUsage
Yansıma Kullanarak Özniteliklere Erişme
Öznitelikleri kullanarak C/C++ birleşimi oluşturma
Ortak Öznitelikler
Arayan Bilgileri
Koleksiyonlar
Kovaryans ve Kontravaryans
Genel Bakış
Genel Arabirimlerde Varyans
Değişken Genel Arabirimler Oluşturma
Genel Koleksiyonlar için Arabirimlerde Varyans Kullanma
Temsilcilerde Varyans
Temsilcilerde Varyans Kullanma
İşlev ve Eylem Genel Temsilcileri için Varyans Kullanma
İfade Ağaçları
Genel Bakış
İfade ağaçlarını yürütme
İfade ağaçlarını değiştirme
Dinamik sorgular derlemek için ifade ağaçları kullanma
Visual Studio’da İfade Ağacı Hatalarını Ayıklama
DebugView Sözdizimi
Yineleyiciler
Dil ile Tümleşik Sorgu (LINQ)
Genel Bakış
C#'de LINQ'e Başlarken
LINQ Sorgularına Giriş
LINQ ve Genel Türler
Temel LINQ Sorgu İşlemleri
LINQ ile Veri Dönüştürmeler
LINQ Sorgu İşlemlerinde Tür İlişkileri
LINQ'te Sorgu Sözdizimi ve Yöntem Sözdizimi
LINQ'i Destekleyen C# Özellikleri
İzlenecek yol: C#'de Sorgu Yazma (LINQ)
Standart Sorgu İşleçlerine Genel Bakış
Genel Bakış
Standart Sorgu İşleçleri için Sorgu İfade Sözdizimi
Standart Sorgu İşleçlerinin Yürütme Yöntemine Göre Sınıflandırılması
Verileri Sıralama
Ayarlama İşlemleri
Verileri Filtreleme
Niceleyici İşlemleri
Projeksiyon İşlemleri
Veri Bölümlendirme
Birleştirme İşlemleri
Verileri Gruplandırma
Oluşturma İşlemleri
Eşitlik İşlemleri
Öğe İşlemleri
Veri Türlerini Dönüştürme
Birleştirme İşlemleri
Toplama İşlemleri
Nesnelere LINQ
Genel Bakış
LINQ ve Dizeler
Nasıl yapılır makaleleri
Bir sözcüğün bir dizede kaç kez geçtiğini sayma (LINQ)
Nasıl yapılır: Belirli bir Sözcükler Kümesini İçeren Cümleleri Sorgulama (LINQ)
Nasıl yapılır: Bir Dizedeki Karakterleri Sorgulama (LINQ)
Normal ifadelerle LINQ sorgularını birleştirme
Nasıl yapılır: İki Liste Arasında Ayarlanmış Farkı Bulma (LINQ)
Nasıl yapılır: Herhangi bir Sözcük veya Alana Göre Metin Verilerini Sıralama
veya Filtreleme (LINQ)
Nasıl yapılır: Sınırlandırılmış bir Dosyanın Alanlarını Yeniden Sıralama (LINQ)
Dize koleksiyonlarını birleştirme ve karşılaştırma (LINQ)
Nasıl yapılır: Birden Fazla Kaynaktan Nesne Koleksiyonları Doldurma (LINQ)
Nasıl yapılır: Gruplar Kullanarak Bir Dosyayı Birden Çok Dosyaya Bölme (LINQ)
Nasıl yapılır: Farklı Dosyalardan İçerik Birleştirme (LINQ)
Bir CSV metin dosyasında sütun değerlerini hesaplama (LINQ)
LINQ ve Yansıma
Nasıl yapılır: Bir Derlemenin Meta Verilerini Yansıma ile Sorgulama (LINQ)
LINQ ve Dosya Dizinleri
Genel Bakış
Nasıl yapılır: Belirli bir Öznitelik veya Ada Sahip Dosyaları Sorgulama
Nasıl yapılır: Dosyaları Uzantıya Göre Gruplama (LINQ)
Nasıl yapılır: Bir Klasör Kümesindeki Toplam Bayt Sayısını Sorgulama (LINQ)
İki klasörün içeriğini karşılaştırma (LINQ)
Nasıl yapılır: Bir Dizin Ağacındaki En Büyük Dosya veya Dosyalar için Sorgu
(LINQ)
Nasıl yapılır: Bir Dizin Ağacında Yineleyen Dosyalar için Sorgu (LINQ)
Nasıl yapılır: Bir Klasördeki Dosyaların İçeriğini Sorgulama (LINQ)
Nasıl yapılır: LINQ ile ArrayList Sorgulama
LINQ sorguları için özel yöntem ekleme
LINQ - XML
Başlarken (LINQ to XML)
LINQ to XML’e Genel Bakış
LINQ to XML ile DOM Karşılaştırması
LINQ to XML ile Diğer XML Teknolojileri Karşılaştırması
Programlama Kılavuzu (LINQ to XML)
LINQ to XML Programlamaya Genel Bakış
XML Ağaçları
XML Ad Alanları ile Çalışma
XML Ağaçlarını Serileştirme
LINQ to XML Eksenleri
XML Ağaçlarını Sorgulama
XML Ağaçlarını Değiştirme (LINQ to XML)
Performans (LINQ to XML)
Gelişmiş LINQ to XML Programlama
LINQ to XML Güvenliği
Örnek XML Belgeleri (LINQ to XML)
Başvuru (LINQ to XML)
ADO.NET'e LINQ (Portal Sayfası)
LINQ Sorgusu için Veri Kaynağı Etkinleştirme
Visual Studio IDE ve LINQ için Araçlar Desteği
Nesne Odaklı Programlama
Yansıma
Serileştirme (C# )
Genel Bakış
Nasıl yapılır: Nesne Verilerini bir XML Dosyasına Yazma
Nasıl yapılır: Nesne Verilerini bir XML Dosyasından Okuma
İzlenecek yol: Visual Studio’da Bir Nesneyi Kalıcı Kılma
Deyimler, İfadeler ve İşleçler
Genel Bakış
Deyimler
İfadeler
İfade gövdeli üyeler
Anonim işlevler
Genel Bakış
Lambda ifadeleri
Nasıl yapılır: Sorguda lambda ifadeleri kullanma
Eşitlik ve eşitlik karşılaştırmaları
Eşitlik karşılaştırmaları
Nasıl yapılır: Tür için değer eşitliği tanımlama
Nasıl yapılır: Başvuru eşitliği testi (kimlik)
Türler
Türleri tanımlama ve kullanma
Atama ve Tür Dönüşümleri
Kutulama ve Kutudan Çıkarma
Nasıl yapılır: byte Dizisini int'e Dönüştürme
Nasıl yapılır: Bir Dizeyi Sayıya Dönüştürme
Nasıl yapılır: Onaltılık Dizeler ve Sayısal Türler Arasında Dönüştürme
Tür dinamiği kullanma
İzlenecek yol: Dinamik Nesneler Oluşturma ve Kullanma (C# and Visual Basic)
Sınıflar ve Yapılar
Genel Bakış
Sınıflar
Nesneler
Yapılar
Genel Bakış
Yapıları Kullanma
Devralma
Çok Biçimlilik
Genel Bakış
Geçersiz Kılma ve Yeni Anahtar Sözcüklerle Sürüm Oluşturma
Geçersiz Kılmanın ve Yeni Anahtar Sözcüklerin Ne Zaman Kullanılacağını Bilme
ToString yöntemini geçersiz kılma
Üyeler
Üyelere genel bakış
Soyut ve Korumalı Sınıflar ve Sınıf Üyeleri
Statik Sınıflar ve Statik Sınıf Üyeleri
Erişim Değiştiricileri
Alanlar
Sabitler
Soyut özellikleri tanımlama
C# içinde sabitleri tanımlama
Özellikler
Özelliklere genel bakış
Özellikleri Kullanma
Arabirim Özellikleri
Erişimci Erişilebilirliğini Kısıtlama
Okuma yazma özellikleri bildirme ve kullanma
Otomatik Uygulanan Özellikler
Nasıl yapılır: Otomatik uygulanan özelliklerle hafif bir sınıf uygulama
Yöntemler
Metotlara genel bakış
Yerel işlevler
Ref dönüşler ve ref yerel ayarlar
Parametreler
Parametreleri geçirme
Değer Türü Parametrelerini Geçirme
Başvuru Türü Parametreleri Geçirme
Yapı geçirme ile yönteme sınıf başvurusu geçirme arasındaki farkı bilme
Örtülü Olarak Yazılan Yerel Değişkenler
Sorgu ifadesinde türü örtük olarak belirlenmiş yerel değişkenleri ve dizileri
kullanma
Genişletme Yöntemleri
Özel bir genişletme yöntemi uygulama ve arama
Numaralandırma için yeni bir yöntem oluşturma
Adlandırılmış ve İsteğe Bağlı Bağımsız Değişkenler
Office programlamada adlandırılmış ve isteğe bağlı bağımsız değişkenleri kullanma
Oluşturucular
Oluşturuculara genel bakış
Oluşturucular Kullanma
Örnek Oluşturucuları
Özel Oluşturucular
Statik Oluşturucular
Kopya oluşturucu yazma
Sonlandırıcılar
Nesne ve Koleksiyon Başlatıcıları
Nesne başlatıcı kullanarak nesneleri başlatma
Nasıl yapılır: Koleksiyon Başlatıcısı ile bir Sözlük Başlatma
İç içe Geçmiş Türler
Parçalı Sınıflar ve Yöntemler
Anonim Türler
Bir sorguda öğe özelliklerinin alt kümelerini döndürme
Arabirimler
Genel Bakış
Açık Arabirim Uygulaması
Nasıl yapılır: Arabirim Üyelerini Açıkça Uygulama
Nasıl yapılır: İki Arabirimin Üyelerini Açıkça Uygulama
Numaralandırma Türleri
Temsilciler
Genel Bakış
Temsilcileri Kullanma
Temsilcilerin Adlandırılmış ve Anonim Yöntemler
Nasıl yapılır: Temsilcileri Birleştirme (Çok Noktaya Yayın Temsilcileri)(C#
Programlama Kılavuzu)
Nasıl yapılır: Temsilci Bildirme, Oluşturma ve Kullanma
Diziler
Genel Bakış
Nesne Olarak Diziler
Tek Boyutlu Diziler
Çok Boyutlu Diziler
Düzensiz Diziler
Dizilerle foreach kullanma
Dizileri Bağımsız Değişkenler Olarak Geçirme
Türü Örtük Olarak Belirlenmiş Diziler
Dizeler
Dizeler ile programlama
Nasıl yapılır: Bir Dizenin Sayısal bir Değeri Temsil Edip Etmediğini Belirleme
Dizin Oluşturucular
Genel Bakış
Dizin Oluşturucular Kullanma
Arabirimlerdeki Dizin Oluşturucular
Özellikler ve Dizin Oluşturucular Arasında Karşılaştırma
Olaylar
Genel Bakış
Nasıl yapılır: Olaylara Abone Olma ve Aboneliği Kaldırma
Nasıl yapılır: .NET Framework Yönergeleriyle Uyumlu Olayları Yayımlama
Nasıl yapılır: Türetilmiş Sınıflarda Temel Sınıf Olayları Oluşturma
Nasıl yapılır: Arabirim Olaylarını Uygulama
Nasıl yapılır: Özel Olay Erişimcilerini Uygulama
Genel Türler
Genel Bakış
Genel Tür Parametreleri
Tür Parametrelerindeki Kısıtlamalar
Genel Sınıflar
Genel Arabirimler
Genel Yöntemler
Genel Türler ve Diziler
Genel Temsilciler
C++ Şablonları ve C# Genel Türleri Arasındaki Farklar
Çalışma Zamanındaki Genel Türler
Genel Türler ve Yansıma
Genel Türler ve Öznitelikler
Ad Alanları
Genel Bakış
Ad alanlarını kullanma
Nasıl yapılır: Ad Alanımı kullanma
Güvenli Olmayan Kod ve İşaretçiler
Genel bakış ve kısıtlamalar
Sabit Boyutlu Arabellekler
İşaretçi türleri
Genel Bakış
İşaretçi Dönüştürmeler
Nasıl yapılır: Bayt Dizisine Kopyalamak için İşaretçiler Kullanma
XML Belgeleri Yorumları
Genel Bakış
Belge Açıklamaları için Önerilen Etiketler
XML Dosyasını İşleme
Belge Etiketleri için Sınırlayıcılar
Nasıl yapılır: XML Belgesi Özelliklerini Kullanma
Belge etiketi başvurusu
<c>
<code>
cref Özniteliği
<example>
<exception>
<include>
<list>
<para>
<param>
<paramref>
<permission>
<remarks>
<returns>
<see>
<seealso>
<summary>
<typeparam>
<typeparamref>
<value>
Özel Durumlar ve Özel Durum İşleme
Genel Bakış
Özel Durumlar Kullanma
Özel Durum İşleme
Özel Durumlar Oluşturma ve Atma
Derleyicinin Ürettiği Özel Durumlar
Nasıl yapılır: try/catch Kullanarak Özel Durum İşleme
Nasıl yapılır: Finally Kullanarak Temizleme Kodu Yürütme
Nasıl yapılır: CLS Olmayan Özel Durum Değerlendirme
Dosya Sistemi ve Kayıt Defteri
Genel Bakış
Nasıl yapılır: Dizin Ağacı ile Yineleme
Nasıl yapılır: Dosyalar, Klasörler ve Sürücüler Hakkında Bilgi Alma
Nasıl yapılır: Dosya veya Klasör Oluşturma
Nasıl yapılır: Dosyaları ve Klasörleri Kopyalama, Silme ve Taşıma
Nasıl yapılır: Dosya İşlemleri için İlerleme Durumu İletişim Kutusu Sağlama
Nasıl yapılır: Metin Dosyasına Yazma
Nasıl yapılır: Metin Dosyasından Okuma
Nasıl yapılır: Bir Defada bir Satır Olarak bir Metin Dosyasını Okuma (Visual C#)
Nasıl yapılır: Kayıt Defterinde Anahtar Oluşturma (Visual C#)
Birlikte Çalışabilirlik
.NET Birlikte Çalışabilirliği
Birlikte Çalışabilirliğe Genel Bakış
Nasıl yapılır: Visual C# Özelliklerini Kullanarak Office Birlikte Çalışma Nesnelerine
Erişim
Nasıl yapılır: COM Birlikte Çalışma Programlamada Dizin Oluşturulmuş Özellikleri
Kullanma
Nasıl yapılır: Wave Dosyasını Oynatmak için Platform Çağırma Kullanma
İzlenecek yol: Office Programlama (C# ve Visual Basic)
Örnek COM Sınıfı
Dil Başvurusu
Genel Bakış
Dil sürümünü yapılandırma
C# anahtar sözcükleri
Genel Bakış
Yerleşik türler
Değer türleri
Değer türlerinin özellikleri
Tamsayı sayısal türler
Kayan nokta sayısal türleri
Yerleşik sayısal dönüşümler
bool
char
enum
struct
Boş değer atanabilen değer türleri
Başvuru türleri
Başvuru türlerinin özellikleri
Yerleşik başvuru türleri
sınıf
arabirim
void
var
Yönetilmeyen türler
Türler için başvuru tabloları
Yerleşik türler tablosu
Değer türleri tablosu
Varsayılan değerler tablosu
Sayısal sonuçlar tablosunu biçimlendirme
Değiştiriciler
Erişim Değiştiricileri
Hızlı başvuru
Erişilebilirlik Düzeyleri
Erişilebilirlik Etki Alanı
Erişilebilirlik Düzeylerinin Kullanılmasındaki Kısıtlamalar
internal
private
protected
public
protected internal
private protected
abstract
async
const
olay
extern
in (genel değiştirici)
new (üye değiştiricisi)
out (genel değiştirici)
override
readonly
korumalı
static
unsafe
virtual
volatile
Deyim Anahtar Sözcükleri
Deyim kategorileri
Seçim Deyimleri
if-else
anahtarı
Yineleme Deyimleri
do
for
foreach, in
while
Atlama Deyimleri
break
continue
goto
return
Özel Durum İşleme Deyimleri
throw
try-catch
try-finally
try-catch-finally
Checked ve Unchecked
Genel Bakış
checked
unchecked
fixed Deyimi
lock Deyimi
Yöntem Parametreleri
Parametreleri geçirme
params
in (Parametre Değiştirici)
ref
out (Parametre Değiştirici)
Ad Alanı Anahtar Sözcükleri
ad alanı
kullanma
using bağlamları
using Yönergesi
using static Yönergesi
using Deyimi
extern alias
Tür testi anahtar sözcükleri
is
Genel Tür Kısıtlaması Anahtar Sözcükleri
new kısıtlaması
Burada
Anahtar Sözcüklere Erişim
taban
this
Değişmez Değer Anahtar Sözcükleri
null
true ve false
default
Bağlamsal Anahtar Sözcükler
Hızlı başvuru
add
get
partial (Tür)
partial (Yöntem)
remove
set
when (filtre koşulu)
value
yield
Sorgu Anahtar Sözcükleri
Hızlı başvuru
from tümcesi
where tümcesi
select tümcesi
group tümcesi
into
orderby tümcesi
join tümcesi
let tümcesi
ascending
descending
on
eşittir
by
içinde
C# işleçleri
Genel Bakış
Aritmetik İşleçler
Boole mantıksal işleçleri
Bit düzeyinde ve kaydırma işleçleri
Eşitlik İşleçleri
Karşılaştırma işleçleri
Üye erişimi işleçleri
Tür testi ve atama işleçleri
Kullanıcı tanımlı dönüştürme işleçleri
İşaretçi bağlantılı işleçler
Atama işleçleri
+ and += işleçleri
- and -= işleçleri
?: işleci
! (null-forgiving) işleci
?? and ??= işleçleri
=> işleci
:: işleci
await işleci
varsayılan işleç
delegate işleci
nameof işleci
new işleci
sizeof işleci
stackalloc işleci
true ve false işleçleri
İşleç aşırı yüklemesi
C# özel karakterleri
Genel Bakış
$ -- dize ilişkilendirme
@-- tam tanımlayıcı
C# ön işlemci yönergeleri
Genel Bakış
#if
#else
#elif
#endif
#define
#undef
#warning
#error
#line
#region
#endregion
#pragma
#pragma warning
#pragma checksum
C# derleyici seçenekleri
Genel Bakış
csc.exe Kullanarak Komut Satırı Derleme
Visual Studio Komut Satırı için ortam değişkenlerini ayarlama
Kategorilere Göre Listelenen C# Derleyici Seçenekleri
Alfabetik Listelenmiş C# Derleyici Seçenekleri
@
-addmodule
-appconfig
-baseaddress
-bugreport
-checked
-codepage
-debug
-define
-delaysign
-deterministic
-doc
-errorreport
-filealign
-fullpaths
-help, -?
-highentropyva
-keycontainer
-keyfile
-langversion
-lib
-link
-linkresource
-main
-moduleassemblyname
-noconfig
-nologo
-nostdlib
-nowarn
-nowin32manifest
-optimize
-out
-pathmap
-pdb
-platform
-preferreduilang
-publicsign
-recurse
-reference
-refout
-refonly
-resource
-subsystemversion
-target
-target:appcontainerexe
-target:exe
-target:library
-target:module
-target:winexe
-target:winmdobj
-unsafe
-utf8output
-warn
-warnaserror
-win32icon
-win32manifest
-win32res
C# derleyici hataları
C# 6.0 taslak belirtimi
C# 7.0 - 8.0 teklifleri
İzlenecek Yollar
C# kullanmaya başlama
31.10.2019 • 3 minutes to read • Edit Online

Bu bölümde, ve .NET Core kullanarak C# hızlı bir şekilde uygulama oluşturmanıza olanak sağlayan kısa ve basit
öğreticiler sağlanmaktadır. Visual Studio 2017 ve Visual Studio Code için Başlarken konuları vardır. Bu makalelerde
bazı programlama deneyimleri varsayılmaktadır. Programlama için yeni bir deneyimize tıkladığınızda etkileşimli
öğreticilere giriş C# ' i deneyin.
Aşağıdaki konular kullanılabilir:
C# Dile ve .NET Framework giriş
C# Dile ve .net 'e genel bakış sunar.
Visual Studio 2017’de .NET Core ile bir C# Merhaba Dünya uygulaması derleme
Visual Studio, uygulamalarınızı Windows veya Mac için tümleşik bir geliştirme ortamından kodlamanıza,
derlemenize, çalıştırmanıza, hata ayıklamanıza, profilinize ve yayımlamanıza olanak sağlar.
Bu konu, basit bir Merhaba Dünya uygulaması oluşturup çalıştırmanıza ve sonra biraz daha etkileşimli
Merhaba Dünya uygulaması çalıştıracak şekilde değiştirmenize olanak sağlar. Uygulamanızı oluşturmayı ve
çalıştırmayı tamamladıktan sonra, nasıl hata ayıklaması yapacağınızı ve .NET Core tarafından desteklenen
herhangi bir platformda çalıştırılabilmesi için nasıl yayımlayacağınızı öğrenebilirsiniz.
Visual Studio 2017’de C# ve .NET Core ile bir sınıf kitaplığı derleme
Bir sınıf kitaplığı, başka bir uygulamadan çağrılabilen türleri ve tür üyelerini tanımlamanıza olanak sağlar. Bu
konu, bir dizenin büyük harfli bir karakterle başlayıp başlamadığını belirleyen tek bir yöntemle bir sınıf
kitaplığı oluşturmanıza olanak sağlar. Kitaplığı oluşturmayı tamamladıktan sonra, beklendiği gibi
çalıştığından emin olmak için bir birim testi geliştirebilir ve bunu kullanmak istediğiniz uygulamalariçin
kullanılabilir hale getirebilirsiniz.
C# ve Visual Studio Code kullanmaya başlama
Visual Studio Code, Modern Web ve bulut uygulamaları oluşturmak ve bu uygulamalarda hata ayıklamak
için iyileştirilmiş, ücretsiz bir kod düzenleyicisidir. IntelliSense 'i destekler ve Linux, macOS ve Windows için
kullanılabilir.
Bu konuda, Visual Studio Code ve .NET Core ile basit bir Merhaba Dünya uygulamasının nasıl
oluşturulacağı ve çalıştırılacağı gösterilmektedir.

İlgili bölümler
C# Programlama Kılavuzu
Programlama kavramları hakkında C# bilgi sağlar ve içinde C#çeşitli görevlerin nasıl gerçekleştirileceğini
açıklar.
C#Başvurunun
Anahtar sözcükler, işleçler, C# Önişlemci yönergeleri, derleyici seçenekleri ve derleyici hataları ve uyarıları
hakkında ayrıntılı başvuru bilgileri sağlar.
İzlenecek yollar
C# kullanan programlama yollarına ve her izlenecek yola ilişkin kısa bir açıklamaya bağlantılar sağlar.
Ayrıca bkz.
C#Visual Studio ile geliştirme
C# Diline ve.NET Framework'e Giriş
25.11.2019 • 9 minutes to read • Edit Online

C#, geliştiricilerin .NET Framework çalışan çeşitli güvenli ve güçlü uygulamalar oluşturmalarına olanak tanıyan, şık
ve tür açısından güvenli bir nesne yönelimli dildir. Windows istemci uygulamaları C# , XML Web Hizmetleri,
dağıtılmış bileşenler, istemci-sunucu uygulamaları, veritabanı uygulamaları ve çok daha fazlasını oluşturmak için
kullanabilirsiniz. Visual C# , gelişmiş bir kod düzenleyici, uygun Kullanıcı arabirimi tasarımcıları, tümleşik hata
ayıklayıcı ve C# dile ve .NET Framework göre uygulama geliştirmeyi kolaylaştırmak için birçok diğer araç sağlar.

NOTE
Görsel C# belgeler, temel programlama kavramlarını anladığınızı varsayar. Yeni bir başlangıç yapıyorsanız, Web 'de bulunan
Visual C# Express 'i incelemek isteyebilirsiniz. Ayrıca, pratik programlama becerileri öğrenmek C# için kitaplar ve Web
kaynaklarından yararlanabilirsiniz.

C# Dili
C#sözdizimi büyük ölçüde ifade edilir, ancak kolayca öğrenilmesi ve kolay bir işlemdir.Küme ayracı sözdizimi C# ,
C C++ veya Java 'yı bilen herkese anında tanınacaktır. Bu dillerden herhangi birini bilen geliştiriciler genellikle çok
kısa bir süre C# içinde üretken bir şekilde çalışmaya başlayabilirler. C#sözdizimi, C++ ' nin birçok karmaşıklıklarını
basitleştirir ve null yapılabilir değer türleri, numaralandırmalar, temsilciler, lambda ifadeleri ve doğrudan bellek
erişimi gibi Java 'da bulunmayan güçlü özellikler sağlar. C#, Artırılmış tür güvenliği ve performans ve yineleyiciler
sağlayan genel yöntemleri ve türleri destekler ve bu sayede, istemci kodu tarafından kullanılması kolay olan özel
yineleme davranışları tanımlamak için koleksiyon sınıflarının uygulayıcıları özelliğini etkinleştirir. Dil ile Tümleşik
Sorgu (LINQ ) ifadeler, türü kesin belirlenmiş sorguyu birinci sınıf dil yapısına getirir.
Nesne yönelimli bir dil olarak kapsülleme, C# devralma ve çok biçimlilik kavramlarını destekler. Main yöntemi
dahil olmak üzere tüm değişkenler ve Yöntemler, uygulamanın giriş noktası, sınıf tanımları içinde kapsüllenir. Bir
sınıf doğrudan bir üst sınıftan devralınabilir, ancak herhangi bir sayıda arabirim uygulayabilir. Bir üst sınıftaki sanal
yöntemleri geçersiz kılan yöntemler, yanlışlıkla yeniden tanımlama önlemek için override anahtar sözcüğünü
gerektirir. ' C#De, bir yapı hafif bir sınıf gibidir; arabirim uygulayan, ancak devralmayı desteklemeyen, yığın olarak
ayrılmış bir türdür.
Bu temel nesne odaklı ilkelere ek olarak, C# aşağıdakiler de dahil olmak üzere çeşitli yenilikçi dil yapıları aracılığıyla
yazılım bileşenleri geliştirmeyi kolaylaştırır:
Tür kullanımı uyumlu olay bildirimlerini etkinleştiren Temsilcileradlı Kapsüllenmiş yöntem imzaları.
Özel üye değişkenleri için erişimci işlevi sunan özellikler.
Çalışma zamanında türler hakkında bildirime dayalı meta veriler sağlayan öznitelikler.
Satır içi XML belge açıklamaları.
çeşitli veri kaynakları genelinde yerleşik sorgu özellikleri sağlayan Dil ile Tümleşik Sorgu (LINQ ).
COM nesneleri veya yerel Win32 DLL 'Leri gibi diğer Windows yazılımlarıyla etkileşimde bulunmak istiyorsanız
bunu "birlikte çalışma" adlı bir işlem C# aracılığıyla yapabilirsiniz. Birlikte çalışabilirlik C# , programların bir yerel
C++ uygulamanın yapabildiği neredeyse her şeyi yapmasına olanak sağlar. C#, doğrudan bellek erişiminin
kesinlikle kritik olduğu durumlar için işaretçileri ve "güvenli olmayan" kod kavramını destekler.
Yapı C# Işlemi, Java 'dan daha fazla C ve C++ daha esnek ile karşılaştırılır. Ayrı bir üst bilgi dosyası yoktur ve
yöntemlerin ve türlerin belirli bir sırada bildirildiği hiçbir gereksinimi yoktur. C# Kaynak dosya herhangi bir sayıda
sınıf, yapı, arabirim ve olay tanımlayabilir.
Ek C# kaynaklar aşağıda verilmiştir:
Dile yönelik iyi bir genel giriş için, bkz. C# dil belirtimininBölüm 1.
C# Dilin belirli yönleri hakkında ayrıntılı bilgi için bkz. C# başvuru.
LINQhakkında daha fazla bilgi için bkz. LINQ (dil Ile tümleşik sorgu).

.NET Framework platform mimarisi


C#Programlar, ortak dil çalışma zamanı (CLR ) ve Birleşik sınıf kitaplıkları kümesi adlı bir sanal yürütme sistemi
içeren, Windows 'un integral bir bileşeni olan .NET Framework çalışır. CLR, dil ve kitaplıkların sorunsuz şekilde
çalıştığı yürütme ve geliştirme ortamları oluşturmaya yönelik temel bir uluslararası standart olan ortak dil
altyapısının (CLı) Microsoft tarafından oluşturulan ticari bir uygulamasıdır.
İçinde C# yazılan kaynak kodu, CLI belirtimine uyan bir Ara dilde (IL ) derlenir. Il kodu ve bit eşlemler ve dizeler gibi
kaynaklar, genellikle bir. exe veya. dll uzantısıyla derleme adlı yürütülebilir bir dosyada diskte depolanır.
Bütünleştirilmiş kod, derlemenin türleri, sürümü, kültürü ve güvenlik gereksinimleri hakkında bilgi sağlayan bir
bildirim içerir.
C# Program yürütüldüğünde, derleme clr 'ye yüklenir ve bu, bildirimdeki bilgilere bağlı olarak çeşitli eylemler
gerçekleştirebilir. Daha sonra, güvenlik gereksinimleri karşılanırsa, Il kodunu yerel makine yönergelerine
dönüştürmek için CLR tam zamanında (JıT) derleme gerçekleştirir. CLR Ayrıca otomatik çöp toplama, özel durum
işleme ve kaynak yönetimiyle ilgili diğer hizmetleri de sağlar. CLR tarafından yürütülen kod bazen "yönetilen kod"
olarak adlandırılır. Bu, belirli bir sistemi hedefleyen yerel makine dilinde derlenen "yönetilmeyen kodun" aksine.
Aşağıdaki diyagramda C# kaynak kodu dosyalarının derleme zamanı ve çalışma zamanı ilişkileri, .NET Framework
sınıf kitaplıkları, derlemeler ve clr gösterilmektedir.

Dil birlikte çalışabilirliği, .NET Framework temel bir özelliğidir. C# Derleyici tarafından üretilen IL kodu ortak tür
BELIRTIMINE (Cts) uygun olduğundan, ÖĞESINDEN C# oluşturulan IL kodu Visual Basic, görselin C++.net
sürümlerinden veya 20 ' den daha fazlası tarafından oluşturulan kodla etkileşime girebilirler CTS uyumlu diller. Tek
bir derleme, farklı .NET dillerinde yazılmış birden çok modül içerebilir ve türler aynı dilde yazıldıklarında olduğu
gibi birbirlerine başvurabilir.
Çalışma zamanı hizmetlerine ek olarak .NET Framework, dosya girişi ve çıktısından dize işlemeye XML 'e kadar her
şey için çok çeşitli yararlı işlevler sağlayan ad alanları halinde düzenlenmiş 4000 ' den fazla sınıftan oluşan
kapsamlı bir kitaplık içerir. Windows Forms denetimleri için ayrıştırma. Tipik C# uygulama, ortak "sıhhi tesisat"
kullanımlarını işlemek için .NET Framework sınıf kitaplığını kapsamlı şekilde kullanır.
.NET Framework hakkında daha fazla bilgi için bkz. Microsoft .NET Framework 'e genel bakış.

Ayrıca bkz.
Görsele BaşlarkenC#
C# öğreticiler
4.11.2019 • 6 minutes to read • Edit Online

C# Öğreticilere hoş geldiniz. Bu, tarayıcınızda çalıştırabileceğiniz etkileşimli dersler ile başlar. Daha sonraki
öğreticiler ve daha gelişmiş öğreticiler, makinenizde program oluşturmak C# için .NET geliştirme araçlarıyla
çalışmanıza yardımcı olur.

C# Etkileşimli öğreticilere giriş


Araştırmayı video biçiminde başlatmak istiyorsanız, C# 101 video serisi öğesine C#bir giriş sağlar. Bu öğreticilerde
keşfedebileceğiniz kavramlar hakkında bilgi edineceksiniz.
İlk dersler, kodun C# küçük parçacıkları kullanılarak kavramları açıklamaktadır.C# Sözdiziminin temel bilgilerini ve
dizeler, sayılar ve Boole değerleri gibi veri türleriyle nasıl çalışacağınızı öğreneceksiniz. Bu, tüm etkileşimlidir ve
dakikalar içinde kod yazmak ve çalıştırmak isteyeceksiniz. Bu ilk dersler daha önce programlama veya C# dil
bilgisine sahip değildir.

Merhaba dünya
Merhaba Dünya öğreticisinde en temel C# programı oluşturacaksınız. string türünü ve metinle çalışmayı
keşfedebilirsiniz.

C# numaraları
Öğreticideki sayılarda C# , bilgisayarların sayıları nasıl depolayacağınızı ve farklı sayısal türlerle hesaplamaların
nasıl gerçekleştirileceğini öğreneceksiniz. Yuvarlama hakkında temel bilgileri ve kullanarak C#matematik
hesaplamaları yapmayı öğreneceksiniz. Bu öğretici, makinenizde yerel olarak çalışmak içinde kullanılabilir.
Bu öğreticide, Hello World ders 'i tamamladığınız varsayılmaktadır.

Dal ve döngüler
Dallar ve döngüler öğreticisinde, değişkenlerde depolanan değerlere göre farklı kod yürütme yolları seçmenin
temelleri öğretilir. Denetim akışının temel bilgilerini öğrenirsiniz. Bu, programların kararlar alma ve farklı eylemler
seçme işlemlerinin temelini oluşturur. Bu öğretici, makinenizde yerel olarak çalışmak içinde kullanılabilir.
Bu öğreticide, Merhaba Dünya ve derslerin numaralarını C# tamamladığınız varsayılmaktadır.

Liste koleksiyonu
Liste koleksiyonu dersi, veri dizilerini depolayan liste koleksiyonu türünün bir turuna sahip olmanızı sağlar. Öğe
ekleme ve kaldırma, öğe arama ve listeleri sıralama hakkında bilgi edineceksiniz. Farklı liste türleri keşfedebilirsiniz.
Bu öğretici, makinenizde yerel olarak çalışmak içinde kullanılabilir.
Bu öğreticide, yukarıda listelenen dersleri tamamladığınız varsayılmaktadır.

Giriş C# --yerel olarak çalışın


Merhaba Dünya dersi izleyen tüm giriş öğreticileri kendi yerel geliştirme ortamınızda bulunabilir. Her öğreticinin
sonunda, çevrimiçi olarak veya kendi makinenizde bir sonraki ders ile devam etmek istediğinize karar verirsiniz.
Ortamınızı ayarlamanıza ve makinenizde bir sonraki öğreticiye devam etmenize yardımcı olacak bağlantılar vardır.
C# 'teki yeni özellikleri keşfet
6. adımda yeni C# Özellikler 'i etkileşimli olarak deneyin: tarayıcınızda C# 6 . adımda eklenen özellikleri
araştırma.
Dize ilişkilendirme: ' de C#biçimlendirilen dizeler oluşturmak için dize ilişkilendirmeyi nasıl kullanacağınızı
gösterir.
Null yapılabilir başvuru türleri: null Başvurular için amacınızı ifade etmek üzere null yapılabilir başvuru türlerini
nasıl kullanacağınızı gösterir.
Null yapılabilir başvuru türlerini kullanmak için bir projeyi güncelleştirme: mevcut bir projeyi, null yapılabilir
başvuru türlerini kullanmak için yükseltme tekniklerini gösterir.
Model eşleştirme kullanarak veri yeteneklerini genişletme: türleri temel özelliklerinin ötesinde genişletmek için
model eşleştirmeyi nasıl kullanacağınızı gösterir.
Dizinler ve aralıklar kullanarak veri dizileri Ile çalışma: bir sıralı veri kapsayıcısının tek öğelerine veya aralıklarına
erişmek için yeni uygun sözdizimi gösterir.

Genel öğreticiler
Aşağıdaki öğreticiler .NET Corekullanarak program oluşturmanızı C# sağlar:
Konsol uygulaması: konsol g/ç, konsol uygulamasının yapısını ve görev tabanlı zaman uyumsuz programlama
modelinin temellerini gösterir.
Rest istemcisi: C# DILDEKI Web iletişimlerini, JSON serileştirmesini ve nesne yönelimli özellikleri gösterir.
Ve .NET C# içinde devralma: temel sınıfları, C#soyut temel sınıfları ve türetilmiş sınıfları tanımlamak için
devralma kullanımı dahil olmak üzere ' de devralım işlemini gösterir.
LINQ Ile çalışma: LINQ özelliklerinin çoğunu ve bunu destekleyen dil öğelerini gösterir.
Öznitelikleri kullanma: ' de C#özniteliklerin nasıl oluşturulduğunu ve kullanıldığını gösterir.
Dize ilişkilendirme öğreticisi, bir dizeye nasıl değer ekleneceğini gösterir. Katıştırılmış C# ifadelerle bir
enterpolasyonlu dize oluşturmayı ve sonuç dizesinde ifade sonuçlarının metin görünümünü denetlemeyi
öğreneceksiniz. Bu öğretici, makinenizde yerel olarak çalışmak içinde kullanılabilir.
C# giriş
4.11.2019 • 3 minutes to read • Edit Online

C# Öğreticilere giriş konusuna hoş geldiniz. Bu, tarayıcınızda çalıştırabileceğiniz etkileşimli dersler ile başlar. Bu
etkileşimli dersleri başlatmadan önce C# C# 101 video serisinden temel bilgileri öğrenebilirsiniz.

İlk dersler, kodun C# küçük parçacıkları kullanılarak kavramları açıklamaktadır.C# Sözdiziminin temel bilgilerini ve
dizeler, sayılar ve Boole değerleri gibi veri türleriyle nasıl çalışacağınızı öğreneceksiniz. Bu, tüm etkileşimlidir ve
dakikalar içinde kod yazmak ve çalıştırmak isteyeceksiniz. Bu ilk dersler daha önce programlama veya C# dil
bilgisine sahip değildir.
Merhaba Dünya dersi izleyen tüm giriş öğreticileri, çevrimiçi tarayıcı deneyimi veya kendi yerel geliştirme
ortamınızdabulunabilir. Her öğreticinin sonunda, çevrimiçi olarak veya kendi makinenizde bir sonraki ders ile
devam etmek istediğinize karar verirsiniz. Ortamınızı ayarlamanıza ve makinenizde bir sonraki öğreticiye devam
etmenize yardımcı olacak bağlantılar vardır.

Merhaba dünya
Merhaba Dünya öğreticisinde en temel C# programı oluşturacaksınız. string türünü ve metinle çalışmayı
keşfedebilirsiniz.

C# numaraları
Öğreticideki sayılarda C# , bilgisayarların sayıları nasıl depolayacağınızı ve farklı sayısal türlerle hesaplamaların
nasıl gerçekleştirileceğini öğreneceksiniz. Yuvarlama hakkında temel bilgileri ve kullanarak C#matematik
hesaplamaları yapmayı öğreneceksiniz. Bu öğretici, makinenizde yerel olarak çalışmak içinde kullanılabilir.
Bu öğreticide, Hello World ders 'i tamamladığınız varsayılmaktadır.

Dal ve döngüler
Dallar ve döngüler öğreticisinde, değişkenlerde depolanan değerlere göre farklı kod yürütme yolları seçmenin
temelleri öğretilir. Denetim akışının temel bilgilerini öğrenirsiniz. Bu, programların kararlar alma ve farklı eylemler
seçme işlemlerinin temelini oluşturur. Bu öğretici, makinenizde yerel olarak çalışmak içinde kullanılabilir.
Bu öğreticide, Merhaba Dünya ve derslerin numaralarını C# tamamladığınız varsayılmaktadır.

Liste koleksiyonu
Liste koleksiyonu dersi, veri dizilerini depolayan liste koleksiyonu türünün bir turuna sahip olmanızı sağlar. Öğe
ekleme ve kaldırma, öğe arama ve listeleri sıralama hakkında bilgi edineceksiniz. Farklı liste türleri
keşfedebilirsiniz. Bu öğretici, makinenizde yerel olarak çalışmak içinde kullanılabilir.
Bu öğreticide, yukarıda listelenen dersleri tamamladığınız varsayılmaktadır.

Sınıflara giriş
Bu son öğretici yalnızca kendi yerel geliştirme ortamınız ve .NET Core kullanılarak makinenizde çalıştırılabilir. Bir
konsol uygulaması oluşturup C# dilin parçası olan temel nesne yönelimli özellikleri görürsünüz.
Bu öğreticide, çevrimiçi giriş öğreticilerini tamamladığınız ve .NET Core SDK ve Visual Studio Codeyüklediğiniz
varsayılmaktadır.
.NET geliştirme araçları hakkında bilgi sahibi olun
23.11.2019 • 2 minutes to read • Edit Online

Makinenizde bir öğretici çalıştırmanın ilk adımı bir geliştirme ortamı kurmak. 10 dakika içinde Merhaba Dünya
.NET öğreticisi, Windows, Linux veya MacOS 'ta yerel geliştirme ortamınızı ayarlamaya yönelik yönergeler içerir.
Alternatif olarak, .NET Core SDK ve Visual Studio Codeyükleyebilirsiniz.

Temel uygulama geliştirme akışı


dotnet new komutunu kullanarak uygulamalar oluşturacaksınız. Bu komut, uygulamanız için gerekli olan
dosyaları ve varlıkları oluşturur. C# Öğreticilere giriş, console uygulama türünü kullanır. Temel bilgileri aldıktan
sonra diğer uygulama türlerine genişletebilirsiniz.
Kullanacağınız diğer komutlar yürütülebilir dosyayı oluşturmak için dotnet build ve çalıştırılabilir dosyayı
çalıştırmak için dotnet run .

Öğreticinizi seçin
Aşağıdaki öğreticilerden herhangi biriyle başlayabilirsiniz:

C# numaraları
Öğreticideki sayılarda C# , bilgisayarların sayıları nasıl depolayacağınızı ve farklı sayısal türlerle hesaplamaların
nasıl gerçekleştirileceğini öğreneceksiniz. ' İ yuvarlama hakkında temel bilgileri ve kullanarak C#matematik
hesaplamaları yapmayı öğreneceksiniz.
Bu öğreticide, Hello World ders 'i tamamladığınız varsayılmaktadır.

Dal ve döngüler
Dallar ve döngüler öğreticisinde, değişkenlerde depolanan değerlere göre farklı kod yürütme yolları seçmenin
temelleri öğretilir. Denetim akışının temel bilgilerini öğrenirsiniz. Bu, programların kararlar alma ve farklı eylemler
seçme işlemlerinin temelini oluşturur.
Bu öğreticide, Merhaba Dünya ve derslerin numaralarını C# tamamladığınız varsayılmaktadır.

Liste koleksiyonu
Liste koleksiyonu dersi, veri dizilerini depolayan liste koleksiyonu türünün bir turuna sahip olmanızı sağlar. Öğe
ekleme ve kaldırma, öğe arama ve listeleri sıralama hakkında bilgi edineceksiniz. Farklı liste türleri
keşfedebilirsiniz.
Bu öğreticide, yukarıda listelenen dersleri tamamladığınız varsayılmaktadır.

Sınıflara giriş
C# Öğreticiye en son giriş, kendi yerel geliştirme ortamınız ve .NET Core kullanılarak yalnızca makinenizde
çalıştırılabilir. Bir konsol uygulaması oluşturup C# dilin parçası olan temel nesne yönelimli özellikleri görürsünüz.
C # integral ve kayan nokta numaralarını işleme
8.11.2019 • 13 minutes to read • Edit Online

Bu öğretici, size etkileşimli olarak C# sayısal türler öğretir. Küçük miktarlarda kod yazacaksınız, daha sonra bu
kodu derleyip çalıştıracaksınız. Öğreticide, içindeki C#sayıları ve matematik işlemlerini keşfettiği bir dizi ders
bulunur. Bu dersler, C# dilin temellerini öğretir.
Bu öğreticide, geliştirme için kullanabileceğiniz bir makineniz olması beklenir. 10 dakika içinde Merhaba Dünya
.NET öğreticisi, Windows, Linux veya MacOS 'ta yerel geliştirme ortamınızı ayarlamaya yönelik yönergeler içerir.
Kullanacağınız komutlara hızlı bir genel bakış, daha fazla ayrıntı için bağlantılarla birlikte geliştirme araçları
hakkında bilgi sahibi olmaya gelmiştir .

Tamsayı matematiğini keşfet


Sayı adlı bir dizin oluşturun -hızlı başlangıç. Geçerli dizini yapın ve şu komutu çalıştırın:

dotnet new console -n NumbersInCSharp -o .

En sevdiğiniz düzenleyicide program.cs açın ve satır Console.WriteLine("Hello World!"); aşağıdaki kodla


değiştirin:

int a = 18;
int b = 6;
int c = a + b;
Console.WriteLine(c);

Komut pencerenize dotnet run yazarak bu kodu çalıştırın.


Yalnızca tamsayılarla temel matematik işlemlerinden birini gördünüz. int türü bir tamsayıyı, sıfır, pozitif veya
negatif bir tam sayıyı temsil eder. Ek için + sembolünü kullanırsınız. Tamsayılar için diğer yaygın matematik
işlemleri şunlardır:
çıkarma için -
Çarpma için *
Bölüm için /
Bu farklı işlemleri inceleyerek başlayın. c değerini yazan satırdan sonra bu satırları ekleyin:

// subtraction
c = a - b;
Console.WriteLine(c);

// multiplication
c = a * b;
Console.WriteLine(c);

// division
c = a / b;
Console.WriteLine(c);

Komut pencerenize dotnet run yazarak bu kodu çalıştırın.


İsterseniz aynı satırda birden çok matematik işlemi gerçekleştirerek da deneyebilirsiniz. Örneğin
c = a + b - 12 * 17; deneyin. Değişkenlerin ve sabit sayıların karıştırılmasına izin verilir.

TIP
Keşfederken C# (veya herhangi bir programlama dilini), kod yazarken hata oluşturursunuz. Derleyici bu hataları bulacak ve
size rapor eder. Çıktı hata iletileri içerdiğinde, nelerin düzeltileceğini görmek için örnek koda ve penceredeki koda yakından
bakın. Bu alıştırma, C# kod yapısını öğrenmenize yardımcı olur.

İlk adımı tamamladınız. Sonraki bölüme başlamadan önce geçerli kodu ayrı bir yönteme taşıyalim. Bu, yeni bir
örnekle çalışmaya başlamasını kolaylaştırır. Main yönteminizi WorkingWithIntegers olarak yeniden adlandırın ve
WorkingWithIntegers çağıran yeni bir Main yöntemi yazın. Bitirdiğinizde, kodunuzun şöyle görünmesi gerekir:

using System;

namespace NumbersInCSharp
{
class Program
{
static void WorkingWithIntegers()
{
int a = 18;
int b = 6;

// addition
int c = a + b;
Console.WriteLine(c);

// subtraction
c = a - b;
Console.WriteLine(c);

// multiplication
c = a * b;
Console.WriteLine(c);

// division
c = a / b;
Console.WriteLine(c);
}

static void Main(string[] args)


{
WorkingWithIntegers();
}
}
}

İşlem sırasını keşfet


WorkingWithIntegers() çağrısını açıklama. Bu bölümde çalışırken çıktının daha az karışık hale gelir:

//WorkingWithIntegers();

// içinde C#bir yorum başlatır. Açıklamalar, kaynak kodunuzda tutmak istediğiniz tüm metinlerdir, ancak kod
olarak yürütülmez. Derleyici açıklamalardan herhangi bir yürütülebilir kod oluşturmaz.
C# Dil, matematiksel olarak öğrendiğiniz kurallarla tutarlı kurallara sahip farklı matematik işlemlerinin önceliğini
tanımlar. Çarpma ve bölme, toplama ve çıkarma konusunda önceliklidir. Main yöntemine aşağıdaki kodu
ekleyerek ve dotnet run yürüterek bunu keşfedebilirsiniz:

int a = 5;
int b = 4;
int c = 2;
int d = a + b * c;
Console.WriteLine(d);

Çıktı, çarpma 'nın ekleme işleminden önce gerçekleştirildiğini gösterir.


Önce gerçekleştirilmesini istediğiniz işlemin veya işlemlerin çevresine parantez ekleyerek farklı bir işlem sırası
zorlayabilirsiniz. Aşağıdaki satırları ekleyin ve yeniden çalıştırın:

d = (a + b) * c;
Console.WriteLine(d);

Birçok farklı işlemi birleştirerek daha fazlasını keşfedebilirsiniz. Main yönteminizin en altında aşağıdaki satırlara
benzer bir şey ekleyin. Yeniden dotnet run deneyin.

d = (a + b) - 6 * c + (12 * 4) / 3 + 12;
Console.WriteLine(d);

Tamsayılar için ilginç bir davranış fark etmiş olabilirsiniz. Sonucun ondalık veya kesir kısmını içermesini
bekleseniz bile, tam sayı bölümü her zaman bir tamsayı sonucu üretir.
Bu davranışı görmediyseniz, Main yönteminizin sonunda aşağıdaki kodu deneyin:

int e = 7;
int f = 4;
int g = 3;
int h = (e + f) / g;
Console.WriteLine(h);

Sonuçları görmek için yeniden dotnet run yazın.


' In üzerine geçmeden önce, bu bölümde yazdığınız tüm kodu alıp yeni bir yönteme koyabilirsiniz. Yeni yöntemin
OrderPrecedence çağırın. Şöyle bir işlem yapmanız gerekir:
using System;

namespace NumbersInCSharp
{
class Program
{
static void WorkingWithIntegers()
{
int a = 18;
int b = 6;

// addition
int c = a + b;
Console.WriteLine(c);

// subtraction
c = a - b;
Console.WriteLine(c);

// multiplication
c = a * b;
Console.WriteLine(c);

// division
c = a / b;
Console.WriteLine(c);
}

static void OrderPrecedence()


{
int a = 5;
int b = 4;
int c = 2;
int d = a + b * c;
Console.WriteLine(d);

d = (a + b) * c;
Console.WriteLine(d);

d = (a + b) - 6 * c + (12 * 4) / 3 + 12;
Console.WriteLine(d);

int e = 7;
int f = 4;
int g = 3;
int h = (e + f) / g;
Console.WriteLine(h);
}

static void Main(string[] args)


{
WorkingWithIntegers();

OrderPrecedence();

}
}
}

Tamsayı hassasiyetini ve limitleri keşfet


Bu son örnek, bu tamsayı bölümünün sonucu ne olduğunu gösterdi. % karakteri olan Modül işlecini kullanarak
kalanı alabilirsiniz. Main yönteminde aşağıdaki kodu deneyin:
int a = 7;
int b = 4;
int c = 3;
int d = (a + b) / c;
int e = (a + b) % c;
Console.WriteLine($"quotient: {d}");
Console.WriteLine($"remainder: {e}");

C# Tamsayı türü matematik tamlarından farklı bir şekilde farklılık gösterir: int türü en az ve en fazla sınırlara
sahiptir. Bu sınırları görmek için bu kodu Main yöntemine ekleyin:

int max = int.MaxValue;


int min = int.MinValue;
Console.WriteLine($"The range of integers is {min} to {max}");

Hesaplama bu sınırları aşan bir değer üretirse, bir yetersiz yer veya taşma koşulunuz vardır. Yanıt bir sınırdan
diğerine kaydırılır. Örnek görmek için bu iki satırı Main yöntemine ekleyin:

int what = max + 3;


Console.WriteLine($"An example of overflow: {what}");

Yanıtın en düşük (negatif) tamsayıya çok yakın olduğuna dikkat edin. min + 2 aynıdır. Toplama işlemi, tamsayılar
için izin verilen değerleri taşırdı . Bir taşma, olası en büyük tamsayı değerinden en küçüğe "kaydırdığı için, yanıt
çok büyük negatif bir sayıdır.
int türü gereksinimlerinizi karşılamıyorsa kullanabileceğiniz farklı sınırlara ve duyarlığa sahip başka sayısal
türler vardır. Bundan sonra bu ileri keşfedelim.
Bir kez daha, bu bölümde yazdığınız kodu ayrı bir yönteme taşıyalim. TestLimits adlandırın.

Double türüyle çalışma


double sayısal türü bir çift duyarlıklı kayan noktalı sayıyı temsil eder. Bu terimler sizin için yeni olabilir. Kayan
noktalı sayı, çok büyük veya küçük olabilecek tamsayı olmayan sayıları temsil etmek için kullanışlıdır. Çift
duyarlıklı , bu sayıların tek duyarlığagöre daha fazla duyarlık kullanılarak depolandığı anlamına gelir. Modern
bilgisayarlarda, tek duyarlık sayılarıyla çift duyarlık kullanmak daha yaygındır. Keşfedelim. Aşağıdaki kodu ekleyin
ve sonucu görüntüleyin:

double a = 5;
double b = 4;
double c = 2;
double d = (a + b) / c;
Console.WriteLine(d);

Yanıtın, bölümün ondalık kısmını içerdiğine dikkat edin. Double değerleri ile biraz daha karmaşık bir ifade
deneyin:

double e = 19;
double f = 23;
double g = 8;
double h = (e + f) / g;
Console.WriteLine(h);

Double değerinin aralığı tamsayı değerlerinden çok daha büyüktür. Şu ana kadar yazdıklarınız için aşağıdaki
kodu deneyin:

double max = double.MaxValue;


double min = double.MinValue;
Console.WriteLine($"The range of double is {min} to {max}");

Bu değerler bilimsel gösterimde yazdırılır. E solundaki sayı mantisinin ' dir. Sağdaki sayı, 10 ' un üssü olarak üs
değeri olan sayıdır.
Matematiği gibi ondalık sayılar gibi, içindeki Double C# değerleri de yuvarlama hataları içerebilir. Şu kodu
deneyin:

double third = 1.0 / 3.0;


Console.WriteLine(third);

Yinelenen 0.3 1/3 tam olarak aynı olmadığını bilirsiniz.


Sına
double türünü kullanarak büyük sayılar, küçük sayılar, çarpma ve bölme ile diğer hesaplamaları deneyin. Daha
karmaşık hesaplamalar deneyin.
Zorluğa bir süre harcadıktan sonra yazdığınız kodu alın ve yeni bir yönteme yerleştirin. Yeni yöntemin
WorkWithDoubles adı.

Sabit nokta türleriyle çalışma


Temel sayısal türleri C#: tamsayılar ve Double değerleri ile gördünüz. Öğreneceğinizi bir başka tür vardır:
decimal türü. decimal türü daha küçük bir aralığa sahiptir, ancak double daha fazla duyarlığa sahiptir. Sabit
nokta terimi, ondalık noktanın (veya ikili noktanın) taşınmayacağı anlamına gelir. Şimdi bir göz atalım:

decimal min = decimal.MinValue;


decimal max = decimal.MaxValue;
Console.WriteLine($"The range of the decimal type is {min} to {max}");

Aralığın double türünden küçük olduğuna dikkat edin. Aşağıdaki kodu deneyerek ondalık türüyle daha büyük
duyarlık görebilirsiniz:

double a = 1.0;
double b = 3.0;
Console.WriteLine(a / b);

decimal c = 1.0M;
decimal d = 3.0M;
Console.WriteLine(c / d);

Sayıların M soneki, bir sabitin decimal türünü kullanması gerektiğini gösterir.


Ondalık türü kullanan matematik, ondalık noktanın sağında daha fazla basamağa sahip olduğuna dikkat edin.
Sına
Farklı sayısal türleri gördüğünüze göre, yarıçapı 2,50 santimetre olan bir dairenin alanını hesaplayan bir kod
yazın. Bir daire alanının, Radius ile çarpıldığı bir daire olduğunu unutmayın. Bir ipucu: .NET, bu değer için
kullanabileceğiniz PI, Math.PI için bir sabit içerir.
19 ila 20 arasında bir yanıt almanız gerekir. GitHub 'daki tamamlanmış örnek koda bakarak yanıtınızı kontrol
edebilirsiniz
İsterseniz başka formüller de deneyin.
"Numaraları C#" hızlı başlangıç adımlarını tamamladınız. Kendi geliştirme ortamınızda dallar ve döngüler hızlı
başlangıç ile devam edebilirsiniz.
Aşağıdaki konularda, içindeki C# numaralar hakkında daha fazla bilgi edinebilirsiniz:
Integral sayısal türleri
Kayan nokta sayısal türleri
Yerleşik sayısal dönüşümler
Dal ve döngü deyimleri ile koşullu mantık öğrenin
8.11.2019 • 13 minutes to read • Edit Online

Bu öğretici, değişkenleri inceleyen ve bu değişkenlere göre yürütme yolunu değiştiren bir kod yazmayı öğretir.
Kod yazar C# ve bunları derleyip çalıştırmaya ilişkin sonuçları görürsünüz. Öğreticide, ' de C#dallanma ve döngü
yapılarını keşfeden oluşan bir dizi ders bulunur. Bu dersler, C# dilin temellerini öğretir.
Bu öğreticide, geliştirme için kullanabileceğiniz bir makineniz olması beklenir. 10 dakika içinde Merhaba Dünya
.NET öğreticisi, Windows, Linux veya MacOS 'ta yerel geliştirme ortamınızı ayarlamaya yönelik yönergeler içerir.
Kullanacağınız komutlara hızlı bir genel bakış, daha fazla ayrıntı için bağlantılarla birlikte geliştirme araçları
hakkında bilgi sahibi olmaya gelmiştir .

if ifadesini kullanarak kararlar alın


Dallar adlı bir dizin oluşturun -öğretici. Geçerli dizini yapın ve şu komutu çalıştırın:

dotnet new console -n BranchesAndLoops -o .

Bu komut geçerli dizinde yeni bir .NET Core konsol uygulaması oluşturur.
En sevdiğiniz düzenleyicide program.cs açın ve satır Console.WriteLine("Hello World!"); aşağıdaki kodla
değiştirin:

int a = 5;
int b = 6;
if (a + b > 10)
Console.WriteLine("The answer is greater than 10.");

Konsol pencerenize dotnet run yazarak bu kodu deneyin. "Yanıt 10 ' dan büyük" iletisini görmeniz gerekir.
konsolunuza yazdırılır.
Toplamın 10 ' dan küçük olması için b ' ın bildirimini değiştirin:

int b = 3;

dotnet run yeniden yazın. Yanıt 10 ' dan az olduğu için hiçbir şey yazdırılmaz. Test ettiğiniz koşul false 'tur.
Yalnızca bir if ifadesine ait olası dallardan birini yazdığınız için yürütülecek bir kodunuz yok: doğru dal.

TIP
Keşfederken C# (veya herhangi bir programlama dilini), kod yazarken hata oluşturursunuz. Derleyici hataları bulacak ve
rapor eder. Hata çıktısına ve hatayı oluşturan koda yakından bakın. Derleyici hatası genellikle sorunu bulmanıza yardımcı
olabilir.

Bu ilk örnekte if ve Boole türlerinin gücü gösterilmektedir. Boole değeri iki değerden birine sahip olabilir:
true veya false . C#Boole değişkenleri için bool özel bir tür tanımlar. if bildiri bir bool değerini denetler.
Değer true olduğunda, if ' i izleyen ifade yürütülür. Aksi takdirde, atlanır.
Bu koşullara göre koşulları denetleme ve deyimleri yürütme işlemi çok güçlüdür.
Eğer ve başka bir birlikte çalışır yap
Doğru ve yanlış dallarda farklı kodu yürütmek için, koşul yanlış olduğunda yürütülen bir else dalı
oluşturursunuz. Bunu deneyin. Aşağıdaki kodda bulunan son iki satırı Main yöntemine ekleyin (ilk dördü zaten
var olmalıdır):

int a = 5;
int b = 3;
if (a + b > 10)
Console.WriteLine("The answer is greater than 10");
else
Console.WriteLine("The answer is not greater than 10");

else anahtar sözcüğünü izleyen ifade, yalnızca test edilen koşul false olduğunda yürütülür. if ve else Boole
koşullarına göre birleştirmek, hem true hem de false koşulunu işlemek için ihtiyacınız olan tüm gücü sağlar.

IMPORTANT
if ve else deyimlerinin altındaki girintileme insan okuyucular içindir. Dil C# , girintileme veya boşluk olarak kabul
etmez. if veya else anahtar sözcüğünü izleyen ifade, koşula bağlı olarak yürütülür. Bu öğreticideki tüm örnekler,
ifadelerin denetim akışına göre satırları girintilemek için ortak bir uygulama izler.

Girintileme önemli olmadığından, çok sayıda deyimin koşullu olarak yürütülen bloğun bir parçası olmasını
istediğiniz zaman göstermek için { ve } ' i kullanmanız gerekir. C#programcılar genellikle bu ayraçları tüm
if ve else yan tümcelerinde kullanır. Aşağıdaki örnek, az önce oluşturduğunuz ile aynıdır. Yukarıdaki kodu
aşağıdaki kodla eşleşecek şekilde değiştirin:

int a = 5;
int b = 3;
if (a + b > 10)
{
Console.WriteLine("The answer is greater than 10");
}
else
{
Console.WriteLine("The answer is not greater than 10");
}

TIP
Bu öğreticinin geri kalanında, kod örnekleri, kabul edilen uygulamaları takip eden ayraçları içerir.

Daha karmaşık koşulları test edebilirsiniz. Şu ana kadar yazdığınız koddan sonra Main yöntetiniz için aşağıdaki
kodu ekleyin:
int c = 4;
if ((a + b + c > 10) && (a == b))
{
Console.WriteLine("The answer is greater than 10");
Console.WriteLine("And the first number is equal to the second");
}
else
{
Console.WriteLine("The answer is not greater than 10");
Console.WriteLine("Or the first number is not equal to the second");
}

Eşitlikiçin == sembol testi. == kullanmak, a = 5 ' de gördüğünüz sınav için testi birbirinden ayırır.
&& "ve" temsil eder. Doğru dalda deyimin yürütülmesi için her iki koşulun de true olması gerektiği anlamına
gelir. Bu örnekler Ayrıca, { ve } ' de yer alan her bir koşullu dalda birden çok deyim olduğunu gösterir.
Ayrıca, "veya" öğesini göstermek için || de kullanabilirsiniz. Şu ana kadar yazıldıktan sonra aşağıdaki kodu
ekleyin:

if ((a + b + c > 10) || (a == b))


{
Console.WriteLine("The answer is greater than 10");
Console.WriteLine("Or the first number is equal to the second");
}
else
{
Console.WriteLine("The answer is not greater than 10");
Console.WriteLine("And the first number is not equal to the second");
}

a , b ve c değerlerini değiştirip && ile || arasında geçiş yapın. && ve || işleçlerinin nasıl çalıştığını daha iyi
anlayabilirsiniz.
İlk adımı tamamladınız. Sonraki bölüme başlamadan önce geçerli kodu ayrı bir yönteme taşıyalim. Bu, yeni bir
örnekle çalışmaya başlamasını kolaylaştırır. Main yönteminizi ExploreIf olarak yeniden adlandırın ve
ExploreIf çağıran yeni bir Main yöntemi yazın. İşiniz bittiğinde kodunuzun şöyle görünmesi gerekir:
using System;

namespace BranchesAndLoops
{
class Program
{
static void ExploreIf()
{
int a = 5;
int b = 3;
if (a + b > 10)
{
Console.WriteLine("The answer is greater than 10");
}
else
{
Console.WriteLine("The answer is not greater than 10");
}

int c = 4;
if ((a + b + c > 10) && (a > b))
{
Console.WriteLine("The answer is greater than 10");
Console.WriteLine("And the first number is greater than the second");
}
else
{
Console.WriteLine("The answer is not greater than 10");
Console.WriteLine("Or the first number is not greater than the second");
}

if ((a + b + c > 10) || (a > b))


{
Console.WriteLine("The answer is greater than 10");
Console.WriteLine("Or the first number is greater than the second");
}
else
{
Console.WriteLine("The answer is not greater than 10");
Console.WriteLine("And the first number is not greater than the second");
}
}

static void Main(string[] args)


{
ExploreIf();
}
}
}

ExploreIf() çağrısını açıklama. Bu bölümde çalışırken çıktının daha az karışık hale gelir:

//ExploreIf();

// içinde C#bir yorum başlatır. Açıklamalar, kaynak kodunuzda tutmak istediğiniz tüm metinlerdir, ancak kod
olarak yürütülmez. Derleyici açıklamalardan herhangi bir yürütülebilir kod oluşturmaz.

İşlemleri yinelemek için döngüleri kullanma


Bu bölümde deyimlerini yinelemek için döngüleri kullanırsınız. Main yönteminde bu kodu deneyin:
int counter = 0;
while (counter < 10)
{
Console.WriteLine($"Hello World! The counter is {counter}");
counter++;
}

while bildiri bir koşulu denetler ve while takip eden deyimin veya bildiri bloğunu yürütür. Koşul false olana
kadar durumu sürekli olarak denetler ve bu deyimleri gerçekleştirir.
Bu örnekte başka bir yeni işleç vardır. counter değişkenden sonra ++ artırma işleçtir. counter değerine 1 ekler
ve bu değeri counter değişkeninde depolar.

IMPORTANT
Kodu yürütmeden while Loop koşulunun false olarak değiştiği emin olun. Aksi takdirde, programınızın hiç bitmediğini
sonsuz bir döngü oluşturursunuz. Bu örnekte gösterilmediği için, programınızı CTRL-C veya başka yollarla çıkmaya
zorlamaya zorlamanız gerekir.

while döngüsü, while takip eden kodu yürütmeden önce koşulu sınar. do ... while döngüsü önce kodu yürütür
ve sonra koşulu kontrol eder. Do while döngüsü aşağıdaki kodda gösterilmiştir:

int counter = 0;
do
{
Console.WriteLine($"Hello World! The counter is {counter}");
counter++;
} while (counter < 10);

Bu do döngüsü ve önceki while döngüsü aynı çıktıyı üretir.

For döngüsü ile çalışma


For döngüsü genellikle ' de C#kullanılır. Main () yönteminde bu kodu deneyin:

for (int index = 0; index < 10; index++)


{
Console.WriteLine($"Hello World! The index is {index}");
}

Bu, while döngüsü ile aynı çalışmayı ve zaten kullandığınız do döngüsünü yapar. for deyimin nasıl çalıştığını
denetleyen üç bölümü vardır.
İlk bölüm for başlatıcıdır: int index = 0; index döngü değişkeni olduğunu bildirir ve başlangıç değerini 0
olarak ayarlar.
Orta kısım için olan durumdur: index < 10 sayaç değeri 10 ' dan az olduğu sürece bu for döngüsünün
yürütülmeye devam ettiğini bildirir.
Son bölüm Yineleyici için: index++ for deyimden sonra blok yürütüldükten sonra döngü değişkeninin nasıl
değiştirileceğini belirtir. Burada, blok her çalıştırıldığında index 1 ' in artırılabilmelidir.
Bunlarla deneyin. Aşağıdakilerin her birini deneyin:
Başlatıcıyı farklı bir değerle başlayacak şekilde değiştirin.
Koşulu, farklı bir değerde durdurulacak şekilde değiştirin.
İşiniz bittiğinde, öğrendiklerinizi kullanmak için kendinize bir kod yazmak üzere ilerlim.

Dalları ve döngüleri birleştirme


Artık if ifadesini ve bu C# dilin döngü yapılarını gördüğünüze göre, 3 ' e bölünebilen 1 ile 20 C# arasındaki
tüm tamsayıların toplamını bulmak için kod yazıp yazbileceğinizi inceleyin. İşte birkaç ipucu:
% işleci, bir bölme işleminin kalanını sağlar.
if ifade, bir sayının toplamın bir parçası olup olmadığını görmek için koşul sağlar.
for döngüsü, 1 ile 20 arasındaki tüm sayılar için bir dizi adımı yinelemenize yardımcı olabilir.

Kendiniz deneyin. Sonra nasıl yapıldığını kontrol edin. Yanıt için 63 almalısınız. GitHub 'da tamamlanan kodu
görüntüleyerekolası bir yanıt görebilirsiniz.
"Dallar ve döngüler" öğreticisini tamamladınız.
Kendi geliştirme ortamınızda diziler ve koleksiyonlar öğreticisiyle devam edebilirsiniz.
Bu kavramlar hakkında daha fazla bilgi için aşağıdaki konulara bakın:
If ve Else deyimleri
While ekstresi
Do ekstresi
For deyimleri
Genel liste türünü kullanarak veri koleksiyonlarını
yönetmeyi öğrenin
23.11.2019 • 8 minutes to read • Edit Online

Bu giriş öğreticisi, C# dile ve List<T> sınıfının temel bilgilerine bir giriş sağlar.
Bu öğreticide, geliştirme için kullanabileceğiniz bir makineniz olması beklenir. 10 dakika içinde Merhaba Dünya
.NET öğreticisi, Windows, Linux veya MacOS 'ta yerel geliştirme ortamınızı ayarlamaya yönelik yönergeler içerir.
Kullanacağınız komutlara hızlı bir genel bakış, daha fazla ayrıntı bağlantılarıyla birlikte geliştirme araçları
hakkında bilgi sahibiolmak için kullanılır.

Temel liste örneği


List-öğreticisiadlı bir dizin oluşturun. Geçerli dizini yapıp dotnet new console çalıştırın.
En sevdiğiniz düzenleyicide program.cs açın ve mevcut kodu aşağıdaki kodla değiştirin:

using System;
using System.Collections.Generic;

namespace list_tutorial
{
class Program
{
static void Main(string[] args)
{
var names = new List<string> { "<name>", "Ana", "Felipe" };
foreach (var name in names)
{
Console.WriteLine($"Hello {name.ToUpper()}!");
}
}
}
}

<name> , adınızla değiştirin. Program.csKaydet. Denemek için konsol pencerenize dotnet run yazın.
Yalnızca bir dize listesi oluşturdunuz, bu listeye üç ad ekledik ve adları tüm büyük harfler içinde yazdırdınız.
Önceki öğreticilerde, listede döngü gerçekleştirmek için öğrenmiş olduğunuz kavramları kullanıyorsunuz.
Adları görüntülenecek kod, dize ilişkilendirme özelliğini kullanır. Bir string $ karakteri ile önce kullandığınızda,
C# kodu String bildiriminde ekleyebilirsiniz. Gerçek dize, bu C# kodun oluşturduğu değerle değiştirir. Bu örnekte,
ToUpper yöntemini çağırdığı için {name.ToUpper()} her bir adla değiştirir ve büyük harflere dönüştürülür.
Araştırma devam edelim.

Liste içeriğini değiştirme


Oluşturduğunuz koleksiyon List<T> türünü kullanır. Bu tür öğe dizilerini depolar. Açılı ayraçlar arasındaki
öğelerin türünü belirtirsiniz.
Bu List<T> türünün önemli bir yönü büyümenin veya küçülebileceği, böylece öğe eklemenize veya kaldırmanıza
olanak tanır. Main yönteminde kapanış } önce bu kodu ekleyin:
Console.WriteLine();
names.Add("Maria");
names.Add("Bill");
names.Remove("Ana");
foreach (var name in names)
{
Console.WriteLine($"Hello {name.ToUpper()}!");
}

Listenin sonuna iki ad daha eklediniz. Ayrıca bir tane de kaldırmış olursunuz. Dosyayı kaydedin ve dotnet run
yazarak deneyin.
List<T>, tek tek öğeleri dizine göre de başvurmanızı sağlar. Dizini liste adından sonra [ ve ] belirteçleri
arasına yerleştirebilirsiniz. C#ilk dizin için 0 kullanır. Bu kodu, yeni eklediğiniz kodun hemen altına ekleyin ve
deneyin:

Console.WriteLine($"My name is {names[0]}");


Console.WriteLine($"I've added {names[2]} and {names[3]} to the list");

Liste sonunun ötesinde bir dizine erişemezsiniz. Dizinlerin 0 ' dan başlayıp, en büyük geçerli dizinin listedeki öğe
sayısından bir daha az olması gerektiğini unutmayın. Listenin Count özelliğini ne kadar süreyle kullandığını
kontrol edebilirsiniz. Main yönteminin sonuna aşağıdaki kodu ekleyin:

Console.WriteLine($"The list has {names.Count} people in it");

Dosyayı kaydedin ve sonuçları görmek için dotnet run yeniden yazın.

Arama ve sıralama listeleri


Örneklerimizde görece küçük listeler kullanılıyor, ancak uygulamalarınız genellikle binlerce numaralandırma olan
çok sayıda öğesi olan listeler oluşturabilir. Bu daha büyük koleksiyonlardaki öğeleri bulmak için listede farklı
öğeler için arama yapmanız gerekir. IndexOf yöntemi bir öğe arar ve öğenin dizinini döndürür. Bu kodu Main
yönteminizin en altına ekleyin:

var index = names.IndexOf("Felipe");


if (index == -1)
{
Console.WriteLine($"When an item is not found, IndexOf returns {index}");
}
else
{
Console.WriteLine($"The name {names[index]} is at index {index}");
}

index = names.IndexOf("Not Found");


if (index == -1)
{
Console.WriteLine($"When an item is not found, IndexOf returns {index}");
}
else
{
Console.WriteLine($"The name {names[index]} is at index {index}");

Listenizdeki öğeler de sıralanmış olabilir. Sort yöntemi, listedeki tüm öğeleri normal sıralarına göre sıralar
(dizeler söz konusu olduğunda alfabetik olarak). Bu kodu Main yönteminizin en altına ekleyin:
names.Sort();
foreach (var name in names)
{
Console.WriteLine($"Hello {name.ToUpper()}!");
}

Bu en son sürümü denemek için dosyayı kaydedin ve dotnet run yazın.


Sonraki bölüme başlamadan önce geçerli kodu ayrı bir yönteme taşıyalim. Bu, yeni bir örnekle çalışmaya
başlamasını kolaylaştırır. Main yönteminizi WorkingWithStrings olarak yeniden adlandırın ve
WorkingWithStrings çağıran yeni bir Main yöntemi yazın. İşiniz bittiğinde kodunuzun şöyle görünmesi gerekir:

using System;
using System.Collections.Generic;

namespace list_tutorial
{
class Program
{
static void Main(string[] args)
{
WorkingWithStrings();
}

public static void WorkingWithStrings()


{
var names = new List<string> { "<name>", "Ana", "Felipe" };
foreach (var name in names)
{
Console.WriteLine($"Hello {name.ToUpper()}!");
}

Console.WriteLine();
names.Add("Maria");
names.Add("Bill");
names.Remove("Ana");
foreach (var name in names)
{
Console.WriteLine($"Hello {name.ToUpper()}!");
}

Console.WriteLine($"My name is {names[0]}");


Console.WriteLine($"I've added {names[2]} and {names[3]} to the list");

Console.WriteLine($"The list has {names.Count} people in it");

var index = names.IndexOf("Felipe");


Console.WriteLine($"The name {names[index]} is at index {index}");

var notFound = names.IndexOf("Not Found");


Console.WriteLine($"When an item is not found, IndexOf returns {notFound}");

names.Sort();
foreach (var name in names)
{
Console.WriteLine($"Hello {name.ToUpper()}!");
}
}
}
}

Diğer türlerin listeleri


Şu ana kadar listelerde string türü kullanıyorsunuz. List<T> farklı bir tür kullanalım. Bir sayı kümesi
oluşturalım.
Aşağıdakileri yeni Main yönteminizin altına ekleyin:

var fibonacciNumbers = new List<int> {1, 1};

Bu, tamsayıların bir listesini oluşturur ve ilk iki tamsayının değerini 1 değerine ayarlar. Bunlar bir Fibonaccı
sırasınınilk iki değeri, bir dizi sayı. Her bir sonraki Fibonaccı numarası, önceki iki sayının toplamı alınarak bulunur.
Şu kodu ekleyin:

var previous = fibonacciNumbers[fibonacciNumbers.Count - 1];


var previous2 = fibonacciNumbers[fibonacciNumbers.Count - 2];

fibonacciNumbers.Add(previous + previous2);

foreach (var item in fibonacciNumbers)


Console.WriteLine(item);

Sonuçları görmek için dosyayı kaydedin ve dotnet run yazın.

TIP
Yalnızca bu bölüme odaklanmak için WorkingWithStrings(); çağıran kodu açıklama olarak ayarlayabilirsiniz. Çağrının
önüne şu şekilde iki / karakteri koymanız yeterlidir: // WorkingWithStrings(); .

Sına
Bu ve önceki derslerden bazılarını bir araya getirebilirsiniz. Fibonaccı numaralarına en fazla ne kadar derlediğiniz
hakkında ' yı genişletin. Dizideki ilk 20 sayıyı oluşturmak için kodu yazmayı deneyin. (İpucu olarak, 20 fibonaccı
numarası 6765 ' dir.)

Sınama Tamam
GitHub 'daki tamamlanmış örnek koda bakarakörnek bir çözüm görebilirsiniz.
Döngünün her tekrarında, listedeki son iki tamsayının yerine getiriyorsunuz ve bu değeri listeye ekliyor
olursunuz. Döngü, listeye 20 öğe ekleyinceye kadar yinelenir.
Tebrikler, liste öğreticisini tamamladınız. Kendi geliştirme ortamınızda sınıflarla tanışın öğreticisine devam
edebilirsiniz.
Koleksiyonlarhakkında .net Kılavuzu konusundaki List türüyle çalışma hakkında daha fazla bilgi edinebilirsiniz.
Diğer birçok koleksiyon türünü de öğreneceksiniz.
Sınıflar ve nesneler ile nesne odaklı programlamayı
keşfet
8.11.2019 • 13 minutes to read • Edit Online

Bu öğreticide, geliştirme için kullanabileceğiniz bir makineniz olması beklenir. 10 dakika içinde Merhaba Dünya
.NET öğreticisi, Windows, Linux veya MacOS 'ta yerel geliştirme ortamınızı ayarlamaya yönelik yönergeler içerir.
Kullanacağınız komutlara hızlı bir genel bakış, daha fazla ayrıntı için bağlantılarla birlikte geliştirme araçları
hakkında bilgi sahibi olmaya gelmiştir .

Uygulamanızı oluşturma
Bir Terminal penceresi kullanarak, sınıflaradlı bir dizin oluşturun. Uygulamanızı burada oluşturacaksınız. Bu dizine
geçin ve konsol penceresinde dotnet new console yazın. Bu komut uygulamanızı oluşturur. Program.cs'i açın.
Şöyle görünmelidir:

using System;

namespace classes
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}

Bu öğreticide, bir banka hesabını temsil eden yeni türler oluşturacaksınız. Genellikle geliştiriciler her bir sınıfı farklı
bir metin dosyasında tanımlar. Bu, bir program boyutunun büyüdükçe daha kolay yönetilmesini sağlar. Classes
dizininde BankAccount.cs adlı yeni bir dosya oluşturun.
Bu dosya, bir Banka hesabınıntanımını içerir. Nesne odaklı programlama, sınıfbiçiminde türler oluşturarak kodu
düzenler. Bu sınıflar, belirli bir varlığı temsil eden kodu içerir. BankAccount sınıfı bir banka hesabını temsil eder. Kod,
Yöntemler ve özellikler aracılığıyla belirli işlemleri uygular. Bu öğreticide, banka hesabı bu davranışı destekler:
1. Bu, banka hesabını benzersiz bir şekilde tanımlayan 10 basamaklı bir sayı içerir.
2. Sahiplerinin adını veya adlarını depolayan bir dizesi vardır.
3. Bakiye alınabilir.
4. Mevduat kabul eder.
5. Çekme kabul eder.
6. İlk bakiye pozitif olmalıdır.
7. Çekme işlemleri negatif bir bakiyeye neden olamaz.

Banka hesap türünü tanımlayın


Bu davranışı tanımlayan bir sınıfın temellerini oluşturarak başlayabilirsiniz. Şöyle görünür:
using System;

namespace classes
{
public class BankAccount
{
public string Number { get; }
public string Owner { get; set; }
public decimal Balance { get; }

public void MakeDeposit(decimal amount, DateTime date, string note)


{
}

public void MakeWithdrawal(decimal amount, DateTime date, string note)


{
}
}
}

Başlamadan önce, derleydiklerinize göz atalım. namespace bildirimi, kodunuzu mantıksal olarak düzenlemek için
bir yol sağlar. Bu öğretici nispeten küçüktür, bu nedenle tüm kodu bir ad alanına yerleştirebilirsiniz.
public class BankAccount oluşturduğunuz sınıfı veya türü tanımlar. Sınıf bildirimini izleyen { ve } içindeki her
şey, sınıfının davranışını tanımlar. BankAccount sınıfının beş üyesi vardır. İlk üçü özelliklerdir. Özellikler veri
öğeleridir ve doğrulamayı veya diğer kuralları zorlayan koda sahip olabilir. Son ikisi metodlardır. Yöntemler, tek
bir işlevi gerçekleştiren kod bloklarıdır. Her üyenin adını okumak, siz veya başka bir geliştirici tarafından sınıfın ne
yaptığını anlamak için yeterli bilgi sağlamalıdır.

Yeni bir hesap açın


Uygulanacak ilk özellik bir banka hesabı açmak. Bir müşteri bir hesabı açtığında, bir başlangıç bakiyesi ve bu
hesabın sahibi veya sahipleri hakkında bilgi sağlamalıdır.
BankAccount türünde yeni bir nesne oluşturmak, bu değerleri atayan bir oluşturucunun tanımlanması anlamına
gelir. Oluşturucu , sınıfıyla aynı ada sahip olan bir üyedir. Bu sınıf türündeki nesneleri başlatmak için kullanılır.
BankAccount türüne aşağıdaki oluşturucuyu ekleyin:

public BankAccount(string name, decimal initialBalance)


{
this.Owner = name;
this.Balance = initialBalance;
}

Oluşturucular, kullanarak bir nesne oluşturduğunuzda çağrılır. Program.cs içindeki satır


new
Console.WriteLine("Hello World!"); aşağıdaki satırla değiştirin ( <name> adını adınızla değiştirin):

var account = new BankAccount("<name>", 1000);


Console.WriteLine($"Account {account.Number} was created for {account.Owner} with {account.Balance} initial
balance.");

Ne olacağını görmek için dotnet run yazın.


Hesap numarasının boş olduğunu fark muydunuz? Bunun düzeltilmesi zaman alabilir. Nesne oluşturulduğunda
hesap numarası atanmalıdır. Ancak bunu oluşturmak için çağıranın sorumluluğunda olmaması gerekir.
BankAccount sınıfı kodu, yeni hesap numaralarının nasıl atanacağını bilmelidir. Bunu yapmanın basit bir yolu, 10
basamaklı bir sayıyla başlamamaktır. Her yeni hesap oluşturulduğunda bunu artırın. Son olarak, bir nesne
oluşturulduğunda geçerli hesap numarasını saklayın.
BankAccount sınıfına aşağıdaki üye bildirimini ekleyin:

private static int accountNumberSeed = 1234567890;

Bu bir veri üyesidir. private , bu, yalnızca BankAccount sınıfının içindeki kodla erişilebileceği anlamına gelir. Bu,
genel sorumlulukları (hesap numarası gibi) özel uygulamadan (hesap numaraları nasıl oluşturulur) ayırmaktan bir
yoldur. Ayrıca static , bu, tüm BankAccount nesneleri tarafından paylaşıldığını gösterir. Statik olmayan bir
değişkenin değeri, BankAccount nesnesinin her bir örneği için benzersizdir. Hesap numarasını atamak için
oluşturucuya aşağıdaki iki satırı ekleyin:

this.Number = accountNumberSeed.ToString();
accountNumberSeed++;

Sonuçları görmek için dotnet run yazın.

Mevdular ve çekme işlemleri oluşturma


Banka hesabı sınıfınızın, doğru şekilde çalışması için mevdular ve çekme alları kabul etmesi gerekir. Hesap için her
bir işlemin günlüğünü oluşturarak mevduları ve çekme bilgilerini uygulayalim. Bu, her bir işlemin bakiyesini
güncelleştirmek için birkaç avantaj sunar. Geçmiş, tüm işlemleri denetlemek ve günlük bakiyeleri yönetmek için
kullanılabilir. Gerektiğinde, tüm işlemlerin geçmişinden gelen dengeyi hesaplarken, düzeltilen tek bir işlemdeki
tüm hatalar, sonraki hesaplamanın bakiyesine doğru şekilde yansıtılır.
Bir işlemi temsil etmek için yeni bir tür oluşturarak başlayalım. Bu, herhangi bir sorumluluğu bulunmayan basit bir
türdür. Birkaç özelliğe ihtiyaç duyuyor. Transaction.csadlı yeni bir dosya oluşturun. Aşağıdaki kodu buna ekleyin:

using System;

namespace classes
{
public class Transaction
{
public decimal Amount { get; }
public DateTime Date { get; }
public string Notes { get; }

public Transaction(decimal amount, DateTime date, string note)


{
this.Amount = amount;
this.Date = date;
this.Notes = note;
}
}
}

Şimdi, BankAccount sınıfına Transaction nesnelerinin List<T> ekleyelim. Aşağıdaki bildirimi ekleyin:

private List<Transaction> allTransactions = new List<Transaction>();

List<T> sınıfı, farklı bir ad alanını içeri aktarmanızı gerektirir. BankAccount.cs'nin başlangıcına şunu ekleyin:

using System.Collections.Generic;
Şimdi Balance raporlanmasını değiştirelim. Bu, tüm işlemlerin değerlerini toplayarak bulunabilir. BankAccount
sınıfındaki Balance bildirimini aşağıdaki şekilde değiştirin:

public decimal Balance


{
get
{
decimal balance = 0;
foreach (var item in allTransactions)
{
balance += item.Amount;
}

return balance;
}
}

Bu örnekte, özelliklerinönemli bir yönü gösterilmektedir. Artık, başka bir programcı değer istediğinde bakiyeyi
hesaplıyor. Hesaplama tüm işlemleri numaralandırır ve toplamı geçerli Bakiye olarak verir.
Sonra, MakeDeposit ve MakeWithdrawal yöntemlerini uygulayın. Bu yöntemler, son iki kuralı zorunlu tutar: ilk
Bakiyenin pozitif olması ve tüm çekme allarının negatif bir bakiye oluşturmamalıdır.
Bu, özel durumkavramını tanıtır. Bir yöntemin işini başarıyla tamamlayamadığını belirten standart yol, bir özel
durum oluşturmak şeklindedir. Özel durum türü ve onunla ilişkili ileti hatayı anlatmaktadır. Burada, depozito
miktarı negatifse MakeDeposit yöntemi bir özel durum oluşturur. MakeWithdrawal yöntemi, çekme miktarı
negatifse veya çekme sonuçları negatif bir bakiyeye uygulanırsa bir özel durum oluşturur:

public void MakeDeposit(decimal amount, DateTime date, string note)


{
if (amount <= 0)
{
throw new ArgumentOutOfRangeException(nameof(amount), "Amount of deposit must be positive");
}
var deposit = new Transaction(amount, date, note);
allTransactions.Add(deposit);
}

public void MakeWithdrawal(decimal amount, DateTime date, string note)


{
if (amount <= 0)
{
throw new ArgumentOutOfRangeException(nameof(amount), "Amount of withdrawal must be positive");
}
if (Balance - amount < 0)
{
throw new InvalidOperationException("Not sufficient funds for this withdrawal");
}
var withdrawal = new Transaction(-amount, date, note);
allTransactions.Add(withdrawal);
}

throw deyimleri bir özel durum oluşturur . Geçerli bloğun yürütülmesi sonlanır ve çağrı yığınında bulunan ilk
eşleşen catch bloğuna denetim aktarımları yapılır. Daha sonra bu kodu test etmek için bir catch bloğu
ekleyeceksiniz.
Oluşturucunun, bakiyeyi doğrudan güncelleştirmek yerine bir ilk işlem eklemesi için bir değişiklik alması gerekir.
MakeDeposit yöntemini zaten yazmış olduğunuz için oluşturucudan çağırın. Tamamlanmış Oluşturucu şöyle
görünmelidir:
public BankAccount(string name, decimal initialBalance)
{
this.Number = accountNumberSeed.ToString();
accountNumberSeed++;

this.Owner = name;
MakeDeposit(initialBalance, DateTime.Now, "Initial balance");
}

DateTime.Now, geçerli tarih ve saati döndüren bir özelliktir. Main yönteyinizdeki birkaç mevdua ve çekme
bilgilerini ekleyerek bunu test edin:

account.MakeWithdrawal(500, DateTime.Now, "Rent payment");


Console.WriteLine(account.Balance);
account.MakeDeposit(100, DateTime.Now, "Friend paid me back");
Console.WriteLine(account.Balance);

Daha sonra, negatif bakiyeyle bir hesap oluşturmayı deneyerek hata koşullarını yakalama konusunda test edin:

// Test that the initial balances must be positive.


try
{
var invalidAccount = new BankAccount("invalid", -55);
}
catch (ArgumentOutOfRangeException e)
{
Console.WriteLine("Exception caught creating account with negative balance");
Console.WriteLine(e.ToString());
}

Özel durum oluşturabilecek bir kod bloğunu işaretlemek ve istediğiniz hataları yakalamak için try ve catch
deyimlerini kullanın. Negatif bir bakiye için özel durum oluşturan kodu test etmek için aynı tekniği
kullanabilirsiniz:

// Test for a negative balance.


try
{
account.MakeWithdrawal(750, DateTime.Now, "Attempt to overdraw");
}
catch (InvalidOperationException e)
{
Console.WriteLine("Exception caught trying to overdraw");
Console.WriteLine(e.ToString());
}

Dosyayı kaydedin ve denemek için dotnet run yazın.

Sınama-tüm işlemleri günlüğe kaydet


Bu öğreticiyi bitirebilmeniz için, işlem geçmişi için bir string oluşturan GetAccountHistory yöntemi yazabilirsiniz.
Bu yöntemi BankAccount türüne ekleyin:
public string GetAccountHistory()
{
var report = new System.Text.StringBuilder();

decimal balance = 0;
report.AppendLine("Date\t\tAmount\tBalance\tNote");
foreach (var item in allTransactions)
{
balance += item.Amount;
report.AppendLine($"{item.Date.ToShortDateString()}\t{item.Amount}\t{balance}\t{item.Notes}");
}

return report.ToString();
}

Bu, her işlem için bir satır içeren bir dizeyi biçimlendirmek için StringBuilder sınıfını kullanır. Bu öğreticilerde daha
önce dize biçimlendirme kodunu gördünüz. Yeni bir karakter \t . Bu, çıktıyı biçimlendirmek için bir sekme ekler.
Program.csiçinde test etmek için bu satırı ekleyin:

Console.WriteLine(account.GetAccountHistory());

Sonuçları görmek için dotnet run yazın.

Sonraki adımlar
Çıkdıysanız, Bu öğreticinin kaynağını GitHubdeponuzda görebilirsiniz.
Tebrikler, C# öğreticilere giriş yaptığımızı tamamladınız. Daha fazla bilgi edinmek istiyorsanız
öğreticilerimizideneyin.
Biçimlendirilen dizeler oluşturmak için dize
ilişkilendirmeyi kullanın
31.10.2019 • 12 minutes to read • Edit Online

Bu öğretici, tek bir sonuç dizesine C# değer eklemek için dize ilişkilendirmeyi nasıl kullanacağınızı öğretir. Kod
yazar C# ve bunları derleyip çalıştırmaya ilişkin sonuçları görürsünüz. Öğretici, bir dizeye değer ekleme ve bu
değerleri farklı şekillerde biçimlendirme işlemlerinin nasıl yapılacağını gösteren bir dizi ders içerir.
Bu öğreticide, geliştirme için kullanabileceğiniz bir makineniz olması beklenir. 10 dakika içinde Merhaba Dünya
.NET öğreticisi, Windows, Linux veya MacOS 'ta yerel geliştirme ortamınızı ayarlamaya yönelik yönergeler içerir.
Ayrıca, Bu öğreticinin etkileşimli sürümünü tarayıcınızda tamamlayabilirsiniz.

Enterpolasyonlu dize oluşturma


Enterpolasyonluadlı bir dizin oluşturun. Geçerli dizin yapın ve bir konsol penceresinden aşağıdaki komutu
çalıştırın:

dotnet new console

Bu komut geçerli dizinde yeni bir .NET Core konsol uygulaması oluşturur.
En sevdiğiniz düzenleyicide program.cs açın ve satır Console.WriteLine("Hello World!"); aşağıdaki kodla
değiştirin, burada <name> adınızla değiştirin:

var name = "<name>";


Console.WriteLine($"Hello, {name}. It's a pleasure to meet you!");

Konsol pencerenize dotnet run yazarak bu kodu deneyin. Programı çalıştırdığınızda, selamdaki adınızı içeren tek
bir dize görüntüler. WriteLine yöntemi çağrısına dahil edilen dize, bir enterpolasyonlu dize ifadesidir. Katıştırılmış
kodu içeren bir dizeden tek bir dize ( sonuç dizesiolarak adlandırılır) oluşturmanıza imkan tanıyan bir şablon
türüdür. Enterpolasyonlu dizeler, bir dizeye değer eklemek veya dizeleri birleştirmek (bir araya birleştirmek) için
özellikle faydalıdır.
Bu basit örnek, her bir enterpolasyonlu dizenin sahip olması gereken iki öğeyi içerir:
Açılış tırnak işareti karakterinden önce $ karakteriyle başlayan bir dize sabit değeri. $ simgesiyle tırnak
işareti karakteri arasında boşluk olamaz. (Bir tane eklerseniz ne olacağını görmek isterseniz, $ karakterden
sonra bir boşluk ekleyin, dosyayı kaydedin ve konsol penceresine dotnet run yazarak programı yeniden
çalıştırın. C# Derleyici bir hata iletisi görüntülüyor, "Error CS1056: beklenmeyen karakter ' $ '".)
Bir veya daha fazla ilişkilendirme ifadesi. Enterpolasyon ifadesi bir açma ve kapatma ayracı ( { ve } ) ile
belirtilir. Küme ayraçlarının içinde C# ( null dahil) bir değer döndüren herhangi bir ifadeyi
yerleştirebilirsiniz.
Biraz daha farklı veri türleriyle daha fazla dize ilişkilendirme örneği deneyelim.

Farklı veri türleri dahil et


Önceki bölümde, bir dizeyi diğerinin içine eklemek için dize ilişkilendirmeyi kullandınız. Enterpolasyon ifadesinin
sonucu herhangi bir veri türünde olabilir, ancak. Enterpolasyonlu bir dizedeki çeşitli veri türlerinin değerlerini
ekleyelim.
Aşağıdaki örnekte, ilk olarak, Object.ToString() yönteminin davranışını geçersiz kılan bir Name özelliğine ve bir
ToString yönteminesahip Vegetable bir sınıf veri türü tanımladık. public erişim değiştiricisi , bu yöntemi bir
Vegetable örneğinin dize gösterimini almak için herhangi bir istemci kodu için kullanılabilir hale getirir. Örnekte
Vegetable.ToString yöntemi Vegetable oluşturucusundabaşlatılan Name özelliğinin değerini döndürür:

public Vegetable(string name) => Name = name;

Daha sonra, new işlecini kullanarak item adlı Vegetable sınıfının bir örneğini oluşturur ve Oluşturucu Vegetable
için bir ad sağlar:

var item = new Vegetable("eggplant");

Son olarak, item değişkenini Ayrıca bir DateTime değeri, bir Decimal değeri ve Unit numaralandırma değeri
içeren bir ara değerli dizeye dahil ediyoruz. Düzenleyicinizdeki tüm C# kodu aşağıdaki kodla değiştirin ve ardından
çalıştırmak için dotnet run komutunu kullanın:

using System;

public class Vegetable


{
public Vegetable(string name) => Name = name;

public string Name { get; }

public override string ToString() => Name;


}

public class Program


{
public enum Unit { item, kilogram, gram, dozen };

public static void Main()


{
var item = new Vegetable("eggplant");
var date = DateTime.Now;
var price = 1.99m;
var unit = Unit.item;
Console.WriteLine($"On {date}, the price of {item} was {price} per {unit}.");
}
}

Enterpolasyonlu dizedeki enterpolasyon ifadesinin item , sonuç dizesinde "eggbitki" metni olarak çözümlendiğine
unutmayın. Yani, ifade sonucunun türü bir dize olmadığında, sonuç aşağıdaki şekilde bir dizeye çözülür:
Enterpolasyon ifadesi null olarak değerlendirilirse, boş bir dize ("" veya String.Empty) kullanılır.
Enterpolasyon ifadesi null olarak değerlendirilmiyorsa, genellikle sonuç türünün ToString yöntemi
çağrılır. Vegetable.ToString yönteminin uygulamasını güncelleştirerek bunu test edebilirsiniz. Her tür bu
yöntemin bir uygulaması olduğundan ToString yöntemini uygulamanız gerekmez. Bunu test etmek için
örnekteki Vegetable.ToString yönteminin tanımını (bunu yapmak için, bir açıklama simgesi koyun // ,
önüne ekleyin). Çıktıda, "eggbitki" dizesi, Object.ToString() yönteminin varsayılan davranışı olan tam nitelikli
tür adı (Bu örnekteki "Vegetable") ile değiştirilmiştir. Bir numaralandırma değeri için ToString yönteminin
varsayılan davranışı değerin dize gösterimini döndürmektir.
Bu örnekteki çıktıda, tarih çok kesin (eggbitki fiyatı her saniye değişmez) ve fiyat değeri bir para birimi göstermez.
Sonraki bölümde, ifade sonuçlarının dize temsillerini biçimini denetleyerek bu sorunları nasıl düzelteceğinizi
öğreneceksiniz.

Enterpolasyon ifadelerinin biçimlendirmesini denetleme


Önceki bölümde, sonuç dizesine hatalı biçimli iki dize eklenmiştir. Bunlardan biri, yalnızca tarihin uygun olduğu
tarih ve saat değeridir. İkincisi, para birimi birimini göstermediğiniz bir fiyattır. Her iki sorunun de kolay bir şekilde
ele alınır. Dize ilişkilendirme, belirli türlerin biçimlendirilmesini denetleyen Biçim dizelerini belirtmenize olanak
tanır. Aşağıdaki satırda gösterildiği gibi, tarih ve fiyat ifadelerinin biçim dizelerini dahil etmek için önceki örnekteki
Console.WriteLine çağrısını değiştirin:

Console.WriteLine($"On {date:d}, the price of {item} was {price:C2} per {unit}.");

Bir biçim dizesini, iki nokta üst üste (":") ve biçim dizesiyle birlikte enterpolasyon ifadesini izleyerek belirtirsiniz. "d",
kısa tarih biçimini temsil eden Standart bir tarih ve saat biçim dizesidir . "C2", ondalık ayırıcıdan sonraki iki
basamakla para birimi değeri olarak bir sayıyı temsil eden Standart bir sayısal biçim dizesidir .
.NET kitaplıklarında bulunan birçok tür, önceden tanımlanmış bir biçim dizeleri kümesini destekler.Bunlar, tüm
sayısal türleri ve Tarih ve saat türlerini içerir. Biçim dizelerini destekleyen türlerin tüm listesi için bkz. .net
makalesindeki biçimlendirme türleri ' nde Biçim dizeleri ve .NET sınıf kitaplığı türleri .
Metin düzenleyicinizdeki biçim dizelerini değiştirmeyi deneyin ve her değişiklik yaptığınızda, değişikliklerin tarih ve
saat ve sayısal değer biçimlendirmesini nasıl etkilediğini görmek için programı yeniden çalıştırın. {date:d}
içindeki "d" öğesini "t" olarak değiştirin (kısa saat biçimini göstermek için), "y" (yılı ve ayı göstermek için) ve "yyyy"
(yılı dört basamaklı bir sayı olarak göstermek için). {price:C2} içindeki "C2" öğesini "e" (üstel gösterim için) ve
"F3" (ondalık ayırıcıdan sonra üç basamaklı bir sayısal değer için) olarak değiştirin.
Biçimlendirmeyi denetlemenin yanı sıra, sonuç dizesinde bulunan biçimlendirilmiş dizelerin alan genişliğini ve
hizalamasını da denetleyebilirsiniz. Sonraki bölümde bunu nasıl yapacağınızı öğreneceksiniz.

Enterpolasyon ifadelerinin alan genişliğini ve hizalamasını denetleme


Genellikle, bir enterpolasyon ifadesinin sonucu dize olarak biçimlendirildiğinde, bu dize öndeki veya sondaki
boşluklar olmadan bir sonuç dizesine dahil edilir. Özellikle bir veri kümesiyle çalışırken, alan genişliğini
denetleyebilmekte ve metin hizalaması daha okunabilir bir çıktı oluşturulmasına yardımcı olur. Bunu görmek için,
metin düzenleyicinizdeki tüm kodu aşağıdaki kodla değiştirin ve ardından dotnet run yazarak programı yürütün:
using System;
using System.Collections.Generic;

public class Example


{
public static void Main()
{
var titles = new Dictionary<string, string>()
{
["Doyle, Arthur Conan"] = "Hound of the Baskervilles, The",
["London, Jack"] = "Call of the Wild, The",
["Shakespeare, William"] = "Tempest, The"
};

Console.WriteLine("Author and Title List");


Console.WriteLine();
Console.WriteLine($"|{"Author",-25}|{"Title",30}|");
foreach (var title in titles)
Console.WriteLine($"|{title.Key,-25}|{title.Value,30}|");
}
}

Yazarların adları sola hizalanır ve yazdığı başlıklar sağa hizalanır. Bir ilişkilendirme ifadesinden sonra bir virgül (",")
ekleyerek ve en az alan genişliğini belirterek hizalamayı belirlersiniz. Belirtilen değer pozitif bir sayıysa, alan sağa
hizalanır. Negatif bir sayı ise, alan sola hizalanır.
{"Author",-25} ve {title.Key,-25} koddan negatif işaretlerini kaldırmayı deneyin ve aşağıdaki kod olduğu gibi
örneği yeniden çalıştırın:

Console.WriteLine($"|{"Author",25}|{"Title",30}|");
foreach (var title in titles)
Console.WriteLine($"|{title.Key,25}|{title.Value,30}|");

Bu kez, yazar bilgileri sağa hizalanır.


Tek bir ilişkilendirme ifadesi için bir hizalama belirleyicisi ve biçim dizesi birleştirebilirsiniz. Bunu yapmak için önce
hizalamayı, ardından iki nokta üst üste ve biçim dizesini belirtin. Main yöntemi içindeki tüm kodu, tanımlı alan
genişlikleri olan üç biçimli dizeyi görüntüleyen aşağıdaki kodla değiştirin. Ardından dotnet run komutunu girerek
programı çalıştırın.

Console.WriteLine($"[{DateTime.Now,-20:d}] Hour [{DateTime.Now,-10:HH}] [{1063.342,15:N2}] feet");

Çıktı aşağıdakine benzer şekilde görünür:

[04/14/2018 ] Hour [16 ] [ 1,063.34] feet

Dize ilişkilendirme öğreticisini tamamladınız.


Daha fazla bilgi için bkz. dize ilişkilendirme konusu ve öğreticide dize ilişkilendirme C# .
C# 'da dize ilişkilendirme
30.10.2019 • 9 minutes to read • Edit Online

Bu öğretici, bir sonuç dizesinde ifade sonuçlarını biçimlendirmek ve dahil etmek için dize ilişkilendirmeyi nasıl
kullanacağınızı gösterir. Örneklerde temel C# kavramlar ve .net tür biçimlendirmesi hakkında bilgi sahibi
olduğunuz varsayılır. Dize ilişkilendirme veya .NET tür biçimlendirmesi için yeni bir adım kullanıyorsanız, önce
etkileşimli dize ilişkilendirme öğreticisine göz atın. .NET 'teki biçimlendirme türleri hakkında daha fazla bilgi için
bkz. .net konusundaki biçimlendirme türleri .

NOTE
Bu makalede, C# örnekleri çalıştırmak Try.NET satır içi kod Çalıştırıcısı ve oyun alanı. Seçin çalıştırma bir etkileşimli
penceresinde bir örnek çalıştırmak için düğme. Kod yürüttükten sonra değiştirmek ve seçerek değiştirilmiş kodu çalıştırmak
çalıştırma yeniden. Değiştirilmiş ya da çalıştırmalarını etkileşimli pencerede kod ya da derleme başarısız olursa, tüm C#
Derleyici hata iletilerini etkileşimli pencere görüntüler.

Giriş
Dize ilişkilendirme özelliği, Bileşik biçimlendirme özelliğinin üzerine kurulmuştur ve biçimlendirilmiş ifade
sonuçlarının bir sonuç dizesinde yer almasını sağlayan daha okunabilir ve uygun bir sözdizimi sağlar.
Bir dize sabit değerini, enterpolasyonlu bir dize olarak tanımlamak için $ simgesiyle önüne ekleyin.
Enterpolasyonlu bir C# dizede değer döndüren herhangi bir geçerli ifadeyi gömebilirsiniz. Aşağıdaki örnekte, bir
ifade değerlendirildiği anda, sonucu bir dizeye dönüştürülür ve sonuç dizesine dahil edilir:

double a = 3;
double b = 4;
Console.WriteLine($"Area of the right triangle with legs of {a} and {b} is {0.5 * a * b}");
Console.WriteLine($"Length of the hypotenuse of the right triangle with legs of {a} and {b} is
{CalculateHypotenuse(a, b)}");

double CalculateHypotenuse(double leg1, double leg2) => Math.Sqrt(leg1 * leg1 + leg2 * leg2);

// Expected output:
// Area of the right triangle with legs of 3 and 4 is 6
// Length of the hypotenuse of the right triangle with legs of 3 and 4 is 5

Örnekte gösterildiği gibi, araya alınmış dizeye bir ifadeyi küme ayraçları ile çevreleyerek dahil edersiniz:

{<interpolationExpression>}

Enterpolasyonlu dizeler, dize bileşik biçimlendirme özelliğinin tüm yeteneklerini destekler. Bu, String.Format
yönteminin kullanımına daha okunabilir bir alternatif sağlar.

İlişkilendirme ifadesi için biçim dizesi belirtme


İki nokta üst üste (":") ve biçim dizesiyle ilişkilendirme ifadesini izleyerek, ifade sonucunun türü tarafından
desteklenen bir biçim dizesi belirtirsiniz:

{<interpolationExpression>:<formatString>}
Aşağıdaki örnek, tarih ve saat veya sayısal sonuçlar üreten ifadeler için standart ve özel biçim dizelerinin nasıl
kullanılacağını gösterir:

var date = new DateTime(1731, 11, 25);


Console.WriteLine($"On {date:dddd, MMMM dd, yyyy} Leonhard Euler introduced the letter e to denote
{Math.E:F5} in a letter to Christian Goldbach.");

// Expected output:
// On Sunday, November 25, 1731 Leonhard Euler introduced the letter e to denote 2.71828 in a letter to
Christian Goldbach.

Daha fazla bilgi için Bileşik biçimlendirme konusunun Biçim dizesi bileşeni bölümüne bakın. Bu bölüm, .NET
temel türleri tarafından desteklenen standart ve özel biçim dizelerini tanımlayan konulara bağlantılar sağlar.

Biçimlendirilen enterpolasyon ifadesinin alan genişliğini ve hizalamasını


denetleme
Bir virgül (",") ve sabit ifade ile ilişkilendirme ifadesini izleyerek, biçimlendirilen ifade sonucunun en düşük alan
genişliğini ve hizalamasını belirtirsiniz:

{<interpolationExpression>,<alignment>}

Hizalama değeri pozitifse, biçimlendirilen ifade sonucu sağa hizalanır; negatifse, sola hizalanır.
Hem hizalama hem de bir biçim dizesi belirtmeniz gerekiyorsa, hizalama bileşeniyle başlayın:

{<interpolationExpression>,<alignment>:<formatString>}

Aşağıdaki örnek, hizalama belirtme ve metin alanlarını sınırlandırmak için kanal karakterlerinin ("|") nasıl
kullanılacağını gösterir:

const int NameAlignment = -9;


const int ValueAlignment = 7;

double a = 3;
double b = 4;
Console.WriteLine($"Three classical Pythagorean means of {a} and {b}:");
Console.WriteLine($"|{"Arithmetic",NameAlignment}|{0.5 * (a + b),ValueAlignment:F3}|");
Console.WriteLine($"|{"Geometric",NameAlignment}|{Math.Sqrt(a * b),ValueAlignment:F3}|");
Console.WriteLine($"|{"Harmonic",NameAlignment}|{2 / (1 / a + 1 / b),ValueAlignment:F3}|");

// Expected output:
// Three classical Pythagorean means of 3 and 4:
// |Arithmetic| 3.500|
// |Geometric| 3.464|
// |Harmonic | 3.429|

Örnek çıktıda gösterildiği gibi, biçimlendirilen ifade sonucunun uzunluğu belirtilen alan genişliğini aşarsa,
Hizalama değeri yok sayılır.
Daha fazla bilgi için Bileşik biçimlendirme konusunun Hizalama bileşeni bölümüne bakın.

Enterpolasyonlu bir dizede kaçış dizileri kullanma


Enterpolasyonlu dizeler, normal dize değişmez değerlerinde kullanılabilen tüm kaçış dizilerini destekler.Daha fazla
bilgi için bkz. dize kaçış dizileri.
Kaçış dizilerini bire bir yorumlamak için, tam bir dize sabiti kullanın. Enterpolasyonlu bir dize $ karakteriyle
başlar ve ardından @ karakteri gelir. 8,0 ile C# başlayarak, $ ve @ belirteçlerini dilediğiniz sırada kullanabilirsiniz:
her iki $@"..." ve @$"..." geçerli bir ara değerli dizelerdir.
Bir küme ayracı eklemek için, "{" veya "}", bir sonuç dizesinde, "{{" veya "}}" iki küme ayracı kullanın. Daha fazla
bilgi için Bileşik biçimlendirme konusunun kaçış ayraçları bölümüne bakın.
Aşağıdaki örnek, bir sonuç dizesinde küme ayracın nasıl ekleneceğini ve tam bir enterpolasyonlu dize nasıl
oluşturulacağını gösterir:

var xs = new int[] { 1, 2, 7, 9 };


var ys = new int[] { 7, 9, 12 };
Console.WriteLine($"Find the intersection of the {{{string.Join(", ",xs)}}} and {{{string.Join(", ",ys)}}}
sets.");

var userName = "Jane";


var stringWithEscapes = $"C:\\Users\\{userName}\\Documents";
var verbatimInterpolated = $@"C:\Users\{userName}\Documents";
Console.WriteLine(stringWithEscapes);
Console.WriteLine(verbatimInterpolated);

// Expected output:
// Find the intersection of the {1, 2, 7, 9} and {7, 9, 12} sets.
// C:\Users\Jane\Documents
// C:\Users\Jane\Documents

Enterpolasyon ifadesinde Üçlü koşullu işleç ?: kullanma


İki nokta üst üste (":") enterpolasyon ifadesi içeren bir öğe için özel anlam içerdiğinden, bir ifadede koşullu bir
işleç kullanmak için aşağıdaki örnekte gösterildiği gibi, parantez içine alın:

var rand = new Random();


for (int i = 0; i < 7; i++)
{
Console.WriteLine($"Coin flip: {(rand.NextDouble() < 0.5 ? "heads" : "tails")}");
}

Dize ilişkilendirme ile kültüre özgü sonuç dizesi oluşturma


Varsayılan olarak, bir enterpolasyonlu dize, tüm biçimlendirme işlemleri için CultureInfo.CurrentCulture özelliği
tarafından tanımlanan geçerli kültürü kullanır. Bir System.FormattableString örneğine enterpolasyonlu bir dizenin
örtük dönüşümünü kullanın ve kültüre özgü bir sonuç dizesi oluşturmak için ToString(IFormatProvider)
metodunu çağırın. Aşağıdaki örnek bunun nasıl yapılacağını göstermektedir:
var cultures = new System.Globalization.CultureInfo[]
{
System.Globalization.CultureInfo.GetCultureInfo("en-US"),
System.Globalization.CultureInfo.GetCultureInfo("en-GB"),
System.Globalization.CultureInfo.GetCultureInfo("nl-NL"),
System.Globalization.CultureInfo.InvariantCulture
};

var date = DateTime.Now;


var number = 31_415_926.536;
FormattableString message = $"{date,20}{number,20:N3}";
foreach (var culture in cultures)
{
var cultureSpecificMessage = message.ToString(culture);
Console.WriteLine($"{culture.Name,-10}{cultureSpecificMessage}");
}

// Expected output is like:


// en-US 5/17/18 3:44:55 PM 31,415,926.536
// en-GB 17/05/2018 15:44:55 31,415,926.536
// nl-NL 17-05-18 15:44:55 31.415.926,536
// 05/17/2018 15:44:55 31,415,926.536

Örnekte gösterildiği gibi, çeşitli kültürler için birden çok sonuç dizesi oluşturmak üzere bir FormattableString
örneğini kullanabilirsiniz.

Sabit kültür kullanarak sonuç dizesi oluşturma


FormattableString.ToString(IFormatProvider) yöntemiyle birlikte, InvariantCultureiçin bir sonuç dizesine bir ara
değerli dizeyi çözümlemek üzere statik FormattableString.Invariant yöntemini kullanabilirsiniz. Aşağıdaki örnek
bunun nasıl yapılacağını göstermektedir:

string messageInInvariantCulture = FormattableString.Invariant($"Date and time in invariant culture:


{DateTime.Now}");
Console.WriteLine(messageInInvariantCulture);

// Expected output is like:


// Date and time in invariant culture: 05/17/2018 15:46:24

Sonuç
Bu öğreticide, dize ilişkilendirme kullanımının yaygın senaryoları açıklanmaktadır. Dize ilişkilendirme hakkında
daha fazla bilgi için bkz. dize ilişkilendirme konusu. .NET 'teki biçimlendirme türleri hakkında daha fazla bilgi için
bkz. .NET ve Bileşik biçimlendirme konularında biçimlendirme türleri .

Ayrıca bkz.
String.Format
System.FormattableString
System.IFormattable
Dizeler
Öğretici: 8,0 içinde C# varsayılan arabirim
yöntemleriyle arabirimleri güncelleştirme
30.10.2019 • 9 minutes to read • Edit Online

.NET Core C# 3,0 ' de 8,0 ' den başlayarak, bir arabirimin üyesini bildirdiğinizde bir uygulama tanımlayabilirsiniz.
En yaygın senaryo, önceden yayınlanan ve kullanılmayan istemciler tarafından kullanılan bir arabirime güvenli bir
şekilde üye eklemektir.
Bu öğreticide, aşağıdakileri nasıl yapacağınızı öğreneceksiniz:
Uygulamalarla yöntemler ekleyerek arabirimleri güvenli bir şekilde genişletin.
Daha fazla esneklik sağlamak için parametreli uygulamalar oluşturun.
Bir geçersiz kılma biçiminde daha belirli bir uygulama sağlamak için uygulayıcıları etkinleştirin.

Prerequisites
Makinenizi, C# 8,0 derleyicisi dahil .NET Core çalıştıracak şekilde ayarlamanız gerekir. 8,0 C# derleyicisi, Visual
Studio 2019 sürüm 16,3 veya .NET Core 3,0 SDKile başlayarak kullanılabilir.

Senaryoya genel bakış


Bu öğretici, bir müşteri ilişkisi kitaplığının 1. sürümüyle başlar. GitHub 'daki örnekdepolarımızda başlangıç
uygulamasını edinebilirsiniz. Bu kitaplığın, kütüphanesini benimsemesini sağlayan, mevcut uygulamalarla
müşterileri hedefleyen Şirket. Bunlar, kütüphanesinin kullanıcıları için en az sayıda arabirim tanımı sağladık.
Müşterinin arabirim tanımı aşağıda verilmiştir:

public interface ICustomer


{
IEnumerable<IOrder> PreviousOrders { get; }

DateTime DateJoined { get; }


DateTime? LastOrder { get; }
string Name { get; }
IDictionary<DateTime, string> Reminders { get; }
}

Sıralamayı temsil eden ikinci bir arabirim tanımlarlar:

public interface IOrder


{
DateTime Purchased { get; }
decimal Cost { get; }
}

Bu arabirimlerde, takım kullanıcılarına müşterilerine daha iyi bir deneyim oluşturmak için bir kitaplık oluşturabilir.
Bu kişilerin hedefi, mevcut müşterilerle daha derin bir ilişki oluşturmak ve yeni müşterilerle ilişkilerini geliştirmektir.
Şimdi, bir sonraki sürüm için kitaplığı yükseltmeniz zaman atalım. İstenen özelliklerden biri, çok sayıda siparişi olan
müşteriler için bağlılık programı indirimi sunar. Bu yeni bağlılık programı indirimi, bir müşteri sipariş yaptığında
uygulanır. Belirli indirim, her müşterinin bir özelliğidir. ICustomer her bir uygulama, bağlılık programı indirimi için
farklı kurallar ayarlayabilir.
Bu işlevi eklemenin en doğal yolu, ICustomer arabirimini tüm bağlılık programı indirimine uygulanacak bir
yöntemle geliştirmektir. Bu tasarım önerisi, deneyimli geliştiriciler arasında sorun oluşmasına neden oldu:
"arabirimler yayımlandıklarında sabittir! Bu bir son değişiklik! " C#8,0, arabirimleri yükseltmek için varsayılan
arabirim uygulamalarını ekler. Kitaplık yazarları arabirime yeni üyeler ekleyebilir ve bu üyeler için varsayılan bir
uygulama sağlar.
Varsayılan arabirim uygulamaları, geliştiricilerin bu uygulamayı geçersiz kılmak için herhangi bir uygulamayı
etkinleştirirken bir arabirimi yükseltmesini sağlar. Kitaplığın kullanıcıları, varsayılan uygulamayı kırılmamış bir
değişiklik olarak kabul edebilir. İş kuralları farklıysa, geçersiz kılınabilir.

Varsayılan arabirim yöntemleriyle yükselt


Takım, en olası varsayılan uygulamada anlaşmıştır: müşteriler için bağlılık programı indirimi.
Yükseltme, iki özellik ayarlama işlevini sağlamalıdır: indirimle uygun olması gereken siparişlerin sayısı ve indirimin
yüzdesi. Bu, varsayılan arabirim yöntemlerine yönelik kusursuz bir senaryo sağlar. ICustomer arabirimine bir
yöntem ekleyebilir ve en olası uygulamayı sağlayabilirsiniz. Tüm mevcut ve tüm yeni uygulamalar varsayılan
uygulamayı kullanabilir veya kendi özelliklerini sağlayabilir.
Önce, uygulamaya yeni yöntemi ekleyin:

// Version 1:
public decimal ComputeLoyaltyDiscount()
{
DateTime TwoYearsAgo = DateTime.Now.AddYears(-2);
if ((DateJoined < TwoYearsAgo) && (PreviousOrders.Count() > 10))
{
return 0.10m;
}
return 0;
}

Kitaplık yazarı, uygulamayı denetlemek için bir ilk test yazdı:

SampleCustomer c = new SampleCustomer("customer one", new DateTime(2010, 5, 31))


{
Reminders =
{
{ new DateTime(2010, 08, 12), "childs's birthday" },
{ new DateTime(1012, 11, 15), "anniversary" }
}
};

SampleOrder o = new SampleOrder(new DateTime(2012, 6, 1), 5m);


c.AddOrder(o);

o = new SampleOrder(new DateTime(2103, 7, 4), 25m);


c.AddOrder(o);

// Check the discount:


ICustomer theCustomer = c;
Console.WriteLine($"Current discount: {theCustomer.ComputeLoyaltyDiscount()}");

Testin aşağıdaki kısmına dikkat edin:

// Check the discount:


ICustomer theCustomer = c;
Console.WriteLine($"Current discount: {theCustomer.ComputeLoyaltyDiscount()}");
Bu SampleCustomer ICustomer olarak dönüştürme gereklidir. SampleCustomer sınıfın ComputeLoyaltyDiscount için
bir uygulama sağlaması gerekmez; Bu, ICustomer arabirimi tarafından sunulur. Ancak SampleCustomer sınıfı,
arabirimlerinden üyeleri almıyor. Bu kural değiştirilmedi. Arabirimde bildirildiği ve uygulanan herhangi bir yöntemi
çağırmak için, bu örnekte, değişken arabirimin türü, ICustomer olmalıdır.

Parametreleştirme sağlama
Bu iyi bir başlangıç. Ancak, varsayılan uygulama çok kısıtlayıcıdır. Bu sistemin pek çok tüketicisi, satın alma sayısı,
farklı üyelik uzunluğu veya farklı bir yüzde indirimi için farklı eşikler seçebilirler. Bu parametreleri ayarlamak için bir
yol sağlayarak daha fazla müşteri için daha iyi bir yükseltme deneyimi sağlayabilirsiniz. Varsayılan uygulamayı
denetleyen bu üç parametreyi ayarlayan statik bir yöntem ekleyelim:

// Version 2:
public static void SetLoyaltyThresholds(
TimeSpan ago,
int minimumOrders = 10,
decimal percentageDiscount = 0.10m)
{
length = ago;
orderCount = minimumOrders;
discountPercent = percentageDiscount;
}
private static TimeSpan length = new TimeSpan(365 * 2, 0,0,0); // two years
private static int orderCount = 10;
private static decimal discountPercent = 0.10m;

public decimal ComputeLoyaltyDiscount()


{
DateTime start = DateTime.Now - length;

if ((DateJoined < start) && (PreviousOrders.Count() > orderCount))


{
return discountPercent;
}
return 0;
}

Bu küçük kod parçasında gösterilen birçok yeni dil özelliği vardır. Arabirimler artık alanlar ve yöntemler dahil statik
üyeleri içerebilir. Farklı erişim değiştiricileri de etkinleştirilir. Ek alanlar özeldir, yeni yöntem geneldir.Arabirim
üyelerinde değiştiricilerin herhangi birine izin verilir.
Bağlılık programı iskontosunu hesaplamak için genel formülü kullanan uygulamalar, ancak farklı parametreler, özel
bir uygulama sağlanması gerekmez; bağımsız değişkenleri statik bir yöntem aracılığıyla ayarlayabilirler. Örneğin,
aşağıdaki kod, birden fazla aya ait üyeliğe sahip herhangi bir müşteriyi yeniden karşılayan bir "müşteri değer
artırma" ayarlıyor:

ICustomer.SetLoyaltyThresholds(new TimeSpan(30, 0, 0, 0), 1, 0.25m);


Console.WriteLine($"Current discount: {theCustomer.ComputeLoyaltyDiscount()}");

Varsayılan uygulamayı genişletme


Şimdiye kadar eklemiş olduğunuz kod, kullanıcıların varsayılan uygulama gibi bir şey istediği veya ilgisiz bir kural
kümesi sağladığı senaryolar için uygun bir uygulama sağladı. Son bir özellik için, kullanıcıların varsayılan
uygulamada derlemek isteyebileceğiniz senaryolara olanak tanımak için kodu bir bit yeniden düzenleyin.
Yeni müşterileri çekmek isteyen bir başlatma düşünün. Yeni bir müşterinin ilk siparişi için %50 indirim sağlar. Aksi
halde, mevcut müşteriler standart iskontoyu alır. Kitaplık yazarının varsayılan uygulamayı bir protected static
yöntemine taşıması gerekir; böylece bu arabirimi uygulayan herhangi bir sınıf kendi uygulamalarında kodu
yeniden kullanabilir. Arabirim üyesinin varsayılan uygulanması, bu paylaşılan yöntemi de çağırır:

public decimal ComputeLoyaltyDiscount() => DefaultLoyaltyDiscount(this);


protected static decimal DefaultLoyaltyDiscount(ICustomer c)
{
DateTime start = DateTime.Now - length;

if ((c.DateJoined < start) && (c.PreviousOrders.Count() > orderCount))


{
return discountPercent;
}
return 0;
}

Bu arabirimi uygulayan bir sınıfın uygulamasında, geçersiz kılma statik yardımcı yöntemini çağırabilir ve "yeni
müşteri" indirimi sağlamak için bu mantığı genişletebilir:

public decimal ComputeLoyaltyDiscount()


{
if (PreviousOrders.Any() == false)
return 0.50m;
else
return ICustomer.DefaultLoyaltyDiscount(this);
}

Tüm tamamlanmış kodu GitHub 'daki örnekdepoımızda görebilirsiniz. GitHub 'daki örnekdepolarımızda başlangıç
uygulamasını edinebilirsiniz.
Bu yeni özellikler, bu yeni üyeler için makul bir varsayılan uygulama olduğunda arabirimlerin güvenli bir şekilde
güncelleştirilemeyeceği anlamına gelir. Birden çok sınıf tarafından uygulanabilen tek işlevsel fikirlerin hızlı bir
şekilde tasarlanması. Bu, aynı işlevsel fikir için yeni gereksinimler bulunduğunda bu arabirim tanımlarını
yükseltmeyi kolaylaştırır.
Öğretici: varsayılan arabirim yöntemleriyle
arabirimleri kullanarak sınıf oluştururken içindeki
işlevselliği karıştırma
25.11.2019 • 13 minutes to read • Edit Online

.NET Core C# 3,0 ' de 8,0 ' den başlayarak, bir arabirimin üyesini bildirdiğinizde bir uygulama tanımlayabilirsiniz.
Bu özellik, arabirimlerde belirtilen özellikler için varsayılan uygulamaları tanımlayabileceğiniz yeni yetenekler
sağlar. Sınıflar işlevin ne zaman geçersiz kılınacağını, varsayılan işlevselliğin ne zaman kullanılacağını ve ayrık
özellikler için ne zaman destek bildirelemeyeceğini seçebilir.
Bu öğreticide, aşağıdakileri nasıl yapacağınızı öğreneceksiniz:
Ayrık özellikleri tanımlayan uygulamalarla arabirim oluşturun.
Varsayılan uygulamaları kullanan sınıflar oluşturun.
Varsayılan uygulamaların bazılarını veya tümünü geçersiz kılan sınıflar oluşturun.

Prerequisites
Makinenizi, C# 8,0 derleyicisi dahil .NET Core çalıştıracak şekilde ayarlamanız gerekir. C# 8,0 derleyicisi, Visual
Studio 2019, 16,3veya .NET Core 3,0 SDK veya sonraki sürümleriyle başlayarak kullanılabilir.

Uzantı yöntemlerinin sınırlamaları


Bir arabirimin parçası olarak görünen davranışı uygulayabileceğiniz yollardan biri, varsayılan davranışı sağlayan
Uzantı yöntemlerini tanımlamaktır. Arabirimler, bu arabirimi uygulayan her sınıf için daha büyük bir yüzey alanı
sağlarken, minimum üye kümesini bildirir. Örneğin, Enumerable uzantı yöntemleri herhangi bir dizinin bir LINQ
sorgusunun kaynağı olması için uygulama sağlar.
Uzantı yöntemleri, değişkenin belirtilen türü kullanılarak derleme zamanında çözümlenir. Arabirimini uygulayan
sınıflar, herhangi bir genişletme yöntemi için daha iyi bir uygulama sağlayabilir. Derleyicinin bu uygulamayı
seçmesini sağlamak için değişken bildirimlerinin uygulama türüyle eşleşmesi gerekir. Derleme zamanı türü
arabirimiyle eşleştiğinde, Yöntem çağrıları uzantı yöntemine çözümlenir. Uzantı yöntemleriyle ilgili başka bir sorun
da bu yöntemlere uzantı yöntemlerini içeren sınıfın erişilebilir olduğu her yerde erişilebilir. Sınıflar, uzantı
yöntemlerinde belirtilen özellikleri sağlamalıdır veya sağlamamaları gerekip gerekmediğini bildiremez.
8,0 ' C# den başlayarak, varsayılan uygulamaları arabirim yöntemleri olarak bildirebilirsiniz. Ardından, her sınıf
otomatik olarak varsayılan uygulamayı kullanır. Daha iyi bir uygulama sağlayabilen herhangi bir sınıf arabirim
yöntemi tanımını daha iyi bir algoritmayla geçersiz kılabilir. Bu teknik, tek bir anlamda, Uzantı yöntemlerininasıl
kullanabileceğiniz ile benzer şekilde ses olarak da kullanabilir.
Bu makalede, varsayılan arabirim uygulamalarının yeni senaryoları nasıl etkinleştirdiklerini öğreneceksiniz.

Uygulamayı tasarlama
Bir giriş otomasyon uygulaması düşünün. Belki de şirket genelinde kullanılabilecek birçok farklı ışık ve gösterge
türü vardır. Her ışığın açıp kapatmak ve geçerli durumu raporlamak için API 'Leri desteklemesi gerekir. Bazı ışıklar
ve göstergeler, gibi diğer özellikleri destekleyebilir:
Işığı açın, sonra bir zamanlayıcının ardından devre dışı bırakın.
Bir süre için ışığı yanıp söndürme.
Bu genişletilmiş yeteneklerin bazıları, en az kümeyi destekleyen cihazlarda öykünüyolabilir. Bu, varsayılan bir
uygulama sağlamayı gösterir. İçinde daha fazla özelliğe yerleşik olan cihazlar için, cihaz yazılımı yerel özellikleri
kullanır. Diğer ışıklar için, arabirimi uygulamayı ve varsayılan uygulamayı kullanmayı seçebilirler.
Varsayılan arabirim üyeleri bu senaryoya uzantı yöntemlerinden daha iyi bir çözümdür. Sınıf yazarları, hangi
arabirimlerin uygulanacağını seçebilecekleri denetleyebilir. Tercih ettikleri arabirimler yöntemler olarak kullanılabilir.
Ek olarak, varsayılan arabirim yöntemleri varsayılan olarak sanal olduğundan, yöntemi dağıtım her zaman
sınıfındaki uygulamayı seçer.
Bu farklılıkları göstermek için kodu oluşturalım.

Arabirim oluşturma
Tüm ışıklarının davranışını tanımlayan arabirimi oluşturarak başlayın:

public interface ILight


{
void SwitchOn();
void SwitchOff();
bool IsOn();
}

Temel bir ek yük hafif armakodu, aşağıdaki kodda gösterildiği gibi bu arabirimi uygulayabilir:

public class OverheadLight : ILight


{
private bool isOn;
public bool IsOn() => isOn;
public void SwitchOff() => isOn = false;
public void SwitchOn() => isOn = true;

public override string ToString() => $"The light is {isOn: \"on\", \"off\"}";

Bu öğreticide, kod IoT cihazlarını sürücüden almaz, ancak konsola ileti yazarak bu etkinliklere öykünür. Evinizi
otomatikleştirmeden kodu keşfedebilirsiniz.
Daha sonra, bir zaman aşımından sonra otomatik olarak kapatıbir ışığın arabirimini tanımlayalim:

public interface ITimerLight : ILight


{
Task TurnOnFor(int duration);
}

Ek yük ışığıyla temel bir uygulama ekleyebilirsiniz, ancak daha iyi bir çözüm, bu arabirim tanımını virtual
varsayılan bir uygulama sağlamak üzere değiştirmektir:
public interface ITimerLight : ILight
{
public async Task TurnOnFor(int duration)
{
Console.WriteLine("Using the default interface method for the ITimerLight.TurnOnFor.");
SwitchOn();
await Task.Delay(duration);
SwitchOff();
Console.WriteLine("Completed ITimerLight.TurnOnFor sequence.");
}
}

Bu değişikliği ekleyerek OverheadLight sınıfı, arabirim için destek bildirerek Zamanlayıcı işlevini uygulayabilir:

public class OverheadLight : ITimerLight { }

Farklı bir ışık türü, daha karmaşık bir protokolü destekleyebilir. Aşağıdaki kodda gösterildiği gibi, TurnOnFor için
kendi uygulamasını sağlayabilir:

public class HalogenLight : ITimerLight


{
private enum HalogenLightState
{
Off,
On,
TimerModeOn
}

private HalogenLightState state;


public void SwitchOn() => state = HalogenLightState.On;
public void SwitchOff() => state = HalogenLightState.Off;
public bool IsOn() => state != HalogenLightState.Off;
public async Task TurnOnFor(int duration)
{
Console.WriteLine("Halogen light starting timer function.");
state = HalogenLightState.TimerModeOn;
await Task.Delay(duration);
state = HalogenLightState.Off;
Console.WriteLine("Halogen light finished custom timer function");
}

public override string ToString() => $"The light is {state}";


}

Sanal Sınıf yöntemlerinin geçersiz kılınmasından farklı olarak, HalogenLight sınıfındaki TurnOnFor bildirimi
override anahtar sözcüğünü kullanmaz.

Karıştırma ve eşleştirme özellikleri


Daha gelişmiş özellikleri tanıtdığınızda varsayılan arabirim yöntemlerinin avantajları daha net hale gelir.
Arabirimleri kullanmak, özellikleri karıştırmanızı ve eşleştirmeye olanak sağlar. Ayrıca, her sınıf yazarının varsayılan
uygulama ve özel bir uygulama arasında seçim yapmasına olanak sağlar. Yanıp sönen bir ışık için varsayılan
uygulamayla bir arabirim ekleyelim:
public interface IBlinkingLight : ILight
{
public async Task Blink(int duration, int repeatCount)
{
Console.WriteLine("Using the default interface method for IBlinkingLight.Blink.");
for (int count = 0; count < repeatCount; count++)
{
SwitchOn();
await Task.Delay(duration);
SwitchOff();
await Task.Delay(duration);
}
Console.WriteLine("Done with the default interface method for IBlinkingLight.Blink.");
}
}

Varsayılan uygulama herhangi bir ışığın yanıp sönmesini sağlar. Ek yük ışığı, varsayılan uygulamayı kullanarak hem
Zamanlayıcı hem de yanıp sönme özellikleri ekleyebilir:

public class OverheadLight : ILight, ITimerLight, IBlinkingLight


{
private bool isOn;
public bool IsOn() => isOn;
public void SwitchOff() => isOn = false;
public void SwitchOn() => isOn = true;

public override string ToString() => $"The light is {isOn: \"on\", \"off\"}";
}

Yeni bir hafif türü, LEDLight doğrudan Zamanlayıcı işlevini ve BLINK işlevini destekler. Bu ışık stili hem
ITimerLight hem IBlinkingLight arabirimlerini uygular ve Blink yöntemini geçersiz kılar:

public class LEDLight : IBlinkingLight, ITimerLight, ILight


{
private bool isOn;
public void SwitchOn() => isOn = true;
public void SwitchOff() => isOn = false;
public bool IsOn() => isOn;
public async Task Blink(int duration, int repeatCount)
{
Console.WriteLine("LED Light starting the Blink function.");
await Task.Delay(duration * repeatCount);
Console.WriteLine("LED Light has finished the Blink funtion.");
}

public override string ToString() => $"The light is {isOn: \"on\", \"off\"}";
}

Bir ExtraFancyLight doğrudan yanıp sönme ve Zamanlayıcı işlevlerini destekleyebilir:


public class ExtraFancyLight : IBlinkingLight, ITimerLight, ILight
{
private bool isOn;
public void SwitchOn() => isOn = true;
public void SwitchOff() => isOn = false;
public bool IsOn() => isOn;
public async Task Blink(int duration, int repeatCount)
{
Console.WriteLine("Extra Fancy Light starting the Blink function.");
await Task.Delay(duration * repeatCount);
Console.WriteLine("Extra Fancy Light has finished the Blink funtion.");
}
public async Task TurnOnFor(int duration)
{
Console.WriteLine("Extra Fancy light starting timer function.");
await Task.Delay(duration);
Console.WriteLine("Extra Fancy light finished custom timer function");
}

public override string ToString() => $"The light is {isOn: \"on\", \"off\"}";
}

Daha önce oluşturduğunuz HalogenLight yanıp sönmesini desteklemez. Bu nedenle, IBlinkingLight desteklenen
arabirimlerinin listesine eklemeyin.

Model eşleştirmeyi kullanarak ışık türlerini Algıla


Daha sonra bazı test kodu yazalım. Desteklediği arabirimleri inceleyerek ışığın yeteneklerini C#tespit etmek için,
model eşleme özelliğinden yararlanabilirsiniz. Aşağıdaki yöntem her bir ışığın desteklenen yeteneklerini
alıştırmaları:

private static async Task TestLightCapabilities(ILight light)


{
// Perform basic tests:
light.SwitchOn();
Console.WriteLine($"\tAfter switching on, the light is {(light.IsOn() ? "on" : "off")}");
light.SwitchOff();
Console.WriteLine($"\tAfter switching off, the light is {(light.IsOn() ? "on" : "off")}");

if (light is ITimerLight timer)


{
Console.WriteLine("\tTesting timer function");
await timer.TurnOnFor(1000);
Console.WriteLine("\tTimer function completed");
}
else
{
Console.WriteLine("\tTimer function not supported.");
}

if (light is IBlinkingLight blinker)


{
Console.WriteLine("\tTesting blinking function");
await blinker.Blink(500, 5);
Console.WriteLine("\tBlink function completed");
}
else
{
Console.WriteLine("\tBlink function not supported.");
}
}
Main yönteminizin aşağıdaki kodu, her ışık türünü sırayla oluşturur ve bu ışığı sınar:

static async Task Main(string[] args)


{
Console.WriteLine("Testing the overhead light");
var overhead = new OverheadLight();
await TestLightCapabilities(overhead);
Console.WriteLine();

Console.WriteLine("Testing the halogen light");


var halogen = new HalogenLight();
await TestLightCapabilities(halogen);
Console.WriteLine();

Console.WriteLine("Testing the LED light");


var led = new LEDLight();
await TestLightCapabilities(led);
Console.WriteLine();

Console.WriteLine("Testing the fancy light");


var fancy = new ExtraFancyLight();
await TestLightCapabilities(fancy);
Console.WriteLine();
}

Derleyicinin en iyi uygulamayı nasıl belirlediği


Bu senaryo, herhangi bir uygulama olmadan temel bir arabirim gösterir. ILight arabirimine bir yöntemi eklemek
yeni karmaşıklıkları tanıtır. Varsayılan arabirim yöntemlerini yöneten dil kuralları, birden fazla türetilmiş arabirimi
uygulayan somut sınıflarda etkiyi en aza indirir. Bunun nasıl kullanıldığını göstermek için yeni bir yöntemi olan
özgün arabirimi geliştirelim. Her gösterge ışığı, güç durumunu numaralandırılmış bir değer olarak rapor edebilir:

public enum PowerStatus


{
NoPower,
ACPower,
FullBattery,
MidBattery,
LowBattery
}

Varsayılan uygulama AC gücünü varsayar:

public interface ILight


{
void SwitchOn();
void SwitchOff();
bool IsOn();
public PowerStatus Power() => PowerStatus.NoPower;
}

Bu değişiklikler, ExtraFancyLight ILight arabirimi ve hem türetilmiş arabirimler, ITimerLight ve IBlinkingLight


için destek bildirse de düzgün şekilde derlenir. ILight arabiriminde belirtilen yalnızca bir "en yakın" uygulama
vardır. Bir geçersiz kılma belirten herhangi bir sınıf "en yakın" uygulama haline gelir. Diğer türetilmiş arabirimlerin
üyelerini içeren önceki sınıflarda örnekleri gördünüz.
Birden çok türetilmiş arabirimde aynı yöntemi geçersiz kılmaktan kaçının. Bunun yapılması, bir sınıf hem türetilmiş
arabirimleri her uygularsa belirsiz bir yöntem çağrısı oluşturur. Derleyici bir hata verecek şekilde tek bir daha iyi
yöntem seçemiyor. Örneğin, hem IBlinkingLight hem de ITimerLight PowerStatus bir geçersiz kılma
uyguladıysanız, OverheadLight daha belirli bir geçersiz kılma sağlaması gerekir. Aksi halde, derleyici iki türetilmiş
arabirimde uygulamalar arasında seçim yapamıyor. Bu durum genellikle, arabirim tanımlarını küçük tutarak tek bir
özelliğe odaklanarak önleyebilirsiniz. Bu senaryoda, bir ışığın her özelliği kendi arayüzüdür; birden çok arabirim
yalnızca sınıflar tarafından devralınır.
Bu örnekte, sınıflara karışabilir ayrık Özellikler tanımlayabileceğiniz bir senaryo gösterilmektedir. Bir sınıfın
desteklediği arabirimleri bildirerek, desteklenen herhangi bir işlev kümesini bildirirsiniz. Sanal varsayılan arabirim
yöntemlerinin kullanımı, sınıfların herhangi bir veya tüm arabirim yöntemleri için farklı bir uygulama kullanmasını
sağlar veya tanımlar. Bu dil özelliği, oluşturmakta olduğunuz gerçek dünya sistemlerini modellemek için yeni yollar
sağlar. Varsayılan arabirim yöntemleri, bu özelliklerin sanal uygulamalarını kullanarak farklı özelliklerle
karıştırabilecek ve eşleşebilecek ilgili sınıfları hızlı bir şekilde ifade etmenin daha net bir yolunu sağlar.
Dizinler ve aralıklar
30.10.2019 • 6 minutes to read • Edit Online

Aralıklar ve dizinler, bir dizideki tek öğe veya aralıklara erişmek için bir kısa sözdizimi sağlar.
Bu öğreticide, aşağıdakileri nasıl yapacağınızı öğreneceksiniz:
Bir dizideki aralıklar için söz dizimini kullanın.
Her bir sıranın başlangıcı ve bitişi için tasarım kararlarını anlayın.
Index ve Range türleri için senaryolar öğrenin.

Dizinler ve aralıklar için dil desteği


Bu dil desteği iki yeni türe ve iki yeni işleçlere dayanır:
System.Index bir dizinin bir dizinini temsil eder.
Bitiş işlecinden Dizin ^ , bir dizinin bir dizinin sonuna göre olduğunu belirtir.
System.Range bir dizinin alt aralığını temsil eder.
Aralık işleci .. , bir aralığın işlenenleri olarak başlangıcını ve sonunu belirtir.
Dizin kurallarıyla başlayalım. Dizi sequence değerlendirin. 0 Dizin sequence[0] ile aynıdır. ^0 Dizin
sequence[sequence.Length] ile aynıdır. sequence[^0] , sequence[sequence.Length] olduğu gibi bir özel durum
oluşturur. Herhangi bir sayı n için Dizin ^n sequence[sequence.Length - n] ile aynıdır.

string[] words = new string[]


{
// index from start index from end
"The", // 0 ^9
"quick", // 1 ^8
"brown", // 2 ^7
"fox", // 3 ^6
"jumped", // 4 ^5
"over", // 5 ^4
"the", // 6 ^3
"lazy", // 7 ^2
"dog" // 8 ^1
}; // 9 (or words.Length) ^0

Son kelimeyi ^1 diziniyle alabilirsiniz. Başlatmanın altına aşağıdaki kodu ekleyin:

Console.WriteLine($"The last word is {words[^1]}");

Aralık, bir aralığın başlangıcını ve sonunu belirtir. Aralıklar dışlamalı, yani bitiş aralığa dahil değildir. Aralık
[0..^0] , tüm aralığı temsil eden [0..sequence.Length] aralığını temsil eder.

Aşağıdaki kod, "hızlı", "kahverengi" ve "Fox" sözcüklerinin bulunduğu bir alt Aralık oluşturur. words[3] üzerinden
words[1] içerir. Öğe words[4] Aralık içinde değil. Aşağıdaki kodu aynı yönteme ekleyin. Etkileşimli pencerenin alt
kısmına kopyalayıp yapıştırın.
string[] quickBrownFox = words[1..4];
foreach (var word in quickBrownFox)
Console.Write($"< {word} >");
Console.WriteLine();

Aşağıdaki kod, "Lazy" ve "köpek" ile bir alt Aralık oluşturur. words[^2] ve words[^1] içerir. Son dizin words[^0]
dahil değildir. Aşağıdaki kodu da ekleyin:

string[] lazyDog = words[^2..^0];


foreach (var word in lazyDog)
Console.Write($"< {word} >");
Console.WriteLine();

Aşağıdaki örnekler, başlangıç, bitiş veya her ikisi için açık olarak biten aralıklar oluşturur:

string[] allWords = words[..]; // contains "The" through "dog".


string[] firstPhrase = words[..4]; // contains "The" through "fox"
string[] lastPhrase = words[6..]; // contains "the, "lazy" and "dog"
foreach (var word in allWords)
Console.Write($"< {word} >");
Console.WriteLine();
foreach (var word in firstPhrase)
Console.Write($"< {word} >");
Console.WriteLine();
foreach (var word in lastPhrase)
Console.Write($"< {word} >");
Console.WriteLine();

Ayrıca, aralıkları veya dizinleri değişken olarak da bildirebilirsiniz. Değişken daha sonra [ ve ] karakterleri
içinde kullanılabilir:

Index the = ^3;


Console.WriteLine(words[the]);
Range phrase = 1..4;
string[] text = words[phrase];
foreach (var word in text)
Console.Write($"< {word} >");
Console.WriteLine();

Aşağıdaki örnekte, bu seçimlerin pek çok nedeni gösterilmektedir. Farklı birleşimler denemek için x , y ve z
değiştirin. Denemeler yaparken, x y ' den küçük olan değerleri kullanın ve y geçerli birleşimler için z
küçüktür. Aşağıdaki kodu yeni bir yöntemine ekleyin. Farklı birleşimler deneyin:
int[] numbers = Enumerable.Range(0, 100).ToArray();
int x = 12;
int y = 25;
int z = 36;

Console.WriteLine($"{numbers[^x]} is the same as {numbers[numbers.Length - x]}");


Console.WriteLine($"{numbers[x..y].Length} is the same as {y - x}");

Console.WriteLine("numbers[x..y] and numbers[y..z] are consecutive and disjoint:");


Span<int> x_y = numbers[x..y];
Span<int> y_z = numbers[y..z];
Console.WriteLine($"\tnumbers[x..y] is {x_y[0]} through {x_y[^1]}, numbers[y..z] is {y_z[0]} through
{y_z[^1]}");

Console.WriteLine("numbers[x..^x] removes x elements at each end:");


Span<int> x_x = numbers[x..^x];
Console.WriteLine($"\tnumbers[x..^x] starts with {x_x[0]} and ends with {x_x[^1]}");

Console.WriteLine("numbers[..x] means numbers[0..x] and numbers[x..] means numbers[x..^0]");


Span<int> start_x = numbers[..x];
Span<int> zero_x = numbers[0..x];
Console.WriteLine($"\t{start_x[0]}..{start_x[^1]} is the same as {zero_x[0]}..{zero_x[^1]}");
Span<int> z_end = numbers[z..];
Span<int> z_zero = numbers[z..^0];
Console.WriteLine($"\t{z_end[0]}..{z_end[^1]} is the same as {z_zero[0]}..{z_zero[^1]}");

Dizinler ve aralıklar için tür desteği


Bir tür bir Index veya Range parametresi olan bir Dizin Oluşturucu sağlıyorsa, sırasıyla dizinleri veya aralıkları
açıkça destekler.
Bir tür, erişilebilir bir alıcı ve int dönüş türü Length veya Count adlı bir özelliğe sahipse bir tür oluşturulabilir.
Dizinleri veya aralıkları açıkça desteklemeyen bir sayılabilir türü, bunlar için örtülü bir destek sağlayabilir. Daha
fazla bilgi için, özellik teklifi notunun örtük Dizin desteği ve örtük Aralık desteği bölümlerine bakın.
Örneğin, aşağıdaki .NET türleri hem dizinleri hem de aralıkları destekler: Array, String, Span<T>ve
ReadOnlySpan<T>. List<T> dizinleri destekler ancak aralıkları desteklemez.

Dizinler ve aralıklar için senaryolar


Genellikle tüm bir sıranın alt aralığında bazı analizler gerçekleştirmek istediğinizde aralıklar ve dizinler
kullanırsınız. Yeni söz dizimi, tam olarak hangi alt aralığın ilgili olduğunu okumaktan daha net. Yerel işlev
MovingAverage bağımsız değişkeni olarak bir Range alır. Bu yöntem daha sonra Min, Max ve Average hesaplama
yaparken yalnızca o aralığı numaralandırır. Projenizde aşağıdaki kodu deneyin:
int[] sequence = Sequence(1000);

for(int start = 0; start < sequence.Length; start += 100)


{
Range r = start..(start+10);
var (min, max, average) = MovingAverage(sequence, r);
Console.WriteLine($"From {r.Start} to {r.End}: \tMin: {min},\tMax: {max},\tAverage: {average}");
}

for (int start = 0; start < sequence.Length; start += 100)


{
Range r = ^(start + 10)..^start;
var (min, max, average) = MovingAverage(sequence, r);
Console.WriteLine($"From {r.Start} to {r.End}: \tMin: {min},\tMax: {max},\tAverage: {average}");
}

(int min, int max, double average) MovingAverage(int[] subSequence, Range range) =>
(
subSequence[range].Min(),
subSequence[range].Max(),
subSequence[range].Average()
);

int[] Sequence(int count) =>


Enumerable.Range(0, count).Select(x => (int)(Math.Sqrt(x) * 100)).ToArray();

Tamamlanan kodu DotNet/Samples deposundan indirebilirsiniz.


Öğretici: tasarım amacınızı null olabilen ve null
yapılamayan başvuru türleriyle daha net bir şekilde
Ifade edin
30.10.2019 • 16 minutes to read • Edit Online

C#8,0, null olabilen değer türleri olan değer türlerini tamamlayan aynı şekilde başvuru türlerini tamamlayan null
yapılabilir başvuru türlerinitanıtır. Türe bir ? ekleyerek null olabilen bir başvuru türü olarak bir değişken
bildirirsiniz. Örneğin string? , Nullable string temsil eder. Tasarım amacınızı daha net bir şekilde ifade etmek
için bu yeni türleri kullanabilirsiniz: bazı değişkenlerin her zaman bir değeri olması gerekir, bazılarında bir değer
eksikolabilir.
Bu öğreticide, aşağıdakileri nasıl yapacağınızı öğreneceksiniz:
Null yapılabilir ve null yapılamayan başvuru türlerini tasarımlarınız içine ekleyin
Kodunuzun tamamında null yapılabilir başvuru türü denetimlerini etkinleştirin.
Derleyicinin bu tasarım kararlarını zorladığı kodu yazın.
Kendi tasarımlarınızın Nullable başvuru özelliğini kullanın

Prerequisites
Makinenizi, C# 8,0 derleyicisi dahil .NET Core çalıştıracak şekilde ayarlamanız gerekir. C# 8,0 derleyicisi, Visual
Studio 2019veya .NET Core 3,0ile kullanılabilir.
Bu öğreticide, Visual Studio veya C# .NET Core CLI dahil olmak üzere, .net hakkında bilgi sahibi olduğunuz
varsayılır.

Tasarımlarınız için null yapılabilir başvuru türleri ekleyin


Bu öğreticide, bir anketi çalıştıran modellerle ilgili bir kitaplık oluşturacaksınız. Kod, gerçek dünya kavramlarını
temsil etmek için hem Nullable başvuru türlerini hem de null değer atanamaz başvuru türlerini kullanır. Anket
soruları hiçbir şekilde null olamaz. Bir yanıtlayanın soru cevaplanmayı tercih edemeyebilir. Yanıtlar bu durumda
null olabilir.

Bu örnek için yazdığınız kod, amacı ifade eder ve derleyici bu amacı zorunlu kılar.

Uygulamayı oluşturun ve null yapılabilir başvuru türlerini etkinleştirin


Visual Studio 'da ya da dotnet new console kullanarak komut satırından yeni bir konsol uygulaması oluşturun.
Uygulamayı NullableIntroduction olarak adlandırın. Uygulamayı oluşturduktan sonra, tüm projenin
etkinleştirilmiş bir null yapılabilir ek açıklama bağlamındaderlendiğini belirtmeniz gerekir. . Csproj dosyasını
açın ve PropertyGroup öğesine Nullable öğesi ekleyin. Değerini enable olarak ayarlayın. 8,0 projesinde bile null
yapılabilir başvuru türleri özelliğini kabul etmeniz gerekir. C# Bunun nedeni, özellik açık olduğunda, mevcut
başvuru değişkeni bildirimleri null yapılamayan başvuru türlerihaline gelir. Bu karar, var olan kodun doğru null
denetimleri olmayan sorunları bulmaya yardımcı olur, ancak özgün tasarım hedefini doğru bir şekilde
yansıtmayabilir:

<Nullable>enable</Nullable>
Uygulama için türleri tasarlama
Bu anket uygulaması için birkaç sınıf oluşturulması gerekir:
Soruların listesini modelleyen bir sınıf.
Anket için iletişim kurulan kişilerin listesini modelleyen sınıf.
Anketi geçen bir kişiden yanıtları modelleyen sınıf.
Bu türler, hangi üyelerin gerekli olduğunu ve hangi üyelerin isteğe bağlı olduğunu ifade etmek için hem null
yapılabilir hem de null yapılamayan başvuru türlerini kullanır. Null yapılabilir başvuru türleri, tasarım amacını
açıkça iletir:
Anketin parçası olan sorular hiçbir şekilde null olamaz: boş bir soru sormasına hiçbir fikir vermez.
Yanıtlayanlar hiçbir şekilde null olamaz. Görüştüğünüz kişileri, hatta katılmayı reddeden yanıt verenleri izlemek
isteyeceksiniz.
Bir soruya herhangi bir yanıt null olabilir. Yanıtlayanlar bazı veya tüm soruları yanıtlamak için reddedebilirler.
İçinde C#programlamış olmanız durumunda, null olamayan örnekleri bildirmek için diğer fırsatları kaçırmış
olabilecek null değerlerine izin veren başvuru türlerine alışkın olabilirsiniz:
Soruların toplanması null atanamaz olmalıdır.
Yanıtlayanlar koleksiyonu null atanamaz olmalıdır.
Kodu yazarken, başvurular için varsayılan olarak null yapılamayan bir başvuru türünün, NullReferenceExceptions '
y e yol açabilecek yaygın hataları önleyip bu şekilde olduğunu göreceksiniz. Bu öğreticiden bir derste, hangi
değişkenlerin null , hangilerinin olmadığı hakkında kararlar vermezsiniz. Dil, bu kararları ifade etmek için
sözdizimi sağlamadı. Şimdi.
Derlenecek uygulama aşağıdaki adımları yapar:
1. Bir anket oluşturur ve ona sorular ekler.
2. Anket için sahte rastgele bir yanıt veren kümesi oluşturur.
3. Tamamlanan anket boyutu hedef numarasına ulaşıncaya kadar kişilere yanıtlayanlar.
4. Anket yanıtlarına önemli istatistikleri yazar.

Null yapılabilir ve null yapılamayan türler ile anketi oluşturun


Yazacağınız ilk kod anketi oluşturur. Bir anket sorusu ve bir anket çalıştırması modellemek için sınıflar yazacaksınız.
Anketiniz, yanıtın biçimine göre ayırt edilen üç tür soru içerir: Evet/Hayır yanıt, sayı yanıtı ve metin yanıtları.
public SurveyQuestion sınıfı oluşturun:

namespace NullableIntroduction
{
public class SurveyQuestion
{
}
}

Derleyici, her başvuru türü değişkeni bildirimini, etkin bir Nullable ek açıklama bağlamındaki kod için null
yapılamayan bir başvuru türü olarak yorumlar. Aşağıdaki kodda gösterildiği gibi soru metni ve soru türü için
özellikler ekleyerek ilk uyarılarınızı görebilirsiniz:
namespace NullableIntroduction
{
public enum QuestionType
{
YesNo,
Number,
Text
}

public class SurveyQuestion


{
public string QuestionText { get; }
public QuestionType TypeOfQuestion { get; }
}
}

QuestionText başlatılamadığından, derleyici null yapılamayan bir özelliğin başlatılmadığını belirten bir uyarı verir.
Tasarımınız, soru metninin null olmasını gerektirir, bu nedenle onu başlatmak için bir Oluşturucu ve QuestionType
değeri de ekleyebilirsiniz. Tamamlanmış sınıf tanımı aşağıdaki kod gibi görünür:

namespace NullableIntroduction
{
public enum QuestionType
{
YesNo,
Number,
Text
}

public class SurveyQuestion


{
public string QuestionText { get; }
public QuestionType TypeOfQuestion { get; }

public SurveyQuestion(QuestionType typeOfQuestion, string text) =>


(TypeOfQuestion, QuestionText) = (typeOfQuestion, text);
}
}

Oluşturucuyu eklemek uyarıyı kaldırır. Oluşturucu bağımsız değişkeni aynı zamanda null atanamaz bir başvuru
türüdür, bu nedenle derleyici hiçbir uyarı vermez.
Sonra, SurveyRun adlı public sınıfı oluşturun. Bu sınıf, aşağıdaki kodda gösterildiği gibi SurveyQuestion
nesnelerinin ve ankete soru ekleme yöntemlerinin bir listesini içerir:

using System.Collections.Generic;

namespace NullableIntroduction
{
public class SurveyRun
{
private List<SurveyQuestion> surveyQuestions = new List<SurveyQuestion>();

public void AddQuestion(QuestionType type, string question) =>


AddQuestion(new SurveyQuestion(type, question));
public void AddQuestion(SurveyQuestion surveyQuestion) => surveyQuestions.Add(surveyQuestion);
}
}

Daha önce olduğu gibi, liste nesnesini null olmayan bir değere başlatmalısınız veya derleyici bir uyarı yayınlar.
AddQuestion ikinci aşırı yüklerinde hiçbir null denetim yoktur çünkü bunlar gerekli değildir: Bu değişkenin null
değer atanamaz olduğunu bildirdiniz. Değeri null olamaz.
Düzenleyicinizde program.cs 'e geçin ve Main ' in içeriğini aşağıdaki kod satırlarıyla değiştirin:

var surveyRun = new SurveyRun();


surveyRun.AddQuestion(QuestionType.YesNo, "Has your code ever thrown a NullReferenceException?");
surveyRun.AddQuestion(new SurveyQuestion(QuestionType.Number, "How many times (to the nearest 100) has that
happened?"));
surveyRun.AddQuestion(QuestionType.Text, "What is your favorite color?");

Projenin tamamı etkin bir null yapılabilir ek açıklama bağlamında olduğundan, null olamayan bir başvuru türü
bekleyen herhangi bir yönteme null geçirdiğinizde uyarılar alırsınız. Main için aşağıdaki satırı ekleyerek deneyin:

surveyRun.AddQuestion(QuestionType.Text, default);

Katılımcıları oluşturun ve ankete yanıt alın


Sonra, ankete yanıtlar üreten kodu yazın. Bu işlem birkaç küçük görevi kapsar:
1. Yanıtlayanın nesneleri üreten bir yöntem oluşturun. Bu kişiler, anketi doldurduonları temsil eder.
2. Bir yanıtlayanın sorularını sormasına, yanıtları toplamaya veya bir yanıtlayanın yanıt vermedi olduğunu
benzetmek için mantığı oluşturun.
3. Ankete yanıt veren yeterli sayıda yanıt verene kadar tekrarlayın.
Bir anket yanıtını temsil eden bir sınıfa ihtiyacınız vardır, bu nedenle şimdi ekleyin. Null yapılabilir desteğini
etkinleştirin. Aşağıdaki kodda gösterildiği gibi Id özelliği ve onu başlatan bir Oluşturucu ekleyin:

namespace NullableIntroduction
{
public class SurveyResponse
{
public int Id { get; }

public SurveyResponse(int id) => Id = id;


}
}

Sonra, rastgele bir KIMLIK oluşturarak yeni katılımcılar oluşturmak için static yöntemi ekleyin:

private static readonly Random randomGenerator = new Random();


public static SurveyResponse GetRandomId() => new SurveyResponse(randomGenerator.Next());

Bu sınıfın ana sorumluluğu, bir katılımcının yanıtlarını Anketteki sorulara üretmesidir. Bu sorumluluk birkaç
adımdan daha sahiptir:
1. Ankete katılım isteyin. Kişi onay vermezse, eksik (veya null) bir yanıt döndürün.
2. Her soruyu sorun ve yanıtı kaydedin. Her cevap da eksik olabilir (veya null).
SurveyResponse Sınıfınıza aşağıdaki kodu ekleyin:
private Dictionary<int, string>? surveyResponses;
public bool AnswerSurvey(IEnumerable<SurveyQuestion> questions)
{
if (ConsentToSurvey())
{
surveyResponses = new Dictionary<int, string>();
int index = 0;
foreach (var question in questions)
{
var answer = GenerateAnswer(question);
if (answer != null)
{
surveyResponses.Add(index, answer);
}
index++;
}
}
return surveyResponses != null;
}

private bool ConsentToSurvey() => randomGenerator.Next(0, 2) == 1;

private string? GenerateAnswer(SurveyQuestion question)


{
switch (question.TypeOfQuestion)
{
case QuestionType.YesNo:
int n = randomGenerator.Next(-1, 2);
return (n == -1) ? default : (n == 0) ? "No" : "Yes";
case QuestionType.Number:
n = randomGenerator.Next(-30, 101);
return (n < 0) ? default : n.ToString();
case QuestionType.Text:
default:
switch (randomGenerator.Next(0, 5))
{
case 0:
return default;
case 1:
return "Red";
case 2:
return "Green";
case 3:
return "Blue";
}
return "Red. No, Green. Wait.. Blue... AAARGGGGGHHH!";
}
}

Anket yanıtlarının depolaması, null olabileceğini belirten bir Dictionary<int, string>? ' dır. Tasarım amacınızı, her
ikisi de derleyiciye ve kodunuzu daha sonra okuyan herkese bildirmek için yeni dil özelliğini kullanıyorsunuz. Önce
null değerini denetlemeden surveyResponses başvuru yaptıysanız bir derleyici uyarısı alırsınız. Derleyici
surveyResponses değişkeninin yukarıda null olmayan bir değere ayarlandığını belirleyebileceğinden AnswerSurvey
yönteminde uyarı almanız gerekmez.
Eksik yanıtlar için null kullanmak, null yapılabilir başvuru türleriyle çalışmak için bir anahtar noktası vurgular:
Amacınız tüm null değerlerini programınızdan kaldırmıyor. Bunun yerine amacınız, yazdığınız kodun
tasarımınızın amacını ifade etmek için gereklidir. Eksik değerler kodunuzda ifade etmek için gerekli bir kavramdır.
null değeri, eksik değerleri ifade etmenin açık bir yoludur. Tüm null değerleri kaldırılmaya çalışılması, yalnızca
null olmayan eksik değerleri ifade etmek için başka bir yol tanımlamaya neden oluyor.

Sonra, SurveyRun sınıfına PerformSurvey yöntemini yazmanız gerekir. SurveyRun sınıfına aşağıdaki kodu ekleyin:
private List<SurveyResponse>? respondents;
public void PerformSurvey(int numberOfRespondents)
{
int repondentsConsenting = 0;
respondents = new List<SurveyResponse>();
while (repondentsConsenting < numberOfRespondents)
{
var respondent = SurveyResponse.GetRandomId();
if (respondent.AnswerSurvey(surveyQuestions))
repondentsConsenting++;
respondents.Add(respondent);
}
}

Burada, null yapılabilir List<SurveyResponse>? seçiminiz yanıtın null olabileceğini gösterir. Bu, anketin henüz
herhangi bir yanıtlayanlara verilmediğini belirtir. Yanıt verenlerin yeterli olana kadar eklendiğine dikkat edin.
Anketi çalıştırmanın son adımı, Main yönteminin sonunda anketi gerçekleştirmek için bir çağrı eklemektir:

surveyRun.PerformSurvey(50);

Anket yanıtlarını İnceleme


Son adım, anket sonuçlarını görüntülemektir. Yazdığınız sınıfların çoğuna kod ekleyeceksiniz. Bu kod, null
yapılabilir ve null yapılamayan başvuru türlerini ayırt etme değerini gösterir. Aşağıdaki iki Expression-Bodied
üyesini SurveyResponse sınıfına ekleyerek başlayın:

public bool AnsweredSurvey => surveyResponses != null;


public string Answer(int index) => surveyResponses?.GetValueOrDefault(index) ?? "No answer";

surveyResponses Nullable bir başvuru türü olduğundan, null denetimleri buna başvurulmadan önce gereklidir.
Answer yöntemi null yapılamayan bir dize döndürür. bu nedenle, null birleşim işlecini kullanarak eksik bir yanıtın
durumunu kapsamalıdır.
Ardından, bu üç Expression-Bodied üyelerini SurveyRun sınıfına ekleyin:

public IEnumerable<SurveyResponse> AllParticipants => (respondents ?? Enumerable.Empty<SurveyResponse>());


public ICollection<SurveyQuestion> Questions => surveyQuestions;
public SurveyQuestion GetQuestion(int index) => surveyQuestions[index];

AllParticipants üye, respondents değişkeninin null olabileceğini, ancak dönüş değerinin null olduğunu dikkate
almalıdır. ?? ve aşağıdaki boş diziyi kaldırarak bu ifadeyi değiştirirseniz, derleyici yöntemi null
döndürebileceğini ve dönüş imzası null yapılamayan bir tür döndürdüğünü uyarır.
Son olarak, aşağıdaki döngüyü Main yönteminin altına ekleyin:
foreach (var participant in surveyRun.AllParticipants)
{
Console.WriteLine($"Participant: {participant.Id}:");
if (participant.AnsweredSurvey)
{
for (int i = 0; i < surveyRun.Questions.Count; i++)
{
var answer = participant.Answer(i);
Console.WriteLine($"\t{surveyRun.GetQuestion(i)} : {answer}");
}
}
else
Console.WriteLine("\tNo responses");
}

Bu kodda null denetimleri gerekmez, çünkü hepsi null yapılamayan başvuru türleri döndürecek şekilde temel
arabirimleri tasarlamış oldunuz.

Kodu alın
Örnek deponuzdan, CSharp/Nullabletanıtım klasöründe bulunan örnek depomuza yönelik kodu alabilirsiniz.
Null atanabilir ve null yapılamayan başvuru türleri arasında tür bildirimleri değiştirerek deneyin. Bunun, yanlışlıkla
null başvurmamasını sağlamak için farklı uyarılar üretmesinin nasıl yapıldığını görün.

Sonraki adımlar
Mevcut bir uygulamayı null yapılabilir başvuru türlerini kullanacak şekilde geçirerek daha fazla bilgi edinin:
Bir uygulamayı null yapılabilir başvuru türlerini kullanacak şekilde yükseltme
Öğretici: mevcut kodu Nullable başvuru türleriyle
geçirme
25.11.2019 • 22 minutes to read • Edit Online

C#8, null olabilen değer türleri için aynı şekilde, başvuru türlerini tamamlayan null yapılabilir başvuru
türlerinitanıtır. Türe bir ? ekleyerek null olabilen bir başvuru türü olarak bir değişken bildirirsiniz. Örneğin
string? , null yapılabilir bir string temsil eder. Tasarım amacınızı daha net bir şekilde ifade etmek için bu yeni
türleri kullanabilirsiniz: bazı değişkenlerin her zaman bir değeri olması gerekir, bazılarında bir değer eksikolabilir.
Bir başvuru türünün varolan değişkenleri, null olamayan bir başvuru türü olarak yorumlanır.
Bu öğreticide, aşağıdakileri nasıl yapacağınızı öğreneceksiniz:
Kodla çalışırken null başvuru denetimlerini etkinleştirin.
Null değerlerle ilgili farklı uyarıları tanılayın ve düzeltin.
Null yapılabilir etkin ve null yapılabilir devre dışı bağlamların arabirimini yönetin.
Null yapılabilir ek açıklama bağlamlarını denetleyin.

Prerequisites
Makinenizi, C# 8,0 derleyicisi dahil .NET Core çalıştıracak şekilde ayarlamanız gerekir. 8 C# derleyicisi, Visual
Studio 2019 sürüm 16,3 veya .NET Core 3,0 SDKile başlayarak kullanılabilir.
Bu öğreticide, Visual Studio veya C# .NET Core CLI dahil olmak üzere, .net hakkında bilgi sahibi olduğunuz
varsayılır.

Örnek uygulamayı keşfet


Geçirilecek örnek uygulama bir RSS Akış okuyucusu web uygulamasıdır. Tek bir RSS akışından okur ve en son
makalelerin özetlerini görüntüler. Siteyi ziyaret etmek için makalelerden herhangi birini seçebilirsiniz. Uygulama
nispeten yenidir ancak null yapılabilir başvuru türleri kullanılabilir olmadan önce yazılmıştır. Uygulama için
gösterilen ve bu önemli dil özelliğinden yararlanmamak için sunulan tasarım kararları.
Örnek uygulama, uygulamanın ana işlevlerini doğrulayan bir birim testi kitaplığı içerir. Oluşturulan uyarılara göre
herhangi bir uygulamayı değiştirirseniz, bu proje güvenli bir şekilde yükseltmeyi daha kolay hale getirir. Başlangıç
kodunu DotNet/Samples GitHub deposundan indirebilirsiniz.
Bir projeyi geçirme hedefiniz yeni dil özelliklerinden faydalanmak için olmalıdır. böylece, amacınızı null olabilir ve
bu nedenle, null yapılabilir ek açıklama bağlamına sahip olduğunuzda derleyicinin uyarı üretmemesi ve null
yapılabilir uyarı bağlamı enabled olarak ayarlanır.

Projeleri 8 ' e C# yükseltin


Geçiş görevinin kapsamını belirlemekte iyi bir ilk adım vardır. Projeyi C# 8,0 (veya daha yeni) sürümüne
yükselterek başlayın. Web projesi ve birim test projesi için LangVersion öğesini her iki csproj dosyasına ekleyin:

<LangVersion>8.0</LangVersion>

Dil sürümünü yükseltmek 8,0 seçer C# , ancak null yapılabilir ek açıklama bağlamını veya null yapılabilir uyarı
bağlamını etkinleştirmez. Uyarı vermeden oluşturulduğundan emin olmak için projeyi yeniden derleyin.
İyi bir sonraki adım, null yapılabilir ek açıklama bağlamını açıp kaç uyarı oluşturulduğunu görmenizde yarar vardır.
Çözümdeki her iki csproj dosyasına doğrudan LangVersion öğesi altında aşağıdaki öğeyi ekleyin:

<Nullable>enable</Nullable>

Bir test derlemesi yapın ve uyarı listesine dikkat edin. Bu küçük uygulamada, derleyici beş uyarı üretir, bu nedenle
null yapılabilir ek açıklama bağlamını etkin bırakıp tüm proje için uyarıları düzeltmeye başlayabilirsiniz.
Bu strateji yalnızca daha küçük projeler için geçerlidir. Daha büyük projeler için, tüm kod tabanı için Nullable ek
açıklama bağlamını etkinleştirerek oluşturulan uyarı sayısı, uyarıları sistematik olarak gidermeyi zorlaştırır. Daha
büyük kurumsal projelerde, genellikle bir projeyi tek seferde geçirmek isteyeceksiniz. Her projede, tek bir sınıf
veya dosyayı aynı anda geçirin.

Uyarılar özgün tasarım amacını bulmaya yardımcı olur


Birden çok uyarı oluşturan iki sınıf vardır. NewsStoryViewModel sınıfıyla başlayın. Uyarı kapsamını çalıştığınız kodun
bölümleriyle sınırlayabilmeniz için her iki csproj dosyasından Nullable öğesini kaldırın. NewsStoryViewModel.cs
dosyasını açın ve aşağıdaki yönergeleri ekleyerek NewsStoryViewModel için Nullable ek açıklama bağlamını
etkinleştirin ve bu sınıf tanımını izleyerek geri yükleyin:

#nullable enable
public class NewsStoryViewModel
{
public DateTimeOffset Published { get; set; }
public string Title { get; set; }
public string Uri { get; set; }
}
#nullable restore

Bu iki yönergeler, geçiş çabalarınıza odaklanmaya yardımcı olur.Üzerinde etkin olarak çalışmakta olduğunuz kod
alanı için null yapılabilir uyarılar oluşturulur. Projenin tamamına yönelik uyarıları açmaya hazırsanız, bunları açık
bırakmalısınız. Tüm proje için null yapılabilir ek açıklamaları açtığınızda bağlamı yanlışlıkla devre dışı
bırakabilmeniz için disable değeri yerine restore kullanmanız gerekir. Tüm proje için null yapılabilir ek açıklama
bağlamını etkinleştirdikten sonra, bu projeden tüm #nullable pragmaları kaldırabilirsiniz.
NewsStoryViewModel sınıfı bir veri aktarım nesnesidir (DTO ) ve özelliklerden ikisi okuma/yazma dizeleridir:

public class NewsStoryViewModel


{
public DateTimeOffset Published { get; set; }
public string Title { get; set; }
public string Uri { get; set; }
}

Bu iki özellik CS8618 , "null yapılamayan özelliğin başlatılmamış" olmasına neden olur. Bu yeterince net: her iki
string özelliği de bir NewsStoryViewModel oluşturulduğunda null varsayılan değerine sahiptir. Bulma için
önemli olan özellikler NewsStoryViewModel nesneleri nasıl oluşturulur. Bu sınıfa bakarak, null değerinin tasarımın
bir parçası olup olmadığını veya bu nesnelerin her biri oluşturulduğunda null olmayan değerlere ayarlanmış
olduğunu söyleyebilirsiniz. Haber hikayeleri, NewsService sınıfının GetNews yönteminde oluşturulur:

ISyndicationItem item = await feedReader.ReadItem();


var newsStory = _mapper.Map<NewsStoryViewModel>(item);
news.Add(newsStory);
Yukarıdaki kod bloğunda oldukça bir bit vardır. Bu uygulama, bir ISyndicationItem haber öğesi oluşturmak için
Automaber NuGet paketini kullanır. Haber hikayesi öğelerinin oluşturulduğunu ve özellikler söz konusu bir
bildirimde ayarlandığını keşfettiniz. Bu, NewsStoryViewModel tasarımının bu özelliklerin hiçbir durumda null
değerine sahip olmayacağını gösterir. Bu özellikler null atanamaz başvuru türleriolmalıdır. Bu, özgün tasarım
amacını en iyi ifade eder. Aslında, hiçbir NewsStoryViewModel null olmayan değerler ile doğru şekilde oluşturulur.
Bu, aşağıdaki başlatma kodunu geçerli bir çözüm haline getirir:

public class NewsStoryViewModel


{
public DateTimeOffset Published { get; set; }
public string Title { get; set; } = default!;
public string Uri { get; set; } = default!;
}

string tür için nullolan default Title ve Uri ataması programın çalışma zamanı davranışını değiştirmez.
NewsStoryViewModel hala null değerlerle oluşturulmuş, ancak derleyici hiçbir uyarı raporluyor. Null -forverme
işleci, default ifadesini izleyen ! karakteri derleyiciye önceki ifadenin null olmadığını söyler. Bu teknik, diğer
değişiklikler bir kod tabanında çok daha büyük değişiklikler yaparken, ancak bu uygulamada görece hızlı ve daha
iyi bir çözüm olduğu zaman, NewsStoryViewModel : tüm özelliklerin oluşturucuda ayarlandığı sabit bir tür haline
gelebilir. NewsStoryViewModel aşağıdaki değişiklikleri yapın:

#nullable enable
public class NewsStoryViewModel
{
public NewsStoryViewModel(DateTimeOffset published, string title, string uri) =>
(Published, Title, Uri) = (published, title, uri);

public DateTimeOffset Published { get; }


public string Title { get; }
public string Uri { get; }
}
#nullable restore

Bu yapıldıktan sonra, özellikleri ayarlamak yerine, oluşturucuyu kullanması için Automaber 'yi yapılandıran kodu
güncelleştirmeniz gerekir. NewsService.cs açın ve dosyanın en altında aşağıdaki kodu arayın:

public class NewsStoryProfile : Profile


{
public NewsStoryProfile()
{
// Create the AutoMapper mapping profile between the 2 objects.
// ISyndicationItem.Id maps to NewsStoryViewModel.Uri.
CreateMap<ISyndicationItem, NewsStoryViewModel>()
.ForMember(dest => dest.Uri, opts => opts.MapFrom(src => src.Id));
}
}

Bu kod, ISyndicationItem nesnesinin özelliklerini NewsStoryViewModel özellikleriyle eşler. Bunun yerine bir
Oluşturucu kullanarak, Automaber 'nin eşleme sağlamasını istersiniz. Yukarıdaki kodu aşağıdaki automaber
yapılandırmasıyla değiştirin:
#nullable enable
public class NewsStoryProfile : Profile
{
public NewsStoryProfile()
{
// Create the AutoMapper mapping profile between the 2 objects.
// ISyndicationItem.Id maps to NewsStoryViewModel.Uri.
CreateMap<ISyndicationItem, NewsStoryViewModel>()
.ForCtorParam("uri", opt => opt.MapFrom(src => src.Id));
}

Bu sınıf küçük olduğu ve dikkatle incelediğiniz için, bu sınıf bildiriminin üzerinde #nullable enable yönergesini
açmanız gerektiğine dikkat edin. Kurucudaki değişiklik bir şeyi bozarak, tüm testleri çalıştırmak ve devam etmeden
önce uygulamayı test etmek daha fazla olabilir.
İlk değişiklik kümesi, özgün tasarımın değişkenlerin null olarak ayarlanmamalıdır. Teknik, oluşturma tarafından
doğruolarak adlandırılır. Bir nesne ve özellikleri oluşturulduğunda null olduğunu bildirirsiniz. Derleyicinin akış
analizi, bu özelliklerin oluşturulduktan sonra null olarak ayarlanmadığından emin olmak için güvence sağlar. Bu
oluşturucunun dış kod tarafından çağrıldığını ve kodun null değer atanabilir yükümlülüğüolduğunu
unutmayın. Yeni sözdizimi çalışma zamanı denetimi sağlamaz. Dış kod derleyicinin akış analizini atlatılabilir.
Diğer zamanlarda, bir sınıfın yapısı amaç için farklı ipuçları sağlar. Error.cshtml.cs dosyasını Sayfalar klasöründe
açın. ErrorViewModel aşağıdaki kodu içerir:

public class ErrorModel : PageModel


{
public string RequestId { get; set; }

public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);

public void OnGet()


{
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
}
}

Sınıf bildiriminden önce #nullable enable yönergesini ve sonra bir #nullable restore yönergesini ekleyin.
RequestId başlatılmamış bir uyarı alırsınız. Sınıfına bakarak, bazı durumlarda RequestId özelliğinin null olması
gerektiğine karar vermeniz gerekir. ShowRequestId özelliğinin varlığı eksik değerlerin mümkün olduğunu gösterir.
null geçerli olduğundan, RequestId özelliğinin null yapılabilir bir başvuru türüolduğunu göstermek için string
türüne ? ekleyin. Son sınıf aşağıdaki örneğe benzer şekilde görünür:

#nullable enable
public class ErrorModel : PageModel
{
public string? RequestId { get; set; }

public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);

public void OnGet()


{
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
}
}
#nullable restore

Özelliğin kullanımlarını denetleyin ve ilgili sayfada özelliği, biçimlendirme sırasında işlemeden önce, özelliğinin
null olarak denetlendiğini görürsünüz. Bu, null olabilen bir başvuru türünün güvenli bir kullanımı olduğundan bu
sınıfla işiniz bitti.

Null değerleri düzeltme değişikliğine neden olur


Genellikle, bir uyarı kümesinin düzeltilmesi ilgili kodda yeni uyarılar oluşturur. index.cshtml.cs sınıfını düzelterek,
uyarıları eylemde görelim. index.cshtml.cs dosyasını açın ve kodu inceleyin. Bu dosya dizin sayfası için
arkasındaki kodu içerir:

public class IndexModel : PageModel


{
private readonly NewsService _newsService;

public IndexModel(NewsService newsService)


{
_newsService = newsService;
}

public string ErrorText { get; private set; }

public List<NewsStoryViewModel> NewsItems { get; private set; }

public async Task OnGet()


{
string feedUrl = Request.Query["feedurl"];

if (!string.IsNullOrEmpty(feedUrl))
{
try
{
NewsItems = await _newsService.GetNews(feedUrl);
}
catch (UriFormatException)
{
ErrorText = "There was a problem parsing the URL.";
return;
}
catch (WebException ex) when (ex.Status == WebExceptionStatus.NameResolutionFailure)
{
ErrorText = "Unknown host name.";
return;
}
catch (WebException ex) when (ex.Status == WebExceptionStatus.ProtocolError)
{
ErrorText = "Syndication feed not found.";
return;
}
catch (AggregateException ae)
{
ae.Handle((x) =>
{
if (x is XmlException)
{
ErrorText = "There was a problem parsing the feed. Are you sure that URL is a
syndication feed?";
return true;
}
return false;
});
}
}
}
}

#nullable enable yönergesini ekleyin ve iki uyarı görürsünüz. ErrorText özelliği ne de NewsItems özelliği
başlatılmaz. Bu sınıfın incelenmesi, her iki özelliği de null yapılabilir başvuru türleri olması gerektiğini
düşünmenize yol açacağından, her Ikisinin de özel ayarlayıcıları vardır. OnGet yönteminde tam olarak bir atanır.
Değişiklik yapmadan önce her iki özelliği de tüketicilere bakın. Sayfanın kendisinde, herhangi bir hata için
biçimlendirme oluşturmadan önce ErrorText null olarak denetlenir. NewsItems koleksiyonu null karşı denetlenir
ve koleksiyonda öğeler olduğundan emin olmak için denetlenir. Hızlı bir çözüm, her iki özelliği de null yapılabilir
başvuru türlerini yapmak olacaktır. Daha iyi bir çözüm, koleksiyonu null yapılamayan bir başvuru türü yapmak ve
haberleri alırken mevcut koleksiyona öğe eklemek olacaktır. İlk çözüm, ? ErrorText``string türüne eklemektir:

public string? ErrorText { get; private set; }

ErrorText özelliğine herhangi bir erişim null denetimleri tarafından zaten korunduğu için, bu değişiklik diğer kod
aracılığıyla görünmez olmayacaktır. Sonra, NewsItems listesini başlatın ve özellik ayarlayıcısını kaldırarak salt
okunur bir özellik yaparak:

public List<NewsStoryViewModel> NewsItems { get; } = new List<NewsStoryViewModel>();

Bu, uyarıyı düzeltti ancak bir hata sunmuştur. NewsItems listesi artık yapım tarafından düzeltilir, ancak OnGet
listesini ayarlayan kod yeni API ile eşleşecek şekilde değişmelidir. Bir atama yerine, mevcut listeye haber öğelerini
eklemek için AddRange çağırın:

NewsItems.AddRange(await _newsService.GetNews(feedUrl));

Atama yerine AddRange kullanmak GetNews yönteminin List yerine IEnumerable döndürebileceği anlamına gelir.
Bu, bir ayırmayı kaydeder. Metodun imzasını değiştirin ve aşağıdaki kod örneğinde gösterildiği gibi ToList
çağrısını kaldırın:
public async Task<IEnumerable<NewsStoryViewModel>> GetNews(string feedUrl)
{
var news = new List<NewsStoryViewModel>();
var feedUri = new Uri(feedUrl);

using (var xmlReader = XmlReader.Create(feedUri.ToString(),


new XmlReaderSettings { Async = true }))
{
try
{
var feedReader = new RssFeedReader(xmlReader);

while (await feedReader.Read())


{
switch (feedReader.ElementType)
{
// RSS Item
case SyndicationElementType.Item:
ISyndicationItem item = await feedReader.ReadItem();
var newsStory = _mapper.Map<NewsStoryViewModel>(item);
news.Add(newsStory);
break;

// Something else
default:
break;
}
}
}
catch (AggregateException ae)
{
throw ae.Flatten();
}
}

return news.OrderByDescending(story => story.Published);


}

İmzanın değiştirilmesi, testlerin birini de keser. NewsServiceTests.cs dosyasını SimpleFeedReader.Tests projesinin


Services klasöründe açın. Returns_News_Stories_Given_Valid_Uri testine gidin ve result değişkeninin türünü
IEnumerable<NewsItem> olarak değiştirin. Türü değiştirmek Count özelliğinin artık kullanılamadığı anlamına gelir,
bu nedenle Assert Count özelliğini Any() çağrısıyla değiştirin:

// Act
IEnumerable<NewsStoryViewModel> result =
await _newsService.GetNews(feedUrl);

// Assert
Assert.True(result.Any());

Dosyanın başlangıcına de using System.Linq bir ifade eklemeniz gerekecektir.


Bu değişiklik kümesi, genel örneklemeleri içeren kodu güncelleştirirken özel bir değerlendirme vurgulamaktadır.
Hem liste hem de öğeler null yapılamayan türler listesinde. Ya da her ikisi de null yapılabilir türler olabilir.
Aşağıdaki bildirimlere izin verilir:
List<NewsStoryViewModel> : yinelenmeyen görünüm modellerinin null yapılamayan listesi.
List<NewsStoryViewModel?> : null yapılabilir görünüm modellerinin Nullable listesi.
List<NewsStoryViewModel>? : null yapılamayan görünüm modellerinin null olabilir listesi.
List<NewsStoryViewModel?>? : null yapılabilir görünüm modellerinin null olabilir listesi.
Dış kod içeren arabirimler
NewsService sınıfında değişiklikler yaptınız, bu nedenle söz konusu sınıfın #nullable enable ek açıklamasını
etkinleştirin. Bu, yeni uyarı oluşturmaz. Ancak, sınıfının dikkatle incelenmesi derleyicinin akış analizinin bazı
sınırlamalarını göstermeye yardımcı olur. Oluşturucuyu inceleyin:

public NewsService(IMapper mapper)


{
_mapper = mapper;
}

IMapper parametresi null atanamaz bir başvuru olarak yazılmış. ASP.NET Core altyapı kodu tarafından çağrılır, bu
nedenle derleyici IMapper hiçbir şekilde null olmadığını bilmez. Varsayılan ASP.NET Core bağımlılık ekleme (dı)
kapsayıcısı, gerekli bir hizmeti çözümleyemezse, kod doğru olduğunda bir özel durum oluşturur. Kodunuz null
yapılabilir ek açıklama bağlamlarıyla derlense bile derleyici ortak API 'lerinize yapılan tüm çağrıları doğrulayamaz.
Ayrıca, kitaplıklarınız henüz null yapılabilir başvuru türlerini kullanarak onaylanmamış projeler tarafından
tüketilebilir. Bu girdileri null yapılamayan türler olarak bildirseniz bile ortak API 'lere yönelik girişleri doğrulayın.

Kodu alın
İlk test derlenmesi sırasında belirlediğiniz uyarıları düzelttiniz, bu nedenle artık her iki proje için de null yapılabilir
ek açıklama bağlamını açabilirsiniz. Projeleri yeniden derleyin; Derleyici hiçbir uyarı rapor vermez.
DotNet/Samples GitHub deposundaki tamamlanmış projenin kodunu alabilirsiniz.
Null yapılabilir başvuru türlerini destekleyen yeni özellikler, kodunuzda null değerleri nasıl işleyeceğinizi
bulmanıza ve düzeltmenize yardımcı olur. Null yapılabilir ek açıklama bağlamını etkinleştirmek, tasarım amacınızı
ifade etmenizi sağlar: bazı değişkenler hiçbir şekilde null olmamalıdır, diğer değişkenler de null değerler içerebilir.
Bu özellikler tasarım amacınızı bildirmenize daha kolay bir hale getirir. Benzer şekilde, null yapılabilir uyarı
bağlamı derleyiciye bu amacı ihlal ettiğinizde uyarı vermesini söyler. Bu uyarılar, kodunuzu daha dayanıklı hale
getirmek ve yürütme sırasında NullReferenceException oluşturması olasılığını azaltır. Geri kalan kod temeli
dokunulmamış olsa da, geçirilecek yerel kod alanına odaklanabilmeniz için bu bağlamların kapsamını kontrol
edebilirsiniz. Uygulamada, bu geçiş görevini sınıflarınıza düzenli bakımın bir parçası yapabilirsiniz. Bu öğretici, bir
uygulamayı null yapılabilir başvuru türlerini kullanacak şekilde geçirme işlemini göstermiştir. Bu işlemin daha
büyük bir gerçek dünya örneğini, null yapılabilir başvuru türlerini Nodadtimeile birleştirmek IÇIN yapılan PR Jon
iskeet 'i inceleyerek inceleyebilirsiniz.
Öğretici: 8,0 ve .NET Core 3,0 kullanarak C# zaman
uyumsuz akışlar oluşturma ve kullanma
30.10.2019 • 12 minutes to read • Edit Online

C#8,0, veri akışındaki öğeler alınabilir veya zaman uyumsuz olarak oluşturulduğunda verilerin akış kaynağını
modelleyebilir ve zaman uyumsuz akışlarıtanıtır. Zaman uyumsuz akışlar .NET Standard 2,1 ' de tanıtılan ve .NET
Core 3,0 ' de uygulanan yeni arabirimleri kullanır ve zaman uyumsuz akış veri kaynakları için doğal bir
programlama modeli sağlar.
Bu öğreticide, aşağıdakileri nasıl yapacağınızı öğreneceksiniz:
Zaman uyumsuz bir veri öğeleri dizisi üreten bir veri kaynağı oluşturun.
Bu veri kaynağını zaman uyumsuz olarak tükettin.
Yeni arabirim ve veri kaynağı daha önceki zaman uyumlu veri dizileri için tercih edildiği zaman tanıyın.

Prerequisites
Makinenizi, C# 8,0 derleyicisi dahil .NET Core çalıştıracak şekilde ayarlamanız gerekir. 8 C# derleyicisi, Visual
Studio 2019 sürüm 16,3 veya .NET Core 3,0 SDKile başlayarak kullanılabilir.
GitHub GraphQL uç noktasına erişebilmek için bir GitHub erişim belirteci oluşturmanız gerekir. GitHub erişim
belirteciniz için aşağıdaki izinleri seçin:
Depo: durum
public_repo
Erişim belirtecini, GitHub API uç noktasına erişim kazanmak için kullanabilmeniz için güvenli bir yere kaydedin.

WARNING
Kişisel erişim belirtecinizi güvende tutun. Kişisel erişim belirtecinize sahip tüm yazılımlar, erişim haklarınızı kullanarak GitHub
API çağrıları yapabilir.

Bu öğreticide, Visual Studio veya C# .NET Core CLI dahil olmak üzere, .net hakkında bilgi sahibi olduğunuz
varsayılır.

Başlangıç uygulamasını çalıştırma


Bu öğreticide kullanılan başlangıç uygulamasının kodunu CSharp/öğreticiler/AsyncStreams klasöründeki
DotNet/Samples depomızdan alabilirsiniz.
Başlangıç uygulaması, DotNet/docs deposunda yazılan son sorunları almak Için GitHub graphql arabirimini
kullanan bir konsol uygulamasıdır. Başlangıç uygulaması Main yöntemi için aşağıdaki koda bakarak başlayın:
static async Task Main(string[] args)
{
//Follow these steps to create a GitHub Access Token
// https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/#creating-a-
token
//Select the following permissions for your GitHub Access Token:
// - repo:status
// - public_repo
// Replace the 3rd parameter to the following code with your GitHub access token.
var key = GetEnvVariable("GitHubKey",
"You must store your GitHub key in the 'GitHubKey' environment variable",
"");

var client = new GitHubClient(new Octokit.ProductHeaderValue("IssueQueryDemo"))


{
Credentials = new Octokit.Credentials(key)
};

var progressReporter = new progressStatus((num) =>


{
Console.WriteLine($"Received {num} issues in total");
});
CancellationTokenSource cancellationSource = new CancellationTokenSource();

try
{
var results = await runPagedQueryAsync(client, PagedIssueQuery, "docs",
cancellationSource.Token, progressReporter);
foreach(var issue in results)
Console.WriteLine(issue);
}
catch (OperationCanceledException)
{
Console.WriteLine("Work has been cancelled");
}
}

Kişisel erişim belirtecinize bir GitHubKey ortam değişkeni ayarlayabilir veya çağrdaki son bağımsız değişkeni
kişisel erişim belirtecinizle birlikte GenEnvVariable olarak değiştirebilirsiniz. Kaynağı başkalarıyla kaydediyorsanız
veya paylaşılan bir kaynak deposuna koymak istiyorsanız, erişim kodunuzu kaynak koda yerleştirmeyin.
GitHub istemcisini oluşturduktan sonra Main kod, bir ilerleme raporlama nesnesi ve bir iptal belirteci oluşturur. Bu
nesneler oluşturulduktan sonra Main en son 250 oluşturulan sorunları almak için runPagedQueryAsync çağırır. Bu
görev bittikten sonra sonuçlar görüntülenir.
Başlangıç uygulamasını çalıştırdığınızda, bu uygulamanın nasıl çalıştığı hakkında bazı önemli gözlemlerinizi
yapabilirsiniz. GitHub 'dan döndürülen her sayfa için ilerleme durumunu görürsünüz. GitHub her yeni sorun
sayfasını geri döndürdüğünden, dikkat çekici bir duraklama gözlemleyebilirsiniz. Son olarak, sorunlar yalnızca
GitHub 'dan 10 sayfa alındıktan sonra görüntülenir.

Uygulamayı İnceleme
Uygulama, önceki bölümde ele alınan davranışı neden gözlemlediğinizi ortaya çıkarır. runPagedQueryAsync için kodu
inceleyin:
private static async Task<JArray> runPagedQueryAsync(GitHubClient client, string queryText, string repoName,
CancellationToken cancel, IProgress<int> progress)
{
var issueAndPRQuery = new GraphQLRequest
{
Query = queryText
};
issueAndPRQuery.Variables["repo_name"] = repoName;

JArray finalResults = new JArray();


bool hasMorePages = true;
int pagesReturned = 0;
int issuesReturned = 0;

// Stop with 10 pages, because these are large repos:


while (hasMorePages && (pagesReturned++ < 10))
{
var postBody = issueAndPRQuery.ToJsonText();
var response = await client.Connection.Post<string>(new Uri("https://api.github.com/graphql"),
postBody, "application/json", "application/json");

JObject results = JObject.Parse(response.HttpResponse.Body.ToString());

int totalCount = (int)issues(results)["totalCount"];


hasMorePages = (bool)pageInfo(results)["hasPreviousPage"];
issueAndPRQuery.Variables["start_cursor"] = pageInfo(results)["startCursor"].ToString();
issuesReturned += issues(results)["nodes"].Count();
finalResults.Merge(issues(results)["nodes"]);
progress?.Report(issuesReturned);
cancel.ThrowIfCancellationRequested();
}
return finalResults;

JObject issues(JObject result) => (JObject)result["data"]["repository"]["issues"];


JObject pageInfo(JObject result) => (JObject)issues(result)["pageInfo"];
}

Yukarıdaki kodun disk belleği algoritmasına ve zaman uyumsuz yapısına odaklanalım. (GitHub GraphQL API 'SI
ile ilgili ayrıntılar için GitHub graphql belgelerine başvurabilirsiniz.) runPagedQueryAsync yöntemi en sonuncudan
en eskiye doğru olan sorunları numaralandırır. Sayfa başına 25 sorun ister ve önceki sayfaya devam etmek için
yanıtın pageInfo yapısını inceler. Bu, çok sayfalı yanıtlar için GraphQL 'in standart disk belleği desteğini izler. Yanıt,
bir hasPreviousPages değeri ve önceki sayfayı istemek için kullanılan bir startCursor değeri içeren bir pageInfo
nesnesi içerir. Sorunlar nodes dizidir. runPagedQueryAsync yöntemi, tüm sayfalardaki sonuçları içeren bir diziye bu
düğümleri ekler.
Bir sonuç sayfasını aldıktan ve geri yükledikten sonra, runPagedQueryAsync ilerlemeyi raporlar ve iptal olup
olmadığını denetler. İptal isteniyorsa, runPagedQueryAsync bir OperationCanceledException oluşturur.
Bu kodda iyileştirilen birkaç öğe vardır. En önemlisi runPagedQueryAsync , döndürülen tüm sorunlar için depolama
alanı ayırmalıdır. Tüm açık sorunların alınması, alınan tüm sorunları depolamak için çok daha fazla bellek
gerektirdiğinden, bu örnek 250 sorunlarını durduruyor. Ayrıca, ilerlemeyi destekleme ve iptali destekleme
protokolleri, algoritmayı ilk okuma konusunda daha zor hale getirir. İlerleme durumunun nerede bildirileceğini
bulmak için ilerleme sınıfına bakmanız gerekir. Ayrıca, İptalin istendiği ve nerede verildiğini anlamak için
CancellationTokenSource ve ilişkili CancellationToken arasındaki iletişimleri izlemeniz gerekir.

Zaman uyumsuz akışlar daha iyi bir yol sağlar


Zaman uyumsuz akışlar ve ilişkili dil desteği Bu kaygıların tümünü ele. Diziyi oluşturan kod artık, async
değiştiricisiyle bildirildi bir yöntemde öğe döndürmek için yield return kullanabilir. Bir await foreach
döngüsünü kullanarak, bir foreach döngüsü kullanarak herhangi bir diziyi tükettiğinizde zaman uyumsuz bir akış
kullanabilirsiniz.
Bu yeni dil özellikleri, 2,1 .NET Standard eklenen ve .NET Core 3,0 ' de uygulanan üç yeni arabirime bağımlıdır:

namespace System.Collections.Generic
{
public interface IAsyncEnumerable<out T>
{
IAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = default);
}

public interface IAsyncEnumerator<out T> : IAsyncDisposable


{
T Current { get; }

ValueTask<bool> MoveNextAsync();
}
}

namespace System
{
public interface IAsyncDisposable
{
ValueTask DisposeAsync();
}
}

Bu üç arabirim çoğu C# geliştiricilere tanıdık gelmelidir. Zaman uyumlu ortaklarınıza benzer bir şekilde davranır:
System.Collections.Generic.IEnumerable<T>
System.Collections.Generic.IEnumerator<T>
System.IDisposable
Alışkın olabilecek bir tür System.Threading.Tasks.ValueTask. ValueTask yapısı, System.Threading.Tasks.Task sınıfına
benzer bir API sağlar. ValueTask , performans nedenleriyle bu arabirimlerde kullanılır.

Zaman uyumsuz akışlara Dönüştür


Sonra, runPagedQueryAsync yöntemini bir zaman uyumsuz akış oluşturacak şekilde dönüştürün. İlk olarak,
runPagedQueryAsync imzasını bir IAsyncEnumerable<JToken> döndürecek şekilde değiştirin ve aşağıdaki kodda
gösterildiği gibi parametre listesinden iptal belirtecini ve ilerleme nesnelerini kaldırın:

private static async IAsyncEnumerable<JToken> runPagedQueryAsync(GitHubClient client,


string queryText, string repoName)

Başlangıç kodu, aşağıdaki kodda gösterildiği gibi her sayfayı sayfa alındığından işler:

finalResults.Merge(issues(results)["nodes"]);
progress?.Report(issuesReturned);
cancel.ThrowIfCancellationRequested();

Bu üç satırı aşağıdaki kodla değiştirin:

foreach (JObject issue in issues(results)["nodes"])


yield return issue;

Ayrıca, bu yöntemin önceki finalResults bildirimini ve değiştirdiğiniz döngüyü izleyen return bildirimini de
kaldırabilirsiniz.
Zaman uyumsuz akış oluşturma değişikliklerini tamamladınız. Tamamlanan yöntem aşağıdaki koda benzemelidir:

private static async IAsyncEnumerable<JToken> runPagedQueryAsync(GitHubClient client,


string queryText, string repoName)
{
var issueAndPRQuery = new GraphQLRequest
{
Query = queryText
};
issueAndPRQuery.Variables["repo_name"] = repoName;

bool hasMorePages = true;


int pagesReturned = 0;
int issuesReturned = 0;

// Stop with 10 pages, because these are large repos:


while (hasMorePages && (pagesReturned++ < 10))
{
var postBody = issueAndPRQuery.ToJsonText();
var response = await client.Connection.Post<string>(new Uri("https://api.github.com/graphql"),
postBody, "application/json", "application/json");

JObject results = JObject.Parse(response.HttpResponse.Body.ToString());

int totalCount = (int)issues(results)["totalCount"];


hasMorePages = (bool)pageInfo(results)["hasPreviousPage"];
issueAndPRQuery.Variables["start_cursor"] = pageInfo(results)["startCursor"].ToString();
issuesReturned += issues(results)["nodes"].Count();

foreach (JObject issue in issues(results)["nodes"])


yield return issue;
}

JObject issues(JObject result) => (JObject)result["data"]["repository"]["issues"];


JObject pageInfo(JObject result) => (JObject)issues(result)["pageInfo"];
}

Daha sonra, zaman uyumsuz akışı kullanmak için koleksiyonu tüketen kodu değiştirirsiniz. Sorun koleksiyonunu
işleyen Main aşağıdaki kodu bulun:

var progressReporter = new progressStatus((num) =>


{
Console.WriteLine($"Received {num} issues in total");
});
CancellationTokenSource cancellationSource = new CancellationTokenSource();

try
{
var results = await runPagedQueryAsync(client, PagedIssueQuery, "docs",
cancellationSource.Token, progressReporter);
foreach(var issue in results)
Console.WriteLine(issue);
}
catch (OperationCanceledException)
{
Console.WriteLine("Work has been cancelled");
}

Bu kodu aşağıdaki await foreach döngüsüyle değiştirin:


int num = 0;
await foreach (var issue in runPagedQueryAsync(client, PagedIssueQuery, "docs"))
{
Console.WriteLine(issue);
Console.WriteLine($"Received {++num} issues in total");
}

Tamamlanan öğreticinin kodunu CSharp/öğreticiler/AsyncStreams klasöründeki DotNet/Samples deposundan


alabilirsiniz.

Tamamlanmış uygulamayı çalıştırma


Uygulamayı yeniden çalıştırın. Davranışını, başlangıç uygulamasının davranışıyla kontrast. Sonuçların ilk sayfası,
kullanılabilir duruma geldiğinde numaralandırılır. Her yeni sayfa istendiği ve alındığı için bir observable
durakladıkça, sonraki sayfanın sonuçları hızla numaralandırılır. try / catch bloğu iptali işlemek için gerekli
değildir: çağıran, koleksiyonu listemeyi durdurabilir. Zaman uyumsuz akış, her sayfa indirildiğinden sonuçlar
oluşturduğundan, ilerleme durumu açıkça raporlanır. Döndürülen her bir sorunun durumu await foreach
döngüsüne sorunsuz bir şekilde dahildir. İlerlemeyi izlemek için bir geri çağırma nesnesine gerek yoktur.
Kodu inceleyerek, bellek kullanımıyla iyileştirmeleri görebilirsiniz. Artık tüm sonuçları numaralandırılmadan önce
depolamak için bir koleksiyon ayırmanız gerekmez. Çağıran, sonuçların nasıl kullanıldığını ve bir depolama
koleksiyonu gerekip gerekmediğini belirleyebilir.
Hem Başlatıcı hem de tamamlanmış uygulamaları çalıştırın ve uygulamalar arasındaki farklılıkları
gözlemleyebilirsiniz. İşiniz bittiğinde, bu öğreticiyi başlattığınızda oluşturduğunuz GitHub erişim belirtecini
silebilirsiniz. Bir saldırgan bu belirtece erişim kazanırsa, kimlik bilgilerinizi kullanarak GitHub API 'Lerine
erişebilirler.
Öğretici: veri türlerini genişletmek için model
eşleştirme özelliklerini kullanma
30.10.2019 • 22 minutes to read • Edit Online

C#7 temel desenler eşleşen özellikler sunmuştur. Bu özellikler yeni ifadelerle ve C# desenlerle 8 ' de genişletilir.
Başka kitaplıklarda olabilecek türleri genişletmekle birlikte davranan işlevselliği yazabilirsiniz. Desenler için başka
bir kullanım, uygulamanızın genişletilmekte olan türün temel bir özelliği olmayan bir işlev oluşturmasını gerektirir.
Bu öğreticide, aşağıdakileri nasıl yapacağınızı öğreneceksiniz:
Model eşleştirmesinin kullanılması gereken durumları tanıyın.
Türleri ve özellik değerlerini temel alan davranışı uygulamak için kalıp eşleştirme ifadelerini kullanın.
Tüm algoritmalar oluşturmak için model eşleştirmeyi diğer tekniklerle birleştirin.

Prerequisites
Makinenizi, C# 8,0 derleyicisi dahil .NET Core çalıştıracak şekilde ayarlamanız gerekir. 8 C# derleyicisi, Visual
Studio 2019 sürüm 16,3 veya .NET Core 3,0 SDKile başlayarak kullanılabilir.
Bu öğreticide, Visual Studio veya C# .NET Core CLI dahil olmak üzere, .net hakkında bilgi sahibi olduğunuz
varsayılır.

Model eşleştirme senaryoları


Modern geliştirme genellikle birden çok kaynaktaki verilerin tümleştirilmesine ve bu verilerden tek bir ortak
uygulamada bilgi ve Öngörüler sunmaya dahildir. Siz ve takımınız gelen verileri temsil eden tüm türler için
denetime veya erişime sahip olmayacaktır.
Klasik nesne odaklı tasarım, uygulamanızda, bu birden çok veri kaynağından her bir veri türünü temsil eden türler
oluşturmak için çağrı yapılır. Daha sonra uygulamanız bu yeni türlerle çalışarak devralma hiyerarşileri oluşturun,
sanal yöntemler oluşturur ve soyutlamalar uygular. Bu teknikler çalışır ve bazen en iyi araçlardır. Diğer zamanlarda
da daha az kod yazabilirsiniz. Verileri işleyen işlemlerden verileri ayıran teknikleri kullanarak daha fazla şifresiz kod
yazabilirsiniz.
Bu öğreticide, tek bir senaryo için çeşitli dış kaynaklardan gelen verileri alan bir uygulama oluşturacaksınız ve
keşfedeceğiz. Düzenin , bu verileri özgün sistemin parçası olmayan yollarla tüketmek ve işlemek için etkili bir yol
sağladığını görürsünüz.
Trafiği yönetmek için Tolls ve yoğun zaman fiyatlandırması kullanan bir ana metropol alanı düşünün. Türüne göre
bir araç için Tolls 'yi hesaplayan bir uygulama yazarsınız. Daha sonraki geliştirmeler, araç çubuğundaki alan
sayısına göre fiyatlandırmaya dahil değildir. Daha fazla geliştirmeler, haftanın saatine ve gününe göre fiyatlandırma
ekler.
Bu kısa açıklamadan, bu sistemi modellemek için bir nesne hiyerarşisinde hızlıca taslak oluşturabilirsiniz. Ancak,
verileriniz diğer araç kayıt yönetimi sistemleri gibi birden çok kaynaktan geliyor. Bu sistemler, verileri modellemek
için farklı sınıflar sağlar ve kullanabileceğiniz tek bir nesne modeli yoktur. Bu öğreticide, aşağıdaki kodda
gösterildiği gibi bu dış sistemlerden araç verilerini modellemek için bu Basitleştirilmiş sınıfları kullanacaksınız:
namespace ConsumerVehicleRegistration
{
public class Car
{
public int Passengers { get; set; }
}
}

namespace CommercialRegistration
{
public class DeliveryTruck
{
public int GrossWeightClass { get; set; }
}
}

namespace LiveryRegistration
{
public class Taxi
{
public int Fares { get; set; }
}

public class Bus


{
public int Capacity { get; set; }
public int Riders { get; set; }
}
}

Başlangıç kodunu DotNet/Samples GitHub deposundan indirebilirsiniz. Araç sınıflarının farklı sistemlerden
olduğunu ve farklı ad alanlarında olduğunu görebilirsiniz. System.Object dışındaki ortak bir temel sınıf
yararlanılabilir olabilir.

Desen eşleştirme tasarımları


Bu öğreticide kullanılan senaryo, düzenin eşleşmesi için uygun olan sorun türlerini vurgular:
Çalışmanız gereken nesneler, hedeflerinizle eşleşen bir nesne hiyerarşisinde değildir.İlişkisiz sistemlerin parçası
olan sınıflarla çalışıyor olabilirsiniz.
Eklemekte olduğunuz işlevsellik, bu sınıfların temel soyutlama kapsamında değildir. Bir araç tarafından ücretli
bir araç, farklı araç türlerine göre değişir ancak ücretli bir temel işlev değildir.
Verilerin şekli ve bu verilerdeki işlemler birlikte açıklanmadığında, ' deki C# model eşleme özellikleri ile çalışmayı
kolaylaştırır.

Temel ücretli hesaplamaları uygulayın


En temel ücretli hesaplama yalnızca araç türüne bağlıdır:
Car $2,00 ' dir.
Taxi $3,50 ' dir.
Bus $5,00 ' dir.
DeliveryTruck $10,00

Yeni bir TollCalculator sınıfı oluşturun ve ücretli miktarı almak için araç türünde kalıp eşleştirmeyi uygulayın.
Aşağıdaki kod TollCalculator ilk uygulamasını gösterir.
using System;
using CommercialRegistration;
using ConsumerVehicleRegistration;
using LiveryRegistration;

namespace toll_calculator
{
public class TollCalculator
{
public decimal CalculateToll(object vehicle) =>
vehicle switch
{
Car c => 2.00m,
Taxi t => 3.50m,
Bus b => 5.00m,
DeliveryTruck t => 10.00m,
{ } => throw new ArgumentException(message: "Not a known vehicle type", paramName:
nameof(vehicle)),
null => throw new ArgumentNullException(nameof(vehicle))
};
}
}

Yukarıdaki kod, tür modelinitest eden bir switch ifadesi (bir switch ifadesiyle aynı değildir) kullanır. Bir switch
ifadesi , önceki kodda vehicle ve ardından switch anahtar sözcüğü ile başlar. Ardından, küme ayraçları içindeki
tüm anahtar kolları gelir. switch ifadesi, switch deyimini çevreleyen söz dizimi için diğer işlevselliklerindeki
yapar. case anahtar sözcüğü atlanır ve her bir ARM 'nin sonucu bir ifadedir. Son iki kolonun yeni bir dil özelliği
gösterir. { } Case, önceki bir ARM ile eşleşmeyen null olmayan tüm nesneler ile eşleşir. Bu ARM, bu yönteme
geçirilen hatalı türleri yakalar. { } durum, her bir araç türü için durumları izlemelidir. Sıra tersine çevrilirse, { }
durumu öncelik kazanır. Son olarak, null deseninin bu yönteme bir null geçtiğini algılar. Diğer tür desenleri
doğru türdeki yalnızca null olmayan bir nesneyle eşleştiğinden null deseni son olabilir.
Program.cs ' de aşağıdaki kodu kullanarak bu kodu test edebilirsiniz:
using System;
using CommercialRegistration;
using ConsumerVehicleRegistration;
using LiveryRegistration;

namespace toll_calculator
{
class Program
{
static void Main(string[] args)
{
var tollCalc = new TollCalculator();

var car = new Car();


var taxi = new Taxi();
var bus = new Bus();
var truck = new DeliveryTruck();

Console.WriteLine($"The toll for a car is {tollCalc.CalculateToll(car)}");


Console.WriteLine($"The toll for a taxi is {tollCalc.CalculateToll(taxi)}");
Console.WriteLine($"The toll for a bus is {tollCalc.CalculateToll(bus)}");
Console.WriteLine($"The toll for a truck is {tollCalc.CalculateToll(truck)}");

try
{
tollCalc.CalculateToll("this will fail");
}
catch (ArgumentException e)
{
Console.WriteLine("Caught an argument exception when using the wrong type");
}
try
{
tollCalc.CalculateToll(null);
}
catch (ArgumentNullException e)
{
Console.WriteLine("Caught an argument exception when using null");
}
}
}
}

Bu kod, başlatıcı projesine dahil edilmiştir, ancak açıklama eklenir. Açıklamaları kaldırın ve ne yazdığınızı test
edebilirsiniz.
Desenlerin kodun ve verilerin ayrı olduğu algoritmalar oluşturmanıza nasıl yardımcı olduğunu görmeyi başlıyoruz.
switch ifade, türü sınar ve sonuçlara göre farklı değerler üretir. Bu yalnızca başlangıç amaçlıdır.

İskan fiyatlandırması Ekle


Ücretli yetkili, en yüksek kapasiteden gezilerin gezmelerini teşvik etmek istiyor. Araçlar daha az pastlar olduğunda
daha fazla ücret ödemelerine ve daha düşük fiyatlandırma sunarak tam bir şekilde teşvik etmeye karar vermiştir:
Otomobiller ve Tax, hiçbir Pasca, ek $0,50 ödeyebilir.
Otomobiller ve Tax, iki pasa, $0,50 indirimi alır.
Üç veya daha fazla Pascal ile otomobiller ve Tax, $1,00 indirimi alır.
%50 ' den küçük veri yolları, fazladan $2,00 oranında ödeyin.
%90 ' den fazla tam veri yolları $1,00 indirimi elde edin.
Bu kurallar, aynı anahtar ifadesinde özellik düzeniyle kullanılarak uygulanabilir. Özellik deseninin türü
belirlendikten sonra nesnenin özellikleri incelenir. Car için tek durum dört farklı durumda genişler:
vehicle switch
{
Car { Passengers: 0} => 2.00m + 0.50m,
Car { Passengers: 1 } => 2.0m,
Car { Passengers: 2} => 2.0m - 0.50m,
Car c => 2.00m - 1.0m,

// ...
};

İlk üç durum türü Car olarak test edin ve sonra Passengers özelliğinin değerini denetleyin. Her ikisi de
eşleşiyorsa, bu ifade değerlendirilir ve döndürülür.
Ayrıca, taxiçin de benzer bir şekilde durum da genişletebilirsiniz:

vehicle switch
{
// ...

Taxi { Fares: 0} => 3.50m + 1.00m,


Taxi { Fares: 1 } => 3.50m,
Taxi { Fares: 2} => 3.50m - 0.50m,
Taxi t => 3.50m - 1.00m,

// ...
};

Yukarıdaki örnekte, son durumda when yan tümcesi atlandı.


Ardından, aşağıdaki örnekte gösterildiği gibi, veri yolları için durumları genişleterek sahiplik kurallarını uygulayın:

vehicle switch
{
// ...

Bus b when ((double)b.Riders / (double)b.Capacity) < 0.50 => 5.00m + 2.00m,


Bus b when ((double)b.Riders / (double)b.Capacity) > 0.90 => 5.00m - 1.00m,
Bus b => 5.00m,

// ...
};

Ücretli yetkili, teslim kamyonları içindeki pastıcılar sayısıyla ilgilenmez. Bunun yerine, aşağıdaki gibi, kamyonlar
ağırlık sınıfına göre ücretli miktarı ayarlar:
5000 lbs üzerinde structuralks, fazladan $5,00 ücretlendirilir.
3000 lbs kapsamında hafif bir $2,00 indirimi verilir.
Bu kural aşağıdaki kodla uygulanır:

vehicle switch
{
// ...

DeliveryTruck t when (t.GrossWeightClass > 5000) => 10.00m + 5.00m,


DeliveryTruck t when (t.GrossWeightClass < 3000) => 10.00m - 2.00m,
DeliveryTruck t => 10.00m,
};
Yukarıdaki kod, anahtar ARM 'nin when yan tümcesini gösterir. Bir özellikte eşitlik dışındaki koşulları test etmek
için when yan tümcesini kullanırsınız. İşiniz bittiğinde aşağıdakine benzer bir yönteme sahip olacaksınız:

vehicle switch
{
Car { Passengers: 0} => 2.00m + 0.50m,
Car { Passengers: 1} => 2.0m,
Car { Passengers: 2} => 2.0m - 0.50m,
Car c => 2.00m - 1.0m,

Taxi { Fares: 0} => 3.50m + 1.00m,


Taxi { Fares: 1 } => 3.50m,
Taxi { Fares: 2} => 3.50m - 0.50m,
Taxi t => 3.50m - 1.00m,

Bus b when ((double)b.Riders / (double)b.Capacity) < 0.50 => 5.00m + 2.00m,


Bus b when ((double)b.Riders / (double)b.Capacity) > 0.90 => 5.00m - 1.00m,
Bus b => 5.00m,

DeliveryTruck t when (t.GrossWeightClass > 5000) => 10.00m + 5.00m,


DeliveryTruck t when (t.GrossWeightClass < 3000) => 10.00m - 2.00m,
DeliveryTruck t => 10.00m,

{ } => throw new ArgumentException(message: "Not a known vehicle type", paramName: nameof(vehicle)),
null => throw new ArgumentNullException(nameof(vehicle))
};

Bu anahtar kolları çoğu özyinelemeli desenlereörnektir. Örneğin Car { Passengers: 1} , bir özellik deseninin
içinde sabit bir model gösterir.
İç içe geçmiş anahtarlar kullanarak bu kodu daha az tekrarlı hale getirebilirsiniz. Car ve Taxi her ikisi de önceki
örneklerde dört farklı kollu bir sahiptir. Her iki durumda da, bir özellik düzeninde akışlara bir tür stili
oluşturabilirsiniz. Bu teknik aşağıdaki kodda gösterilmiştir:
public decimal CalculateToll(object vehicle) =>
vehicle switch
{
Car c => c.Passengers switch
{
0 => 2.00m + 0.5m,
1 => 2.0m,
2 => 2.0m - 0.5m,
_ => 2.00m - 1.0m
},

Taxi t => t.Fares switch


{
0 => 3.50m + 1.00m,
1 => 3.50m,
2 => 3.50m - 0.50m,
_ => 3.50m - 1.00m
},

Bus b when ((double)b.Riders / (double)b.Capacity) < 0.50 => 5.00m + 2.00m,


Bus b when ((double)b.Riders / (double)b.Capacity) > 0.90 => 5.00m - 1.00m,
Bus b => 5.00m,

DeliveryTruck t when (t.GrossWeightClass > 5000) => 10.00m + 5.00m,


DeliveryTruck t when (t.GrossWeightClass < 3000) => 10.00m - 2.00m,
DeliveryTruck t => 10.00m,

{ } => throw new ArgumentException(message: "Not a known vehicle type", paramName: nameof(vehicle)),
null => throw new ArgumentNullException(nameof(vehicle))
};

Önceki örnekte, özyinelemeli bir ifade kullanılması, özellik değerini test eden alt kolları içeren Car ve Taxi kolları
yinelemediğiniz anlamına gelir. Bu özellikler, Bus ve DeliveryTruck kolları için kullanılmaz, çünkü bu Koller özellik
için aralıkları test ettiğinden ayrık değerler değildir.

Tepe fiyatlandırması Ekle


Son özellik için, ücretli yetkili zamana duyarlı tepe fiyatlandırması eklemek istemektedir. Sabah ve akşam aceleniz
saatlerinde, Tolls iki katına çıkar. Bu kural yalnızca bir yönde trafiği etkiler: sabah şehrine gelen ve akşam aceleniz
Hour 'daki çıkış. İş gününde diğer saatlerde, Tolls %50 oranında artar. Geç gece ve erken sabah, Tolls %25 oranında
azaltılır. Hafta sonu sırasında, zamandan bağımsız olarak normal fiyat olur.
Bu özellik için model eşleştirmeyi kullanacaksınız, ancak diğer tekniklerle tümleştirilecek. Tüm yön, hafta günü ve
saat birleşimleri için hesap oluşturacak tek bir kalıp eşleştirme ifadesi oluşturabilirsiniz. Sonuç karmaşık bir ifade
olacaktır. Okunması zor olabilir. Bu, doğruluğu garanti etmelerini zorlaştırır. Bunun yerine, öz 'in tüm bu durumları
açıkladığı bir dizi değer oluşturmak için bu yöntemleri birleştirin. Ardından, ücretli bir çarpanı hesaplamak için
model eşleştirmeyi kullanın. Kayıt düzeni üç farklı koşul içerir:
Gün, bir hafta içi veya bir hafta sonu olabilir.
Ücretli sürenin toplanacağı zaman bandı.
Yön City veya City 'den
Aşağıdaki tabloda, giriş değerleri ve en yüksek fiyatlandırma çarpanı birleşimleri gösterilmektedir:

GÜN ZAMAN YÖN PREMIUM

HAFTANINGÜNÜ sabah aceleniz Gelen x 2,00

HAFTANINGÜNÜ sabah aceleniz Giden x 1,00


GÜN ZAMAN YÖN PREMIUM

HAFTANINGÜNÜ saati Gelen x 1,50

HAFTANINGÜNÜ saati Giden x 1,50

HAFTANINGÜNÜ akşam aceleniz Gelen x 1,00

HAFTANINGÜNÜ akşam aceleniz Giden x 2,00

HAFTANINGÜNÜ gece Gelen x 0,75

HAFTANINGÜNÜ gece Giden x 0,75

Hafta sabah aceleniz Gelen x 1,00

Hafta sabah aceleniz Giden x 1,00

Hafta saati Gelen x 1,00

Hafta saati Giden x 1,00

Hafta akşam aceleniz Gelen x 1,00

Hafta akşam aceleniz Giden x 1,00

Hafta gece Gelen x 1,00

Hafta gece Giden x 1,00

Üç değişkenin 16 farklı birleşimi vardır. Bazı koşulları birleştirerek son anahtar ifadesini basitleştirirsiniz.
Tolls 'yi toplayan sistem, ücretli bir süre için DateTime yapısını kullanır. Yukarıdaki tablodan değişkenleri oluşturan
üye yöntemleri oluşturun. Aşağıdaki işlev bir DateTime hafta sonu veya haftanın gününü temsil edip etmediğini
ifade etmek için bir model eşleştirme anahtar ifadesi kullanır:

private static bool IsWeekDay(DateTime timeOfToll) =>


timeOfToll.DayOfWeek switch
{
DayOfWeek.Monday => true,
DayOfWeek.Tuesday => true,
DayOfWeek.Wednesday => true,
DayOfWeek.Thursday => true,
DayOfWeek.Friday => true,
DayOfWeek.Saturday => false,
DayOfWeek.Sunday => false
};

Bu yöntem işe yarar, ancak repetitious. Aşağıdaki kodda gösterildiği gibi basitleşebilir:
private static bool IsWeekDay(DateTime timeOfToll) =>
timeOfToll.DayOfWeek switch
{
DayOfWeek.Saturday => false,
DayOfWeek.Sunday => false,
_ => true
};

Sonra, zaman bloklara zaman kategorize etmek için benzer bir işlev ekleyin:

private enum TimeBand


{
MorningRush,
Daytime,
EveningRush,
Overnight
}

private static TimeBand GetTimeBand(DateTime timeOfToll)


{
int hour = timeOfToll.Hour;
if (hour < 6)
return TimeBand.Overnight;
else if (hour < 10)
return TimeBand.MorningRush;
else if (hour < 16)
return TimeBand.Daytime;
else if (hour < 20)
return TimeBand.EveningRush;
else
return TimeBand.Overnight;
}

Önceki yöntem, model eşleştirme kullanmaz. if deyimleri tanıdık bir basamakla daha net. Her zaman aralığını
ayrı bir değere dönüştürmek için özel bir enum eklersiniz.
Bu yöntemleri oluşturduktan sonra, fiyatlandırma Premium 'u hesaplamak için tanımlama grubu düzeniyle
başka bir switch ifadesini kullanabilirsiniz. Tüm 16 kollu bir switch ifadesi oluşturabilirsiniz:

public decimal PeakTimePremiumFull(DateTime timeOfToll, bool inbound) =>


(IsWeekDay(timeOfToll), GetTimeBand(timeOfToll), inbound) switch
{
(true, TimeBand.MorningRush, true) => 2.00m,
(true, TimeBand.MorningRush, false) => 1.00m,
(true, TimeBand.Daytime, true) => 1.50m,
(true, TimeBand.Daytime, false) => 1.50m,
(true, TimeBand.EveningRush, true) => 1.00m,
(true, TimeBand.EveningRush, false) => 2.00m,
(true, TimeBand.Overnight, true) => 0.75m,
(true, TimeBand.Overnight, false) => 0.75m,
(false, TimeBand.MorningRush, true) => 1.00m,
(false, TimeBand.MorningRush, false) => 1.00m,
(false, TimeBand.Daytime, true) => 1.00m,
(false, TimeBand.Daytime, false) => 1.00m,
(false, TimeBand.EveningRush, true) => 1.00m,
(false, TimeBand.EveningRush, false) => 1.00m,
(false, TimeBand.Overnight, true) => 1.00m,
(false, TimeBand.Overnight, false) => 1.00m,
};

Yukarıdaki kod işe yarar, ancak basitleştirilebilir.Hafta sonu için sekiz kombinasyonun hepsi de aynı ücretli bir. Tüm
sekiz değerini aşağıdaki satırla değiştirebilirsiniz:
(false, _, _) => 1.0m,

Hem gelen hem de giden trafik, hafta içi gündüz ve gece saatlerinde aynı katkılar. Bu dört anahtar kolları aşağıdaki
iki satır ile değiştirilebilir:

(true, TimeBand.Overnight, _) => 0.75m,


(true, TimeBand.Daytime, _) => 1.5m,

Kod, bu iki değişiklikten sonra aşağıdaki kod gibi görünmelidir:

public decimal PeakTimePremium(DateTime timeOfToll, bool inbound) =>


(IsWeekDay(timeOfToll), GetTimeBand(timeOfToll), inbound) switch
{
(true, TimeBand.MorningRush, true) => 2.00m,
(true, TimeBand.MorningRush, false) => 1.00m,
(true, TimeBand.Daytime, _) => 1.50m,
(true, TimeBand.EveningRush, true) => 1.00m,
(true, TimeBand.EveningRush, false) => 2.00m,
(true, TimeBand.Overnight, _) => 0.75m,
(false, _, _) => 1.00m,
};

Son olarak, normal fiyatı ödeyerek iki aceleniz saatlik saati kaldırabilirsiniz. Bu kolları kaldırdıktan sonra, false
son anahtar ARM içindeki bir atma ( _ ) ile değiştirebilirsiniz. Aşağıdaki tamamlanmış yönteme sahip olacaksınız:

public decimal PeakTimePremium(DateTime timeOfToll, bool inbound) =>


(IsWeekDay(timeOfToll), GetTimeBand(timeOfToll), inbound) switch
{
(true, TimeBand.Overnight, _) => 0.75m,
(true, TimeBand.Daytime, _) => 1.5m,
(true, TimeBand.MorningRush, true) => 2.0m,
(true, TimeBand.EveningRush, false) => 2.0m,
(_, _, _) => 1.0m,
};

Bu örnek, düzen eşleştirmesinin avantajlarından birini vurgular: düzen dalları sırayla değerlendirilir. Daha önceki
bir dalın daha sonraki durumlardan birini işleyeceği şekilde yeniden ayarlarsanız, derleyici ulaşılamaz kod
hakkında sizi uyarır. Bu dil kuralları, önceki basitleştirmeleri kodun değiştirmiyordu güvenle daha kolay hale getirir.
Model eşleştirme bazı kod türlerini daha okunaklı hale getirir ve sınıflarınıza kod ekleyemadığınızda nesne odaklı
teknikler için bir alternatif sağlar. Bulut, verilerin ve işlevlerin canlı olmasına neden oluyor. Verilerin şekli ve
üzerindeki işlemler birlikte açıklanmamaktadır. Bu öğreticide, var olan verileri özgün işlevinden tamamen farklı
şekillerde kullandınız. Model eşleştirme, bunları genişletmemiş olsanız bile, bu türlerin üzerine geçen işlevselliği
yazma olanağını vermiştir.

Sonraki adımlar
Tamamlanan kodu DotNet/Samples GitHub deposundan indirebilirsiniz. Kendi hiyerarşinizdeki desenleri
keşfedebilir ve bu tekniği düzenli kodlama etkinliklerinize ekleyin. Bu teknikleri öğrenirken, sorun yaklaşımı ve yeni
işlevler oluşturmak için kullanabileceğiniz başka bir yol sunulmaktadır.
Konsol Uygulaması
30.10.2019 • 19 minutes to read • Edit Online

Bu öğretici, .NET Core ve bu C# dilin çeşitli özelliklerini öğretir. Şunları öğreneceksiniz:


.NET Core komut satırı arabirimi (CLı) temelleri
C# Konsol uygulamasının yapısı
Konsol g/ç
.NET 'teki dosya g/ç API 'Lerinin temelleri
.NET ' te görev tabanlı zaman uyumsuz programlama temelleri
Bir metin dosyasını okuyan ve bu metin dosyasının içeriğini konsola yansıtan bir uygulama oluşturacaksınız.
Konsola giden çıkış, okumayı yüksek sesle eşleştirmeye yönelik olarak ilerleyebileceğiniz bir adım adım olur. ' < '
(Küçüktür) veya ' > ' (büyüktür) anahtarlarına basarak hızla hızlandıramaz veya azaltabilirsiniz.
Bu öğreticide birçok özellik vardır. Bunları birer birer oluşturalım.

Prerequisites
.NET Core 'u çalıştırmak için makinenizi ayarlamanız gerekir. Yükleme yönergelerini .NET Core İndirmeleri
sayfasında bulabilirsiniz. Bu uygulamayı Windows, Linux, macOS veya bir Docker kapsayıcısında çalıştırabilirsiniz.
En sevdiğiniz kod düzenleyicinizi yüklemeniz gerekir.

Uygulamayı oluşturma
İlk adım yeni bir uygulama oluşturmaktır. Bir komut istemi açın ve uygulamanız için yeni bir dizin oluşturun.
Geçerli dizini oluşturun. Komut istemine komut dotnet new console yazın. Bu, temel bir "Merhaba Dünya"
uygulaması için başlangıç dosyalarını oluşturur.
Değişiklik yapmaya başlamadan önce, basit Merhaba Dünya uygulamasını çalıştırmak için adımları ilerlim.
Uygulamayı oluşturduktan sonra komut istemine dotnet restore yazın. Bu komut NuGet paketi geri yükleme
işlemini çalıştırır. NuGet bir .NET paket yöneticisidir. Bu komut, projeniz için eksik bağımlılıkları indirir. Bu yeni bir
proje olduğundan, bağımlılıklardan hiçbiri yerinde değildir, bu nedenle ilk çalıştırma .NET Core çerçevesini indirir.
Bu ilk adımdan sonra, yalnızca yeni bağımlı paketler eklediğinizde dotnet restore çalıştırmanız veya
bağımlılıklarınızın herhangi birinin sürümlerini güncelleştirmeniz gerekir.

NOTE
.NET Core 2.0 SDK'sı ile başlayarak, çalıştırma gerekmez dotnet restore bir geri yükleme, örneğin, gerçekleşmesi için
gerekli tüm komutlar tarafından örtük olarak çalıştırıldığından dotnet new , dotnet build ve dotnet run . Bunu hala
geçerli bir komut burada açık bir geri yükleme yaparsanız anlamlı, bazı senaryolarda olduğu gibi sürekli tümleştirme
derlemeleri Azure DevOps Hizmetleri'nde veya açıkça zaman denetlemek için gereken derleme sistemlerinde geri yükleme
gerçekleşir.

Paketleri geri yükledikten sonra dotnet build çalıştırırsınız. Bu, yapı altyapısını yürütür ve uygulamanızı
çalıştırılabilir olarak oluşturur. Son olarak, uygulamanızı çalıştırmak için dotnet run yürütün.
Basit Merhaba Dünya uygulama kodu Program.cs ' de bulunur. Bu dosyayı en sevdiğiniz metin düzenleyicinizle
açın. İlk değişikliklerimizi yapmak bizim için çalışıyoruz. Dosyanın en üstünde, bkz. using deyimleri:
using System;

Bu ifade, derleyiciye System ad alanındaki herhangi bir türün kapsam içinde olduğunu söyler. Kullandığınız diğer
nesne yönelimli diller gibi, C# türleri düzenlemek için ad alanlarını kullanır. Bu Merhaba Dünya program farklı
değildir. Programın adı ile geçerli dizinin adına bağlı olarak ad alanı içinde bulunduğunu görebilirsiniz. Bu öğretici
için ad alanının adını TeleprompterConsole olarak değiştirelim:

namespace TeleprompterConsole

Dosyayı okuma ve Yankılandırın


Eklenecek ilk özellik, bir metin dosyasını okuma ve bu metnin tümünü konsola görüntüleme olanağıdır. İlk olarak
bir metin dosyası ekleyelim. Bu örnek için GitHub deposundan samplequotes. txt dosyasını proje dizininize
kopyalayın. Bu, uygulamanız için komut dosyası olarak görev yapar. Bu konu için örnek uygulamanın nasıl
indirileceği hakkında bilgi isterseniz, örnekler ve öğreticiler konusundaki yönergelere bakın.
Sonra, Program Sınıfınıza aşağıdaki yöntemi ekleyin ( Main yönteminin hemen altına):

static IEnumerable<string> ReadFrom(string file)


{
string line;
using (var reader = File.OpenText(file))
{
while ((line = reader.ReadLine()) != null)
{
yield return line;
}
}
}

Bu yöntem iki yeni ad alanından türler kullanır. Bu derleme için, dosyanın en üstüne aşağıdaki iki satırı eklemeniz
gerekir:

using System.Collections.Generic;
using System.IO;

IEnumerable<T> arabirimi System.Collections.Generic ad alanında tanımlanmıştır. File sınıfı, System.IO ad


alanında tanımlanmıştır.
Bu yöntem, yineleyici yöntemiolarak adlandırılan C# özel bir yöntem türüdür. Numaralandırıcı yöntemleri
değerlendirilen dizileri döndürür geç. Bu, dizideki her öğe, diziyi kullanan kod tarafından istenerek oluşturulduğu
anlamına gelir. Numaralandırıcı yöntemleri bir veya daha fazla yield return deyimi içeren yöntemlerdir.
ReadFrom yöntemi tarafından döndürülen nesne, dizideki her bir öğeyi oluşturmak için kodu içerir. Bu örnekte,
kaynak dosyadaki bir sonraki metin satırını okumayı ve bu dizeyi döndürmeyle ilgilidir. Çağıran kod, sıradaki bir
sonraki öğeyi her istediğinde, kod dosyadaki metnin bir sonraki satırını okur ve döndürür. Dosya tamamen
okunmadığında, dizi daha fazla öğe olmadığını gösterir.
Size yeni olabilecek iki C# farklı sözdizimi öğesi vardır. Bu yöntemdeki using ifadesinin kaynağı temizleme
işlemini yönetir. using bildiriminde ( reader , bu örnekte) başlatılan değişken IDisposable arabirimini
gerçekleştirmelidir. Bu arabirim, kaynak yayınlanacaksa çağrılması gereken tek bir yöntemi Dispose tanımlar. ,
Yürütme using deyimin kapanış ayracına ulaştığında derleyici bu çağrıyı oluşturur. Derleyici tarafından
oluşturulan kod, using ifadesiyle tanımlanan bloktaki koddan bir özel durum oluşsa bile kaynağın serbest
bırakılacağını sağlar.
reader değişkeni var anahtar sözcüğü kullanılarak tanımlanır. var örtük olarak yazılmış bir yerel
değişkenitanımlar. Bu, değişkenin türü değişkene atanan nesnenin derleme zamanı türü tarafından belirlendiği
anlamına gelir. Burada, bir StreamReader nesnesi olan OpenText(String) yönteminin dönüş değeridir.
Şimdi de Main yönteminde dosyayı okumak için kodu dolduralım:

var lines = ReadFrom("sampleQuotes.txt");


foreach (var line in lines)
{
Console.WriteLine(line);
}

Programı çalıştırın ( dotnet run kullanarak) ve konsolda yazdırılan her satırı görebilirsiniz.

Gecikme ve biçimlendirme çıktısı ekleme


Ne kadar hızlı görüntülendikleriniz çok yüksek. Şimdi çıktıdaki gecikmeleri eklemeniz gerekir. Başladığınızda,
zaman uyumsuz işleme sağlayan çekirdek koddan bazılarını oluşturacaksınız. Bununla birlikte, bu ilk adımlar
birkaç tane kenar deseninden daha izlenecek. Siz kodu eklerken yorumlara desenler görüntülenir ve kod sonraki
adımlarda güncelleştirilir.
Bu bölümde iki adım vardır. İlk olarak, yineleyici yöntemini tüm satırlar yerine tek bir sözcük döndürecek şekilde
güncelleştireceksiniz. Bu değişiklikler bu değişikliklerle yapılır. yield return line; ifadesini aşağıdaki kodla
değiştirin:

var words = line.Split(' ');


foreach (var word in words)
{
yield return word + " ";
}
yield return Environment.NewLine;

Ardından, dosyanın satırlarını nasıl kullanacağınızı değiştirmeniz ve her bir kelime yazıldıktan sonra bir gecikme
eklemeniz gerekir. Main yöntemindeki Console.WriteLine(line) ifadesini aşağıdaki blokla değiştirin:

Console.Write(line);
if (!string.IsNullOrWhiteSpace(line))
{
var pause = Task.Delay(200);
// Synchronously waiting on a task is an
// anti-pattern. This will get fixed in later
// steps.
pause.Wait();
}

Task sınıfı System.Threading.Tasks ad alanında olduğundan, bu using ifadesini dosyanın en üstüne eklemeniz
gerekir:

using System.Threading.Tasks;

Örneği çalıştırın ve çıktıyı denetleyin. Şimdi, her bir sözcük yazdırılır ve ardından 200 ms gecikme gelir. Ancak,
görüntülenen çıktıda bazı sorunlar gösterilmektedir çünkü kaynak metin dosyasında satır sonu olmadan 80 ' ten
fazla karakter içeren birkaç satır vardır. Bu, kaydırma sırasında okunması zor olabilir. Bu, düzeltilmesi kolay bir
işlemdir. Her satırın uzunluğunu takip edersiniz ve satır uzunluğu belirli bir eşiğe ulaştığında yeni bir satır
oluşturacaksınız. Satır uzunluğunu tutan ReadFrom yönteminde words bildiriminden sonra yerel bir değişken
bildirin:

var lineLength = 0;

Sonra, yield return word + " "; deyiminden sonra aşağıdaki kodu ekleyin (kapatma küme ayracından önce):

lineLength += word.Length + 1;
if (lineLength > 70)
{
yield return Environment.NewLine;
lineLength = 0;
}

Örneği çalıştırın, daha önceden yapılandırılmış hızda sesli okuyabileceksiniz.

Zaman uyumsuz görevler


Bu son adımda, çıktıyı zaman uyumsuz olarak bir görevde yazacak şekilde, Ayrıca metin görüntüsünü hızlandırmak
veya yavaşlatacak şekilde Kullanıcı girişini okumak için başka bir görevi çalıştırırken, metin görüntülemeyi
tamamen durdurmak için kodu ekleyeceksiniz. Bunun içinde ve sonunda birkaç adım vardır, ihtiyacınız olan tüm
güncelleştirmelere sahip olacaksınız. İlk adım, dosyayı okuyup görüntülemesi için oluşturduğunuz kodu temsil
eden zaman uyumsuz Task döndüren bir yöntem oluşturmaktır.
Bu yöntemi Program sınıfa ekleyin ( Main yönteminizin gövdesinden alınır):

private static async Task ShowTeleprompter()


{
var words = ReadFrom("sampleQuotes.txt");
foreach (var word in words)
{
Console.Write(word);
if (!string.IsNullOrWhiteSpace(word))
{
await Task.Delay(200);
}
}
}

İki değişiklik fark edeceksiniz. İlk olarak, yöntemin gövdesinde, bir görevin bitmesini zaman uyumlu olarak
beklemek Wait() yerine, bu sürüm await anahtar sözcüğünü kullanır. Bunu yapmak için yöntem imzasına async
değiştiricisini eklemeniz gerekir. Bu yöntem bir Task döndürür. Task nesnesi döndüren bir dönüş deyimi
olmadığına dikkat edin. Bunun yerine, Task nesnesi, await işlecini kullandığınızda derleyicinin oluşturduğu kodla
oluşturulur. Bu yöntemin, bir await ulaştığında döndürdüğünü düşünün. Döndürülen Task , çalışmanın
tamamlanmadığını gösterir. Yöntemi, beklenen görev tamamlandığında devam eder. Tamamlanmayı
yürütüldüğünde, döndürülen Task tamamlandığını gösterir. Çağıran kod, ne zaman tamamlandığını öğrenmek
için döndürülen Task izleyebilir.
Main yönteminde bu yeni yöntemi çağırabilirsiniz:

ShowTeleprompter().Wait();

Burada Main , kod zaman uyumlu olarak bekler. Mümkün olduğunca zaman uyumlu bekleme yerine await
işlecini kullanmanız gerekir. Ancak, bir konsol uygulamasının Main yönteminde await işlecini kullanamazsınız.
Bu, uygulamanın tüm görevler tamamlanmadan çıkılması ile sonuçlanır.
NOTE
C# 7,1 veya sonraki bir sürümü kullanıyorsanız, async Main yöntemiylekonsol uygulamaları oluşturabilirsiniz.

Sonra, konsolundan okumak için ikinci zaman uyumsuz yöntemi yazmanız ve ' < ' (küçüktür), ' > ' (büyüktür) ve ' x
' veya ' x ' tuşlarından daha fazla bilgi almanız gerekir. Bu görev için eklediğiniz yöntem aşağıda verilmiştir:

private static async Task GetInput()


{
var delay = 200;
Action work = () =>
{
do {
var key = Console.ReadKey(true);
if (key.KeyChar == '>')
{
delay -= 10;
}
else if (key.KeyChar == '<')
{
delay += 10;
}
else if (key.KeyChar == 'X' || key.KeyChar == 'x')
{
break;
}
} while (true);
};
await Task.Run(work);
}

Bu, konsolundan bir anahtar okuyan bir Action temsilcisini temsil eden bir lambda ifadesi oluşturur ve Kullanıcı ' <
' (küçüktür) veya ' > ' (büyüktür) tuşlarından sonra gelen gecikmeyi temsil eden yerel bir değişkeni değiştirir.
Temsilci yöntemi, Kullanıcı ' X ' veya ' x ' tuşlarına bastığında sona erdiğinde, kullanıcının metin görüntüsünü
istediğiniz zaman durdurmasına izin verir. Bu yöntem, engellemek için ReadKey() kullanır ve kullanıcının bir tuşa
basması için bekleyin.
Bu özelliği bitirebilmeniz için, bu görevlerin her ikisini de ( GetInput ve ShowTeleprompter ) Başlatan yeni bir
async Task döndürme yöntemi oluşturmanız ve ayrıca bu iki görev arasındaki paylaşılan verileri de yönetmesi
gerekir.
Bu iki görev arasında paylaşılan verileri işleyebilen bir sınıf oluşturmak zaman alabilir. Bu sınıf iki genel özellik
içerir: gecikme ve bir bayrak, dosyanın tamamen okunduğunu göstermek için Done :
namespace TeleprompterConsole
{
internal class TelePrompterConfig
{
public int DelayInMilliseconds { get; private set; } = 200;

public void UpdateDelay(int increment) // negative to speed up


{
var newDelay = Min(DelayInMilliseconds + increment, 1000);
newDelay = Max(newDelay, 20);
DelayInMilliseconds = newDelay;
}

public bool Done { get; private set; }

public void SetDone()


{
Done = true;
}
}
}

Bu sınıfı yeni bir dosyaya yerleştirin ve bu sınıfı yukarıda gösterildiği gibi TeleprompterConsole ad alanına iliştirin.
Ayrıca, kapsayan sınıf veya ad alanı adları olmadan Min ve Max yöntemlerine başvurabilmeniz için using static
bir ifade eklemeniz gerekir. using static bir ifade, bir sınıftan yöntemleri içeri aktarır. Bu, bir ad alanından tüm
sınıfları içeri aktarmış olan bu noktaya kadar kullanılan using deyimlerinden farklıdır.

using static System.Math;

Sonra, yeni config nesnesini kullanmak için ShowTeleprompter ve GetInput yöntemlerini güncelleştirmeniz
gerekir. Her iki görevi başlatmak ve ilk görev tamamlandığında çıkış yapmak için async yöntemi döndüren bir son
Task yazın:

private static async Task RunTeleprompter()


{
var config = new TelePrompterConfig();
var displayTask = ShowTeleprompter(config);

var speedTask = GetInput(config);


await Task.WhenAny(displayTask, speedTask);
}

Burada yeni bir yöntem WhenAny(Task[]) çağrıdır. Bu, bağımsız değişken listesindeki görevlerden herhangi biri
tamamlandıktan hemen sonra sona erbir Task oluşturur.
Sonra, gecikme için config nesnesini kullanmak üzere hem ShowTeleprompter hem de GetInput yöntemlerini
güncelleştirmeniz gerekir:
private static async Task ShowTeleprompter(TelePrompterConfig config)
{
var words = ReadFrom("sampleQuotes.txt");
foreach (var word in words)
{
Console.Write(word);
if (!string.IsNullOrWhiteSpace(word))
{
await Task.Delay(config.DelayInMilliseconds);
}
}
config.SetDone();
}

private static async Task GetInput(TelePrompterConfig config)


{
Action work = () =>
{
do {
var key = Console.ReadKey(true);
if (key.KeyChar == '>')
config.UpdateDelay(-10);
else if (key.KeyChar == '<')
config.UpdateDelay(10);
else if (key.KeyChar == 'X' || key.KeyChar == 'x')
config.SetDone();
} while (!config.Done);
};
await Task.Run(work);
}

ShowTeleprompter yeni sürümü TeleprompterConfig sınıfında yeni bir yöntemi çağırır. Şimdi, ShowTeleprompter
yerine RunTeleprompter çağırmak için Main güncelleştirmeniz gerekir:

RunTeleprompter().Wait();

Sonuç
Bu öğreticide, C# dil etrafındaki ve konsol uygulamalarında çalışmaya yönelik .NET Core kitaplıklarının çeşitli
özellikleri gösterildi. Bu bilgiyi, dil ve burada tanıtılan sınıflar hakkında daha fazla bilgi için oluşturabilirsiniz. Dosya
ve konsol g/ç, görev tabanlı zaman uyumsuz programlama ile ilgili temel bilgileri, C# dilin bir turuna ve
programların nasıl C# düzenlendiğini ve .NET Core komut satırı arabirimini ve araçlarını gördünüz.
Dosya g/ç hakkında daha fazla bilgi için bkz. dosya ve akış g/ç konusu. Bu öğreticide kullanılan zaman uyumsuz
programlama modeli hakkında daha fazla bilgi için görev tabanlı zaman uyumsuz programlama konusuna ve
zaman uyumsuz programlama konusuna bakın.
REST istemcisi
23.10.2019 • 24 minutes to read • Edit Online

Giriş
Bu öğretici, .NET Core ve bu C# dilin çeşitli özelliklerini öğretir. Şunları öğreneceksiniz:
.NET Core komut satırı arabirimi (CLı) temelleri.
C# Dil özelliklerine genel bakış.
NuGet ile bağımlılıkları yönetme
HTTP Iletişimleri
JSON bilgilerini işleme
Yapılandırmayı özniteliklerle yönetme.
GitHub 'da REST hizmetine HTTP Istekleri veren bir uygulama oluşturacaksınız. JSON biçiminde bilgileri
okuyacaksınız ve bu JSON paketini C# nesnelerine dönüştürürsünüz. Son olarak, C# nesneleriyle nasıl
çalışacaksınız görürsünüz.
Bu öğreticide birçok özellik vardır. Bunları birer birer oluşturalım.
Bu konuyla ilgili son örnekle birlikte izlemeyi tercih ediyorsanız, indirebilirsiniz. İndirme yönergeleri için bkz.
örnekler ve öğreticiler.

Önkoşullar
Makinenizi .NET Core çalıştıracak şekilde ayarlamanız gerekir. Yükleme yönergelerini .NET Core İndirmeleri
sayfasında bulabilirsiniz. Bu uygulamayı Windows, Linux, macOS veya bir Docker kapsayıcısında çalıştırabilirsiniz.
En sevdiğiniz kod düzenleyicinizi yüklemeniz gerekir. Aşağıdaki açıklamalar açık kaynaklı, platformlar arası bir
düzenleyici olan Visual Studio Codekullanır. Bununla birlikte, rahat olan her türlü aracı kullanabilirsiniz.

Uygulamayı oluşturma
İlk adım yeni bir uygulama oluşturmaktır. Bir komut istemi açın ve uygulamanız için yeni bir dizin oluşturun.
Geçerli dizini oluşturun. dotnet new console Komutu komut istemine yazın. Bu, temel bir "Merhaba Dünya"
uygulaması için başlangıç dosyalarını oluşturur. Bu yeni bir proje olduğundan, bağımlılıklardan hiçbiri yerinde
değildir, bu nedenle ilk çalıştırma .NET Core Framework 'ü indirir, bir geliştirme sertifikası yükler ve eksik
bağımlılıkları geri yüklemek için NuGet Paket Yöneticisi 'ni çalıştırır.
Değişiklik yapmaya başlamadan önce, uygulamanızı çalıştırmak dotnet run için komut isteminde (bkz. Note)
yazın. dotnet run ortamınızda bağımlılıklar dotnet restore eksik olursa otomatik olarak gerçekleştirilir.
Uygulamanızın yeniden oluşturulması dotnet build gerekiyorsa de çalışır. İlk kurulumdan sonra, yalnızca projeniz
için anlamlı olduğunda veya dotnet restore dotnet build çalıştırmanız gerekir.

Yeni bağımlılıklar ekleniyor


.NET Core için önemli tasarım amaçlarından biri, .NET yüklemesinin boyutunu en aza indirmektir. Bir uygulamanın
bazı özellikleri için ek kitaplıklar gerekiyorsa, bu bağımlılıkları C# proje (*. csproj) dosyanıza eklersiniz. Örneğimiz
için, uygulamanızın JSON yanıtlarını işleyebilmesi için System.Runtime.Serialization.Json paketini eklemeniz
gerekir.
csproj Proje dosyanızı açın. Dosyanın ilk satırı şöyle görünmelidir:
<Project Sdk="Microsoft.NET.Sdk">

Bu satırdan hemen sonra aşağıdakini ekleyin:

<ItemGroup>
<PackageReference Include="System.Runtime.Serialization.Json" Version="4.3.0" />
</ItemGroup>

Çoğu kod Düzenleyicisi, bu kitaplıkların farklı sürümleri için tamamlama sağlar. Genellikle eklediğiniz herhangi bir
paketin en son sürümünü kullanmak isteyeceksiniz. Ancak, tüm paketlerin sürümlerinin eşleştiğinden ve ayrıca
.NET Core uygulama çerçevesinin sürümüyle eşleştiğinden emin olmak önemlidir.
Bu değişiklikleri yaptıktan sonra, paketin sisteminizde yüklü dotnet restore olması için yürütün (bkz. Note).

Web Istekleri yapma


Artık Web 'den veri almaya başlamaya hazırsınız. Bu uygulamada, GITHUB API'sindeki bilgileri okuyacaksınız. .Net
Foundation şemsiye kapsamındaki projelerle ilgili bilgileri okuyalim. Projeler hakkındaki bilgileri almak için GitHub
API 'sine istek yaparak başlayacaksınız. Kullanacağınız uç nokta: https://api.github.com/orgs/dotnet/repos. Bu
projelerle ilgili tüm bilgileri almak istiyorsunuz, bu nedenle bir HTTP GET isteği kullanacaksınız. Tarayıcınız ayrıca
HTTP GET isteklerini kullanır; bu nedenle, hangi bilgileri almak ve işlemek istediğinizi görmek için bu URL 'YI
tarayıcınıza yapıştırabilirsiniz.
Web istekleri yapmak HttpClient için sınıfını kullanırsınız. Tüm modern .NET API 'lerinde olduğu HttpClient gibi,
uzun süre çalışan API 'ler için yalnızca zaman uyumsuz yöntemleri destekler. Zaman uyumsuz bir yöntem yaparak
başlayın. Uygulamanın işlevlerini oluştururken uygulamayı doldurursunuz. program.cs Dosyayı proje dizininizde
açıp Program sınıfına aşağıdaki yöntemi ekleyerek başlayın:

private static async Task ProcessRepositories()


{
}

Derleyicinin türü tanıması using Main için yönteminizin en üstüne bir ifade eklemeniz gerekir: Task C#

using System.Threading.Tasks;

Bu noktada projenizi oluşturursanız, herhangi await bir işleç içermediğinden ve zaman uyumlu olarak çalışacağı
için bu yöntem için bir uyarı alırsınız. Şimdilik bunu yoksayın; yöntemi doldurduktan sonra await işleçleri
ekleyeceksiniz.
Sonra, bildiriminde tanımlanan ad alanını öğesinin varsayılan değerini ConsoleApp olarak
namespace
WebAPIClient yeniden adlandırın. Daha sonra bu ad alanında repo bir sınıf tanımlayacağız.

Sonra, Main yöntemi bu yöntemi çağırmak için güncelleştirin. ProcessRepositories Yöntemi bir görevi döndürür
ve bu görev tamamlanmadan önce programdan çıkmamanız gerekir. Bu nedenle, görevi engellemek ve Wait
görevin bitmesini beklemek için yöntemini kullanmanız gerekir:

static void Main(string[] args)


{
ProcessRepositories().Wait();
}

Artık hiçbir şey yapmaz ancak zaman uyumsuz olarak bunu yapar. Bunu geliştirelim.
Önce, Web 'den veri alan bir nesne gerekir; Bunu yapmak HttpClient için kullanabilirsiniz. Bu nesne, isteği ve
yanıtları işler. Program.cs dosyasının içindeki Program sınıfta bu türün tek bir örneğini oluşturun.

namespace WebAPIClient
{
class Program
{
private static readonly HttpClient client = new HttpClient();

static void Main(string[] args)


{
//...
}
}
}

ProcessRepositories Yönteme dönüp ilk bir sürümünü dolduralım:

private static async Task ProcessRepositories()


{
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/vnd.github.v3+json"));
client.DefaultRequestHeaders.Add("User-Agent", ".NET Foundation Repository Reporter");

var stringTask = client.GetStringAsync("https://api.github.com/orgs/dotnet/repos");

var msg = await stringTask;


Console.Write(msg);
}

Bunun derlenmesi için dosyanın en üstüne iki yeni using deyimi de eklemeniz gerekir:

using System.Net.Http;
using System.Net.Http.Headers;

Bu ilk sürüm, DotNet Foundation kuruluşundaki tüm depoların listesini okumak için bir Web isteği oluşturur. (.NET
Foundation için gitHub KIMLIĞI ' DotNet '). İlk birkaç satır bu istek HttpClient için ayarlayın. İlk olarak, GitHub
JSON yanıtlarını kabul edecek şekilde yapılandırılmıştır. Bu biçim yalnızca JSON 'dir. Sonraki satır, bu nesneden
gelen tüm isteklere bir Kullanıcı Aracısı üst bilgisi ekler. Bu iki üst bilgi GitHub sunucusu kodu tarafından denetlenir
ve GitHub 'dan bilgi almak için gereklidir.
Yapılandırmasını HttpClientyaptıktan sonra bir Web isteği yapar ve yanıtı alırsınız. Bu ilk sürümde,
HttpClient.GetStringAsync(String) kolaylık yöntemini kullanırsınız. Bu kolaylık yöntemi, web isteğini yapan bir
görevi başlatır ve ardından istek döndürüldüğünde yanıt akışını okur ve içeriği akıştan ayıklar. Yanıtın gövdesi bir
Stringolarak döndürülür. Dize, görev tamamlandığında kullanılabilir.
Bu yöntemin son iki satırı bu görevi bekler ve ardından yanıtı konsola yazdırır. Uygulamayı derleyin ve çalıştırın.
ProcessRepositories Şimdi bir await işleç içerdiğinden, derleme uyarısı şimdi çıktı. JSON biçimli metnin uzun bir
görüntüsünü görürsünüz.

JSON sonucunu işleme


Bu noktada, bir Web sunucusundan yanıt almak için kodu yazmış ve bu yanıtta bulunan metni görüntüdiniz. Sonra,
bu JSON yanıtını C# nesnelere dönüştürelim.
JSON seri hale getirici JSON verilerini C# nesnelerine dönüştürür. İlk göreviniz, bu yanıttan kullandığınız bilgileri
C# içeren bir sınıf türü tanımlamaktır. Bunu yavaş oluşturalım, bu nedenle deponun adını içeren basit C# bir türle
başlayın:

using System;

namespace WebAPIClient
{
public class repo
{
public string name;
}
}

Yukarıdaki kodu ' repo. cs ' adlı yeni bir dosyaya yerleştirin. Sınıfının bu sürümü JSON verilerini işlemek için en
basit yolu temsil eder. Sınıf adı ve üye adı, aşağıdaki C# kurallar yerine JSON paketinde kullanılan adlarla eşleşir.
Daha sonra bazı yapılandırma öznitelikleri sağlayarak bunu düzeltireceksiniz. Bu sınıf, JSON serileştirme ve seri
durumundan çıkarma için başka bir önemli özelliği gösterir: JSON paketindeki tüm alanlar bu sınıfın bir parçası
değil. JSON seri hale getiricisi, kullanılmakta olan sınıf türünde bulunmayan bilgileri yoksayacaktır. Bu özellik,
JSON paketindeki alanların yalnızca bir alt kümesiyle çalışan türler oluşturmayı kolaylaştırır.
Türü oluşturduğunuza göre, artık bunu serisini çıkaralım. Bir DataContractJsonSerializer nesnesi oluşturmanız
gerekir. Bu nesne, aldığı JSON paketi için beklenen CLR türünü bilmelidir. GitHub ' dan paket, bir List<repo> dizi
depo içerir, bu nedenle, doğru türdür. Aşağıdaki satırı ProcessRepositories yöntemine ekleyin:

var serializer = new DataContractJsonSerializer(typeof(List<repo>));

İki yeni ad alanı kullanıyorsunuz, bu nedenle bunları da eklemeniz gerekir:

using System.Collections.Generic;
using System.Runtime.Serialization.Json;

Ardından, JSON 'ı C# nesnelere dönüştürmek için seri hale getirici 'yi kullanacaksınız. Yöntemdeki
ProcessRepositories çağrısını GetStringAsync( String) aşağıdaki iki satır ile değiştirin:

var streamTask = client.GetStreamAsync("https://api.github.com/orgs/dotnet/repos");


var repositories = serializer.ReadObject(await streamTask) as List<repo>;

GetStreamAsync(String) ArtıkGetStringAsync(String)yerine kullandığınızdan emin olun. Serileştirici, kaynağı


olarak bir dize yerine bir akış kullanır. Yukarıdaki ikinci satırda kullanılmakta olan C# dilin birkaç özelliğini
açıklayalim. Bağımsız değişkeni ReadObject(Stream) bir await ifadedir. Await ifadeleri kodunuzda neredeyse her
yerde görünebilir, ancak şu anda yalnızca bir atama bildiriminin parçası olarak gördünüz.
İkinci olarak, as işleç derleme zaman object türünden öğesine List<repo> dönüştürür. Bildirimi
ReadObject(Stream) , türünde System.Objectbir nesne döndüren bildirir. ReadObject(Stream), oluşturduğunuzda
belirttiğiniz türü döndürür ( List<repo> Bu öğreticide). Dönüştürme başarılı olmazsa, as bir özel durum
oluşturmak yerine işleci olarak null değerlendirilir.
Bu bölümde neredeyse işiniz bitti. JSON 'ı C# nesnelere dönüştürdüğüne göre, her deponun adını görüntülim.
Okunan satırları değiştirin:

var msg = await stringTask; //**Deleted this


Console.Write(msg);

aşağıdakiler ile:
foreach (var repo in repositories)
Console.WriteLine(repo.name);

Uygulamayı derleyin ve çalıştırın. .NET Foundation 'ın parçası olan Depoların adlarını yazdıracaktır.

Serileştirme denetleniyor
Daha fazla özellik eklemeden önce, repo türü ele alalım ve daha standart C# Kurallara uyalım. Bunu, JSON seri
hale getiricinin repo nasıl çalıştığını denetleyen özniteliklerle türe açıklama ekleyerek yapabilirsiniz. Bu durumda,
JSON anahtar adları ve C# sınıf ile üye adları arasında bir eşleme tanımlamak için bu öznitelikleri kullanacaksınız.
Kullanılan iki öznitelik DataContractAttribute ve DataMemberAttribute öznitelikleridir. Kurala göre, tüm öznitelik
sınıfları sonta Attribute sona erdir. Ancak, bir özniteliği uyguladığınızda o soneki kullanmanız gerekmez.
Ve öznitelikleri farklı bir kitaplıkta olduğundan, bu kitaplığı C# proje dosyanıza bağımlılık olarak eklemeniz gerekir.
DataMemberAttribute DataContractAttribute Aşağıdaki satırı <ItemGroup> proje dosyanızın bölümüne ekleyin:

<PackageReference Include="System.Runtime.Serialization.Primitives" Version="4.3.0" />

Dosyayı kaydettikten sonra, bu paketi almak dotnet restore için (bkz. Note) öğesini çalıştırın.
Sonra repo.cs dosyayı açın. Bu adı, Pascal durumunu kullanacak şekilde değiştirelim ve adı Repository tamamen
heceleyin. Hala bu tür JSON ' repo ' düğümlerini eşlemek istiyoruz, bu nedenle DataContractAttribute özniteliği
sınıf bildirimine eklemeniz gerekir. Özniteliğin Name özelliğini, bu türle eşlenen json düğümlerinin adına
ayarlayacaksınız:

[DataContract(Name="repo")]
public class Repository

, Ad alanının bir üyesidir using , bu yüzden dosyanın en üstüne uygun ifadeyi eklemeniz gerekir:
System.Runtime.Serialization DataContractAttribute

using System.Runtime.Serialization;

repo Sınıfının adını olarak Repository değiştirdiniz. bu nedenle, program.cs içinde aynı ad değişikliğini yapmanız
gerekir (bazı düzenleyiciler, bu değişikliği otomatik olarak yapan bir yeniden adlandırma yeniden düzenlemesi
destekleyebilir:)

var serializer = new DataContractJsonSerializer(typeof(List<Repository>));

// ...

var repositories = serializer.ReadObject(await streamTask) as List<Repository>;

Daha sonra, name DataMemberAttribute sınıfını kullanarak aynı değişikliği alanla yapalim. Repo.cs içindeki name
alanın bildiriminde aşağıdaki değişiklikleri yapın:

[DataMember(Name="name")]
public string Name;

Bu değişiklik, program.cs içindeki her deponun adını yazan kodu değiştirmeniz gereken anlamına gelir:
Console.WriteLine(repo.Name);

Eşlemelerinizin doğru olduğundan emin dotnet run olmak için bir takipedin. dotnet build Önceki ile aynı çıktıyı
görmeniz gerekir. Web sunucusundan daha fazla özellik işleyebilmemiz için Repository , sınıfa daha fazla
değişiklik yapalım. Name Üye, herkese açık bir alandır. Bu iyi bir nesne odaklı uygulama değildir, bu nedenle bunu
bir özellik olarak değiştirelim. Özelliği alırken veya ayarlarken çalıştırmak için belirli bir kod gerekmez, ancak bir
özelliği değiştirmek, bu değişiklikleri Repository sınıfını kullanan kodları bozmadan daha sonra eklemeyi
kolaylaştırır.
Alan tanımını kaldırın ve Otomatik uygulanan bir özellikile değiştirin:

public string Name { get; set; }

Derleyici, get ve erişimcilerinin gövdesini ve set adı depolamak için özel bir alanı üretir. Bu, el ile yazabileceğiniz
aşağıdaki koda benzer olacaktır:

public string Name


{
get { return this._name; }
set { this._name = value; }
}
private string _name;

Yeni özellikler eklemeden önce bir değişiklik yapalim. ProcessRepositories Yöntemi zaman uyumsuz çalışmayı
yapabilir ve depoların bir koleksiyonunu döndürebilir. Bu yöntemden ' ı List<Repository> dönelim ve bilgileri
Main yöntemine yazan kodu taşıyalim.

Sonucunu bir Repository nesne listesi ProcessRepositories olan bir görevi döndürmek için imzasını değiştirin:

private static async Task<List<Repository>> ProcessRepositories()

Ardından, JSON yanıtını işledikten sonra depoları geri döndürün:

var repositories = serializer.ReadObject(await streamTask) as List<Repository>;


return repositories;

Bu yöntemi olarak async işaretlediğiniz Task<T> için derleyici, döndürme için nesnesi oluşturur. Ardından, Main
yöntemi bu sonuçları yakalayıp, her depo adını konsola yazar şekilde değiştirelim. Main Yönteminiz şu şekilde
görünür:

public static void Main(string[] args)


{
var repositories = ProcessRepositories().Result;

foreach (var repo in repositories)


Console.WriteLine(repo.Name);
}

Görev tamamlanana kadar görev bloklarının özelliğineerişme. Result Normalde, ProcessRepositories


yönteminde olduğu gibi, await ancak Main yönteminde izin verilmeyen görevi tamamlamayı tercih edersiniz.

Daha fazla bilgi okunuyor


Bu işlemi, GitHub API 'sinden gönderilen JSON paketindeki özelliklerden daha fazlasını işleyerek tamamlayalim.
Her şeyi almak istemezsiniz, ancak birkaç özelliği eklemek C# dilin birkaç özelliğini gösterir.
Daha fazla basit türü Repository sınıf tanımına ekleyerek başlayalım. Bu özellikleri bu sınıfa ekleyin:

[DataMember(Name="description")]
public string Description { get; set; }

[DataMember(Name="html_url")]
public Uri GitHubHomeUrl { get; set; }

[DataMember(Name="homepage")]
public Uri Homepage { get; set; }

[DataMember(Name="watchers")]
public int Watchers { get; set; }

Bu özellikler dize türünden (JSON paketlerinin içerdiği), hedef türüne yerleşik Dönüştürmelere sahiptir. Uri Tür
sizin için yeni olabilir. Bir URI 'yi veya bu durumda bir URL 'yi temsil eder. Uri Ve int türleri söz konusu
olduğunda, JSON paketi hedef türüne Dönüştürülmeyen veriler içeriyorsa, serileştirme eylemi bir özel durum
oluşturur.
Bunları ekledikten sonra, bu öğeleri göstermek için Main yöntemini güncelleştirin:

foreach (var repo in repositories)


{
Console.WriteLine(repo.Name);
Console.WriteLine(repo.Description);
Console.WriteLine(repo.GitHubHomeUrl);
Console.WriteLine(repo.Homepage);
Console.WriteLine(repo.Watchers);
Console.WriteLine();
}

Son bir adım olarak, son gönderme işlemi için bilgileri ekleyelim. Bu bilgiler, JSON yanıtında bu biçimde
biçimlendirilir:

2016-02-08T21:27:00Z

Bu biçim standart .net DateTime biçimlerinden hiçbirini izlemez. Bu nedenle, özel bir dönüştürme yöntemi
yazmanız gerekir. Ham dizenin, Repository sınıfın kullanıcılarına gösterilmesini de istemezsiniz. Öznitelikleri, bu
da denetim sağlanmasına yardımcı olabilir. İlk olarak, sınıfınıza private Repository ait tarih saatinin dize
gösterimini tutacak bir özellik tanımlayın:

[DataMember(Name="pushed_at")]
private string JsonDate { get; set; }

DataMemberAttribute Özniteliği, seri hale getiricinin, ortak üye olmasa bile bu işleme yönelik olduğunu bildirir.
Sonra, dizeyi geçerli DateTime bir nesneye dönüştüren ortak bir salt okunurdur ve bu DateTimeözelliği yazmanız
gerekir:
[IgnoreDataMember]
public DateTime LastPush
{
get
{
return DateTime.ParseExact(JsonDate, "yyyy-MM-ddTHH:mm:ssZ", CultureInfo.InvariantCulture);
}
}

Yukarıdaki yeni yapıları inceleyelim. IgnoreDataMember Özniteliği, seri hale getirici bu türün herhangi bir JSON
nesnesine okunmamalıdır veya yazılamaz olması gerektiğini söyler. Bu özellik yalnızca bir get erişimci içerir. set
Erişimci yok. İçinde C# salt okunurdur bir özelliği nasıl tanımlayacaksınız. (Evet, öğesinde C# salt yazılır özellikler
oluşturabilirsiniz, ancak değerleri sınırlıdır.) Yöntemi bir dizeyi ayrıştırır ve bir DateTime nesne DateTime
kullanarak CultureInfo bir nesne oluşturur. ParseExact(String, String, IFormatProvider) Ayrıştırma işlemi başarısız
olursa, özellik erişimcisi bir özel durum oluşturur.
Kullanmak InvariantCultureiçin, System.Globalization ad alanını using içindeki repo.cs deyimlere eklemeniz
gerekir:

using System.Globalization;

Son olarak, konsolda bir çıkış bildirisi daha ekleyin ve bu uygulamayı yeniden oluşturup çalıştırmak için hazırsınız:

Console.WriteLine(repo.LastPush);

Sürümünüz artık tamamlanmış örnekleeşleşmelidir.

Sonuç
Bu öğretici, Web istekleri oluşturma, sonucu ayrıştırma ve bu sonuçların özelliklerini görüntüleme konusunda sizi
gösterdi. Ayrıca, yeni paketleri projenize bağımlılıklar olarak eklediniz. Nesne odaklı teknikleri destekleyen C# dilin
bazı özelliklerini gördünüz.

NOTE
.NET Core 2.0 SDK'sı ile başlayarak, çalıştırma gerekmez dotnet restore bir geri yükleme, örneğin, gerçekleşmesi için
gerekli tüm komutlar tarafından örtük olarak çalıştırıldığından dotnet new , dotnet build ve dotnet run . Bunu hala
geçerli bir komut burada açık bir geri yükleme yaparsanız anlamlı, bazı senaryolarda olduğu gibi sürekli tümleştirme
derlemeleri Azure DevOps Hizmetleri'nde veya açıkça zaman denetlemek için gereken derleme sistemlerinde geri yükleme
gerçekleşir.
C# ve .NET içinde devralma
31.10.2019 • 40 minutes to read • Edit Online

Bu öğretici, ' de C#devralma işlemini tanıtır. Devralma, belirli işlevleri (veri ve davranış) sağlayan bir temel sınıf
tanımlamanızı ve bu işlevi devralıp geçersiz kılan türetilmiş sınıfları tanımlamanızı sağlayan nesne odaklı
programlama dillerinin bir özelliğidir.

Prerequisites
Bu öğreticide .NET Core SDK yüklediğinizi varsayılmaktadır. .NET Core İndirmeleri sayfasını ziyaret ederek indirin.
Ayrıca bir kod düzenleyicisine ihtiyacınız vardır. Bu öğretici Visual Studio Codekullanır, ancak istediğiniz herhangi
bir kod düzenleyicisini kullanabilirsiniz.

Örnekleri çalıştırma
Bu öğreticide örnekleri oluşturmak ve çalıştırmak için, komut satırından DotNet yardımcı programını kullanın. Her
örnek için aşağıdaki adımları izleyin:
1. Örneği depolamak için bir dizin oluşturun.
2. Yeni bir .NET Core projesi oluşturmak için bir komut isteminde DotNet yeni konsol komutunu girin.
3. Kod düzenleyicinize örnekteki kodu kopyalayın ve yapıştırın.
4. Projenin bağımlılıklarını yüklemek veya geri yüklemek için komut satırından DotNet restore komutunu girin.

NOTE
.NET Core 2.0 SDK'sı ile başlayarak, çalıştırma gerekmez dotnet restore bir geri yükleme, örneğin, gerçekleşmesi için
gerekli tüm komutlar tarafından örtük olarak çalıştırıldığından dotnet new , dotnet build ve dotnet run . Bunu hala
geçerli bir komut burada açık bir geri yükleme yaparsanız anlamlı, bazı senaryolarda olduğu gibi sürekli tümleştirme
derlemeleri Azure DevOps Hizmetleri'nde veya açıkça zaman denetlemek için gereken derleme sistemlerinde geri yükleme
gerçekleşir.

1. Örneği derlemek ve yürütmek için DotNet Run komutunu girin.

Arka plan: devralma nedir?


Devralma , nesne odaklı programlamanın temel özniteliklerinden biridir. Bir üst sınıfın davranışını yeniden
kullanan (devralan), genişleten veya değiştiren bir alt sınıf tanımlamanızı sağlar. Üyelerine devralınan sınıfa temel
sınıfdenir. Taban sınıfının üyelerini devralan sınıf türetilmiş sınıfolarak adlandırılır.
C#ve .NET yalnızca tek devralma desteği. Diğer bir deyişle, bir sınıf yalnızca tek bir sınıftan devralınabilir. Ancak,
devralma geçişlidir ve bu, bir tür kümesi için devralma hiyerarşisi tanımlamanızı sağlar. Diğer bir deyişle D , temel
sınıf türü A devralan B türünden devralan tür C devralabilir. Devralma geçişli olduğundan, A türündeki Üyeler
D türü için kullanılabilir.

Bir taban sınıfın tüm üyeleri türetilmiş sınıflar tarafından devralınmaz. Aşağıdaki Üyeler devralınmaz:
Statik oluşturucular, bir sınıfın statik verilerini başlatır.
Sınıfının yeni bir örneğini oluşturmak için çağırdığınız örnek oluşturucular. Her sınıfın kendi oluşturucuları
tanımlanmalıdır.
Çalışma zamanının atık toplayıcısı tarafından bir sınıfın örneklerini yok etmek için çağrılan sonlandırıcılar.
Bir temel sınıfın diğer tüm üyeleri türetilmiş sınıflar tarafından devralınırken, görünür olup olmadığı ve
erişilebilirliğine bağlı olup olmadığı. Üyenin erişilebilirliği, türetilmiş sınıfların görünürlüğünü aşağıdaki gibi etkiler:
Özel Üyeler yalnızca kendi temel sınıfında iç içe yerleştirilmiş türetilmiş sınıflarda görünür. Aksi takdirde,
bunlar türetilmiş sınıflarda görünür değildir. Aşağıdaki örnekte, A.B A türetilen iç içe bir sınıftır ve C A
türetilir. Özel A.value alanı A.B. içinde görülebilir Ancak, C.GetValue yönteminden açıklamaları kaldırır ve
örneği derlemeye çalışırsanız, CS0122 derleyici hatası üretir: "' A. Value ', koruma düzeyi nedeniyle
erişilemez."

using System;

public class A
{
private int value = 10;

public class B : A
{
public int GetValue()
{
return this.value;
}
}
}

public class C : A
{
// public int GetValue()
// {
// return this.value;
// }
}

public class Example


{
public static void Main(string[] args)
{
var b = new A.B();
Console.WriteLine(b.GetValue());
}
}
// The example displays the following output:
// 10

Korunan Üyeler yalnızca türetilmiş sınıflarda görülebilir.


İç Üyeler yalnızca temel sınıfla aynı derlemede bulunan türetilmiş sınıflarda görülebilir. Bunlar, temel
sınıftan farklı bir derlemede bulunan türetilmiş sınıflarda görünür değildir.
Ortak Üyeler türetilmiş sınıflarda görünür ve türetilmiş sınıf ' genel arabiriminin bir parçasıdır. Ortak
devralınmış Üyeler, türetilmiş sınıfta tanımlandıklarında olduğu gibi çağrılabilir. Aşağıdaki örnekte, sınıf A
Method1 adlı bir yöntemi tanımlar ve sınıf B sınıf A devralır. Örnek daha sonra Method1 B bir örnek
yöntemi gibi çağırır.
public class A
{
public void Method1()
{
// Method implementation.
}
}

public class B : A
{ }

public class Example


{
public static void Main()
{
B b = new B();
b.Method1();
}
}

Türetilmiş sınıflar, alternatif bir uygulama sağlayarak devralınan üyeleri de geçersiz kılabilir . Bir üyeyi geçersiz
kılabilmek için, temel sınıftaki üyenin sanal anahtar sözcüğüyle işaretlenmesi gerekir. Varsayılan olarak, temel sınıf
üyeleri virtual olarak işaretlenmez ve geçersiz kılınamaz. Şu örnekte olduğu gibi sanal olmayan bir üyeyi
geçersiz kılma girişimi, CS0506: "<member >, devralınan üye <üye > geçersiz kılamaz çünkü sanal, Özet veya
geçersiz kılma olarak işaretlenmemiş.

public class A
{
public void Method1()
{
// Do something.
}
}

public class B : A
{
public override void Method1() // Generates CS0506.
{
// Do something else.
}
}

Bazı durumlarda, türetilmiş bir sınıf temel sınıf uygulamasını geçersiz kılmalıdır . Soyut anahtar sözcükle
işaretlenmiş temel sınıf üyeleri, türetilmiş sınıfların bunları geçersiz kılmasını gerektirir. Aşağıdaki örnek
derlenmeye çalışıldığında, "<Class> devralınan soyut üye <üye>" uygulamıyor, çünkü sınıf B A.Method1 için
uygulama sağlamaz.

public abstract class A


{
public abstract void Method1();
}

public class B : A // Generates CS0534.


{
public void Method3()
{
// Do something.
}
}
Devralma yalnızca sınıflar ve arabirimler için geçerlidir. Diğer tür kategorileri (yapılar, temsilciler ve
numaralandırmalar) devralmayı desteklemez. Bu kurallar nedeniyle, aşağıdaki örnek gibi kodu derlemeye çalışmak
derleyici hatası oluşturur CS0527: "tür ' ValueType ', arabirim listesinde bir arabirim değil." Hata iletisi, bir yapının
uyguladığı arabirimleri tanımlayabilseniz de devralmanın desteklenmediğini belirtir.

using System;

public struct ValueStructure : ValueType // Generates CS0527.


{
}

Örtük devralma
Tek devralmayla devraldıkları türlerin yanı sıra, .NET tür sistemindeki tüm türler Object veya ondan türetilmiş bir
türden örtülü olarak devralınır. Object ortak işlevselliği her türlü tür için kullanılabilir.
Örtük devralmanın ne anlama geldiğini görmek için yalnızca boş bir sınıf tanımı olan SimpleClass yeni bir sınıf
tanımlayalim:

public class SimpleClass


{ }

Daha sonra, SimpleClass türüne ait üyelerin bir listesini almak için yansıma (Bu tür hakkında bilgi almak üzere bir
türün meta verilerini incelemenizi sağlar) kullanabilirsiniz. SimpleClass sınıfınızda herhangi bir üye
tanımlamasanız da, örnekteki çıkış aslında dokuz üyeye sahip olduğunu gösterir. Bu üyelerden biri, C# derleyici
tarafından SimpleClass türü için otomatik olarak sağlanan parametresiz (veya varsayılan) bir oluşturucudur. Kalan
sekiz, .NET tür sistemindeki tüm sınıfların ve arabirimlerin sonunda örtük olarak devraldığı Objectüyeleridir.
using System;
using System.Reflection;

public class Example


{
public static void Main()
{
Type t = typeof(SimpleClass);
BindingFlags flags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public |
BindingFlags.NonPublic | BindingFlags.FlattenHierarchy;
MemberInfo[] members = t.GetMembers(flags);
Console.WriteLine($"Type {t.Name} has {members.Length} members: ");
foreach (var member in members)
{
string access = "";
string stat = "";
var method = member as MethodBase;
if (method != null)
{
if (method.IsPublic)
access = " Public";
else if (method.IsPrivate)
access = " Private";
else if (method.IsFamily)
access = " Protected";
else if (method.IsAssembly)
access = " Internal";
else if (method.IsFamilyOrAssembly)
access = " Protected Internal ";
if (method.IsStatic)
stat = " Static";
}
var output = $"{member.Name} ({member.MemberType}): {access}{stat}, Declared by
{member.DeclaringType}";
Console.WriteLine(output);

}
}
}
// The example displays the following output:
// Type SimpleClass has 9 members:
// ToString (Method): Public, Declared by System.Object
// Equals (Method): Public, Declared by System.Object
// Equals (Method): Public Static, Declared by System.Object
// ReferenceEquals (Method): Public Static, Declared by System.Object
// GetHashCode (Method): Public, Declared by System.Object
// GetType (Method): Public, Declared by System.Object
// Finalize (Method): Internal, Declared by System.Object
// MemberwiseClone (Method): Internal, Declared by System.Object
// .ctor (Constructor): Public, Declared by SimpleClass

Object sınıfından örtük devralma, bu yöntemleri SimpleClass sınıfı için kullanılabilir hale getirir:
Bir SimpleClass nesnesini dize gösterimine dönüştüren public ToString yöntemi, tam nitelikli tür adını
döndürür. Bu durumda ToString yöntemi "SimpleClass" dizesini döndürür.
İki nesnenin eşitlik için test eden üç yöntem: ortak örnek Equals(Object) yöntemi, genel statik
Equals(Object, Object) yöntemi ve genel statik ReferenceEquals(Object, Object) yöntemi. Varsayılan
olarak, bu yöntemler başvuru eşitliği için test; diğer bir deyişle, eşit olması için iki nesne değişkeninin aynı
nesneye başvurması gerekir.
Karma koleksiyonlarda kullanılacak tür örneğine izin veren bir değeri hesaplayan ortak GetHashCode
yöntemi.
SimpleClass türünü temsil eden bir Type nesnesi döndüren public GetType yöntemi.
Bir nesnenin belleğinden önce yönetilmeyen kaynakları serbest bırakmak için tasarlanan korumalı Finalize
yöntemi çöp toplayıcı tarafından geri kazanılır.
Geçerli nesnesinin basit bir kopyasını oluşturan Protected MemberwiseClone yöntemi.
Örtük devralma nedeniyle, bir SimpleClass nesnesinden devralınan herhangi bir üyeyi, aslında SimpleClass
sınıfında tanımlanmış bir üye gibi çağırabilirsiniz. Örneğin, aşağıdaki örnek Objectdevralan SimpleClass
SimpleClass.ToString yöntemini çağırır.

using System;

public class SimpleClass


{}

public class Example


{
public static void Main()
{
SimpleClass sc = new SimpleClass();
Console.WriteLine(sc.ToString());
}
}
// The example displays the following output:
// SimpleClass

Aşağıdaki tabloda, içinde C# oluşturabileceğiniz türlerin kategorileri ve örtülü olarak devraldığı türler
listelenmektedir. Her temel tür, devralma yoluyla örtülü olarak türetilmiş türlere farklı bir üye kümesi sağlar.

TÜR KATEGORISI ÖRTÜLÜ OLARAK DEVRALIR

sınıf Object

struct ValueType, Object

enum Enum, ValueType, Object

temsilci MulticastDelegate, Delegate, Object

Devralma ve "bir" ilişkidir


Genellikle devralma, bir temel sınıf ve bir veya daha fazla türetilmiş sınıf arasındaki "bir", türetilmiş sınıfların temel
sınıfın özelleşmiş sürümü olduğu bir veya daha fazla türetilmiş sınıf arasındaki ilişkiyi ifade etmek için kullanılır;
türetilmiş sınıf, temel sınıfın bir türüdür. Örneğin, Publication sınıfı her türlü yayını temsil eder ve Book ve
Magazine sınıfları belirli yayın türlerini temsil eder.

NOTE
Bir sınıf veya yapı, bir veya daha fazla arabirim uygulayabilir. Arabirim uygulaması genellikle tek devralma için geçici bir çözüm
olarak veya yapılar ile devralma kullanmanın bir yolu olarak sunulurken, farklı bir ilişki ("bir" ilişki yapabilir) bir arabirim ile
uygulama türü devralmayı. Bir arabirim, bir işlev alt kümesini tanımlar (örneğin, eşitlik için test etme, nesneleri karşılaştırma
veya sıralama veya kültüre duyarlı ayrıştırma ve biçimlendirmeyi destekleme), arabirimin uygulama türleri için kullanılabilir
hale getiren özellik.

"Bunun bir" olduğuna ve bu türün belirli bir örneğini oluşturma arasındaki ilişkiyi ifade eder. Aşağıdaki örnekte
Automobile , üç benzersiz salt okuma özelliği olan bir sınıftır: Make , otomobil üreticisi. Model , otomobil türü; Year
, üretim yılından oluşan yıl. Automobile sınıfınız, bağımsız değişkenleri özellik değerlerine atanan bir oluşturucuya
sahiptir ve Automobile sınıfı yerine Automobile örneğini benzersiz bir şekilde tanımlayan bir dize oluşturmak için
Object.ToString yöntemini geçersiz kılar.

using System;

public class Automobile


{
public Automobile(string make, string model, int year)
{
if (make == null)
throw new ArgumentNullException("The make cannot be null.");
else if (String.IsNullOrWhiteSpace(make))
throw new ArgumentException("make cannot be an empty string or have space characters only.");
Make = make;

if (model == null)
throw new ArgumentNullException("The model cannot be null.");
else if (String.IsNullOrWhiteSpace(model))
throw new ArgumentException("model cannot be an empty string or have space characters only.");
Model = model;

if (year < 1857 || year > DateTime.Now.Year + 2)


throw new ArgumentException("The year is out of range.");
Year = year;
}

public string Make { get; }

public string Model { get; }

public int Year { get; }

public override string ToString() => $"{Year} {Make} {Model}";


}

Bu durumda, belirli otomobil yaptığı ve modellerinin temsil edilebilmesi için devralmadan güvenmemelisiniz.
Örneğin, Packard motor otomobil şirketi tarafından üretilen otomobil 'leri temsil etmek için bir Packard türü
tanımlamanız gerekmez. Bunun yerine, aşağıdaki örnekte olduğu gibi, sınıf oluşturucusuna geçirilmiş uygun
değerlerle bir Automobile nesnesi oluşturarak bunları temsil edebilirsiniz.

using System;

public class Example


{
public static void Main()
{
var packard = new Automobile("Packard", "Custom Eight", 1948);
Console.WriteLine(packard);
}
}
// The example displays the following output:
// 1948 Packard Custom Eight

Bir iş-devralma temelli bir ilişki taban sınıfına ve temel sınıfa ek Üyeler ekleyen ya da temel sınıfta ek işlevsellik
gerektiren türetilmiş sınıflara en iyi şekilde uygulanır.

Temel sınıf ve türetilmiş sınıfları tasarlama


Bir temel sınıf ve türetilmiş sınıfları tasarlama sürecine bakalım. Bu bölümde, kitap, dergi, gazete, günlük, makale
vb. gibi her türlü yayını temsil eden Publication bir temel sınıf tanımlayacaksınız. Ayrıca, Publication türeten bir
Book sınıfını da tanımlayacaksınız. Magazine , Journal , Newspaper ve Article gibi diğer türetilmiş sınıfları
tanımlamak için örneği kolayca genişletebilirsiniz.
Temel yayın sınıfı
Publication sınıfınızı tasarlarken birkaç tasarım kararı vermeniz gerekir:

Temel Publication sınıfınıza dahil edilecek Üyeler ve Publication üyelerin Yöntem uygulamaları sağlayıp
sağlamadığını veya Publication türetilmiş sınıfları için şablon görevi gören bir soyut temel sınıf olup
olmadığını belirtir.
Bu durumda, Publication sınıfı Yöntem uygulamaları sağlar. Soyut temel sınıfları ve bunların türetilmiş
sınıflarını tasarlama bölümü, türetilen sınıfların geçersiz kılınması gereken yöntemleri tanımlamak için soyut
bir temel sınıf kullanan bir örnek içerir. Türetilmiş sınıflar, türetilmiş tür için uygun olan herhangi bir
uygulamayı sağlamak için ücretsizdir.
Kodu yeniden kullanma özelliği (yani, birden çok türetilmiş sınıflar temel sınıf yöntemlerinin bildirimini ve
uygulamasını paylaşır ve bunları geçersiz kılmaları gerekmez) soyut olmayan taban sınıfların
avantajlarından yararlanır. Bu nedenle, kodun bazı veya en özelleştirilmiş Publication türleri tarafından
paylaşılması olasılığı varsa Publication üyeleri eklemeniz gerekir. Temel sınıf uygulamalarını verimli bir
şekilde sağlayamadıysanız, temel sınıfta tek bir uygulama yerine türetilmiş sınıflarda büyük ölçüde özdeş
üye uygulamaları sağlamak zorunda olacaksınız. Yinelenen kodu birden çok konumda sürdürme
gereksinimi, olası hataların kaynağıdır.
Her ikisi de kod yeniden kullanımını en üst düzeye çıkarmak ve mantıksal ve sezgisel bir devralma
hiyerarşisi oluşturmak için Publication sınıfına yalnızca tüm veya en çok yayınlar için ortak olan verileri ve
işlevleri eklediğinizden emin olmak istersiniz. Türetilmiş sınıflar daha sonra temsil ettikleri belirli yayın
türlerine özgü olan üyeleri uygular.
Sınıf hiyerarşinizin ne kadar uzaleceği. Yalnızca bir temel sınıf ve bir ya da daha fazla türetilmiş sınıf yerine
üç veya daha fazla sınıf hiyerarşisi geliştirmek istiyor musunuz? Örneğin, Publication temel bir
Periodical sınıfı olabilir. Bu, sırasıyla Magazine , Journal ve Newspaper temel sınıfıdır.

Örneğinizde, bir Publication sınıfının küçük hiyerarşisini ve tek bir türetilmiş sınıf olan Book
kullanacaksınız. Magazine ve Article gibi Publication türeten bir dizi ek sınıf oluşturmak için bu örneği
kolayca genişletebilirsiniz.
Temel sınıfın örneğini oluşturma konusunda anlamlı olup olmadığı. Değilse, sınıfa soyut anahtar sözcüğünü
uygulamanız gerekir. Aksi takdirde, Publication sınıfınız sınıf oluşturucusu çağırarak örneklenebilir. Sınıf
oluşturucusuna doğrudan çağrı tarafından abstract anahtar sözcüğüyle işaretlenmiş bir sınıf örneği
oluşturmak için bir girişim yapılırsa, C# DERLEYICI hata CS0144 oluşturuyor, "soyut sınıfın veya arabirimin
bir örneği oluşturulamaz." Yansıma kullanarak sınıfın örneğini oluşturmaya yönelik bir girişim yapılırsa,
yansıma yöntemi bir MemberAccessExceptionoluşturur.
Varsayılan olarak, bir temel sınıf, sınıf oluşturucusu çağırarak örneklenebilir. Açıkça bir sınıf oluşturucusu
tanımlamanız gerekmez. Temel sınıfın kaynak kodunda bir tane yoksa, C# derleyici otomatik olarak
varsayılan (parametresiz) bir oluşturucu sağlar.
Örnek olarak, Publication sınıfını Özet olarak işaretleyecek ve bu şekilde örneklendirilirsiniz. Herhangi bir
abstract yöntemi olmayan bir abstract sınıfı, bu sınıfın birkaç somut sınıf ( Book , Journal gibi) arasında
paylaşılan bir soyut kavramı temsil ettiğini belirtir.
Türetilmiş sınıfların belirli üyelerin temel sınıf uygulamasını devralması gerekip gerekmediğini, temel sınıf
uygulamasını geçersiz kılma seçeneğine sahip olup olmadığı veya bir uygulama sağlayıp sağlamamaları
gerekir. Türetilmiş sınıfların bir uygulama sağlamasına zorlamak için soyut anahtar sözcüğünü kullanırsınız.
Türetilmiş sınıfların bir temel sınıf yöntemini geçersiz kılmasına izin vermek için sanal anahtar sözcüğünü
kullanırsınız. Varsayılan olarak, temel sınıfta tanımlanan Yöntemler geçersiz kılınabilir değildir .
Publication sınıfı hiçbir abstract yöntemine sahip değil, ancak sınıfın kendisi abstract .
Türetilmiş bir sınıfın devralma hiyerarşisinde son sınıfı temsil edip etmediği ve kendisi ek türetilmiş sınıflar
için temel sınıf olarak kullanılamaz. Varsayılan olarak, herhangi bir sınıf temel sınıf olarak görev yapabilir. Bir
sınıfın herhangi bir ek sınıf için temel sınıf olarak işlev veremeyeceğini belirtmek için Sealed anahtar
sözcüğünü uygulayabilirsiniz. Sealed sınıf tarafından oluşturulan bir derleyici hatası CS0509, "Sealed Type
<typeName >" öğesinden türetilmeye çalışılıyor.
Örneğinizdeki türetilmiş sınıfınızı sealed olarak işaretlersiniz.

Aşağıdaki örnek, Publication sınıfı için kaynak kodu ve Publication.PublicationType özelliği tarafından
döndürülen PublicationType numaralandırması gösterir. Objectdevraldığı üyelere ek olarak, Publication sınıfı
aşağıdaki benzersiz üyeleri ve üye geçersiz kılmalarını tanımlar:

using System;

public enum PublicationType { Misc, Book, Magazine, Article };

public abstract class Publication


{
private bool published = false;
private DateTime datePublished;
private int totalPages;

public Publication(string title, string publisher, PublicationType type)


{
if (publisher == null)
throw new ArgumentNullException("The publisher cannot be null.");
else if (String.IsNullOrWhiteSpace(publisher))
throw new ArgumentException("The publisher cannot consist only of white space.");
Publisher = publisher;

if (title == null)
throw new ArgumentNullException("The title cannot be null.");
else if (String.IsNullOrWhiteSpace(title))
throw new ArgumentException("The title cannot consist only of white space.");
Title = title;

Type = type;
}

public string Publisher { get; }

public string Title { get; }

public PublicationType Type { get; }

public string CopyrightName { get; private set; }

public int CopyrightDate { get; private set; }

public int Pages


{
get { return totalPages; }
set
{
if (value <= 0)
throw new ArgumentOutOfRangeException("The number of pages cannot be zero or negative.");
totalPages = value;
}
}

public string GetPublicationDate()


{
{
if (!published)
return "NYP";
else
return datePublished.ToString("d");
}

public void Publish(DateTime datePublished)


{
published = true;
this.datePublished = datePublished;
}

public void Copyright(string copyrightName, int copyrightDate)


{
if (copyrightName == null)
throw new ArgumentNullException("The name of the copyright holder cannot be null.");
else if (String.IsNullOrWhiteSpace(copyrightName))
throw new ArgumentException("The name of the copyright holder cannot consist only of white space.");
CopyrightName = copyrightName;

int currentYear = DateTime.Now.Year;


if (copyrightDate < currentYear - 10 || copyrightDate > currentYear + 2)
throw new ArgumentOutOfRangeException($"The copyright year must be between {currentYear - 10} and
{currentYear + 1}");
CopyrightDate = copyrightDate;
}

public override string ToString() => Title;


}

Bir Oluşturucu
Publication sınıfı abstract olduğundan, doğrudan aşağıdaki örnek gibi koddan başlatılamaz:

var publication = new Publication("Tiddlywinks for Experts", "Fun and Games",


PublicationType.Book);

Ancak, Book sınıfının kaynak kodu gösterdiği gibi, örnek Oluşturucusu doğrudan türetilmiş sınıf
oluşturucularından çağrılabilir.
İki yayınla ilgili özellikler
Title , değeri Publication Oluşturucusu çağırarak sağlanan salt okunurdur String bir özelliktir.
Pages , yayının kaç tane sayfa olduğunu gösteren bir okuma-yazma Int32 özelliğidir. Değer, totalPages adlı
bir özel alanda depolanır. Pozitif bir sayı olmalıdır veya ArgumentOutOfRangeException atılır.
Yayımcının ilgili üyeleri
İki salt okuma özelliği, Publisher ve Type . Değerler, başlangıçta Publication sınıf oluşturucusuna yapılan
çağrı tarafından sağlanır.
Yayınlamayla ilgili Üyeler
İki yöntem, Publish ve GetPublicationDate , yayınlama tarihini ayarlayıp döndürür. Publish yöntemi,
çağrıldığında true için özel bir published bayrağını ayarlar ve kendisine geçirilen tarihi özel
datePublished alanına bağımsız değişken olarak atar. GetPublicationDate yöntemi, published bayrağı
false ve true ise datePublished alanının değeri olan "NYP" dizesini döndürür.

Telif hakkı ile ilgili Üyeler


Copyright yöntemi, telif hakkı sahibinin adını ve telif hakkı yılını bağımsız değişken olarak alır ve bunları
CopyrightName ve CopyrightDate özelliklerine atar.
ToString yöntemi geçersiz kılma
Bir tür Object.ToString yöntemini geçersiz kılamadıysa, bir örneği diğerinden Farklılaştırmada kullanılan,
türün tam nitelikli adını döndürür. Publication sınıfı Title özelliğin değerini döndürmek için
Object.ToString geçersiz kılar.
Aşağıdaki şekilde, temel Publication sınıfınız ile örtülü olarak devralınan Object sınıfı arasındaki ilişki
gösterilmektedir.

Book sınıfı
Book sınıfı, bir kitabı özelleşmiş bir yayın türü olarak temsil eder. Aşağıdaki örnek Book sınıfının kaynak kodunu
gösterir.
using System;

public sealed class Book : Publication


{
public Book(string title, string author, string publisher) :
this(title, String.Empty, author, publisher)
{ }

public Book(string title, string isbn, string author, string publisher) : base(title, publisher,
PublicationType.Book)
{
// isbn argument must be a 10- or 13-character numeric string without "-" characters.
// We could also determine whether the ISBN is valid by comparing its checksum digit
// with a computed checksum.
//
if (! String.IsNullOrEmpty(isbn)) {
// Determine if ISBN length is correct.
if (! (isbn.Length == 10 | isbn.Length == 13))
throw new ArgumentException("The ISBN must be a 10- or 13-character numeric string.");
ulong nISBN = 0;
if (! UInt64.TryParse(isbn, out nISBN))
throw new ArgumentException("The ISBN can consist of numeric characters only.");
}
ISBN = isbn;

Author = author;
}

public string ISBN { get; }

public string Author { get; }

public Decimal Price { get; private set; }

// A three-digit ISO currency symbol.


public string Currency { get; private set; }

// Returns the old price, and sets a new price.


public Decimal SetPrice(Decimal price, string currency)
{
if (price < 0)
throw new ArgumentOutOfRangeException("The price cannot be negative.");
Decimal oldValue = Price;
Price = price;

if (currency.Length != 3)
throw new ArgumentException("The ISO currency symbol is a 3-character string.");
Currency = currency;

return oldValue;
}

public override bool Equals(object obj)


{
Book book = obj as Book;
if (book == null)
return false;
else
return ISBN == book.ISBN;
}

public override int GetHashCode() => ISBN.GetHashCode();

public override string ToString() => $"{(String.IsNullOrEmpty(Author) ? "" : Author + ", ")}{Title}";
}
Publication devraldığı üyelere ek olarak, Book sınıfı aşağıdaki benzersiz üyeleri ve üye geçersiz kılmalarını
tanımlar:
İki Oluşturucu
İki Book Oluşturucusu üç ortak parametreyi paylaşır. İki, başlık ve Yayımcı, Publication oluşturucusunun
parametrelerine karşılık gelir. Üçüncü, bir genel sabit Author özelliğine depolanan Yazar. Bir Oluşturucu,
ISBN Auto-özelliğinde depolanan bir ISBN parametresi içerir.

İlk Oluşturucu, diğer oluşturucuyu çağırmak için this anahtar sözcüğünü kullanır. Oluşturucu zincirleme,
Oluşturucu tanımlamalarında ortak bir modeldir. Daha az parametreye sahip oluşturucular, oluşturucuyu en
fazla parametre sayısıyla çağırırken varsayılan değerleri sağlar.
İkinci Oluşturucu, başlığı ve yayımcı adını temel sınıf oluşturucusuna geçirmek için temel anahtar
sözcüğünü kullanır. Kaynak kodunuzda bir taban sınıf oluşturucusuna açık bir çağrı yapmazsanız, C#
derleyici otomatik olarak taban sınıfının varsayılan veya parametresiz oluşturucusuna bir çağrı sağlar.
Book nesnesinin uluslararası standart kitap numarasını, benzersiz bir 10 veya 13 basamaklı bir sayı
döndüren salt okunurdur ISBN özelliği. ISBN, Book oluşturucularından birine bir bağımsız değişken olarak
sağlanır. ISBN, derleyici tarafından otomatik olarak oluşturulan özel bir yedekleme alanında depolanır.
Salt okunurdur Author özelliği. Yazar adı, Book oluşturucularının her ikisine de bir bağımsız değişken
olarak sağlanır ve özelliğinde depolanır.
İki salt okuma fiyatına ilişkin özellikler, Price ve Currency . Değerleri SetPrice Yöntem çağrısında
bağımsız değişken olarak sağlanır. Currency özelliği üç basamaklı ISO para birimi simgedir (örneğin, ABD
Doları için USD ). ISO para birimi sembolleri ISOCurrencySymbol özelliğinden alınabilir. Bu özelliklerin her
ikisi de dışarıdan salt okunurdur, ancak her ikisi de Book sınıfındaki kodla ayarlanabilir.
Priceve Currency özelliklerinin değerlerini ayarlayan SetPrice yöntemi. Bu değerler, aynı özelliklerle
döndürülür.
ToString yöntemine ( Publication devralınmış) ve Object.Equals(Object) ve GetHashCode yöntemlerine
(Objectdevralınmış) geçersiz kılar.
Geçersiz kılınmadıkça Object.Equals(Object) yöntemi başvuru eşitliği sınar. Diğer bir deyişle, aynı nesneye
başvurduklarında iki nesne değişkeninin eşit olduğu kabul edilir. Book sınıfında, diğer taraftan, aynı ıSBN 'e
sahip olmaları durumunda iki Book nesnesi eşit olmalıdır.
Object.Equals(Object) yöntemi geçersiz kıldığınızda, verimli alma için çalışma zamanının öğeleri karma
koleksiyonlara depolamak üzere kullandığı bir değer döndüren GetHashCode yöntemini de geçersiz
kılmanız gerekir. Karma kodu, eşitlik için testle tutarlı bir değer döndürmelidir. İki Book nesnesinin ıSBN
özellikleri eşitse true döndürmek için Object.Equals(Object) geçersiz kıldığından, ISBN özelliği tarafından
döndürülen dizenin GetHashCode yöntemini çağırarak hesaplanan karma kodu döndürürsünüz.
Aşağıdaki şekilde, Book sınıfı ve Publication temel sınıfı arasındaki ilişki gösterilmektedir.
Artık bir Book nesnesi oluşturabilir, hem benzersiz hem de devralınan üyelerini çağırabilir ve aşağıdaki örnekte
gösterildiği gibi, Publication veya Book türünde bir parametre bekleyen bir yönteme bağımsız değişken olarak
geçirebilirsiniz.
using System;
using static System.Console;

public class Example


{
public static void Main()
{
var book = new Book("The Tempest", "0971655819", "Shakespeare, William",
"Public Domain Press");
ShowPublicationInfo(book);
book.Publish(new DateTime(2016, 8, 18));
ShowPublicationInfo(book);

var book2 = new Book("The Tempest", "Classic Works Press", "Shakespeare, William");
Write($"{book.Title} and {book2.Title} are the same publication: " +
$"{((Publication) book).Equals(book2)}");
}

public static void ShowPublicationInfo(Publication pub)


{
string pubDate = pub.GetPublicationDate();
WriteLine($"{pub.Title}, " +
$"{(pubDate == "NYP" ? "Not Yet Published" : "published on " + pubDate):d} by
{pub.Publisher}");
}
}
// The example displays the following output:
// The Tempest, Not Yet Published by Public Domain Press
// The Tempest, published on 8/18/2016 by Public Domain Press
// The Tempest and The Tempest are the same publication: False

Soyut temel sınıfları ve bunların türetilmiş sınıflarını tasarlama


Önceki örnekte, türetilmiş sınıfların kod paylaşmasına izin veren bir dizi yöntem için uygulama sağlayan bir temel
sınıf tanımladınız. Ancak çoğu durumda, temel sınıfın bir uygulama sağlaması beklenmez. Bunun yerine, temel sınıf
soyut yöntemleribildiren soyut bir sınıftır ; Her türetilmiş sınıfın uygulaması gereken üyeleri tanımlayan bir şablon
görevi görür. Genellikle soyut bir temel sınıfta, her türetilmiş türün uygulanması o tür için benzersizdir. Sınıf,
yayınlar için ortak işlevsellik uygulamaları sağladığından, bir Publication nesnesinin örneğini oluşturma
konusunda hiçbir fikir olmadığından, bu sınıfı soyut anahtar sözcükle işaretlenir.
Örneğin, her kapatılan iki boyutlu geometrik şekil iki özellik içerir: alan, şeklin iç kapsamı; ve çevre ya da şeklin
kenarları arasındaki uzaklık. Ancak, bu özelliklerin hesaplanma şekli, ancak tamamen belirli bir şekle bağlıdır.
Örneğin, bir dairenin çevre (veya çevresi) hesaplama formülü, bir üçgenden farklıdır. Shape sınıfı, abstract
Yöntemler içeren bir abstract sınıfıdır. Bu, türetilmiş sınıfların aynı işlevselliği paylaştığından, ancak bu türetilmiş
sınıfların bu işlevselliği farklı şekilde uyguladığını gösterir.
Aşağıdaki örnek, iki özelliği tanımlayan Shape adlı soyut temel sınıfı tanımlar: Area ve Perimeter . Sınıfı soyut
anahtar sözcükle işaretlemeye ek olarak, her örnek üyesi de soyut anahtar sözcüğüyle işaretlenir. Bu durumda
Shape Ayrıca, tam adı yerine türün adını döndürmek için Object.ToString yöntemini geçersiz kılar. Ayrıca,
arayanlara türetilmiş bir sınıfın bir örneğinin alanını ve çevresini kolayca almasına izin veren GetArea ve
GetPerimeter iki statik üye tanımlar. Türetilmiş bir sınıfın bir örneğini bu yöntemlerin herhangi birine
geçirdiğinizde, çalışma zamanı türetilmiş sınıfın yöntem geçersiz kılmasını çağırır.
using System;

public abstract class Shape


{
public abstract double Area { get; }

public abstract double Perimeter { get; }

public override string ToString() => GetType().Name;

public static double GetArea(Shape shape) => shape.Area;

public static double GetPerimeter(Shape shape) => shape.Perimeter;


}

Ardından, belirli şekilleri temsil eden Shape bazı sınıfları türetebilirsiniz. Aşağıdaki örnek, Triangle , Rectangle ve
Circle üç sınıfı tanımlar. Her biri, alanı ve çevresi hesaplamak için bu belirli bir şekil için benzersiz bir formül
kullanır. Türetilmiş sınıflardan bazıları Ayrıca, temsil ettikleri şekle benzersiz olan Rectangle.Diagonal ve
Circle.Diameter gibi özellikleri de tanımlar.
using System;

public class Square : Shape


{
public Square(double length)
{
Side = length;
}

public double Side { get; }

public override double Area => Math.Pow(Side, 2);

public override double Perimeter => Side * 4;

public double Diagonal => Math.Round(Math.Sqrt(2) * Side, 2);


}

public class Rectangle : Shape


{
public Rectangle(double length, double width)
{
Length = length;
Width = width;
}

public double Length { get; }

public double Width { get; }

public override double Area => Length * Width;

public override double Perimeter => 2 * Length + 2 * Width;

public bool IsSquare() => Length == Width;

public double Diagonal => Math.Round(Math.Sqrt(Math.Pow(Length, 2) + Math.Pow(Width, 2)), 2);


}

public class Circle : Shape


{
public Circle(double radius)
{
Radius = radius;
}

public override double Area => Math.Round(Math.PI * Math.Pow(Radius, 2), 2);

public override double Perimeter => Math.Round(Math.PI * 2 * Radius, 2);

// Define a circumference, since it's the more familiar term.


public double Circumference => Perimeter;

public double Radius { get; }

public double Diameter => Radius * 2;


}

Aşağıdaki örnek Shape türetilen nesneleri kullanır. Shape türetilen nesnelerden oluşan bir dizi oluşturur ve Shape
sınıfının statik yöntemlerini çağırarak, return Shape özellik değerlerini sarmalayan şekilde çağırır. Çalışma zamanı
türetilmiş türlerin geçersiz kılınan özelliklerinden değerleri alır. Örnek ayrıca dizideki her bir Shape nesnesini
türetilmiş türüne yayınlar ve atama başarılı olursa Shape söz konusu alt sınıfının özelliklerini alır.
using System;

public class Example


{
public static void Main()
{
Shape[] shapes = { new Rectangle(10, 12), new Square(5),
new Circle(3) };
foreach (var shape in shapes) {
Console.WriteLine($"{shape}: area, {Shape.GetArea(shape)}; " +
$"perimeter, {Shape.GetPerimeter(shape)}");
var rect = shape as Rectangle;
if (rect != null) {
Console.WriteLine($" Is Square: {rect.IsSquare()}, Diagonal: {rect.Diagonal}");
continue;
}
var sq = shape as Square;
if (sq != null) {
Console.WriteLine($" Diagonal: {sq.Diagonal}");
continue;
}
}
}
}
// The example displays the following output:
// Rectangle: area, 120; perimeter, 44
// Is Square: False, Diagonal: 15.62
// Square: area, 25; perimeter, 20
// Diagonal: 7.07
// Circle: area, 28.27; perimeter, 18.85

Ayrıca bkz.
Sınıflar ve nesneler
Devralma (C# Programlama Kılavuzu)
LINQ ile Çalışma
30.10.2019 • 25 minutes to read • Edit Online

Giriş
Bu öğretici, .NET Core ve C# dil özelliklerini size öğretir. Şunları öğreneceksiniz:
LINQ ile diziler oluşturma.
LINQ sorgularında kolayca kullanılabilecek yöntemler yazma.
Eager ve geç değerlendirme arasında ayrım yapma.
Herhangi bir Magician temel becerilerinden birini gösteren bir uygulama oluşturarak bu teknikleri öğrenirsiniz:
Faro karışık. Kısaca, bir kağıt destesi yarısını tamamen yarıya böldüğünüz bir tekniktir, sonra da orijinal destesi
yeniden derlemek için her bir yarısını her bir karmadan karıştırın.
Magicians bu tekniği, her kart her karıştırmadan sonra bilinen bir konumda olduğundan ve sipariş yinelenen bir
düzen olduğundan kullanın.
Amacınıza uygun olarak, veri dizilerini işlemek için bir hafif göz atın. Oluşturacağınız uygulama bir kart destesi
oluşturacak ve sonra her seferinde sırayı yazarak bir dizi karışık olarak bir sıra gerçekleştirecek. Ayrıca,
güncelleştirilmiş siparişi orijinal siparişle karşılaştırırsınız.
Bu öğreticide birden çok adım vardır. Her adımdan sonra, uygulamayı çalıştırabilir ve ilerleme durumunu
görebilirsiniz. Ayrıca, DotNet/Samples GitHub deposunda Tamamlanan örneği görebilirsiniz. İndirme yönergeleri
için bkz. örnekler ve öğreticiler.

Prerequisites
.NET Core 'u çalıştırmak için makinenizi ayarlamanız gerekir. Yükleme yönergelerini .NET Core indirme sayfasında
bulabilirsiniz. Bu uygulamayı Windows, Ubuntu Linux, OS X veya bir Docker kapsayıcısında çalıştırabilirsiniz. En
sevdiğiniz kod düzenleyicinizi yüklemeniz gerekir. Aşağıdaki açıklamalar açık kaynaklı, platformlar arası
düzenleyici olan Visual Studio Code kullanır. Bununla birlikte, rahat olan her türlü aracı kullanabilirsiniz.

Uygulamayı oluşturma
İlk adım yeni bir uygulama oluşturmaktır. Bir komut istemi açın ve uygulamanız için yeni bir dizin oluşturun.
Geçerli dizini oluşturun. Komut istemine komut dotnet new console yazın. Bu, temel bir "Merhaba Dünya"
uygulaması için başlangıç dosyalarını oluşturur.
Daha önce hiç kullanmadıysanız C# , Bu öğretici bir C# programın yapısını açıklar. Bunu okuyabilir ve sonra LINQ
hakkında daha fazla bilgi edinmek için buraya dönebilirsiniz.

Veri kümesi oluşturma


Başlamadan önce, aşağıdaki satırların dotnet new console tarafından oluşturulan Program.cs dosyanın en üstünde
olduğundan emin olun:

// Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
Bu üç satır ( using deyimleri) dosyanın en üstünde değilse, programımız derlenmeyecektir.
İhtiyacınız olan tüm başvurulara sahip olduğunuza göre, kart destesi ne olduğunu göz önünde bulundurun. Yaygın
olarak, kart oynamaya yönelik bir deste dört cins içerir ve her cinsten on yedi değer vardır. Normalde, bir Card
sınıfını doğrudan bat üzerinde oluşturup el ile bir Card nesne koleksiyonu doldurarak göz önüne alabilirsiniz.
LINQ ile, kart destesi oluşturma konusunda olağan yollardan daha kısa bir işlem yapabilirsiniz. Card sınıfı
oluşturmak yerine, sırasıyla cins ve dereceleri temsil eden iki sıra oluşturabilirsiniz. IEnumerable<T>dizeleri olarak
derecelendirmelerinin ve cinslerin üretebileceği, aslında basit bir Yineleyici yöntemleri oluşturacaksınız:

// Program.cs
// The Main() method

static IEnumerable<string> Suits()


{
yield return "clubs";
yield return "diamonds";
yield return "hearts";
yield return "spades";
}

static IEnumerable<string> Ranks()


{
yield return "two";
yield return "three";
yield return "four";
yield return "five";
yield return "six";
yield return "seven";
yield return "eight";
yield return "nine";
yield return "ten";
yield return "jack";
yield return "queen";
yield return "king";
yield return "ace";
}

Bunları Program.cs dosyanıza Main yönteminin altına yerleştirin. Bu iki yöntem her ikisi de çalıştıkları sırada bir
sıra üretmek için yield return söz dizimini kullanır. Derleyici, IEnumerable<T> uygulayan bir nesne oluşturur ve
bunların istendiği sırada dizelerin dizisini oluşturur.
Şimdi, kart destesi oluşturmak için bu yineleyici yöntemleri kullanın. LINQ sorgusunu Main yönteimize
yerleştirebilirsiniz. İşte buna bir göz atın:

// Program.cs
static void Main(string[] args)
{
var startingDeck = from s in Suits()
from r in Ranks()
select new { Suit = s, Rank = r };

// Display each card that we've generated and placed in startingDeck in the console
foreach (var card in startingDeck)
{
Console.WriteLine(card);
}
}

Çoklu from yan tümceleri, ikinci dizideki her öğe ile ilk dizideki her öğeyi birleştiren tek bir sıra oluşturan bir
SelectManyoluşturur. Sıra, amacınız açısından önemlidir. İlk kaynak dizideki (cins) ilk öğe, ikinci dizideki her öğe
(Rütler) ile birleştirilir. Bu, birinci cins 'in tüm üçüncü dört kartını üretir. Bu işlem, ilk dizideki (cins) her öğe ile
yinelenir. Nihai sonuç, cinsler tarafından, ardından değerler tarafından sıralanan kartların bir destesi.
Yukarıda kullanılan sorgu söz diziminde LINQ 'nizi yazmayı veya bunun yerine Yöntem sözdizimini kullanmayı
tercih etmeksizin, bir sözdizimi formundan diğerine gitmeniz her zaman mümkündür. Sorgu sözdiziminde yazılan
yukarıdaki sorgu yöntem sözdiziminde şöyle yazılabilir:

var startingDeck = Suits().SelectMany(suit => Ranks().Select(rank => new { Suit = suit, Rank = rank }));

Derleyici, sorgu söz dizimi ile yazılan LINQ deyimlerini eşdeğer Yöntem çağrısı sözdizimine dönüştürür. Bu
nedenle, söz dizimi seçiminizden bağımsız olarak, sorgunun iki sürümü aynı sonucu üretir. Hangi sözdiziminin
durumunuz için en iyi şekilde çalıştığını seçin: Örneğin, bir ekip içinde çalışıyorsanız, bazı üyelerin Yöntem
sözdizimi konusunda zorluk yaşıyorsanız, sorgu söz dizimini kullanmayı tercih edin.
Devam edin ve bu noktada derlediğiniz örneği çalıştırın. Bu, destedeki tüm 52 kartları görüntüler. Suits() ve
Ranks() yöntemlerinin nasıl yürütüleceğini gözlemlemek için bu örneği bir hata ayıklayıcı altında çalıştırmanın
çok yararlı olduğunu fark edebilirsiniz. Her bir dizinin her bir dizesinin yalnızca gerektiğinde oluşturulduğunu
açıkça görebilirsiniz.

Siparişi düzenleme
Ardından, destedeki kartları nasıl karıştığınıza odaklanın. Her iyi karışmaya yönelik ilk adım, desteyi ikiye
bölmenizde yarar vardır. LINQ API 'lerinin parçası olan Take ve Skip yöntemleri bu özelliği sizin için sağlar.
foreach döngüsünün altına yerleştirin:

// Program.cs
public static void Main(string[] args)
{
var startingDeck = from s in Suits()
from r in Ranks()
select new { Suit = s, Rank = r };

foreach (var c in startingDeck)


{
Console.WriteLine(c);
}

// 52 cards in a deck, so 52 / 2 = 26
var top = startingDeck.Take(26);
var bottom = startingDeck.Skip(26);
}
Ancak, standart kitaplıkta avantajlarından yararlanmak için bir karıştırma yöntemi yoktur, bu nedenle kendi
kodunuzu yazmanız gerekir. Oluşturmakta olduğunuz karıştırma yöntemi, LINQ tabanlı programlarla birlikte
kullanacağınız birkaç tekniği gösterir. bu nedenle, bu işlemin her bir bölümü adımlarda açıklanacaktır.
LINQ sorgularından geri döndüğünüzde IEnumerable<T> nasıl etkileşim kurabileceğine ilişkin bazı işlevler
eklemek için, Uzantı yöntemleriadlı bazı özel tür yöntemler yazmanız gerekir. Kısaca, bir genişletme yöntemi,
işlevselliği eklemek istediğiniz orijinal türü değiştirmek zorunda kalmadan, zaten var olan bir türe yeni işlevsellik
ekleyen özel amaçlı statik bir yöntemdir .
Extensions.cs adlı programınıza yeni bir statik sınıf dosyası ekleyerek uzatma yöntemlerinizi yeni bir giriş yapın
ve ardından ilk uzantı yöntemini oluşturmaya başlayın:

// Extensions.cs
using System;
using System.Collections.Generic;
using System.Linq;

namespace LinqFaroShuffle
{
public static class Extensions
{
public static IEnumerable<T> InterleaveSequenceWith<T>(this IEnumerable<T> first, IEnumerable<T>
second)
{
// Your implementation will go here soon enough
}
}
}

Yöntem imzasına bir süre için bakın, özellikle Parametreler:

public static IEnumerable<T> InterleaveSequenceWith<T> (this IEnumerable<T> first, IEnumerable<T> second)

Yöntemin ilk bağımsız değişkeninde this değiştiricinin eklenmesini görebilirsiniz. Bu, yöntemi ilk bağımsız
değişkenin türünün bir Member yöntemi gibi çağırmış olmanız anlamına gelir. Bu yöntem bildirimi Ayrıca, giriş ve
çıkış türlerinin IEnumerable<T> olduğu standart bir iDom izler. Bu uygulama, LINQ yöntemlerinin daha karmaşık
sorgular gerçekleştirmek için birlikte zincirde olmasını sağlar.
Doğal olarak, desteyi halele böldüğünüz için bu kilitlenenlere birlikte katılmanız gerekir. Kod içinde bu, hem Take,
hem de Skip, öğeleri interleaving ve tek bir sıra oluşturmak istediğiniz her iki diziyi de numaralandırdığınız
anlamına gelir: şimdi karlı kart destesi. İki diziyle çalışacak bir LINQ yöntemi yazmak için IEnumerable<T> nasıl
çalıştığını anlamanız gerekir.
IEnumerable<T> arabiriminin bir yöntemi vardır: GetEnumerator. GetEnumerator tarafından döndürülen nesne,
sonraki öğeye ve dizideki geçerli öğeyi alan bir özelliğe geçiş yöntemine sahiptir. Bu iki üyeyi, koleksiyonu
numaralandırmak ve öğeleri döndürmek için kullanacaksınız. Bu ayırma yöntemi bir yineleyici yöntemi olacak, bu
nedenle bir koleksiyon oluşturmak ve koleksiyonu döndürmek yerine yukarıda gösterilen yield return söz
dizimini kullanacaksınız.
Bu yöntemin uygulanması aşağıda verilmiştir:
public static IEnumerable<T> InterleaveSequenceWith<T>
(this IEnumerable<T> first, IEnumerable<T> second)
{
var firstIter = first.GetEnumerator();
var secondIter = second.GetEnumerator();

while (firstIter.MoveNext() && secondIter.MoveNext())


{
yield return firstIter.Current;
yield return secondIter.Current;
}
}

Bu yöntemi yazdıktan sonra Main yöntemine dönün ve destesi bir kez karışın:

// Program.cs
public static void Main(string[] args)
{
var startingDeck = from s in Suits()
from r in Ranks()
select new { Suit = s, Rank = r };

foreach (var c in startingDeck)


{
Console.WriteLine(c);
}

var top = startingDeck.Take(26);


var bottom = startingDeck.Skip(26);
var shuffle = top.InterleaveSequenceWith(bottom);

foreach (var c in shuffle)


{
Console.WriteLine(c);
}
}

Karşılaştırma
Destesi orijinal sıralarına geri ayarlamak için kaç tane karışık? Bunu öğrenmek için, iki sıranın eşit olup olmadığını
belirleyen bir yöntem yazmanız gerekir. Bu yöntemi aldıktan sonra, destesi bir döngüyle karışık olarak sunan kodu
yerleştirmeniz ve destenin sırasıyla ne zaman geri olduğunu kontrol etmeniz gerekir.
İki sıranın eşit olup olmadığını anlamak için bir yöntem yazmak basit olmalıdır. Bu, destesi karıştırmak için
yazdığınız yöntemin benzer bir yapısıdır. Her bir öğe yield return yerine yalnızca bu kez her bir sıranın eşleşen
öğelerini karşılaştırırsınız. Tüm sıra numaralandırılmışsa, her öğe eşleşiyorsa, sıralar aynıdır:
public static bool SequenceEquals<T>
(this IEnumerable<T> first, IEnumerable<T> second)
{
var firstIter = first.GetEnumerator();
var secondIter = second.GetEnumerator();

while (firstIter.MoveNext() && secondIter.MoveNext())


{
if (!firstIter.Current.Equals(secondIter.Current))
{
return false;
}
}

return true;
}

Bu, ikinci bir LINQ deyimidir: Terminal yöntemlerini gösterir. Bunlar girdi olarak bir sıra alır (veya bu durumda iki
dizi) ve tek bir skaler değer döndürür. Terminal yöntemleri kullanılırken, her zaman bir LINQ sorgusunun Yöntem
zincirindeki son yöntem ve bu nedenle "Terminal" adı verilir.
Bu işlemi, deste 'nın orijinal düzeninde ne zaman geri yükleneceğini tespit etmek için kullandığınızda görebilirsiniz.
Karışık kodu bir döngü içine koyun ve SequenceEquals() yöntemi uygulanarak sıranın özgün sırasına geri
döndüğünüzde durdurulur. Bir dizi yerine tek bir değer döndürdüğünden, her sorguda her zaman son yöntem
olacağını görebilirsiniz:

// Program.cs
static void Main(string[] args)
{
// Query for building the deck

// Shuffling using InterleaveSequenceWith<T>();

var times = 0;
// We can re-use the shuffle variable from earlier, or you can make a new one
shuffle = startingDeck;
do
{
shuffle = shuffle.Take(26).InterleaveSequenceWith(shuffle.Skip(26));

foreach (var card in shuffle)


{
Console.WriteLine(card);
}
Console.WriteLine();
times++;

} while (!startingDeck.SequenceEquals(shuffle));

Console.WriteLine(times);
}

Şimdiye kadar aldığınız kodu çalıştırın ve her bir karıştırmadan destesi nasıl yeniden bir şekilde yeniden düzenler.
8 karışık (do-while döngüsünün yinelemesi) sonrasında, deste başlangıç LINQ sorgusundan ilk kez
oluşturduğunuz sırada bulunduğu özgün yapılandırmaya geri döner.

İyileştirmeleri
Şimdiye kadar derlediğiniz örnek, üst ve alt kartların her çalıştırmada aynı kalacağı karışıkbir şekilde yürütülür. Tek
bir değişiklik yapabiliriz: bunun yerine, tüm 52 kartlar konum değiştiren bir karışık olarak kullanacağız. Bir karışık
olarak, alt yarısı ilk kartın destedeki ilk kart haline gelmesi için destesi bir kez ayırmada kullanırsınız. Bu, üstteki
yarısında son kartın alt kart haline geldiği anlamına gelir. Bu, tekil kod satırında basit bir değişiklik. Take ve
Skipkonumlarını değiştirerek geçerli karıştırma sorgusunu güncelleştirin. Bu, deste 'nın üst ve alt kilitlenme
sırasını değiştirir:

shuffle = shuffle.Skip(26).InterleaveSequenceWith(shuffle.Take(26));

Programı yeniden çalıştırın ve deste 'nın kendisini yeniden sıralamak için 52 yineleme aldığını görürsünüz.
Program çalışmaya devam ettiğinden bazı önemli performans düşüşlerinden de karşılaşırsınız.
Bunun birçok nedeni vardır. Bu performans durmasının önemli nedenlerine bir tane ekleyebilirsiniz: verimsiz
yavaş değerlendirmekullanımı.
Kısaca, yavaş değerlendirme bir deyimin değerlendirmesinin değeri gerekli olana kadar gerçekleştirilmediğini
belirtir. LINQ sorguları, geç değerlendirilen ifadelerdir. Sıralar yalnızca öğeler istendiğinde oluşturulur. Genellikle
bu, LINQ 'ın önemli bir avantajıdır. Bununla birlikte, bu program gibi bir kullanımda, yürütme zamanında üstel
büyümeye neden olur.
Bir LINQ sorgusu kullanarak özgün destesi oluşturduğumuz unutulmamalıdır. Her karıştırma, önceki destede üç
LINQ sorgusu gerçekleştirerek oluşturulur. Bunların tümü geç gerçekleştirilir. Bu Ayrıca, sıranın her istenilişinde
yeniden gerçekleştirdikleri anlamına gelir. 5 TB yinelemesine alışışınızda, ilk desteyi pek çok kez yeniden
oluşturuluyor olursunuz. Bu davranışı göstermek için bir günlük yazalım. Ardından, onu düzeltireceksiniz.
Extensions.cs dosyanızda, aşağıdaki yöntemi yazın veya kopyalayın. Bu genişletme yöntemi, proje dizininizde
debug.log adlı yeni bir dosya oluşturur ve şu anda günlük dosyasına yürütülmekte olan sorguyu kaydeder. Bu
genişletme yöntemi sorgunun yürütüldüğünü işaretlemek için herhangi bir sorguya eklenebilir.

public static IEnumerable<T> LogQuery<T>


(this IEnumerable<T> sequence, string tag)
{
// File.AppendText creates a new file if the file doesn't exist.
using (var writer = File.AppendText("debug.log"))
{
writer.WriteLine($"Executing Query {tag}");
}

return sequence;
}

File altında kırmızı renkli bir çizgi görürsünüz, bunun anlamı yoktur. Derleyici File ne olduğunu bilmediğinden
derlenmez. Bu sorunu çözmek için Extensions.cs ilk satırın altına aşağıdaki kod satırını eklediğinizden emin olun:

using System.IO;

Bu, sorunu çözmeli ve kırmızı hata kaybolur.


Ardından, her bir sorgunun tanımını bir günlük iletisiyle işaretleyin:
// Program.cs
public static void Main(string[] args)
{
var startingDeck = (from s in Suits().LogQuery("Suit Generation")
from r in Ranks().LogQuery("Rank Generation")
select new { Suit = s, Rank = r }).LogQuery("Starting Deck");

foreach (var c in startingDeck)


{
Console.WriteLine(c);
}

Console.WriteLine();
var times = 0;
var shuffle = startingDeck;

do
{
// Out shuffle
/*
shuffle = shuffle.Take(26)
.LogQuery("Top Half")
.InterleaveSequenceWith(shuffle.Skip(26)
.LogQuery("Bottom Half"))
.LogQuery("Shuffle");
*/

// In shuffle
shuffle = shuffle.Skip(26).LogQuery("Bottom Half")
.InterleaveSequenceWith(shuffle.Take(26).LogQuery("Top Half"))
.LogQuery("Shuffle");

foreach (var c in shuffle)


{
Console.WriteLine(c);
}

times++;
Console.WriteLine(times);
} while (!startingDeck.SequenceEquals(shuffle));

Console.WriteLine(times);
}

Her sorguya eriştiğinizde günlüğe kayıt yapmayın. Yalnızca özgün sorguyu oluşturduğunuzda günlüğe kaydedilir.
Programın çalıştırılması uzun sürer, ancak artık neden de görebilirsiniz. Oturum açma özelliği etkinken karışık
olarak çalışan haya 'nın dışında çalıştırırsanız, arka arkaya geri dönün. Hala yavaş değerlendirme etkileri
görürsünüz. Tek bir çalıştırmasında, tüm değer ve cins üretimi dahil 2592 sorgu yürütür.
Yaptığınız yürütmelerin sayısını azaltmak için kodun performansını buradan geliştirebilirsiniz. Yapabilmeniz
gereken basit bir çözüm, kart destesi oluşturan orijinal LINQ sorgusunun sonuçlarını önbelleğe almak için
kullanılır. Şu anda sorguları yeniden yürütüyorsunuz ve do-while döngüsü bir yinelemeden sonra yeniden
oluşturuyor, kartlar ve reshuffling her seferinde yeniden oluşturacağız. Kartların destesi önbelleğe almak için
ToArray LINQ yöntemlerinden yararlanabilir ve ToList; sorguları sorgulara eklediğinizde, onlara söyledikleri aynı
eylemleri gerçekleştirir, ancak artık sonuçları çağırmak istediğiniz yönteme bağlı olarak bir dizide veya listede
depolayacağız. LINQ metodu ToArray her iki sorguya de ekleyin ve programı yeniden çalıştırın:
public static void Main(string[] args)
{
var startingDeck = (from s in Suits().LogQuery("Suit Generation")
from r in Ranks().LogQuery("Value Generation")
select new { Suit = s, Rank = r })
.LogQuery("Starting Deck")
.ToArray();

foreach (var c in startingDeck)


{
Console.WriteLine(c);
}

Console.WriteLine();

var times = 0;
var shuffle = startingDeck;

do
{
/*
shuffle = shuffle.Take(26)
.LogQuery("Top Half")
.InterleaveSequenceWith(shuffle.Skip(26).LogQuery("Bottom Half"))
.LogQuery("Shuffle")
.ToArray();
*/

shuffle = shuffle.Skip(26)
.LogQuery("Bottom Half")
.InterleaveSequenceWith(shuffle.Take(26).LogQuery("Top Half"))
.LogQuery("Shuffle")
.ToArray();

foreach (var c in shuffle)


{
Console.WriteLine(c);
}

times++;
Console.WriteLine(times);
} while (!startingDeck.SequenceEquals(shuffle));

Console.WriteLine(times);
}

Şimdi, karışık karıştırma 30 sorguya kadar. Karıştırma ile birlikte yeniden çalıştırın ve benzer iyileştirmeler
görürsünüz: şimdi 162 sorguları yürütür.
Lütfen bu örneğin, yavaş değerlendirmenin performans sorunlarına neden olabileceği kullanım durumlarını
vurgulamak için tasarlandığını unutmayın. Yavaş değerlendirmenin kod performansını etkileyebileceğini görmek
önemli olsa da, tüm sorguların bir şekilde çalışması gerektiğini anlamak önemlidir. ToArray kullanmadan yaptığınız
performans isabeti, kart destesi için her yeni düzenlemenin önceki düzenlemeden derlenme nedeni. Geç
değerlendirme kullanmak, her yeni deste yapılandırmasının orijinal deste tarafından oluşturulduğu anlamına gelir
ve bu da startingDeck oluşturan kodu yürütüyordur. Bu, büyük miktarda ekstra iş oluşmasına neden olur.
Uygulamada, bazı algoritmalar Eager değerlendirmesi kullanılarak iyi çalışır ve diğerleri, yavaş değerlendirme
kullanarak iyi çalışır. Günlük kullanım için, veri kaynağı bir veritabanı altyapısı gibi ayrı bir işlem olduğunda, yavaş
değerlendirme genellikle daha iyi bir seçenektir. Veritabanları için, yavaş değerlendirme, daha karmaşık sorguların
veritabanı işlemine yalnızca bir gidiş dönüş ve kodunuzun geri kalanına geri dönmesi için izin verir. Bu, yavaş veya
Eager değerlendirmesi kullanmayı tercih etmeksizin, süreçlerinizi ölçmenize ve hangi tür değerlendirme türünün
size en iyi performansı sunmasına bakılmaksızın LINQ esnektir.
Sonuç
Bu projede şunları kapsamış olursunuz:
verileri anlamlı bir sırayla toplamak için LINQ sorguları kullanma
LINQ Sorgularına kendi özel işlevselümüzü eklemek için uzantı yöntemleri yazma
LINQ sorgularımızın, düşürülmüş hız gibi performans sorunları üzerinde çalıştığı, kodumuza ait yerleri bulma
' deki geç ve Eager değerlendirmesi, LINQ sorguları ve sorgu performansı üzerinde olabilecek etkileri
LINQ 'ten itibaren, kart püf noktaları için bir teknik Magicians kullanımı hakkında biraz bilgi edindiniz. Magicians,
her kartın destede nereye taşındığını denetleyebildiğinden Faro karıştırmasını kullanın. Artık bilineceğimize göre,
diğer herkese açık yapmayın!
LINQ hakkında daha fazla bilgi için bkz.
Dil ile Tümleşik Sorgu (LINQ )
LINQ'e Giriş
Temel LINQ sorgu Işlemleri (C#)
LINQ (C#) Ile veri dönüştürmeleri
LINQ (C#) Içinde sorgu sözdizimi ve Yöntem sözdizimi
LINQ'i Destekleyen C# Özellikleri
C# içindeki öznitelikleri kullanma
30.10.2019 • 12 minutes to read • Edit Online

Öznitelikler, bilgileri bildirimli bir şekilde kod ile ilişkilendirmenin bir yolunu sağlar. Ayrıca, çeşitli hedeflere
uygulanabilen yeniden kullanılabilir bir öğe de sağlayabilir.
[Obsolete] özniteliğini göz önünde bulundurun. Bu sınıf, yapı, yöntem, Oluşturucu ve daha fazlasına uygulanabilir.
Öğenin eski olduğunu bildirir . Daha sonra bu özniteliği aramak için C# derleyiciye ve yanıt olarak bazı eylemler
yapılır.
Bu öğreticide, kodunuza nasıl öznitelik ekleneceği, kendi öznitelerinizi nasıl oluşturacağınız ve kullanacağınız ve
.NET Core 'da yerleşik bazı özniteliklerin nasıl kullanılacağı gösterilir.

Prerequisites
.NET Core 'u çalıştırmak için makinenizi ayarlamanız gerekir. Yükleme yönergelerini .NET Core İndirmeleri
sayfasında bulabilirsiniz. Bu uygulamayı Windows, Ubuntu Linux, macOS veya bir Docker kapsayıcısında
çalıştırabilirsiniz. En sevdiğiniz kod düzenleyicinizi yüklemeniz gerekir. Aşağıdaki açıklamalar açık kaynaklı,
platformlar arası düzenleyici olan Visual Studio Code kullanır. Bununla birlikte, rahat olan her türlü aracı
kullanabilirsiniz.

Uygulamayı oluşturma
Tüm araçları yüklemişseniz, yeni bir .NET Core uygulaması oluşturun. Komut satırı Oluşturucuyu kullanmak için,
en sevdiğiniz kabukta aşağıdaki komutu yürütün:
dotnet new console

Bu komut, barekemikler .NET Core proje dosyaları oluşturur. Bu projeyi derlemek için gereken bağımlılıkları geri
yüklemek için dotnet restore yürütmeniz gerekir.

NOTE
.NET Core 2.0 SDK'sı ile başlayarak, çalıştırma gerekmez dotnet restore bir geri yükleme, örneğin, gerçekleşmesi için
gerekli tüm komutlar tarafından örtük olarak çalıştırıldığından dotnet new , dotnet build ve dotnet run . Bunu hala
geçerli bir komut burada açık bir geri yükleme yaparsanız anlamlı, bazı senaryolarda olduğu gibi sürekli tümleştirme
derlemeleri Azure DevOps Hizmetleri'nde veya açıkça zaman denetlemek için gereken derleme sistemlerinde geri yükleme
gerçekleşir.

Programı yürütmek için dotnet run kullanın. Konsola "Hello, World" çıkışını görmeniz gerekir.

Koda öznitelikler ekleme


' C#De, öznitelikleri Attribute temel sınıfından devraldığı sınıflardır. Attribute devralan herhangi bir sınıf, diğer
kod parçalarında "Tag" sıralaması olarak kullanılabilir. Örneğin, ObsoleteAttribute adlı bir öznitelik vardır. Bu,
kodun artık kullanılmıyor olduğunu ve artık kullanılmaması gerektiğini bildirmek için kullanılır. Bu özniteliği bir
sınıfa, örneğin köşeli ayraçları kullanarak yerleştirebilirsiniz.
[Obsolete]
public class MyClass
{

Sınıfı ObsoleteAttribute çağrıldığında yalnızca kodda [Obsolete] kullanılması gerekir. Bu, C# aşağıdaki bir
kuraldır. ' I seçerseniz tam adı [ObsoleteAttribute] kullanabilirsiniz.
Bir sınıf kullanım dışı olarak işaretlenirken, neden kullanımdan kalktı ve/veya bunun yerine ne tür bir bilgi
sağlamanız yararlı olur. Bunu, kullanılmayan özniteliğe bir String parametresi geçirerek yapın.

[Obsolete("ThisClass is obsolete. Use ThisClass2 instead.")]


public class ThisClass
{

Dize, var attr = new ObsoleteAttribute("some string") yazarken olduğu gibi ObsoleteAttribute oluşturucusuna
bağımsız değişken olarak geçirilir.
Öznitelik oluşturucusuna yönelik parametreler basit türler/değişmez değerler:
bool, int, double, string, Type, enums, etc ve bu türlerin dizileri ile sınırlıdır. Bir ifade veya değişken
kullanamazsınız. Konumsal veya adlandırılmış parametrelerin kullanımı ücretsizdir.

Kendi öznitelerinizi oluşturma


Bir öznitelik oluşturmak Attribute temel sınıfından devralma kadar basittir.

public class MySpecialAttribute : Attribute


{

Yukarıdaki gibi, artık kod tabanında başka bir öznitelik olarak [MySpecial] (veya [MySpecialAttribute] )
kullanabilirsiniz.

[MySpecial]
public class SomeOtherClass
{

ObsoleteAttribute gibi .NET temel sınıf kitaplığındaki öznitelikler, derleyicinin içindeki belirli davranışları tetikler.
Ancak, oluşturduğunuz herhangi bir öznitelik yalnızca meta veri olarak davranır ve yürütülen öznitelik sınıfı içinde
herhangi bir koda neden olmaz. Bu meta verileri kodunuzun başka bir yerinde (daha sonra öğreticide daha sonra)
uygulamak sizin için önemlidir.
Burada izlemek için bir ' Gotcha ' bulunur. Yukarıda belirtildiği gibi, öznitelikleri kullanırken yalnızca belirli türlerin
bağımsız değişken olarak geçirilmesine izin verilir. Ancak, bir öznitelik türü oluştururken, derleyici bu C#
parametreleri oluşturmamak için bunu durdurmaz. Aşağıdaki örnekte, yalnızca iyi şekilde derlenen bir
oluşturucuya sahip bir öznitelik oluşturduğdum.
public class GotchaAttribute : Attribute
{
public GotchaAttribute(Foo myClass, string str) {

}
}

Ancak, bu oluşturucuyu öznitelik söz dizimi ile kullanamazsınız.

[Gotcha(new Foo(), "test")] // does not compile


public class AttributeFail
{

Yukarıdaki
Attribute constructor parameter 'myClass' has type 'Foo', which is not a valid attribute parameter type gibi bir
derleyici hatasına neden olur

Öznitelik kullanımını kısıtlama


Öznitelikler, bir dizi "hedef" üzerinde kullanılabilir. Yukarıdaki örneklerde bunları sınıflarda gösterilmektedir, ancak
bunlar üzerinde de kullanılabilir:
Derleme
örneği
Oluşturucu
Temsilci
Enum
Olay
Alan
GenericParameter
Arabirim
Yöntem
Modül
Parametre
Özellik
ReturnValue
Yapı
Bir öznitelik sınıfı oluşturduğunuzda, varsayılan olarak, C# bu özniteliği olası öznitelik hedeflerinin herhangi
birinde kullanmanıza izin verir. Öznitelerinizi belirli hedeflere kısıtlamak istiyorsanız, öznitelik sınıfınıza
AttributeUsageAttribute kullanarak bunu yapabilirsiniz. Bu, öznitelik üzerindeki bir özniteliği!

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
public class MyAttributeForClassAndStructOnly : Attribute
{

Yukarıdaki özniteliği bir sınıf veya yapı olmayan bir şeye koymaya çalışırsanız,
Attribute 'MyAttributeForClassAndStructOnly' is not valid on this declaration type. It is only valid on 'class,
struct' declarations
gibi bir derleyici hatası alacaksınız

public class Foo


{
// if the below attribute was uncommented, it would cause a compiler error
// [MyAttributeForClassAndStructOnly]
public Foo()
{ }
}

Bir kod öğesine eklenen öznitelikleri kullanma


Öznitelikler meta veri olarak davranır. Dışarı hiçbir dışa zorlama olmadan aslında hiçbir şey yapmaz.
Öznitelikleri bulmak ve üzerinde işlem yapmak için, yansıma genellikle gereklidir. Bu öğreticide yansıma
derinlemesine bir savunma ele alınmayacak, ancak temel fikir, yansıma ' de C# diğer kodu incelediği için kod
yazmanıza olanak tanır.
Örneğin, bir sınıf hakkında bilgi almak için yansıma kullanabilirsiniz (kodunuzun baş using System.Reflection;
ekleyin):

TypeInfo typeInfo = typeof(MyClass).GetTypeInfo();


Console.WriteLine("The assembly qualified name of MyClass is " + typeInfo.AssemblyQualifiedName);

Bu, şöyle bir şey yazdıracaktır:


The assembly qualified name of MyClass is ConsoleApplication.MyClass, attributes, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null

TypeInfo bir nesneniz (veya bir MemberInfo , FieldInfo , vb) varsa, GetCustomAttributes yöntemini
kullanabilirsiniz. Bu, Attribute nesnelerinin bir koleksiyonunu döndürür. Ayrıca, GetCustomAttribute kullanabilir
ve bir öznitelik türü belirtebilirsiniz.
Aşağıda, MyClass için bir MemberInfo örneği üzerinde GetCustomAttributes kullanılmasına bir örnek verilmiştir
(daha önce gördük daha önce üzerinde bir [Obsolete] özniteliği vardır).

var attrs = typeInfo.GetCustomAttributes();


foreach(var attr in attrs)
Console.WriteLine("Attribute on MyClass: " + attr.GetType().Name);

Bu işlem konsola yazdıracaktır: Attribute on MyClass: ObsoleteAttribute . MyClass diğer öznitelikleri eklemeyi
deneyin.
Bu nesnelerinin örneklendiği unutulmamalıdır geç. Diğer bir deyişle, GetCustomAttribute veya
Attribute
GetCustomAttributes kullanana kadar bunlar örneklenemez. Bunlar her seferinde de örneklenmiştir. Bir satırda
GetCustomAttributes iki kez çağrılması, ObsoleteAttribute iki farklı örnek döndürür.

Temel sınıf kitaplığındaki (BCL) ortak öznitelikler


Öznitelikler birçok araç ve çerçeve tarafından kullanılır. NUnit, NUnit Test Çalıştırıcısı tarafından kullanılan [Test]
ve [TestFixture] gibi öznitelikleri kullanır. ASP.NET MVC [Authorize] gibi öznitelikleri kullanır ve MVC
eylemleri üzerinde çapraz kesme sorunları gerçekleştirmek için bir eylem filtresi çerçevesi sağlar. Postsharp , ' de
C#en boy yönelimli programlamaya izin vermek için öznitelik sözdizimini kullanır.
.NET Core temel sınıf kitaplıklarında yerleşik olarak bulunan bazı önemli öznitelikleri aşağıda verilmiştir:
[Obsolete] . Bu bir tane Yukarıdaki örneklerde kullanılmıştır ve System ad alanında bulunur. Değişen kod
tabanı hakkında bildirime dayalı belgeler sağlamak yararlıdır. Bir ileti bir dize biçiminde sağlanıyor ve bir
derleyici uyarısına bir derleyici hatasına iletmek için başka bir Boolean parametresi kullanılabilir.
[Conditional] . Bu öznitelik System.Diagnostics ad alanıdır. Bu öznitelik yöntemlere (veya öznitelik
sınıflarına) uygulanabilir. Oluşturucuya bir dize geçirmeniz gerekir. Bu dize bir #define yönergeyle
eşleşmiyorsa, bu yönteme yapılan çağrılar (ancak yöntemin kendisi değil) C# derleyici tarafından kaldırılır.
Genellikle bu, hata ayıklama (Tanılama) amaçlarıyla kullanılır.
[CallerMemberName] . Bu öznitelik, parametrelerde kullanılabilir ve System.Runtime.CompilerServices ad
alanında bulunabilir. Bu, başka bir yöntemi çağıran yöntemin adını eklemek için kullanılan bir özniteliktir. Bu,
genellikle çeşitli kullanıcı arabirimi çerçevelerinde INotifyPropertyChanged uygularken ' sihirli dizeler ' ' i
ortadan kaldırmanın bir yolu olarak kullanılır. Örnek olarak:

public class MyUIClass : INotifyPropertyChanged


{
public event PropertyChangedEventHandler PropertyChanged;

public void RaisePropertyChanged([CallerMemberName] string propertyName = null)


{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

private string _name;


public string Name
{
get { return _name;}
set
{
if (value != _name)
{
_name = value;
RaisePropertyChanged(); // notice that "Name" is not needed here explicitly
}
}
}
}

Yukarıdaki kodda, bir sabit "Name" dize olması gerekmez. Bu, typo ile ilgili hataları önlemeye yardımcı olabilir ve
ayrıca daha yumuşak yeniden düzenleme/yeniden adlandırma sağlar.

Özet
Öznitelikler bildirime dayalı güç sağlar C#, ancak bunlar bir meta veri biçimidir ve kendilerine göre hareket ederler.
C# Dilin turu
24.10.2019 • 8 minutes to read • Edit Online

C#("bkz. diyez") basit, modern, nesne odaklı ve tür açısından güvenli bir programlama dilidir. C#C 'nin dil ailesinde
köklerine sahiptir ve C, C++, Java ve JavaScript programcıları için hemen tanıdık gelecektir. Bu tur, dilin önemli
bileşenlerine genel bir bakış sağlar. Etkileşimli örneklerle dili araştırmak isterseniz, öğreticilere giriş C#
deneyimimizi deneyin.
C#, nesne odaklı bir dildir, ancak C# daha fazla bileşen odaklı programlama desteğini içerir. Modern yazılım
tasarımı giderek, yazılım bileşenlerini, kendi kendine içerilen ve kendi kendine açıklayan işlev paketleri biçiminde
kullanır. Bu bileşenlere anahtar, özellikler, Yöntemler ve olaylar içeren bir programlama modeli sunduklarında;
Bunlar, bileşen hakkında bildirime dayalı bilgiler sağlayan özniteliklere sahiptir; ve kendi belgelerini içerirler. C#,
yazılım bileşenlerinin oluşturulması ve kullanılması için çok doğal bir C# dil sunarak, bu kavramları doğrudan
desteklemek için dil yapıları sağlar.
Birçok C# Özellik sağlam ve dayanıklı uygulamalar oluşturmaya yardımcı olur: çöp toplama , erişilemeyen
kullanılmayan nesneler tarafından kullanılan belleği otomatik olarak geri kazanır; özel durum işleme , hata
algılama ve kurtarmaya yönelik yapılandırılmış ve genişletilebilir bir yaklaşım sağlar; dilin tür kullanımı uyumlu
tasarımı, başlatılmamış değişkenlerden okumayı, sınırları ötesinde dizileri dizin haline getirmek veya
Denetlenmemiş tür yayınları gerçekleştirmeyi olanaksız hale getirir.
C#Birleşik bir tür sisteminesahiptir. int C# ve double gibi temel türler dahil olmak üzere tüm türler tek bir kök
object türünden devralınır. Bu nedenle, tüm türler ortak işlemler kümesini paylaşır ve herhangi bir türdeki
değerler tutarlı bir şekilde depolanabilir, taşınır ve çalıştırılabilir. Ayrıca, C# hem Kullanıcı tanımlı başvuru türlerini
hem de değer türlerini destekler, bu da nesnelerin dinamik ayrılmasına ve basit yapıların satır içi depolamamasına
olanak tanır.
Programlar ve kitaplıkların zaman içinde zaman içinde gelişebilmesini sağlamak için, tasarımına daha fazla vurgu
konulmuştur. C# C# Birçok programlama dili bu sorunla ilgileniyor ve sonuç olarak, bu dillerde yazılmış
programlar, bağımlı kitaplıkların daha yeni sürümleri tanıtıldığında gerekenden çok daha fazla. C#Sürüm
oluşturma konuları tarafından doğrudan etkilenen tasarımın yönleri, ayrı virtual ve override değiştiricileri, yöntem
aşırı yükleme çözümlemesi kurallarını ve açık arabirim üye bildirimleri için desteği içerir.

Merhaba dünya
"Hello, World" programı, genellikle bir programlama dilini tanıtmak için kullanılır. Burada yer C#verilmiştir:

using System;

class Hello
{
static void Main()
{
Console.WriteLine("Hello, World");
}
}

C#Kaynak dosyalar genellikle .cs dosya uzantısına sahiptir. "Hello, World" programının Hello.csdosyasında
depolandığını varsayarsak, program komut satırı kullanılarak derlenmiş olabilir:

csc hello.cs
Hello. exeadlı bir yürütülebilir derleme üreten. Bu uygulama tarafından oluşturulan çıktı şu şekilde çalışır:

Hello, World

IMPORTANT
csc komutu tam Framework için derlenir ve tüm platformlarda bulunmayabilir.

"Hello, World" programı, System ad alanına başvuran bir using yönergesi ile başlar. Ad alanları, programları ve
kitaplıkları düzenlemek C# için hiyerarşik bir yol sağlar. Ad alanları türler ve diğer ad alanlarını içerir — örneğin,
System ad alanı, programda başvurulan Console sınıfı ve IO ve Collections gibi birçok farklı ad alanı gibi bir dizi
tür içerir. Verilen bir ad alanına başvuran using yönergesi, bu ad alanının üyesi olan türlerin nitelenmemiş
kullanımını mümkün değildir. using yönergesi nedeniyle, program System.Console.WriteLine için toplu
Console.WriteLine kullanabilir.

"Hello, World" programı tarafından tanımlanan Hello sınıfı tek bir üyeye sahiptir ve Main adlı yöntem. Main
yöntemi statik değiştiriciyle birlikte bildirilmiştir. Örnek yöntemleri, anahtar sözcük this kullanarak belirli bir
kapsayan nesne örneğine başvurabilir, statik yöntemler belirli bir nesneye başvuru olmadan çalışır. Kurala göre,
Main adlı statik bir yöntem, bir programın giriş noktası olarak işlev görür.

Programın çıktısı, System ad alanındaki Console sınıfının WriteLine yöntemi tarafından üretilir. Bu sınıf,
varsayılan olarak derleyicinin otomatik olarak başvurduğu standart sınıf kitaplıkları tarafından sağlanır.
Hakkında C#daha fazla bilgi edinmek için çok daha fazla şey vardır. Aşağıdaki konular, C# dilin öğelerine bir genel
bakış sağlar. Bu genel bakışlar, dilin tüm öğeleriyle ilgili temel bilgileri sağlar ve bu C# dilin öğelerine daha ayrıntılı
bilgi edinmek için gereken bilgileri verir:
Program Yapısı
C# Dilde temel kurumsal kavramları öğrenin: Programlar, ad alanları, türler, Üyelerve derlemeler.
Türler ve Değişkenler
Dildeki değer türleri, başvuru türlerive değişkenler hakkında bilgi edinin. C#
İfadeler
İfadeler , işlenenler ve işleçlerdenoluşturulur. İfadeler bir değer üretir.
Deyimler
Bir programın eylemlerini ifade etmek için deyimlerini kullanırsınız.
Sınıflar ve nesneler
Sınıflar , türlerin en temel C#larıdır. Nesneler bir sınıfın örnekleridir. Sınıflar, bu konunun de ele alındığı
Üyelerkullanılarak oluşturulmuştur.
Yapılar
Yapılar , sınıfların aksine değer türleri olan veri yapılarıdır.
Diziler
Dizi , hesaplanan dizinler üzerinden erişilen çeşitli değişkenler içeren bir veri yapısıdır.
Arabirimler
Arabirim , sınıflar ve yapılar tarafından uygulanabilecek bir sözleşmeyi tanımlar. Arabirim, Yöntemler,
özellikler, olaylar ve Dizin oluşturucular içerebilir. Arabirim, tanımladığı üyelerin uygulamalarını sağlamaz;
yalnızca arabirimini uygulayan sınıflar veya yapılar tarafından sağlanması gereken üyeleri belirtir.
Sabit listeleri
Sabit listesi türü , adlandırılmış sabitler kümesi olan ayrı bir değer türüdür.
Temsilciler
Bir temsilci türü , belirli bir parametre listesi ve dönüş türü olan yöntemlere yapılan başvuruları temsil
eder. Temsilciler, yöntemleri değişkenlere atanabilecek ve parametre olarak geçirilen varlıklar olarak
işleme olanağı tanır. Temsilciler, bazı diğer dillerde bulunan işlev işaretçileri kavramına benzerdir, ancak
işlev işaretçilerinden farklı olarak Temsilciler nesne yönelimli ve tür açısından güvenlidir.
Öznitelikler
Öznitelikler , programların türler, Üyeler ve diğer varlıklar hakkında ek bildirime dayalı bilgiler
belirtmesini sağlar.

NEXT
Program Yapısı
6.12.2019 • 4 minutes to read • Edit Online

' Deki C# temel kurumsal kavramlar, Programlar, ad alanları, türler, Üyelerve derlemelerdir. C#programlar bir
veya daha fazla kaynak dosyadan oluşur. Programlar, üyeleri içeren ve ad alanları halinde düzenlenebilen türleri
bildirir. Sınıflar ve arabirimler tür örnekleridir. Alanlar, Yöntemler, Özellikler ve olaylar üye örnekleridir. C#
Programlar derlendiğinde, fiziksel olarak derlemeler halinde paketlenir. Derlemeler, sırasıyla uygulama veya
kitaplıkuygulanıp uygulamadığına bağlı olarak dosya uzantısına .exe veya .dll sahiptir.
Örnek, Acme.Collections adlı bir ad alanında Stack adlı bir sınıf bildirir:

using System;
namespace Acme.Collections
{
public class Stack
{
Entry top;
public void Push(object data)
{
top = new Entry(top, data);
}

public object Pop()


{
if (top == null)
{
throw new InvalidOperationException();
}
object result = top.data;
top = top.next;
return result;
}

class Entry
{
public Entry next;
public object data;
public Entry(Entry next, object data)
{
this.next = next;
this.data = data;
}
}
}
}

Bu sınıfın tam nitelikli adı Acme.Collections.Stack . Sınıf birçok üye içerir: top adlı bir alan, Push ve Pop adlı iki
yöntem ve Entry adlı bir iç içe sınıf. Entry sınıfı üç üye içerir: next adlı bir alan, data adlı bir alan ve bir
Oluşturucu. Örneğin kaynak kodunun dosyada acme.cs , komut satırının

csc /t:library acme.cs

örneği bir kitaplık ( Main giriş noktası olmayan kod) olarak derler ve acme.dll adlı bir derleme oluşturur.
IMPORTANT
Yukarıdaki örnekler, komut satırı C# derleyicisi olarak csc kullanır. Bu derleyici bir Windows yürütülebiliridir. Diğer
platformlarda C# kullanmak Için .NET Core araçlarını kullanmanız gerekir. .NET Core ekosistemi, komut satırı yapılarını
yönetmek için dotnet CLı kullanır. Buna bağımlılıkları yönetme ve C# derleyicinin çağrılması dahildir. .NET Core tarafından
desteklenen platformlarda bu araçların tam açıklaması için Bu öğreticiye bakın.

Derlemeler, ara dil (IL ) yönergeleri biçiminde çalıştırılabilir kodu ve meta veri biçimindeki sembolik bilgileri içerir.
Yürütülmeden önce, bir derlemedeki IL kodu, .NET ortak dil çalışma zamanının tam zamanında (JıT) derleyicisi
tarafından otomatik olarak işlemciye özgü koda dönüştürülür.
Bir derleme, hem kodu hem de meta verileri içeren bir işlevsellik birimi olduğundan, içinde C# #include
yönergeler ve üst bilgi dosyaları gerekmez. Belirli bir derlemede yer alan ortak türler ve Üyeler, yalnızca program
derlenirken bu derlemeye C# başvurarak bir programda kullanılabilir hale getirilir. Örneğin, bu program acme.dll
derlemesinden Acme.Collections.Stack sınıfını kullanır:

using System;
using Acme.Collections;
class Example
{
static void Main()
{
Stack s = new Stack();
s.Push(1);
s.Push(10);
s.Push(100);
Console.WriteLine(s.Pop());
Console.WriteLine(s.Pop());
Console.WriteLine(s.Pop());
}
}

Program dosyada depolanıyorsa, example.cs derlendiğinde example.cs Acme. dll derlemesine derleyicinin/r
seçeneği kullanılarak başvurulabilir:

csc /r:acme.dll example.cs

Bu, çalıştırılan example.exe adlı bir çalıştırılabilir derleme oluşturur ve bu, çalıştırıldığında çıktıyı üretir:

100
10
1

C#bir programın kaynak metninin birkaç kaynak dosyada depolanmasına izin verir. Birden çok dosya C# programı
derlendiğinde, tüm kaynak dosyalar birlikte işlenir ve kaynak dosyalar birbirini tamamen başvurabilir — kavramsal
olarak, tüm kaynak dosyaları işlenmeden önce bir büyük dosyada birleştirilmiş olur. Bildirim sırası çok önemli
olduğundan, C# bazı durumlarda ileri bildirimlere hiçbir şekilde gerek yoktur. C#kaynak dosyayı yalnızca bir ortak
tür bildirmek üzere sınırlamaz veya kaynak dosyanın adının kaynak dosyada belirtilen bir türle eşleşmesi gerekir.

ÖN CEKI İL E R I
Türler ve değişkenler
23.11.2019 • 10 minutes to read • Edit Online

' De C#iki tür tür vardır: değer türleri ve başvuru türleri. Değer türlerinin değişkenleri doğrudan verilerini içerir,
ancak başvuru türündeki değişkenler verilerine başvuruları depolar, ikincisi ise nesneler olarak bilinir. Başvuru
türleriyle, iki değişkenin aynı nesneye başvurması ve bu nedenle bir değişkende işlemler için diğer değişken
tarafından başvurulan nesneyi etkilemesi mümkündür. Değer türleriyle, her birinin kendi verilerinin bir kopyasına
sahip olduğu ve bir üzerindeki işlemler ( ref ve out parametre değişkenlerinin olması dışında) üzerinde işlemler
için mümkün değildir.
C#öğesinin değer türleri, basit türler, sabit listesi türleri, yapı türlerive null yapılabilir değer türlerinedaha da
bölünür. C#öğesinin başvuru türleri, Sınıf türlerine, arabirim türlerine, dizi türlerineve temsilci türlerinedaha da
ayrılır.
Aşağıdakiler, tür sistemine genel bir C#bakış sağlar.
Değer türleri
Basit türler
İmzalanan integral: sbyte , short , int , long
İşaretsiz integral: byte , ushort , uint , ulong
Unicode karakterler: char
IEEE ikili kayan nokta: float , double
Yüksek duyarlıklı ondalık kayan nokta: decimal
Boolean: bool
Sabit listesi türleri
Formun Kullanıcı tanımlı türleri enum E {...}
Yapı türleri
Formun Kullanıcı tanımlı türleri struct S {...}
Null yapılabilir değer türleri
null bir değere sahip diğer tüm değer türlerinin uzantıları
Başvuru türleri
Sınıf türleri
Diğer tüm türlerin Ultimate temel sınıfı: object
Unicode dizeleri: string
Formun Kullanıcı tanımlı türleri class C {...}
Arabirim türleri
Formun Kullanıcı tanımlı türleri interface I {...}
Dizi türleri
Tek ve çok boyutlu, örneğin int[] ve int[,]
Temsilci türleri
Formun Kullanıcı tanımlı türleri delegate int D(...)
Sayısal türler hakkında daha fazla bilgi için bkz. Integral türleri ve kayan nokta türleri tablosu.
C# bool türü, Boole değerlerini ( true ya da false olan değerler) temsil etmek için kullanılır.
İçindeki C# karakter ve dize işleme Unicode kodlaması kullanır. char türü bir UTF -16 kod birimini temsil eder ve
string türü bir UTF -16 kod birimi dizisini temsil eder.
C#programlar yeni türler oluşturmak için tür bildirimleri kullanır. Tür bildiriminde yeni türün adı ve üyeleri
belirtilir. C#Türlerin beş kategorisi Kullanıcı tarafından tanımlanabilir: sınıf türleri, yapı türleri, arabirim türleri,
sabit listesi türleri ve temsilci türleri.
class türü, veri üyeleri (alanlar) ve işlev üyeleri (Yöntemler, Özellikler ve diğerleri) içeren bir veri yapısını
tanımlar. Sınıf türleri, tek devralma ve çok biçimlilik destekler, türetilmiş sınıfların temel sınıfları genişletebileceği
ve özelleştireceği mekanizmalar.
struct türü, veri üyeleri ve işlev üyeleri olan bir yapıyı temsil eden bir sınıf türüne benzerdir. Ancak, sınıfların
aksine yapılar değer türlerdir ve genellikle yığın ayırmayı gerektirmez. Yapı türleri Kullanıcı tarafından belirtilen
devralmayı desteklemez ve object türünden dolaylı olarak devralınan tüm yapı türleri.
interface türü, bir sözleşmeyi adlandırılmış bir ortak işlev üyeleri kümesi olarak tanımlar. interface uygulayan
bir class veya struct , arabirimin işlev üyelerinin uygulamalarını sağlamalıdır. interface birden çok temel
arabirimden devralınabilir ve bir class veya struct birden çok arabirim uygulayabilir.
delegate türü, belirli bir parametre listesi ve dönüş türü olan yöntemlere yapılan başvuruları temsil eder.
Temsilciler, yöntemleri değişkenlere atanabilecek ve parametre olarak geçirilen varlıklar olarak işleme olanağı
tanır. Temsilciler, işlevsel diller tarafından sunulan işlev türlerine benzerdir. Bunlar aynı zamanda diğer bazı dillerde
bulunan işlev işaretçileri kavramıyla benzerdir, ancak işlev işaretçilerinden farklı olarak Temsilciler nesne yönelimli
ve tür açısından güvenlidir.
class , struct , interface ve delegate türleri tüm genel türler destekler ve diğer türlerle parametrelenebilir.
enum türü, adlandırılmış sabitleri olan ayrı bir türdür. Her enum türü, sekiz integral türünden biri olması gereken
temel bir tür içerir. enum bir türün değer kümesi, temel alınan türün değerleri kümesiyle aynıdır.
C#herhangi bir türdeki tek ve çok boyutlu dizileri destekler. Yukarıda listelenen türlerin aksine,, kullanılmadan
önce dizi türlerinin bildirilmesini gerektirmez. Bunun yerine, dizi türleri Köşeli parantezlerle bir tür adı izleyerek
oluşturulur. Örneğin, int[] tek boyutlu bir int dizisidir, int[,] iki boyutlu bir int dizisidir ve int[][] tek
boyutlu bir dizi int tek boyutlu dizisidir.
Null yapılabilir değer türlerinin kullanılabilmesi için önce de bildirilmesini gerekmez. Her null yapılamayan değer
türü için T , null ek bir değer içerebilen karşılık gelen null yapılabilir bir değer türü T? vardır. Örneğin int? , 32
bitlik herhangi bir tamsayıyı veya null değer içerebilen bir türdür.
C#tür sistemi, herhangi türden bir değer object olarak işlenemeyeceği şekilde birleştirilmiştir. Her tür doğrudan
C# veya dolaylı olarak object sınıf türünden türetilir ve object tüm türlerin en son temel sınıfıdır. Başvuru
türlerinin değerleri, object türü olarak değerleri görüntüleyerek nesne olarak değerlendirilir. Değer türlerinin
değerleri, kutulama ve kutudan çıkarma işlemlerigerçekleştirerek nesneler olarak değerlendirilir. Aşağıdaki
örnekte, bir int değeri object dönüştürülür ve int ' ye yeniden geri döndürülür.

using System;
class BoxingExample
{
static void Main()
{
int i = 123;
object o = i; // Boxing
int j = (int)o; // Unboxing
}
}

Değer türünün bir değeri object türüne dönüştürüldüğünde, "Box" olarak da bilinen bir object örneği değeri
tutacak şekilde ayrılır ve değer bu kutuya kopyalanır. Buna karşılık, bir object başvurusu bir değer türüne
yayınlanırsa, başvurulan object doğru değer türünün bir kutusu olduğunu ve denetim başarılı olursa, kutudaki
değer kopyalanır.
C#öğesinin Birleşik tür sistemi etkin bir şekilde değer türlerinin "isteğe bağlı" nesneler olabileceği anlamına gelir.
Birleşme nedeniyle object türü kullanan genel amaçlı kitaplıklar, hem başvuru türleri hem de değer türleriyle
kullanılabilir.
İçinde C#alanlar, dizi öğeleri, yerel değişkenler ve parametreler dahil olmak üzere birkaç tür değişken vardır.
Değişkenler, depolama konumlarını temsil eder ve her değişken, aşağıda gösterildiği gibi, değişkende hangi
değerlerin depolanabileceğini belirleyen bir tür içerir.
Null yapılamayan değer türü
Bu tam türden bir değer
Null yapılabilir değer türü
Bir null değeri veya bu tam türde bir değer
object
null başvurusu, herhangi bir başvuru türünün nesnesine başvuru veya herhangi bir değer türünün
paketlenmiş değerine başvuru
Sınıf türü
null başvurusu, bu sınıf türünün bir örneğine başvuru veya bu sınıf türünden türetilmiş bir sınıfın
örneğine başvuru
Arabirim türü
null başvurusu, bu arabirim türünü uygulayan bir sınıf türü örneğine başvuru veya bu arabirim türünü
uygulayan bir değer türünün paketlenmiş değerine başvuru
Dizi türü
null başvurusu, bu dizi türünün bir örneğine başvuru veya uyumlu bir dizi türü örneğine başvuru
Temsilci türü
null başvurusu veya uyumlu bir temsilci türü örneğine başvuru

ÖN CEKI İL E R I
{1>İfadeler<1}
23.11.2019 • 2 minutes to read • Edit Online

İfadeler , işlenenler ve işleçlerdenoluşturulur. Bir ifadenin işleçleri, işlenenlerin hangi işlemleri uygulanacağını
gösterir. Operatör örnekleri arasında + , - , * , / ve new sayılabilir. İşlenenlerin örnekleri, sabit değerleri,
alanları, yerel değişkenleri ve ifadeleri içerir.
Bir ifade birden çok işleç içerdiğinde, işleçlerin önceliği ayrı işleçlerin değerlendirilme sırasını denetler. Örneğin, *
işleci + işlecinden daha yüksek önceliğe sahip olduğu için x + y * z ifade x + (y * z) olarak değerlendirilir.
Aynı önceliğe sahip iki işleç arasında bir işlenen gerçekleştiğinde, işleçlerin ilişkilendirilebilirliği , işlemlerin
gerçekleştirileceği sırayı denetler:
Atama ve null birleşim işleçleri hariç olmak üzere tüm ikili işleçler sola ilişkilendirilebilir, yani işlemler soldan
sağa yapılır. Örneğin, x + y + z (x + y) + z olarak değerlendirilir.
Atama işleçleri, null birleştirme ?? ve ??= işleçleri ve koşullu işleç ?: , doğru ilişkilendirilebilir, yani işlemler
sağdan sola yapılır. Örneğin, x = y = z x = (y = z) olarak değerlendirilir.
Öncelik ve ilişkilendirilebilirlik, parantezler kullanılarak denetlenebilir. Örneğin, x + y * z önce y z ile çarpar
ve sonucu x ekler, ancak (x + y) * z önce x ve y ekler ve sonra sonucu z ile çarpar.
Çoğu işleç aşırıyüklenebilir. İşleç aşırı yüklemesi, Kullanıcı tanımlı operatör uygulamalarının bir veya her ikisinin de
Kullanıcı tanımlı sınıf veya yapı türünde olduğu işlemler için belirtilmesine izin verir.
C#Aritmetik, mantıksal, bit düzeyinde ve vardiya işlemleri ile eşitlik ve sıra karşılaştırmaları gerçekleştirmeye
yönelik bir dizi işleç sağlar.
Öncelik düzeyine göre sıralanan C# işleçlerin tüm listesi için bkz C# . işleçler.

ÖN CEKI İL E R I
Deyimler
23.10.2019 • 5 minutes to read • Edit Online

Bir programın eylemleri kullanılarak ifade edilir deyimleri. C# ifadeleri açısından katıştırılmış deyimi bir dizi
tanımlanmış birkaç farklı türde destekler.
A blok bağlamlarda yazılacak birden çok deyime burada tek bir deyimde izin verir. Sınırlayıcılar yazılan deyimlerin
listesini bir blok oluşan { ve } .
Bildirim deyimleri yerel değişkenleri ve sabitleri bildirmek için kullanılır.
İfade deyimleri ifadeler değerlendirilir. Deyimleri kullanılabilir ifadeler, yöntem çağrılarını içeren nesne ayırmaları
kullanarak new işleç, atamaları kullanarak = ve bileşik atama işleçleri, artırma ve azaltma işlemlerini kullanarak
++ ve -- işleçler ve await ifadeler.

Seçim deyimleri olası deyimleri yürütme bazı ifadesinin değerine göre bir dizi birini seçmek için kullanılır. Bu
gruba if ve switch deyimleri.
Yineleme deyimleri sürekli bir katıştırılmış deyimi yürütmek için kullanılır. Bu gruba while , do , for , ve foreach
deyimleri.
Atlama deyimleri denetim aktarmak için kullanılır. Bu gruba break , continue , goto , throw , return , ve yield
deyimleri.
try ... catch deyimi, bir blok yürütülmesi sırasında oluşan özel durumları yakalamak için kullanılır ve try ...
finally deyimi veya bir özel durum oluştu olup olmadığını her zaman yürütülür, sonlandırma kodu belirtmek için
kullanılır.
checkedVe unchecked ifadeler Tamsayı türünde aritmetik işlemler ve dönüştürmeler için taşma denetimi
bağlamını denetlemek için kullanılır.
lock Deyimi belirli bir nesne için karşılıklı dışlama kilidini almak, bir deyimi yürütün ve sonra kilidi için kullanılır.
using Deyimi bir kaynağı almak, bir deyimi yürütün ve sonra o kaynağını atma için kullanılır.
Aşağıda, her biri için bir örnek sağlar ve kullanılabilir deyimleri türlerini listeler.
Yerel değişken bildirimi:

static void Declarations(string[] args)


{
int a;
int b = 2, c = 3;
a = 1;
Console.WriteLine(a + b + c);
}

Yerel sabit bildiriminde:


static void ConstantDeclarations(string[] args)
{
const float pi = 3.1415927f;
const int r = 25;
Console.WriteLine(pi * r * r);
}

İfade deyimi:

static void Expressions(string[] args)


{
int i;
i = 123; // Expression statement
Console.WriteLine(i); // Expression statement
i++; // Expression statement
Console.WriteLine(i); // Expression statement
}

if deyimi:

static void IfStatement(string[] args)


{
if (args.Length == 0)
{
Console.WriteLine("No arguments");
}
else
{
Console.WriteLine("One or more arguments");
}
}

switch deyimi:

static void SwitchStatement(string[] args)


{
int n = args.Length;
switch (n)
{
case 0:
Console.WriteLine("No arguments");
break;
case 1:
Console.WriteLine("One argument");
break;
default:
Console.WriteLine($"{n} arguments");
break;
}
}

while deyimi:
static void WhileStatement(string[] args)
{
int i = 0;
while (i < args.Length)
{
Console.WriteLine(args[i]);
i++;
}
}

do deyimi:

static void DoStatement(string[] args)


{
string s;
do
{
s = Console.ReadLine();
Console.WriteLine(s);
} while (!string.IsNullOrEmpty(s));
}

for deyimi:

static void ForStatement(string[] args)


{
for (int i = 0; i < args.Length; i++)
{
Console.WriteLine(args[i]);
}
}

foreach deyimi:

static void ForEachStatement(string[] args)


{
foreach (string s in args)
{
Console.WriteLine(s);
}
}

break deyimi:

static void BreakStatement(string[] args)


{
while (true)
{
string s = Console.ReadLine();
if (string.IsNullOrEmpty(s))
break;
Console.WriteLine(s);
}
}

continue deyimi:
static void ContinueStatement(string[] args)
{
for (int i = 0; i < args.Length; i++)
{
if (args[i].StartsWith("/"))
continue;
Console.WriteLine(args[i]);
}
}

goto deyimi:

static void GoToStatement(string[] args)


{
int i = 0;
goto check;
loop:
Console.WriteLine(args[i++]);
check:
if (i < args.Length)
goto loop;
}

return deyimi:

static int Add(int a, int b)


{
return a + b;
}
static void ReturnStatement(string[] args)
{
Console.WriteLine(Add(1, 2));
return;
}

yield deyimi:

static System.Collections.Generic.IEnumerable<int> Range(int start, int end)


{
for (int i = start; i < end; i++)
{
yield return i;
}
yield break;
}
static void YieldStatement(string[] args)
{
foreach (int i in Range(-10,10))
{
Console.WriteLine(i);
}
}

throw deyimleri ve try ifadeleri:


static double Divide(double x, double y)
{
if (y == 0)
throw new DivideByZeroException();
return x / y;
}
static void TryCatch(string[] args)
{
try
{
if (args.Length != 2)
{
throw new InvalidOperationException("Two numbers required");
}
double x = double.Parse(args[0]);
double y = double.Parse(args[1]);
Console.WriteLine(Divide(x, y));
}
catch (InvalidOperationException e)
{
Console.WriteLine(e.Message);
}
finally
{
Console.WriteLine("Good bye!");
}
}

checked ve unchecked ifadeleri:

static void CheckedUnchecked(string[] args)


{
int x = int.MaxValue;
unchecked
{
Console.WriteLine(x + 1); // Overflow
}
checked
{
Console.WriteLine(x + 1); // Exception
}
}

lock deyimi:

class Account
{
decimal balance;
private readonly object sync = new object();
public void Withdraw(decimal amount)
{
lock (sync)
{
if (amount > balance)
{
throw new Exception(
"Insufficient funds");
}
balance -= amount;
}
}
}
using deyimi:

static void UsingStatement(string[] args)


{
using (TextWriter w = File.CreateText("test.txt"))
{
w.WriteLine("Line one");
w.WriteLine("Line two");
w.WriteLine("Line three");
}
}

ÖN CEKI İL E R I
Sınıflar ve nesneler
23.11.2019 • 37 minutes to read • Edit Online

Sınıflar , türlerin en temel C#larıdır. Bir sınıf, durumu (alanları) ve eylemleri (Yöntemler ve diğer işlev üyelerini) tek
bir birimde birleştiren bir veri yapısıdır. Sınıf, nesneolarak da bilinen, sınıfının dinamik olarak oluşturulan örnekleri
için bir tanım sağlar. Sınıflar, Devralma ve çok biçimlilikdesteği, türetilmiş sınıfların temel sınıflarıgenişletebileceği
ve özelleştirilebilecek mekanizmalar.
Yeni sınıflar sınıf bildirimleri kullanılarak oluşturulur. Sınıf bildirimi, sınıfın özniteliklerini ve değiştiricilerini, sınıfın
adını, Taban sınıfını (belirtilmişse) ve sınıf tarafından uygulanan arabirimleri belirten bir üstbilgiyle başlar. Üst bilgi,
{ ve } sınırlayıcılarının yazıldığı üye bildirimlerinin bir listesinden oluşan sınıf gövdesinden gelir.

Aşağıda Point adlı basit bir sınıfın bildirimi verilmiştir:

public class Point


{
public int x, y;
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
}

Sınıf örnekleri, yeni bir örnek için bellek ayıran new işleci kullanılarak oluşturulur, örneği başlatmak için bir
oluşturucu çağırır ve örneğe bir başvuru döndürür. Aşağıdaki deyimler iki nokta nesnesi oluşturur ve bu nesnelere
başvuruları iki değişken halinde depolar:

Point p1 = new Point(0, 0);


Point p2 = new Point(10, 20);

Nesne artık erişilebilir olmadığında bir nesnenin kapladığı bellek otomatik olarak geri kazanılır. Üzerinde
C#nesneleri açıkça serbest bırakmak gerekli değildir veya mümkün değildir.

Üyeler
Bir sınıfın üyeleri statik üyeler veya örnek üyeleridir. Statik Üyeler sınıflara aittir ve örnek üyeleri nesnelere aittir
(sınıf örnekleri).
Aşağıda bir sınıfın içerebileceği üye türlerine ilişkin bir genel bakış sunulmaktadır.
{1>Sabitler<1}
Sınıfla ilişkili sabit değerler
Alanlar
Sınıfın değişkenleri
Yöntemler
Sınıfı tarafından gerçekleştirilebilecek hesaplamalar ve eylemler
Özellikler
Sınıfın adlandırılmış özelliklerini okuma ve yazma ile ilişkili eylemler
Dizin Oluşturucular
Bir dizi gibi sınıfın dizin oluşturma örnekleri ile ilişkili eylemler
Olaylar
Sınıfı tarafından oluşturulabilecek bildirimler
İşleçler
Sınıf tarafından desteklenen dönüşümler ve ifade işleçleri
Oluşturucular
Sınıfın veya sınıfın örneklerinin örneğini başlatmak için gereken eylemler
Sonlandırıcılar
Sınıfın örneklerinden önce gerçekleştirilecek eylemler kalıcı olarak atılır
Türler
Sınıf tarafından tanımlanan iç içe türler

Erişilebilirlik
Bir sınıfın her üyesinin ilişkili bir erişilebilirliği vardır ve bu, üyeye erişebilen program metni bölgelerini denetler.
Olası altı erişilebilirlik biçimi vardır. Bunlar aşağıda özetlenmiştir.
public
Erişim sınırlı değil
protected
Bu sınıftan türetilmiş bu sınıfla veya sınıflarla sınırlı erişim
internal
Geçerli bütünleştirilmiş koda (. exe,. dll, vb.) sınırlı erişim
protected internal
İçerilen sınıfla sınırlı erişim, kapsayan sınıftan türetilmiş sınıflar veya aynı derleme içindeki sınıflar
private
Bu sınıfla sınırlı erişim
private protected
Aynı derleme içindeki kapsayan türden türetilmiş kapsayan sınıf veya sınıflarla sınırlı erişim

Tür parametreleri
Sınıf tanımı, tür parametre adlarının bir listesini kapsayan açılı ayraçları olan sınıf adını izleyerek bir tür
parametreleri kümesi belirtebilir. Daha sonra tür parametreleri sınıfının üyelerini tanımlamak için sınıf
bildirimlerinin gövdesinde kullanılabilir. Aşağıdaki örnekte, Pair türü parametreleri TFirst ve TSecond :

public class Pair<TFirst,TSecond>


{
public TFirst First;
public TSecond Second;
}

Tür parametrelerini almak için belirtilen bir sınıf türüne Genel sınıf türüdenir. Yapı, arabirim ve temsilci türleri de
genel olabilir. Genel sınıf kullanıldığında, tür parametrelerinin her biri için tür bağımsız değişkenlerinin sağlanması
gerekir:

Pair<int,string> pair = new Pair<int,string> { First = 1, Second = "two" };


int i = pair.First; // TFirst is int
string s = pair.Second; // TSecond is string

Yukarıda Pair<int,string> gibi sunulan tür bağımsız değişkenlerine sahip genel bir tür, oluşturulmuş bir
türolarak adlandırılır.

Temel sınıflar
Sınıf bildirimi, sınıf adı ve tür parametreleri iki nokta ve temel sınıfın adı ile birlikte bir temel sınıf belirtebilir. Temel
sınıf belirtiminin atlanması object türünden türeterek aynıdır. Aşağıdaki örnekte, Point3D temel sınıfı Point ve
Point taban sınıfı object :

public class Point


{
public int x, y;
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
}
public class Point3D: Point
{
public int z;
public Point3D(int x, int y, int z) :
base(x, y)
{
this.z = z;
}
}

Bir sınıf, temel sınıfının üyelerini devralır. Devralma, bir sınıfın örnek ve statik oluşturucular ve temel sınıfın
sonlandırıcıları dışında, temel sınıfının tüm üyelerini örtük olarak içerdiği anlamına gelir. Türetilmiş bir sınıf,
devralananlara yeni üyeler ekleyebilir, ancak devralınmış bir üyenin tanımını kaldıramaz. Önceki örnekte, Point3D
x ve y alanları Point devralır ve her Point3D örnek, x , y ve z üç alan içerir.

Bir sınıf türünden, temel sınıf türlerinden herhangi birine örtük bir dönüştürme vardır. Bu nedenle, bir sınıf
türünün değişkeni bu sınıfın bir örneğine veya türetilmiş herhangi bir sınıfın örneğine başvurabilir. Örneğin,
önceki sınıf bildirimleri verildiğinde Point türünde bir değişken Point veya Point3D başvurabilir:

Point a = new Point(10, 20);


Point b = new Point3D(10, 20, 30);

Alanlar
Alan , bir sınıf ile veya bir sınıf örneğiyle ilişkili bir değişkendir.
Statik değiştiriciyle belirtilen bir alan statik bir alan tanımlar. Statik alan tam olarak bir depolama konumunu
tanımlar. Bir sınıfın kaç örneğinin oluşturulduğuna bakılmaksızın, bir statik alanın yalnızca bir kopyası vardır.
Statik değiştirici olmadan belirtilen bir alan bir örnek alanını tanımlar. Bir sınıfın her örneği, bu sınıfın tüm örnek
alanlarının ayrı bir kopyasını içerir.
Aşağıdaki örnekte, Color sınıfının her örneği r , g ve b örneği alanlarının ayrı bir kopyasına sahiptir ancak
Black , White , Red , Green ve Blue statik alanlarının yalnızca bir kopyası vardır:
public class Color
{
public static readonly Color Black = new Color(0, 0, 0);
public static readonly Color White = new Color(255, 255, 255);
public static readonly Color Red = new Color(255, 0, 0);
public static readonly Color Green = new Color(0, 255, 0);
public static readonly Color Blue = new Color(0, 0, 255);
private byte r, g, b;
public Color(byte r, byte g, byte b)
{
this.r = r;
this.g = g;
this.b = b;
}
}

Önceki örnekte gösterildiği gibi, salt okuma alanları readonly değiştiricisi ile bildirilebilecek. Bir readonly alana
atama yalnızca alanın bildiriminin veya aynı sınıftaki bir oluşturucunun parçası olarak gerçekleşebilir.

Yöntemler
Bir Yöntem , bir nesne veya sınıf tarafından gerçekleştirilebilecek bir hesaplama veya eylem uygulayan bir üyesidir.
Statik yöntemlere sınıfı aracılığıyla erişilir. Örnek yöntemlerine , sınıfının örnekleri aracılığıyla erişilir.
Yöntemler, yönteme geçirilen değerleri veya değişken başvurularını temsil eden bir parametrelistesine ve
hesaplanan ve yöntem tarafından döndürülen değer türünü belirten bir dönüş türünesahip olabilir. Bir yöntemin
dönüş türü bir değer döndürmezse void .
Türler gibi yöntemler de bir tür parametreleri kümesine sahip olabilir, bu da yöntem çağrıldığında tür bağımsız
değişkenlerinin belirtilmesi gerekir. Türlerin aksine, tür bağımsız değişkenleri genellikle yöntem çağrısının
bağımsız değişkenlerinden çıkarsanamıyor ve açıkça verilmemelidir.
Yöntemin imzası , yöntemin bildirildiği sınıfta benzersiz olmalıdır. Bir yöntemin imzası yöntemin adından, tür
parametrelerinin sayısına ve parametrelerinin sayısına, değiştiricilerine ve türlerine sahiptir. Bir yöntemin imzası,
dönüş türünü içermez.
Parametreler
Parametreler, değerlere veya değişken başvurularını yöntemlere geçirmek için kullanılır. Bir yöntemin
parametreleri, yöntemi çağrıldığında belirtilen bağımsız değişkenlerden gerçek değerlerini alır. Dört tür parametre
vardır: değer parametreleri, başvuru parametreleri, çıkış parametreleri ve parametre dizileri.
Giriş bağımsız değişkenlerini geçirmek için bir değer parametresi kullanılır. Değer parametresi, parametresi için
geçirilen bağımsız değişkenden ilk değerini alan yerel bir değişkene karşılık gelir. Değer parametresindeki
değişiklikler, parametresi için geçirilen bağımsız değişkeni etkilemez.
Değer parametreleri, ilgili bağımsız değişkenlerin atlanabilmesi için varsayılan bir değer belirtilerek isteğe bağlı
olabilir.
Başvuru parametresi , bağımsız değişkenleri başvuruya göre geçirmek için kullanılır. Başvuru parametresi için
geçirilen bağımsız değişken, kesin bir değere sahip bir değişken olmalıdır ve yöntemin yürütülmesi sırasında
başvuru parametresi, bağımsız değişken değişkeniyle aynı depolama konumunu temsil eder. Bir başvuru
parametresi ref değiştiricisiyle birlikte bildirilmiştir. Aşağıdaki örnek ref parametrelerinin kullanımını gösterir.
using System;
class RefExample
{
static void Swap(ref int x, ref int y)
{
int temp = x;
x = y;
y = temp;
}
public static void SwapExample()
{
int i = 1, j = 2;
Swap(ref i, ref j);
Console.WriteLine($"{i} {j}"); // Outputs "2 1"
}
}

Bir output parametresi , bağımsız değişkenleri başvuruya göre geçirmek için kullanılır. Bir başvuru parametresine
benzer, ancak çağıran tarafından belirtilen bağımsız değişkene açıkça bir değer atamanız gerekmez. Bir çıkış
parametresi out değiştiricisiyle birlikte bildirilmiştir. Aşağıdaki örnek, 7 ' de C# tanıtılan sözdizimi kullanılarak
out parametrelerinin kullanımını gösterir.

using System;
class OutExample
{
static void Divide(int x, int y, out int result, out int remainder)
{
result = x / y;
remainder = x % y;
}
public static void OutUsage()
{
Divide(10, 3, out int res, out int rem);
Console.WriteLine("{0} {1}", res, rem); // Outputs "3 1"
}
}
}

Bir parametre dizisi , bir metoda değişken sayıda bağımsız değişken geçirilmesine izin verir. Bir parametre dizisi
params değiştiricisiyle birlikte bildirilmiştir. Bir yöntemin yalnızca son parametresi bir parametre dizisi olabilir ve
bir parametre dizisinin türü tek boyutlu bir dizi türü olmalıdır. System.Console sınıfının Write ve WriteLine
yöntemleri, parametre dizisi kullanımının iyi örnekleridir. Bunlar aşağıdaki gibi bildirilmiştir.

public class Console


{
public static void Write(string fmt, params object[] args) { }
public static void WriteLine(string fmt, params object[] args) { }
// ...
}

Bir parametre dizisi kullanan bir yöntem içinde, parametre dizisi tam olarak bir dizi türünün normal parametresine
benzer şekilde davranır. Ancak, bir parametre dizisi olan bir yöntem çağrısında, parametre dizisi türünün tek bir
bağımsız değişkenini veya parametre dizisinin öğe türünün herhangi bir sayıda bağımsız değişkenini geçirmek
mümkündür. İkinci durumda, bir dizi örneği otomatik olarak oluşturulur ve verilen bağımsız değişkenlerle
başlatılır. Bu örnek

Console.WriteLine("x={0} y={1} z={2}", x, y, z);


, aşağıdaki yazma ile eşdeğerdir.

string s = "x={0} y={1} z={2}";


object[] args = new object[3];
args[0] = x;
args[1] = y;
args[2] = z;
Console.WriteLine(s, args);

Yöntem gövdesi ve yerel değişkenler


Yöntemin gövdesi, yöntemi çağrıldığında yürütülecek deyimleri belirtir.
Yöntem gövdesi, yöntemi çağrısına özgü değişkenleri bildirebilir. Bu tür değişkenlere yerel değişkenlerdenir. Yerel
bir değişken bildirimi bir tür adı, değişken adı ve muhtemelen bir başlangıç değeri belirtir. Aşağıdaki örnek,
başlangıç değeri sıfır olan i yerel bir değişken ve ilk değeri olmayan j bir yerel değişken bildirir.

using System;
class Squares
{
public static void WriteSquares()
{
int i = 0;
int j;
while (i < 10)
{
j = i * i;
Console.WriteLine($"{i} x {i} = {j}");
i = i + 1;
}
}
}

C#değeri alınabilmesi için önce bir yerel değişkenin kesinlikle atanmasını gerektirir. Örneğin, önceki i bildirimi
bir başlangıç değeri içermiyorsa, i , programda bu noktalarda kesinlikle atanamadığı için, derleyici i sonraki
kullanımları için bir hata raporlayabilir.
Bir yöntem, return deyimlerini kullanarak çağıranına denetim döndürebilir. void döndüren bir yöntemde
return deyimler bir ifade belirtemez. Void olmayan return deyimlerini döndüren bir yöntemde, dönüş değerini
hesaplayan bir ifade içermelidir.
Statik ve örnek yöntemleri
Statik değiştirici ile belirtilen bir yöntem statik bir yöntemdir. Statik bir yöntem belirli bir örnek üzerinde çalışmaz
ve yalnızca statik üyelere doğrudan erişebilir.
Statik değiştirici olmadan belirtilen bir yöntem bir örnek yöntemidir. Örnek yöntemi, belirli bir örnek üzerinde
çalışır ve hem statik hem de örnek üyelerine erişebilir. Örnek yönteminin çağrıldığı örnek, this olarak açıkça
erişilebilir. Statik bir yöntemde this başvurmak hatadır.
Aşağıdaki Entity sınıfı hem statik hem de örnek üyelere sahiptir.
class Entity
{
static int nextSerialNo;
int serialNo;
public Entity()
{
serialNo = nextSerialNo++;
}
public int GetSerialNo()
{
return serialNo;
}
public static int GetNextSerialNo()
{
return nextSerialNo;
}
public static void SetNextSerialNo(int value)
{
nextSerialNo = value;
}
}

Her bir Entity örneği bir seri numarası içerir (ve burada görünmeyen bazı diğer bilgileri kabul etmez). Entity
Oluşturucusu (bir örnek yöntemi gibi) yeni örneği bir sonraki kullanılabilir seri numarası ile başlatır. Oluşturucu
bir örnek üyesi olduğundan, hem serialNo örnek alanına hem de nextSerialNo statik alanına erişim izni verilir.
GetNextSerialNo ve SetNextSerialNo statik yöntemleri nextSerialNo statik alana erişebilir, ancak serialNo örnek
alanına doğrudan erişmesi için bir hata olabilir.
Aşağıdaki örnek, Entity sınıfının kullanımını gösterir.

using System;
class EntityExample
{
public static void Usage()
{
Entity.SetNextSerialNo(1000);
Entity e1 = new Entity();
Entity e2 = new Entity();
Console.WriteLine(e1.GetSerialNo()); // Outputs "1000"
Console.WriteLine(e2.GetSerialNo()); // Outputs "1001"
Console.WriteLine(Entity.GetNextSerialNo()); // Outputs "1002"
}
}

Sınıf üzerinde GetSerialNo örnek yöntemi çağrıldığında, SetNextSerialNo ve GetNextSerialNo statik


yöntemlerinin sınıfında çağırılacağını unutmayın.
Sanal, geçersiz kılma ve soyut yöntemler
Bir örnek yöntemi bildirimi virtual değiştirici içerdiğinde, yöntem sanal bir yöntemolarak kabul edilir. Bir sanal
değiştirici yoksa, yöntem sanal olmayan bir yöntemolarak kabul edilir.
Bir sanal yöntem çağrıldığında, çağrının gerçekleştiği örneğin çalışma zamanı türü , çağrılacak gerçek Yöntem
uygulamasını belirler. Sanal olmayan bir yöntem çağrısında, örneğin derleme zamanı türü belirleme faktörü olur.
Bir sanal yöntem, türetilmiş bir sınıfta geçersiz kılınabilir . Bir örnek yöntemi bildirimi bir geçersiz kılma
değiştiricisi içerdiğinde, yöntemi aynı imzaya sahip devralınmış bir sanal yöntemi geçersiz kılar. Sanal bir yöntem
bildiriminde yeni bir yöntem tanıtıldığı halde, bir geçersiz kılma yöntemi bildirimi, bu yöntemin yeni bir
uygulamasını sağlayarak, var olan bir devralınmış sanal yöntemi uzmanlık eder.
Soyut bir yöntem , uygulama içermeyen bir sanal yöntemdir. Soyut bir yöntem soyut değiştiriciyle birlikte
bildirilmiştir ve yalnızca soyut olarak da tanımlanmış bir sınıfta izin verilir. Soyut olmayan her türetilmiş sınıfta bir
soyut yöntem geçersiz kılınmalıdır.
Aşağıdaki örnek, bir soyut sınıfı, bir ifade ağaç düğümünü temsil eden Expression , üç türetilmiş sınıf, Constant ,
VariableReference ve Operation sabitler, değişken başvuruları ve aritmetik işlemler için ifade ağacı düğümleri
uygulayan bildirir. (Bu şuna benzerdir, ancak ifade ağacı türleriyle karıştırılmamalıdır).
using System;
using System.Collections.Generic;
public abstract class Expression
{
public abstract double Evaluate(Dictionary<string,object> vars);
}
public class Constant: Expression
{
double value;
public Constant(double value)
{
this.value = value;
}
public override double Evaluate(Dictionary<string,object> vars)
{
return value;
}
}
public class VariableReference: Expression
{
string name;
public VariableReference(string name)
{
this.name = name;
}
public override double Evaluate(Dictionary<string,object> vars)
{
object value = vars[name];
if (value == null)
{
throw new Exception("Unknown variable: " + name);
}
return Convert.ToDouble(value);
}
}
public class Operation: Expression
{
Expression left;
char op;
Expression right;
public Operation(Expression left, char op, Expression right)
{
this.left = left;
this.op = op;
this.right = right;
}
public override double Evaluate(Dictionary<string,object> vars)
{
double x = left.Evaluate(vars);
double y = right.Evaluate(vars);
switch (op) {
case '+': return x + y;
case '-': return x - y;
case '*': return x * y;
case '/': return x / y;
}
throw new Exception("Unknown operator");
}
}

Önceki dört sınıf aritmetik ifadeleri modellemek için kullanılabilir. Örneğin, bu sınıfların örneklerini kullanarak
ifade x + 3 aşağıdaki gibi gösterilebilir.
Expression e = new Operation(
new VariableReference("x"),
'+',
new Constant(3));

Bir Expression örneğinin Evaluate Yöntemi verilen ifadeyi değerlendirmek ve bir double değeri üretmek için
çağrılır. Yöntemi, değişken adlarını (girdilerin anahtarları olarak) ve değerlerini (girdilerin değerleri olarak) içeren
Dictionary bir bağımsız değişken alır. Evaluate soyut bir yöntem olduğundan, Expression türetilmiş soyut
olmayan sınıfların Evaluate geçersiz kılması gerekir.
Constant``Evaluate uygulanması yalnızca depolanan sabiti döndürür. VariableReference uygulama, sözlükte
değişken adını arar ve elde edilen değeri döndürür. Operation uygulamasının ilk önce sol ve sağ işlenenleri
değerlendirir ( Evaluate yöntemlerini yinelemeli olarak çağırarak) ve ardından verilen aritmetik işlemi
gerçekleştirir.
Aşağıdaki program, x ve y farklı değerleri için ifade x * (y + 2) değerlendirmek üzere Expression sınıflarını
kullanır.

using System;
using System.Collections.Generic;
class InheritanceExample
{
public static void ExampleUsage()
{
Expression e = new Operation(
new VariableReference("x"),
'*',
new Operation(
new VariableReference("y"),
'+',
new Constant(2)
)
);
Dictionary<string,object> vars = new Dictionary<string, object>();
vars["x"] = 3;
vars["y"] = 5;
Console.WriteLine(e.Evaluate(vars)); // Outputs "21"
vars["x"] = 1.5;
vars["y"] = 9;
Console.WriteLine(e.Evaluate(vars)); // Outputs "16.5"
}
}

Yöntem aşırı yüklemesi


Yöntem aşırı yüklemesi , aynı sınıftaki birden çok metodun benzersiz imzalara sahip oldukları sürece aynı ada
sahip olmasını sağlar. Aşırı yüklenmiş bir yöntemin çağrılması derlenirken, derleyici çağrılacak özel yöntemi
belirlemekte aşırı yükleme çözümü kullanır. Aşırı yükleme çözümlemesi, bağımsız değişkenlerle en iyi eşleşen bir
yöntemi bulur veya tek bir en iyi eşleşme bulunamazsa hata bildiriyor. Aşağıdaki örnekte, etkin olan aşırı yükleme
çözümü gösterilmektedir. UsageExample yöntemi içindeki her çağrının yorumu, hangi yöntemin gerçekten
çağrılacağını gösterir.
using System;
class OverloadingExample
{
static void F()
{
Console.WriteLine("F()");
}
static void F(object x)
{
Console.WriteLine("F(object)");
}
static void F(int x)
{
Console.WriteLine("F(int)");
}
static void F(double x)
{
Console.WriteLine("F(double)");
}
static void F<T>(T x)
{
Console.WriteLine("F<T>(T)");
}
static void F(double x, double y)
{
Console.WriteLine("F(double, double)");
}
public static void UsageExample()
{
F(); // Invokes F()
F(1); // Invokes F(int)
F(1.0); // Invokes F(double)
F("abc"); // Invokes F<string>(string)
F((double)1); // Invokes F(double)
F((object)1); // Invokes F(object)
F<int>(1); // Invokes F<int>(int)
F(1, 1); // Invokes F(double, double)
}
}

Örnekte gösterildiği gibi belirli bir yöntem her zaman bağımsız değişkenleri tam parametre türlerine açıkça
atayarak ve/veya açıkça tür bağımsız değişkenleri sunarak seçilebilir.

Diğer işlev üyeleri


Yürütülebilir kod içeren Üyeler topluca bir sınıfın işlev üyeleri olarak bilinir. Yukarıdaki bölümde, işlev üyelerinin
birincil türü olan yöntemler açıklanmıştır. Bu bölümde, tarafından C#desteklenen diğer işlev üyesi türleri
açıklanmaktadır: oluşturucular, özellikler, Dizin oluşturucular, olaylar, işleçler ve sonlandırıcılar.
Aşağıda, growable bir nesne listesi uygulayan MyList<T> adlı bir genel sınıf gösterilmektedir. Sınıfı, en yaygın işlev
üyesi türlerine birkaç örnek içerir.

NOTE
Bu örnekte, .NET Standard System.Collections.Generic.List<T>ile aynı olmayan bir MyList sınıfı oluşturulur. Bu, bu tur için
gereken kavramları gösterir, ancak bu sınıfın yerini almaz.

public class MyList<T>


{
// Constant
const int defaultCapacity = 4;
// Fields
T[] items;
int count;

// Constructor
public MyList(int capacity = defaultCapacity)
{
items = new T[capacity];
}

// Properties
public int Count => count;

public int Capacity


{
get { return items.Length; }
set
{
if (value < count) value = count;
if (value != items.Length)
{
T[] newItems = new T[value];
Array.Copy(items, 0, newItems, 0, count);
items = newItems;
}
}
}

// Indexer
public T this[int index]
{
get
{
return items[index];
}
set
{
items[index] = value;
OnChanged();
}
}

// Methods
public void Add(T item)
{
if (count == Capacity) Capacity = count * 2;
items[count] = item;
count++;
OnChanged();
}
protected virtual void OnChanged() =>
Changed?.Invoke(this, EventArgs.Empty);

public override bool Equals(object other) =>


Equals(this, other as MyList<T>);

static bool Equals(MyList<T> a, MyList<T> b)


{
if (Object.ReferenceEquals(a, null)) return Object.ReferenceEquals(b, null);
if (Object.ReferenceEquals(b, null) || a.count != b.count)
return false;
for (int i = 0; i < a.count; i++)
{
if (!object.Equals(a.items[i], b.items[i]))
{
return false;
}
}
return true;
return true;
}

// Event
public event EventHandler Changed;

// Operators
public static bool operator ==(MyList<T> a, MyList<T> b) =>
Equals(a, b);

public static bool operator !=(MyList<T> a, MyList<T> b) =>


!Equals(a, b);
}

Oluşturucular
C#hem örnek hem de statik oluşturucuları destekler. Örnek Oluşturucu , bir sınıfın örneğini başlatmak için
gereken eylemleri uygulayan bir üyedir. Statik Oluşturucu , ilk yüklendiği zaman bir sınıfın kendisini başlatmak için
gereken eylemleri uygulayan bir üyesidir.
Bir Oluşturucu, dönüş türü olmayan bir yöntem ve kapsayan sınıfla aynı adı ile birlikte bildirilmiştir. Bir Oluşturucu
bildirimi statik değiştirici içeriyorsa, statik bir Oluşturucu bildirir. Aksi takdirde, bir örnek Oluşturucu bildirir.
Örnek oluşturucular aşırı yüklenebilir ve isteğe bağlı parametrelere sahip olabilir. Örneğin MyList<T> sınıfı, tek bir
isteğe bağlı int parametresine sahip bir örnek Oluşturucu bildirir. Örnek oluşturucular new işleci kullanılarak
çağrılır. Aşağıdaki deyimler, ve isteğe bağlı bağımsız değişken olmadan MyList sınıfının yapıcısını kullanarak iki
MyList<string> örneği ayırır.

MyList<string> list1 = new MyList<string>();


MyList<string> list2 = new MyList<string>(10);

Diğer üyelerin aksine, örnek oluşturucular devralınmaz ve bir sınıfın sınıfta tanımlananlardan farklı örnek
oluşturucuları yoktur. Bir sınıf için örnek Oluşturucu sağlanmazsa, parametresi olmayan boş bir değer otomatik
olarak sağlanır.
Özellikler
Özellikler , alanlar için doğal bir uzantıdır. Her ikisi de ilişkili türlerin bulunduğu isimlerdir ve alanlara ve özelliklere
erişim için sözdizimi aynıdır. Ancak, alanların aksine, Özellikler depolama konumlarını göstermiyor. Bunun yerine,
özellikler, değerleri okunmak veya yazıldığında yürütülecek deyimleri belirten erişimcileri vardır.
Bir özellik, bir alan gibi, bildirim bir get erişimcisi ve/veya sınırlayıcılar arasında yazılmış bir set erişimcisi ve/veya
virgülle sona ermek yerine } { Hem get erişimcisine hem de bir set erişimcisine sahip olan bir özellik okuma -
yazma özelliğidir, yalnızca bir get erişimcisine sahip olan bir özellik salt okunurdurve yalnızca bir set erişimcisi
olan bir özellik yalnızca bir salt yazılır özelliktir.
Get erişimcisi, özellik türünün dönüş değeri olan parametresiz bir yönteme karşılık gelir. Atama hedefi haricinde,
bir ifadede bir özelliğe başvurulduğunda, özelliğin değerini hesaplamak için özelliğin get erişimcisi çağrılır.
Bir set erişimcisi, value adlı tek parametreli ve dönüş türü olmayan bir yönteme karşılık gelir. Bir atamaya bir
atama hedefi olarak veya + + veya--, işleneni olarak başvurulduğunda, yeni değer sağlayan bir bağımsız
değişkenle çağrılır.
MyList<T> sınıfı, sırasıyla salt okuma ve okuma-yazma olan iki özellik Count ve Capacity bildirir. Aşağıda bu
özelliklerin kullanılmasına bir örnek verilmiştir:
MyList<string> names = new MyList<string>();
names.Capacity = 100; // Invokes set accessor
int i = names.Count; // Invokes get accessor
int j = names.Capacity; // Invokes get accessor

Alanlar ve yöntemlere benzer şekilde hem C# örnek özelliklerini hem de statik özellikleri destekler. Statik özellikler
statik değiştirici ile tanımlanır ve örnek özellikleri bu olmadan tanımlanır.
Bir özelliğin erişimcisi sanal olabilir. Bir özellik bildirimi virtual , abstract veya override değiştiricisini
içerdiğinde, özelliğin erişimcilerle geçerli olur.
Dizin Oluşturucular
Dizin Oluşturucu , nesnelerin diziyle aynı şekilde dizinlenmesini sağlayan bir üyedir. Bir Dizin Oluşturucu, üye
adının this ve ardından sınırlayıcı [ ve ] arasında yazılmış bir parametre listesi olması dışında bir özellik gibi
bildirilmiştir. Parametreler, dizin oluşturucunun erişimcisinde kullanılabilir. Özelliklere benzer şekilde, Dizin
oluşturucular okunabilir-yazılır, salt okunurdur ve salt yazılır olabilir ve bir dizin oluşturucunun erişimcisi sanal
olabilir.
MyList<T> sınıfı, bir int parametresi alan tek bir okuma-yazma Dizin oluşturucuyu bildirir. Dizin Oluşturucu,
MyList<T> örneklerinin int değerlerle dizinini oluşturmanızı mümkün kılar. Örneğin:

MyList<string> names = new MyList<string>();


names.Add("Liz");
names.Add("Martha");
names.Add("Beth");
for (int i = 0; i < names.Count; i++)
{
string s = names[i];
names[i] = s.ToUpper();
}

Dizin oluşturucular aşırı yüklenebilir, yani parametrelerinin sayısı veya türleri farklı olduğu sürece bir sınıfın birden
çok dizin kümesini bildirebileceği anlamına gelir.
Olaylar
Bir olay , bir sınıf veya nesnenin bildirimler sağlamasını sağlayan bir üyedir. Bir olay, bildirim bir event anahtar
sözcüğü içermesi ve türün bir temsilci türü olması dışında, bir alan gibi bildirilmiştir.
Olay üyesini bildiren bir sınıf içinde, olay bir temsilci türünün alanı gibi davranır (olay soyut değildir ve erişimcileri
bildirmez). Bu alan, olaya eklenmiş olan olay işleyicilerini temsil eden bir temsilciye bir başvuru depolar. Hiçbir
olay işleyicisi yoksa, alan null .
MyList<T> sınıfı, Changed adlı tek bir olay üyesini bildirir ve bu, listeye yeni bir öğe eklendiğini gösterir.
Değiştirilen olay OnChanged sanal yöntemi tarafından tetiklenir ve bu, önce olayın null olup olmadığını denetler
(hiçbir işleyici yok anlamına gelir). Bir olayı oluşturma kavramı, olayın gösterdiği temsilciyi çağırmak için tam
olarak eşdeğerdir. bu nedenle, olayları yükseltmek için özel dil yapıları yoktur.
İstemciler olay işleyicileriaracılığıyla olaylara tepki verir. Olay işleyicileri += işleci kullanılarak iliştirilir ve -= işleci
kullanılarak kaldırılır. Aşağıdaki örnek, bir MyList<string>``Changed olayına bir olay işleyicisi ekler.
class EventExample
{
static int changeCount;
static void ListChanged(object sender, EventArgs e)
{
changeCount++;
}
public static void Usage()
{
MyList<string> names = new MyList<string>();
names.Changed += new EventHandler(ListChanged);
names.Add("Liz");
names.Add("Martha");
names.Add("Beth");
Console.WriteLine(changeCount); // Outputs "3"
}
}

Bir olayın temeldeki depolamanın denetiminin istendiği Gelişmiş senaryolarda, bir olay bildirimi açıkça bir
özelliğin set erişimcisine benzer olan add ve remove erişimcileri sağlayabilir.
İşleçler
İşleci , bir sınıfın örneklerine belirli bir ifade işlecini uygulamanın anlamını tanımlayan bir üyesidir. Üç tür işleç
tanımlanabilir: Birli İşleçler, ikili işleçler ve dönüştürme işleçleri. Tüm işleçler public ve static olarak
bildirilmelidir.
MyList<T> sınıfı iki işleç bildirir operator == ve operator != ve bu işleçleri MyList örneklerine uygulayan
deyimlere yeni anlam verir. Özel olarak, işleçler iki MyList<T> örneğinin eşitliğini tanımlar ve bu nesnelerin her
birini eşittir yöntemlerini kullanarak karşılaştırır. Aşağıdaki örnek, iki MyList<int> örneğini karşılaştırmak için ==
işlecini kullanır.

MyList<int> a = new MyList<int>();


a.Add(1);
a.Add(2);
MyList<int> b = new MyList<int>();
b.Add(1);
b.Add(2);
Console.WriteLine(a == b); // Outputs "True"
b.Add(3);
Console.WriteLine(a == b); // Outputs "False"

İki liste aynı sırada aynı değerlerle aynı sayıda nesne içerdiğinden, ilk Console.WriteLine True çıkışı oluşur.
operator == tanımlanmayan MyList<T> , a ve b farklı MyList<int> örneklerine başvurduğundan ilk
Console.WriteLine çıkış False sahip olur.

Sonlandırıcılar
Sonlandırıcı , bir sınıfın örneğini tamamlamak için gereken eylemleri uygulayan bir üyesidir. Sonlandırıcılar
parametrelere sahip olamaz, erişilebilirlik değiştiricilerine sahip olamaz ve açıkça çağrılamaz. Örnek için
Sonlandırıcı çöp toplama sırasında otomatik olarak çağrılır.
Çöp toplayıcısına, nesnelerin toplanması ve Sonlandırıcıların ne zaman toplanacağına karar verirken geniş bir
enlem vardır. Özellikle, Sonlandırıcı etkinleştirmeleri zamanlaması belirleyici değildir ve herhangi bir iş
parçacığında sonlandırıcılar çalıştırılabilir. Bu ve diğer nedenlerden dolayı sınıfların yalnızca başka hiçbir çözüm
uygulanabilir olmadığında sonlandırıcılar uygulaması gerekir.
using ifade, nesne yok etme için daha iyi bir yaklaşım sağlar.
ÖN CEKI İL E R I
Yapılar
23.10.2019 • 4 minutes to read • Edit Online

Sınıflar gibi yapılar veri yapıları, veri üyeleri ve işlev üyeleri içerebilir, ancak farklı sınıflar, yapılar değer türleri ve
yığın ayırma gerektirmez. Bir sınıf türünün bir değişkeni dinamik olarak ayrılan bir nesneye başvuru depoladığı bir
yapı türünün değişkenini doğrudan, struct'ın verileri depolar. Yapı türleri, kullanıcı tarafından belirtilen devralma
desteklemez ve tüm yapı türleri örtülü olarak tür devralmasına ValueType, devralınan, örtük olarak buna karşılık
object .

Yapılar değer semantiklere sahip küçük veri yapıları için özellikle yararlıdır. Karmaşık sayılar, koordinat sisteminde
noktaları veya anahtar-değer çiftlerinin bir sözlükteki tüm iyi yapılar örnekleridir. Küçük veri yapıları için sınıflar, bir
uygulama bellek ayırmaları sayısında büyük bir fark yapabilirsiniz yerine yapılar kullanımını gerçekleştirir.
Örneğin, aşağıdaki program oluşturur ve 100 noktaları dizisini başlatır. İle Point sınıfı olarak uygulanır, 101 ayrı
nesneler örneği oluşturulur; bir dizi ve her biri 100 öğeleri için.

public class PointExample


{
public static void Main()
{
Point[] points = new Point[100];
for (int i = 0; i < 100; i++)
points[i] = new Point(i, i);
}
}

Bir yapının nokta yapmak için kullanılan bir alternatiftir.

struct Point
{
public int x, y;
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
}

Şimdi, yalnızca bir nesne örneği — bir dizi — ve Point depolanan satır içi dizi örnekleridir.
Yapı Oluşturucuları ile çağrılır new işleci, bir sınıf oluşturucusuna benzer. Ancak, dinamik olarak yönetilen
yığındaki bir nesne ayırma ve buna bir başvuru döndürmek yerine, bir yapı Oluşturucu yalnızca yapı değerini
kendisi (genellikle geçici bir konuma yığın üzerinde) döndürür ve bu değer daha sonra gerektiğinde kopyalanır.
Sınıfları ile bu iki değişken aynı nesneye başvurmak mümkün ve dolayısıyla işlemler diğer değişkenin başvurduğu
nesneyi etkileyebilir bir değişken üzerinde mümkün olur. Yapılar, her değişkenleri kendi veri kopyası vardır ve
yapılan işlemlerin diğerini etkilemesi olanaklı birinde değil. Örneğin, aşağıdaki kod parçası tarafından üretilen çıkış
noktası bir sınıf veya yapı olduğuna bağlıdır.

Point a = new Point(10, 10);


Point b = a;
a.x = 20;
Console.WriteLine(b.x);
Varsa Point bir sınıf çıkış 20 çünkü a ve b aynı nesneye başvuru. Varsa Point bir yapı çıktı 10 çünkü atamasını
a için b değeri bir kopyasını oluşturur ve bu kopyayı sonraki atamaya tarafından etkilenmez a.x .

Önceki örnekte iki yapılar sınırlamaları vurgular. İlk olarak, bir yapının tamamını kopyalama atama ve değerin
parametre geçirme başvuru türleri ile yapılar ile daha pahalı olabilir. Bu nedenle, bir nesne başvurusu kopyalama
daha genellikle daha az verimlidir. İkinci dışında in , ref , ve out parametreleri, bu durumlarda, çeşitli
kullanımları kullanıma kuralları yapı birimleri için başvuru oluşturmak mümkün değildir.

ÖN CEKI İL E R I
Diziler
23.10.2019 • 4 minutes to read • Edit Online

Bir dizi hesaplanan dizinlerini erişilen değişken bir sayı içeren bir veri yapısıdır. Bir dizi içindeki değişkenler olarak
da bilinir öğeleri dizinin tümü aynı türde ve bu tür çağrılır öğe türü dizi.
Dizi türleri, başvuru türleridir ve bir dizi değişkeni bildirimi yalnızca kenara alanı başvuru bir dizi örneği için
ayarlar. Gerçek bir dizi örnekleri, new işleci kullanılarak çalışma zamanında dinamik olarak oluşturulur. Yeni işlemi
belirtir uzunluğu sonra Örneğin ömrü boyunca sabittir yeni dizi örneği. Dizinleri öğelerinden oluşan bir dizi
aralığından 0 için Length - 1 . new İşleci, örneğin, sıfır olan tüm sayısal türler için varsayılan değerlerine bir
dizinin öğeleri otomatik olarak başlatır ve null tüm başvuru türleri için.
Aşağıdaki örnek, bir dizi oluşturur. int öğeleri, dizi başlatır ve dizinin içeriği yazdırır.

using System;
class ArrayExample
{
static void Main()
{
int[] a = new int[10];
for (int i = 0; i < a.Length; i++)
{
a[i] = i * i;
}
for (int i = 0; i < a.Length; i++)
{
Console.WriteLine($"a[{i}] = {a[i]}");
}
}
}

Bu örneği oluşturur ve üzerinde çalıştığı bir tek boyutlu dizi. C# ' yı da destekler çok boyutlu diziler. Olarak da
bilinen bir dizinin boyut sayısını yazın derece dizi türü köşeli ayraç yazılan virgül sayısı artı bir dizi türünde olduğu.
Aşağıdaki örnek bir tek boyutlu, iki boyutlu bir ve üç boyutlu bir dizi sırasıyla ayırır.

int[] a1 = new int[10];


int[,] a2 = new int[10, 5];
int[,,] a3 = new int[10, 5, 2];

a1 Dizi 10 öğe içeriyor a2 dizi içeriyor 50 (10 × 5) öğeleri ve a3 dizi içeriyor (10 × 5 × 2) 100 öğeleri. Bir
dizinin öğe türü bir dizi türü de dahil olmak üzere herhangi bir tür olabilir. Bir dizi türünde öğelere sahip bir dizi
adlandırılan bir düzensiz dizi öğe dizisi uzunluklarının tümünü değil aynı olmak zorunda olduğu. Aşağıdaki
örnekte dizi ayırır int :

int[][] a = new int[3][];


a[0] = new int[10];
a[1] = new int[5];
a[2] = new int[20];

İlk satır, üç öğeyle her türü bir dizi oluşturur int[] ve her bir başlangıç değeri ile null . Sonraki satırların
başvurular değişen uzunlukları örneklerini tek bir dizi üç öğeleri ardından başlatın.
New işleci Başlangıç değerlerini kullanarak belirtilen dizi öğelerinin izin veren bir dizi Başlatıcısı, sınırlayıcılar
arasında yazılan ifadeler listesi olduğu { ve } . Aşağıdaki örnek ayırır ve başlatan bir int[] üç öğelerle.

int[] a = new int[] {1, 2, 3};

Dizinin uzunluğu arasında ifadelerin sayısından algılanır Not {ve}. Yerel değişken ve alan bildirimleri kısalttık daha
fazla sağlayacak şekilde dizi türü açıklandı gerekmez.

int[] a = {1, 2, 3};

Önceki örneklerin her ikisi de aşağıdakine eşdeğerdir:

int[] t = new int[3];


t[0] = 1;
t[1] = 2;
t[2] = 3;
int[] a = t;

ÖN CEKI İL E R I
Arabirimler
23.10.2019 • 3 minutes to read • Edit Online

Bir arabirimi sınıfları ve yapıları tarafından uygulanan bir sözleşmeyi tanımlar. Bir arabirim yöntemleri, özellikleri,
olayları ve dizin oluşturucular içerebilir. Bir arabirim tanımlar üyelerinin uygulamalarını sağlamaz; yalnızca bir sınıf
ya da arabirimi uygulayan yapının tarafından sağlanması gereken üyeleri belirtir.
, Arabirimleri görevlendirmek birden çok devralma. Aşağıdaki örnekte, arabirim IComboBox hem de devralan
ITextBox ve IListBox .

interface IControl
{
void Paint();
}
interface ITextBox: IControl
{
void SetText(string text);
}
interface IListBox: IControl
{
void SetItems(string[] items);
}
interface IComboBox: ITextBox, IListBox {}

Sınıflar ve yapı birimleri birden fazla arabirim uygulayabilir. Aşağıdaki örnekte, sınıf EditBox hem IControl ve
IDataBound .

interface IDataBound
{
void Bind(Binder b);
}
public class EditBox: IControl, IDataBound
{
public void Paint() { }
public void Bind(Binder b) { }
}

Bir sınıf veya yapı, belirli bir arabirim uygular, bu sınıfın veya yapının örneği, bir arabirim türüne örtük olarak
dönüştürülebilir. Örneğin:

EditBox editBox = new EditBox();


IControl control = editBox;
IDataBound dataBound = editBox;

Dinamik tür atamaları, burada bir örnek statik olarak belirli bir arabirim uygulamak için bilinmiyor durumlarda
kullanılabilir. Örneğin, bir nesnenin elde etmek için dinamik tür atamaları aşağıdaki deyimleri kullanın IControl ve
IDataBound arabirimi uygulamaları. Nesnenin çalışma zamanı gerçek türü olduğundan EditBox , yayınları başarılı.

object obj = new EditBox();


IControl control = (IControl)obj;
IDataBound dataBound = (IDataBound)obj;

Önceki EditBox sınıfı Paint yönteminden IControl arabirimi ve Bind yönteminden IDataBound arabirimi
Genel üyeler kullanılarak uygulanır. C#aynı zamanda açık destekler arabirim üyesi uygulamaları, sınıfın veya
yapının üyeleri genel yapmaktan kaçınmak için etkinleştiriliyor. Açık arabirim üyesi uygulaması, tam bir arabirim
üye adını kullanarak yazılır. Örneğin, EditBox sınıf uygulama IControl.Paint ve IDataBound.Bind yöntemlerini
kullanarak açık arabirim üyesi uygulamaları gibi.

public class EditBox: IControl, IDataBound


{
void IControl.Paint() { }
void IDataBound.Bind(Binder b) { }
}

Açık arabirim üyeleri yalnızca arabirim türü erişilebilir. Örneğin, uygulanması IControl.Paint tarafından önceki
EditBox sınıfı yalnızca ilk dönüştürerek çağrılabilir sağlanan EditBox başvurusu IControl arabirim türü.

EditBox editBox = new EditBox();


editBox.Paint(); // Error, no such method
IControl control = editBox;
control.Paint(); // Ok

ÖN CEKI İL E R I
2 minutes to read
Temsilciler
23.10.2019 • 2 minutes to read • Edit Online

A temsilci türü belirli bir parametre olan yöntemlere başvuruları temsil listesi ve dönüş türü. Temsilciler,
yöntemleri değişkenine atanır ve parametre olarak geçirilen varlıklar olarak değerlendirmek mümkün kılar. Diğer
dillerde bulunan işlev işaretçileri kavramı temsilcileri benzerdir ancak işlev işaretçileri, nesne yönelimli ve tür
kullanımı uyumlu temsilciler.
Aşağıdaki örnek bildirir ve adlandırılmış bir temsilci türü kullanır Function .

using System;
delegate double Function(double x);
class Multiplier
{
double factor;
public Multiplier(double factor)
{
this.factor = factor;
}
public double Multiply(double x)
{
return x * factor;
}
}
class DelegateExample
{
static double Square(double x)
{
return x * x;
}
static double[] Apply(double[] a, Function f)
{
double[] result = new double[a.Length];
for (int i = 0; i < a.Length; i++) result[i] = f(a[i]);
return result;
}
static void Main()
{
double[] a = {0.0, 0.5, 1.0};
double[] squares = Apply(a, Square);
double[] sines = Apply(a, Math.Sin);
Multiplier m = new Multiplier(2.0);
double[] doubles = Apply(a, m.Multiply);
}
}

Örneği Function temsilci türü, alan herhangi bir yöntemi başvurabilir bir double bağımsız değişkeni ve döndürür
bir double değeri. Apply Yöntemi öğelerine verilen işlevi uygular bir double[] , döndüren bir double[] sonuçları.
İçinde Main yöntemi Apply üç farklı işlevlere uygulamak için kullanılan bir double[] .
Bir temsilci bir statik yöntem başvurabilir (gibi Square veya Math.Sin önceki örnekte) veya bir örnek yöntemi
(gibi m.Multiply önceki örnekte). Bir örnek yöntemi başvuran bir temsilci Ayrıca belirli bir nesnenin başvuruda
bulunduğundan ve temsilci örnek yöntemi çağrıldığında, bu nesne haline gelir this çağrısı.
Temsilciler da "anında oluşturulan satır içi yöntemler" anonim işlevler kullanılarak oluşturulabilir. Anonim İşlevler,
yerel değişkenler çevreleyen yöntemlerden görebilirsiniz. Bu nedenle, yukarıdaki çarpan örneği daha kolay bir
çarpan sınıf kullanmadan yazılabilir:
double[] doubles = Apply(a, (double x) => x * 2.0);

Bir ilgi çekici ve kullanışlı bir temsilci, bilmiyorsanız veya yöntemin başvurduğu sınıfı hakkında dikkatli olun,
özelliğidir; önemli olan başvurulan yöntemi aynı parametre ve dönüş türü temsilciyle sahiptir.

ÖN CEKI İL E R I
Öznitelikler
23.10.2019 • 3 minutes to read • Edit Online

Bazı yönlerini davranışlarını denetleyen değiştiriciler, türleri, üyeleri ve diğer varlıkların bir C# programında
destekler. Örneğin, bir yöntemin erişilebilirliği kullanılarak denetlenir public , protected , internal , ve private
değiştiriciler. Bildirim temelli bilgileri kullanıcı tanımlı türde program varlıklara bağlı ve çalışma zamanında alınan
C# bu özellik genelleştirir. Programlar belirtmek bu ek tanımlayıcı bilgiler tanımlama ve kullanma öznitelikleri.
Aşağıdaki örnek bildirir bir HelpAttribute , ilişkili belgelere bağlantılar sağlamak için program varlıkları
yerleştirildiği özniteliği.

using System;

public class HelpAttribute: Attribute


{
string url;
string topic;
public HelpAttribute(string url)
{
this.url = url;
}

public string Url => url;

public string Topic {


get { return topic; }
set { topic = value; }
}
}

Tüm öznitelik sınıfları türetilmesi Attribute temel standart kitaplığı tarafından sağlanan sınıfı. Öznitelik, köşeli
ayraç içinde ilişkili bildirimi hemen önce tüm bağımsız değişkenleri yanı sıra bunların adı vererek uygulanabilir. Bir
özniteliğin adı biterse Attribute , öznitelik başvurulduğunda bu bölümü adı atlanmış olabilir. Örneğin,
HelpAttribute gibi kullanılabilir.

[Help("https://docs.microsoft.com/dotnet/csharp/tour-of-csharp/attributes")]
public class Widget
{
[Help("https://docs.microsoft.com/dotnet/csharp/tour-of-csharp/attributes",
Topic = "Display")]
public void Display(string text) {}
}

Bu örnekte bağlayan bir HelpAttribute için Widget sınıfı. Başka bir ekler HelpAttribute için Display sınıfında
yöntemi. Genel oluşturucular bir öznitelik sınıfı özniteliği için bir program varlığı eklendiğinde sağlanmalıdır
bilgileri denetler. Ek bilgi öznitelik sınıfının ortak okuma-yazma özelliklerine başvurarak sağlanabilir (başvuru gibi
Topic özelliği daha önce).

Öznitelikleri tarafından tanımlanan meta verileri okuyun ve yansıma kullanarak çalışma zamanında değiştirilebilir.
Bu tekniği kullanarak belirli bir özniteliği istendiğinde program kaynakta sağlanan bilgileri ile öznitelik sınıfı için
oluşturucu çağrılır ve sonuçta elde edilen öznitelik örneği döndürülür. Ek bilgi özellikleri aracılığıyla sağlandıysa,
öznitelik örneği döndürülmeden önce bu özellikleri için belirtilen değerlere ayarlanır.
Aşağıdaki kod örneği nasıl alındığını anlatan HelpAttribute ilişkili örnekleri Widget sınıf ve onun Display
yöntemi.

Type widgetType = typeof(Widget);

//Gets every HelpAttribute defined for the Widget type


object[] widgetClassAttributes = widgetType.GetCustomAttributes(typeof(HelpAttribute), false);

if (widgetClassAttributes.Length > 0)
{
HelpAttribute attr = (HelpAttribute)widgetClassAttributes[0];
Console.WriteLine($"Widget class help URL : {attr.Url} - Related topic : {attr.Topic}");
}

System.Reflection.MethodInfo displayMethod = widgetType.GetMethod(nameof(Widget.Display));

//Gets every HelpAttribute defined for the Widget.Display method


object[] displayMethodAttributes = displayMethod.GetCustomAttributes(typeof(HelpAttribute), false);

if (displayMethodAttributes.Length > 0)
{
HelpAttribute attr = (HelpAttribute)displayMethodAttributes[0];
Console.WriteLine($"Display method help URL : {attr.Url} - Related topic : {attr.Topic}");
}

Console.ReadLine();

ÖN CEKI
C# 8,0 sürümündeki yenilikler
27.11.2019 • 25 minutes to read • Edit Online

C#8,0 aşağıdaki özellikleri ve geliştirmeleri C# dile ekler:


Salt okunur Üyeler
Varsayılan arabirim yöntemleri
Desenler eşleşen geliştirmeler:
Anahtar ifadeleri
Özellik desenleri
Demet desenleri
Konumsal desenler
Bildirimleri kullanma
Statik yerel işlevler
Atılabilir ref yapıları
Boş değer atanabilir başvuru türleri
Zaman uyumsuz akışlar
Dizinler ve aralıklar
Null birleştirme ataması
Yönetilmeyen oluşturulmuş türler
İç içe ifadelerde stackalloc
Ara değerli tam dizelerin geliştirilmesi
C#8,0, .NET Core 3. x ve .NET Standard 2,1' de desteklenir. Daha fazla bilgi için bkz C# . dil sürümü oluşturma.
Bu makalenin geri kalanında bu özellikler kısaca açıklanmaktadır. Ayrıntılı makalelerin nerede kullanılabildiği, bu
öğreticiler ve genel bakışların bağlantıları sağlanmıştır. Ortamınızdaki bu özellikleri, dotnet try genel aracını
kullanarak inceleyebilirsiniz:
1. DotNet-TRY küresel aracını yükler.
2. DotNet/TRY -Samples deposunu kopyalayın.
3. TRY -Samples deposu için geçerli dizini csharp8 alt dizinine ayarlayın.
4. dotnet try 'i çalıştırın.

Salt okunur Üyeler


readonly değiştiricisini bir yapının üyelerine uygulayabilirsiniz. Üyenin durumu değiştirmediğini belirtir. readonly
değiştiricisinin struct bildirimine uygulanmasıyla daha ayrıntılı bir hale gelir. Aşağıdaki kesilebilir yapıyı göz
önünde bulundurun:

public struct Point


{
public double X { get; set; }
public double Y { get; set; }
public double Distance => Math.Sqrt(X * X + Y * Y);

public override string ToString() =>


$"({X}, {Y}) is {Distance} from the origin";
}
Çoğu yapı gibi ToString() yöntemi durumunu değiştirmez. ToString() bildirimine readonly değiştiricisini
ekleyerek bunu belirtebilirsiniz:

public readonly override string ToString() =>


$"({X}, {Y}) is {Distance} from the origin";

Önceki değişiklik bir derleyici uyarısı oluşturur, çünkü ToString , readonly işaretlenmemiş Distance özelliğine
erişir:

warning CS8656: Call to non-readonly member 'Point.Distance.get' from a 'readonly' member results in an
implicit copy of 'this'

Derleyici, savunma kopyası oluşturması gerektiğinde sizi uyarır. Distance özelliği durumu değiştirmez, bu nedenle
readonly değiştiricisini bildirime ekleyerek bu uyarıyı çözebilirsiniz:

public readonly double Distance => Math.Sqrt(X * X + Y * Y);

readonly değiştiricinin salt okunurdur özelliğinde gerekli olduğuna dikkat edin. Derleyici get erişimcilerinin
durumu değiştirmediğini varsaymaz; readonly açıkça bildirmeniz gerekir. Otomatik uygulanan özellikler bir özel
durumdur; derleyici otomatik uygulanan tüm alıcıları ReadOnly olarak değerlendirir, bu nedenle X ve Y
özelliklerine readonly değiştiricisini eklemeniz gerekmez.
Derleyici, readonly üyelerin durumu değiştirmiyor kuralını zorlar. readonly değiştiricisini kaldırmadığınız takdirde
aşağıdaki yöntem derlenmez:

public readonly void Translate(int xOffset, int yOffset)


{
X += xOffset;
Y += yOffset;
}

Bu özellik, tasarım amacınızı derleyicinin uygulamayı zorunlu kılabilir ve bu amaca göre iyileştirmeler
yapabilmesini sağlar. readonly dil başvurusu makalesindeki salt okunur Üyeler hakkında daha fazla bilgi
edinebilirsiniz.

Varsayılan arabirim metotları


Artık, arabirimlere Üyeler ekleyebilir ve bu üyeler için bir uygulama sağlayabilirsiniz. Bu dil özelliği, API
yazarlarının, bu arabirimin var olan uygulamalarıyla kaynak veya ikili uyumluluğu bozmadan sonraki sürümlerde
bir arabirime Yöntemler eklemesine olanak sağlar. Mevcut uygulamalar varsayılan uygulamayı devralınır . Bu
özellik aynı zamanda C# , benzer özellikleri destekleyen Android veya Swift 'Ları hedefleyen API 'Lerle birlikte
çalışmaya de olanak sağlar. Varsayılan arabirim yöntemleri, "nitelikler" dil özelliğine benzer senaryolar da sağlar.
Varsayılan arabirim yöntemleri birçok senaryoyu ve dil öğelerini etkiler. İlk öğreticimiz , bir arabirimin varsayılan
uygulamalarla güncelleştirilmesinikapsamaktadır. Diğer öğreticiler ve başvuru güncelleştirmeleri genel sürüm için
zaman içinde geliyor.

Daha fazla yerde daha fazla desen


Model eşleştirme , ilişkili ancak farklı veri türleri arasında şekle bağımlı işlevsellik sağlamaya yönelik araçlar
sağlar. C#7,0 is ifade ve switch deyimi kullanılarak tür desenleri ve sabit desenler için sözdizimi sunuldu. Bu
özellikler, verileri ve işlevselliği birbirinden canlı olarak programlama paradigmalarına desteklemeye yönelik ilk
belirsiz adımları temsil eder. Sektör daha fazla mikro hizmete ve diğer bulut tabanlı mimarilere doğru hareket
ederken diğer dil araçları gerekir.
C#8,0, kodunuzda daha fazla yerde daha fazla model ifadesi kullanabilmeniz için bu sözlüğü genişletir. Verileriniz
ve işlevselliklerinizin ayrı olması durumunda bu özellikleri göz önünde bulundurun. Algoritmalarınız nesnenin
çalışma zamanı türü dışında bir olgusuna bağımlıysa, model eşleştirmeyi düşünün. Bu teknikler, hızlı tasarımlar için
başka bir yol sağlar.
Yeni yerlerdeki yeni desenlere ek olarak C# 8,0 özyinelemeli desenlerekler. Herhangi bir model ifadesinin sonucu
bir ifadedir. Özyinelemeli bir model, sadece başka bir model ifadesinin çıktısına uygulanan bir model ifadesi olur.
Anahtar ifadeleri
Genellikle switch bir ifade, case bloklarının her birinde bir değer üretir. Anahtar ifadeleri , daha kısa ifade
sözdizimi kullanmanıza olanak sağlar. Daha az sayıda yinelenen case ve break anahtar sözcüğü ve daha az küme
ayraçları vardır. Örnek olarak, gökkuşağı renklerini listeleyen aşağıdaki sabit listesini göz önünde bulundurun:

public enum Rainbow


{
Red,
Orange,
Yellow,
Green,
Blue,
Indigo,
Violet
}

Uygulamanız R , G ve B bileşenlerinden oluşturulan bir RGBColor türü tanımlıysa, bir anahtar ifadesi içeren
aşağıdaki yöntemi kullanarak bir Rainbow değerini RGB değerlerine dönüştürebilirsiniz:

public static RGBColor FromRainbow(Rainbow colorBand) =>


colorBand switch
{
Rainbow.Red => new RGBColor(0xFF, 0x00, 0x00),
Rainbow.Orange => new RGBColor(0xFF, 0x7F, 0x00),
Rainbow.Yellow => new RGBColor(0xFF, 0xFF, 0x00),
Rainbow.Green => new RGBColor(0x00, 0xFF, 0x00),
Rainbow.Blue => new RGBColor(0x00, 0x00, 0xFF),
Rainbow.Indigo => new RGBColor(0x4B, 0x00, 0x82),
Rainbow.Violet => new RGBColor(0x94, 0x00, 0xD3),
_ => throw new ArgumentException(message: "invalid enum value", paramName:
nameof(colorBand)),
};

Burada birkaç sözdizimi geliştirmesi vardır:


Değişkeni, switch anahtar sözcüğünden önce gelir. Farklı sıra, switch ifadesinin Switch deyiminin ayırt
edilmesini görsel açıdan kolaylaştırır.
case ve : öğeleri => ile değiştirilmiştir. Daha kısa ve sezgisel.
default durum, _ bir atma ile değiştirilmiştir.
Gövdeler deyimlerdir, deyimler değildir.
Klasik switch ifadesini kullanarak denk kodla kontrast:
public static RGBColor FromRainbowClassic(Rainbow colorBand)
{
switch (colorBand)
{
case Rainbow.Red:
return new RGBColor(0xFF, 0x00, 0x00);
case Rainbow.Orange:
return new RGBColor(0xFF, 0x7F, 0x00);
case Rainbow.Yellow:
return new RGBColor(0xFF, 0xFF, 0x00);
case Rainbow.Green:
return new RGBColor(0x00, 0xFF, 0x00);
case Rainbow.Blue:
return new RGBColor(0x00, 0x00, 0xFF);
case Rainbow.Indigo:
return new RGBColor(0x4B, 0x00, 0x82);
case Rainbow.Violet:
return new RGBColor(0x94, 0x00, 0xD3);
default:
throw new ArgumentException(message: "invalid enum value", paramName: nameof(colorBand));
};
}

Özellik desenleri
Özellik deseninin incelenen nesnenin özellikleriyle eşleştirmenize olanak sağlar. Alıcının adresine göre satış
vergisini hesaplamak zorunda olan bir eCommerce sitesini düşünün. Bu hesaplama, bir Address sınıfının temel
sorumluluğu değildir. Büyük olasılıkla, adres biçimi değişikliklerinden daha fazla sıklıkta değişecektir. Satış vergisi
miktarı, adresin State özelliğine bağlıdır. Aşağıdaki yöntem, adresten ve fiyattan satış vergisini hesaplamak için
özellik modelini kullanır:

public static decimal ComputeSalesTax(Address location, decimal salePrice) =>


location switch
{
{ State: "WA" } => salePrice * 0.06M,
{ State: "MN" } => salePrice * 0.75M,
{ State: "MI" } => salePrice * 0.05M,
// other cases removed for brevity...
_ => 0M
};

Model eşleştirme, bu algoritmayı ifade etmek için kısa bir sözdizimi oluşturur.
Demet desenleri
Bazı algoritmalar birden fazla girişe bağımlıdır. Demet desenleri , kayıt düzeniolarak ifade edilen birden çok
değere göre geçiş yapmanıza olanak sağlar. Aşağıdaki kod, oyun rock, Paper, makasiçin bir switch ifadesi gösterir:

public static string RockPaperScissors(string first, string second)


=> (first, second) switch
{
("rock", "paper") => "rock is covered by paper. Paper wins.",
("rock", "scissors") => "rock breaks scissors. Rock wins.",
("paper", "rock") => "paper covers rock. Paper wins.",
("paper", "scissors") => "paper is cut by scissors. Scissors wins.",
("scissors", "rock") => "scissors is broken by rock. Rock wins.",
("scissors", "paper") => "scissors cuts paper. Scissors wins.",
(_, _) => "tie"
};

İletiler kazanan kişiyi gösterir. Atma durumu, TIES veya diğer metin girişleri için üç birleşimi temsil eder.
Konumsal desenler
Bazı türler, özelliklerini ayrık değişkenlere bağlayan bir Deconstruct yöntemi içerir. Deconstruct yöntemi erişilebilir
olduğunda, nesnenin özelliklerini incelemek ve bu özellikleri bir desen için kullanmak üzere konumsal desenleri
kullanabilirsiniz. X ve Y için ayrık değişkenler oluşturmak üzere bir Deconstruct yöntemi içeren aşağıdaki Point
sınıfını göz önünde bulundurun:

public class Point


{
public int X { get; }
public int Y { get; }

public Point(int x, int y) => (X, Y) = (x, y);

public void Deconstruct(out int x, out int y) =>


(x, y) = (X, Y);
}

Ayrıca, bir Çeyrekli konumların çeşitli konumlarını temsil eden aşağıdaki sabit listesini göz önünde bulundurun:

public enum Quadrant


{
Unknown,
Origin,
One,
Two,
Three,
Four,
OnBorder
}

Aşağıdaki yöntem x ve y değerlerini ayıklamak için konumsal model kullanır. Sonra, noktanın Quadrant
belirlenmesi için bir when yan tümcesi kullanır:

static Quadrant GetQuadrant(Point point) => point switch


{
(0, 0) => Quadrant.Origin,
var (x, y) when x > 0 && y > 0 => Quadrant.One,
var (x, y) when x < 0 && y > 0 => Quadrant.Two,
var (x, y) when x < 0 && y < 0 => Quadrant.Three,
var (x, y) when x > 0 && y < 0 => Quadrant.Four,
var (_, _) => Quadrant.OnBorder,
_ => Quadrant.Unknown
};

Yukarıdaki anahtardaki atma deseninin x ya da y 0 olması ancak her ikisi birden olmaması durumunda eşleşir.
Switch ifadesinin bir değer üretmesi veya bir özel durum oluşturması gerekir. Durumlardan hiçbiri eşleşmezse,
switch ifadesi bir özel durum oluşturur. Anahtar ifadenizde olası tüm durumları kapsamıyorsanız, derleyici sizin için
bir uyarı oluşturur.
Bu Gelişmiş öğreticide, model eşleştirmetekniklerini inceleyebilirsiniz.

Bildirimleri kullanma
Using bildirimi , using anahtar sözcüğünün önünde yer aldığı bir değişken bildirimidir. Derleyiciye, bildirildiği
değişkenin kapsayan kapsamın sonunda atılmasını söyler. Örneğin, bir metin dosyası yazan aşağıdaki kodu göz
önünde bulundurun:
static int WriteLinesToFile(IEnumerable<string> lines)
{
using var file = new System.IO.StreamWriter("WriteLines2.txt");
// Notice how we declare skippedLines after the using statement.
int skippedLines = 0;
foreach (string line in lines)
{
if (!line.Contains("Second"))
{
file.WriteLine(line);
}
else
{
skippedLines++;
}
}
// Notice how skippedLines is in scope here.
return skippedLines;
// file is disposed here
}

Yukarıdaki örnekte, yöntemi için kapanış ayracı ne zaman ulaşıldığında dosya atıldı. file bildirildiği kapsamın
sonu. Yukarıdaki kod, klasik using ifadesinikullanan aşağıdaki koda eşdeğerdir:

static int WriteLinesToFile(IEnumerable<string> lines)


{
// We must declare the variable outside of the using block
// so that it is in scope to be returned.
int skippedLines = 0;
using (var file = new System.IO.StreamWriter("WriteLines2.txt"))
{
foreach (string line in lines)
{
if (!line.Contains("Second"))
{
file.WriteLine(line);
}
else
{
skippedLines++;
}
}
} // file is disposed here
return skippedLines;
}

Yukarıdaki örnekte, using ifadesiyle ilişkilendirilen kapanış ayracı erişildiğinde dosya atıldı.
Her iki durumda da derleyici Dispose() çağrısı oluşturur. using deyimindeki ifade atılabilir değilse derleyici bir
hata oluşturur.

Statik yerel işlevler


Yerel işlevin kapsayan kapsamdaki herhangi bir değişkeni yakalamamasına (başvuru) izin vermek için artık yerel
işlevlere static değiştiricisini ekleyebilirsiniz. Bunu yapmak CS8421 üretir, "statik bir yerel işlev > <değişkenine
başvuru içeremez."
Aşağıdaki kodu göz önünde bulundurun. Yerel işlev LocalFunction , kapsayan kapsamda ( M yöntemi) belirtilen y
değişkenine erişir. Bu nedenle, LocalFunction static değiştiricisiyle bildirilemez:
int M()
{
int y;
LocalFunction();
return y;

void LocalFunction() => y = 0;


}

Aşağıdaki kod statik bir yerel işlev içerir. Bu, kapsayan kapsamdaki herhangi bir değişkene erişemediğinden statik
olabilir:

int M()
{
int y = 5;
int x = 7;
return Add(x, y);

static int Add(int left, int right) => left + right;


}

Atılabilir ref yapıları


ref değiştiricisiyle bildirildiği struct hiçbir arabirim uygulayamaz, bu nedenle IDisposableuygulayamaz. Bu
nedenle, bir ref struct elden çıkarılbilmesini sağlamak için, erişilebilir bir void Dispose() yöntemine sahip
olmalıdır. Bu özellik readonly ref struct bildirimleri için de geçerlidir.

Boş değer atanabilir başvuru türleri


Null olabilen bir ek açıklama bağlamında, başvuru türündeki herhangi bir değişken null yapılamayan bir
başvuru türüolarak kabul edilir. Bir değişkenin null olabileceğini belirtmek isterseniz, değişkeni null olabilen bir
başvuru türüolarak bildirmek için tür adını ? eklemeniz gerekir.
Null yapılamayan başvuru türleri için derleyici, yerel değişkenlerin bildirildiği sırada null olmayan bir değere
başlatıldığından emin olmak için akış analizini kullanır. Alanlar oluşturma sırasında başlatılmalıdır. Derleyici,
değişken kullanılabilir oluşturuculardan herhangi birine veya bir başlatıcı tarafından ayarlanmamışsa bir uyarı
oluşturur. Ayrıca, null olamayan başvuru türlerine null olabilecek bir değer atanamaz.
Null yapılabilir başvuru türleri atanmamış veya null olarak başlatılmamış olduğundan emin olmak için
denetlenmez. Ancak, derleyici, null olabilen bir başvuru türü değişkeninin erişilebilir olması veya null yapılamayan
bir başvuruya atanmadan önce null olarak denetlendiğinden emin olmak için akış analizini kullanır.
Özelliği hakkında daha fazla bilgiyi null yapılabilir başvuru türlerinegenel bakış bölümünde bulabilirsiniz. Bu null
yapılabilir başvuru türleri öğreticisindekiyeni bir uygulamada kendiniz deneyin. Bir uygulamayı, null yapılabilir
başvuru türlerini kullanmak için geçirmebölümünde null yapılabilir başvuru türlerini kullanmak için mevcut bir kod
temeli geçirme adımları hakkında bilgi edinin.

Zaman uyumsuz akışlar


8,0 ile C# başlayarak akışları zaman uyumsuz olarak oluşturabilir ve kullanabilirsiniz. Zaman uyumsuz akış
döndüren bir yöntem üç özelliğe sahiptir:
1. async değiştiricisiyle birlikte bildirilmiştir.
2. Bir IAsyncEnumerable<T>döndürür.
3. Yöntemi, zaman uyumsuz akıştaki birbirini izleyen öğeleri döndürmek için yield return deyimlerini içerir.
Zaman uyumsuz bir akışın kullanılması, akışın öğelerini Numaralandırdığınızda foreach anahtar sözcüğünden
önce await anahtar sözcüğünü eklemenizi gerektirir. await anahtar sözcüğünü eklemek, zaman uyumsuz akışı,
async değiştiricisiyle belirtilecek ve bir async yöntemi için izin verilen bir tür döndürecek şekilde numaralandırır.
Genellikle bu, Task veya Task<TResult>döndürme anlamına gelir. Ayrıca, bir ValueTask veya
ValueTask<TResult>olabilir. Bir yöntem, bir zaman uyumsuz akış tüketebilir ve üretebilir, bu da bir
IAsyncEnumerable<T>dönecektir. Aşağıdaki kod, 0 ile 19 arasında bir sıra üretir, her bir sayı üretilmeden 100 ms
bekler:

public static async System.Collections.Generic.IAsyncEnumerable<int> GenerateSequence()


{
for (int i = 0; i < 20; i++)
{
await Task.Delay(100);
yield return i;
}
}

await foreach ifadesini kullanarak sırayı numaralandırabilirsiniz:

await foreach (var number in GenerateSequence())


{
Console.WriteLine(number);
}

Zaman uyumsuz akışları oluşturma vekullanma öğreticimizde, zaman uyumsuz akışları kendiniz deneyebilirsiniz.

Dizinler ve aralıklar
Dizinler ve aralıklar bir dizideki tek öğelere veya aralıklara erişmek için bir kısa söz dizimi sağlar.
Bu dil desteği iki yeni türe ve iki yeni işleçlere dayanır:
System.Index bir dizini bir diziye temsil eder.
Bir dizinin dizinin sonuna göre olduğunu belirten bitiş işlecinden Dizin ^ .
System.Range bir dizinin alt aralığını temsil eder.
Aralık işleci, bir aralığın işlenenlerinin başlangıcını ve sonunu belirten .. .

Dizin kurallarıyla başlayalım. Dizi sequence değerlendirin. 0 Dizin sequence[0] ile aynıdır. ^0 Dizin
sequence[sequence.Length] ile aynıdır. sequence[^0] , sequence[sequence.Length] olduğu gibi bir özel durum
oluşturur. Herhangi bir sayı n için Dizin ^n sequence.Length - n ile aynıdır.
Aralık, bir aralığın başlangıcını ve sonunu belirtir. Aralığın başlangıcı dahil, ancak aralığın sonu dışlamalı, ancak
Başlangıç aralığa dahil değildir ancak uç aralığa dahil değildir. Aralık [0..^0] , tüm aralığı temsil eden
[0..sequence.Length] aralığını temsil eder.

Birkaç örneğe bakalım. Başlangıç ve bitişten dizin ile açıklana ek olarak, aşağıdaki diziyi göz önünde bulundurun:
var words = new string[]
{
// index from start index from end
"The", // 0 ^9
"quick", // 1 ^8
"brown", // 2 ^7
"fox", // 3 ^6
"jumped", // 4 ^5
"over", // 5 ^4
"the", // 6 ^3
"lazy", // 7 ^2
"dog" // 8 ^1
}; // 9 (or words.Length) ^0

Son kelimeyi ^1 diziniyle alabilirsiniz:

Console.WriteLine($"The last word is {words[^1]}");


// writes "dog"

Aşağıdaki kod, "quick", "brown" ve "fox" sözcüklerinin bulunduğu bir alt aralık oluşturur. words[3] üzerinden
words[1] içerir. Öğe words[4] Aralık içinde değil.

var quickBrownFox = words[1..4];

Aşağıdaki kod, "lazy" ve "dog" sözcüklerini içeren bir alt aralık oluşturur. words[^2] ve words[^1] içerir. Son dizin
words[^0] dahil değildir:

var lazyDog = words[^2..^0];

Aşağıdaki örnekler, başlangıç, bitiş veya her ikisi için açık olarak biten aralıklar oluşturur:

var allWords = words[..]; // contains "The" through "dog".


var firstPhrase = words[..4]; // contains "The" through "fox"
var lastPhrase = words[6..]; // contains "the", "lazy" and "dog"

Aralıkları, değişkenler olarak da bildirebilirsiniz:

Range phrase = 1..4;

Aralık daha sonra [ ve ] karakterleri içinde kullanılabilir:

var text = words[phrase];

Yalnızca dizin ve aralıkları destekleyen diziler değil. Ayrıca, dizin ve aralıkları dize, Span<T>veya
ReadOnlySpan<T>ile de kullanabilirsiniz. Daha fazla bilgi için bkz. Dizinler ve aralıklar için destek türü.
Dizinler ve aralıklarhakkında öğreticide dizinler ve aralıklar hakkında daha fazla bilgi bulabilirsiniz.

Null birleştirme ataması


C#8,0, null birleşim atama işleci ??= tanıtır. Sağ işleneninin değerini yalnızca sol taraftaki işlenenin null
değerlendirilirse, sol taraftaki işlenene atamak için ??= işlecini kullanabilirsiniz.
List<int> numbers = null;
int? i = null;

numbers ??= new List<int>();


numbers.Add(i ??= 17);
numbers.Add(i ??= 20);

Console.WriteLine(string.Join(" ", numbers)); // output: 17 17


Console.WriteLine(i); // output: 17

Daha fazla bilgi için?? ve?? = operatörler makalesi.

Yönetilmeyen oluşturulmuş türler


7,3 ve önceki sürümlerde, oluşturulmuş bir tür (en az bir tür bağımsız değişkeni içeren bir tür) yönetilmeyen bir tür
olamaz. C# 8,0 ile C# başlayarak, oluşturulmuş bir değer türü yalnızca yönetilmeyen türlerin alanlarını içeriyorsa
yönetilmez.
Örneğin, genel Coords<T> türünün Aşağıdaki tanımı verildiğinde:

public struct Coords<T>


{
public T X;
public T Y;
}

Coords<int> türü, C# 8,0 ve sonraki sürümlerde yönetilmeyen bir türdür. Herhangi bir yönetilmeyen tür için
olduğu gibi, bu türden bir değişkene bir işaretçi oluşturabilir veya bu türün örnekleri için yığında bir bellek bloğu
ayırabilirsiniz :

Span<Coords<int>> coordinates = stackalloc[]


{
new Coords<int> { X = 0, Y = 0 },
new Coords<int> { X = 0, Y = 3 },
new Coords<int> { X = 4, Y = 0 }
};

Daha fazla bilgi için bkz. yönetilmeyen türler.

İç içe ifadelerde stackalloc


8,0 ile C# başlayarak, bir stackalloc ifadesinin sonucu System.Span<T> veya System.ReadOnlySpan<T> türünde
ise, diğer ifadelerde stackalloc ifadesini kullanabilirsiniz:

Span<int> numbers = stackalloc[] { 1, 2, 3, 4, 5, 6 };


var ind = numbers.IndexOfAny(stackalloc[] { 2, 4, 6 ,8 });
Console.WriteLine(ind); // output: 1

Ara değerli tam dizelerin geliştirilmesi


$ ve @ belirteçlerinin sırası, her ikisi de olabilir : hem $@"..." hem de @$"..." geçerli bir ara değerli dizelerdir.
Önceki C# sürümlerde $ belirtecinin @ belirtecinden önce görünmesi gerekir.
C# 7,3 sürümündeki yenilikler
27.11.2019 • 11 minutes to read • Edit Online

C# 7,3 sürümünün iki ana teması vardır. Bir tema, güvenli kodun güvenli olmayan kod olarak performans sağlamak
için gereken özellikler sağlar. İkinci tema, mevcut özelliklerle artımlı iyileştirmeler sağlar. Ayrıca, bu yayına yeni
derleyici seçenekleri eklenmiştir.
Aşağıdaki yeni özellikler, güvenli kod için daha iyi performans temasını destekler:
Sabitlemeden sabit alanlara erişebilirsiniz.
ref yerel değişkenleri yeniden atayabilirsiniz.
stackalloc dizileri üzerinde başlatıcılar kullanabilirsiniz.
fixed deyimlerini, bir kalıbı destekleyen herhangi bir türle birlikte kullanabilirsiniz.
Ek genel kısıtlamalar kullanabilirsiniz.
Mevcut özelliklerde aşağıdaki geliştirmeler yapılmıştır:
== ve != demet türleriyle test edebilirsiniz.
İfade değişkenlerini daha fazla konumda kullanabilirsiniz.
Otomatik uygulanan özelliklerin yedekleme alanına öznitelikler iliştirebilirsiniz.
in farklı değişkenleri farklılık gösterdiği zaman Yöntem çözümlemesi geliştirildi.
Aşırı yükleme çözümlemesi artık daha az belirsiz durum içeriyor.
Yeni derleyici seçenekleri şunlardır:
Açık kaynak yazılım (OSS ) derlemelerinin imzalanmasını etkinleştirmek için -publicsign .
Kaynak dizinler için eşleme sağlamak üzere -pathmap .
Bu makalenin geri kalanında, geliştirmelerin her biri hakkında daha fazla bilgi edinmek için Ayrıntılar ve bağlantılar
sağlanmaktadır. Ortamınızdaki bu özellikleri, dotnet try genel aracını kullanarak inceleyebilirsiniz:
1. DotNet-TRY küresel aracını yükler.
2. DotNet/TRY -Samples deposunu kopyalayın.
3. TRY -Samples deposu için geçerli dizini csharp7 alt dizinine ayarlayın.
4. dotnet try 'i çalıştırın.

Daha verimli güvenli kod etkinleştirme


Güvenli olmayan kod ve güvenli kod C# yazmanız gerekir. Güvenli kod, arabellek taşmaları, başıya işaretçileri ve
diğer bellek erişim hataları gibi hata sınıflarını önler. Bu yeni özellikler, doğrulanabilir güvenli kod yeteneklerini
genişletir. Güvenli yapılar kullanarak kodunuzun daha fazlasını yazmak için çaba harcar. Bu özellikler daha kolay
hale getirir.
Dizin oluşturma fixed alanları sabitleme gerektirmez
Bu yapıyı göz önünde bulundurun:

unsafe struct S
{
public fixed int myFixedField[10];
}
Önceki sürümlerinde C#, myFixedField bir parçası olan tamsayıların birine erişmek için bir değişkeni sabitlemeyi
gerekiyordu. Şimdi, aşağıdaki kod p değişkeni ayrı bir fixed ifadesinde sabitlemeden derlenir:

class C
{
static S s = new S();

unsafe public void M()


{
int p = s.myFixedField[5];
}
}

Değişken p myFixedField bir öğeye erişir. Ayrı bir int* değişkeni bildirmeniz gerekmez. Hala unsafe bir bağlam
gerekeceğini unutmayın. Önceki sürümlerinde C#ikinci bir sabit işaretçi bildirmeniz gerekir:

class C
{
static S s = new S();

unsafe public void M()


{
fixed (int* ptr = s.myFixedField)
{
int p = ptr[5];
}
}
}

Daha fazla bilgi için fixed deyimindekimakaleye bakın.


ref yerel değişkenler yeniden atanabilir
Şimdi, ref Yereller başlatıldıktan sonra farklı örneklere başvuracak şekilde yeniden atanabilir. Aşağıdaki kod artık
derlenir:

ref VeryLargeStruct refLocal = ref veryLargeStruct; // initialization


refLocal = ref anotherVeryLargeStruct; // reassigned, refLocal refers to different storage.

Daha fazla bilgi için ref geri dönüş ve ref Yerellerve foreach makalesindeki makaleye bakın.
stackalloc dizileri başlatıcıları destekler
Bir dizideki öğeler için değerleri, başlatma sırasında belirtebilirsiniz:

var arr = new int[3] {1, 2, 3};


var arr2 = new int[] {1, 2, 3};

Artık, aynı söz dizimi stackalloc ile belirtilen dizilere de uygulanabilir:

int* pArr = stackalloc int[3] {1, 2, 3};


int* pArr2 = stackalloc int[] {1, 2, 3};
Span<int> arr = stackalloc [] {1, 2, 3};

Daha fazla bilgi için stackalloc operatör makalesine bakın.


Daha fazla tür fixed ifadesini destekler
fixed bildiriminde sınırlı bir tür kümesi desteklenir. 7,3 ile C# başlayarak, bir ref T veya ref readonly T
döndüren GetPinnableReference() yöntemi içeren herhangi bir tür fixed olabilir. Bu özelliğin eklenmesi, fixed
System.Span<T> ve ilgili türlerle kullanılabileceği anlamına gelir.
Daha fazla bilgi için bkz. dil başvurusunda fixed ifade makalesi.
Gelişmiş genel kısıtlamalar
Artık tür parametresi için temel sınıf kısıtlamaları olarak System.Enum veya System.Delegate türünü
belirtebilirsiniz.
Ayrıca, bir tür parametresinin null yapılamayan yönetilmeyen bir türolması gerektiğini belirtmek için yeni
unmanaged kısıtlamasını de kullanabilirsiniz.

Daha fazla bilgi için bkz. tür parametrelerinde genel kısıtlamalar ve kısıtlamalar where makaleleri.
Bu kısıtlamaları var olan türlere eklemek uyumsuz bir değişiklik. Kapalı genel türler artık bu yeni kısıtlamaları
karşılamayabilir.

Mevcut özellikleri daha iyi yapın


İkinci tema, dildeki özelliklere yönelik iyileştirmeler sağlar. Bu özellikler yazarken C#üretkenliği geliştirir.
Tanımlama grubu desteği == ve !=

C# Demet türleri artık == ve != desteklemektedir. Daha fazla bilgi için bkz. tanımlamabilgileri hakkındaki
makaleleri kapsayan bölüm .
Otomatik uygulanan özellikler için yedekleme alanlarına öznitelikler iliştirme
Bu sözdizimi artık desteklenmektedir:

[field: SomeThingAboutFieldAttribute]
public int SomeProperty { get; set; }

SomeThingAboutFieldAttribute özniteliği, SomeProperty için derleyicinin ürettiği yedekleme alanına uygulanır. Daha
fazla bilgi için bkz . C# programlama kılavuzundaki öznitelikler.
in yöntemi aşırı yükleme çözünürlüğü tiekesici
in bağımsız değişken değiştiricisi eklendiğinde, bu iki yöntem bir belirsizliğe neden olur:

static void M(S arg);


static void M(in S arg);

Artık, by değeri (önceki örnekte ilk olarak) aşırı yüklemesi, salt okunur başvuru sürümünden daha iyidir. Sürümü
ReadOnly başvuru bağımsız değişkeniyle çağırmak için yöntemi çağırırken in değiştiricisini dahil etmeniz gerekir.

NOTE
Bu bir hata düzeltilme olarak uygulandı. Dil sürümü "7,2" olarak ayarlanmış olsa bile bu artık belirsizdir.

Daha fazla bilgi için in parametresi değiştiricisiyleilgili makaleye bakın.


Başlatıcılarda ifade değişkenlerini genişletme
out değişken bildirimlerinin alan C# başlatıcıları, özellik başlatıcıları, Oluşturucu başlatıcıları ve sorgu yan
tümcelerini kapsayacak şekilde genişletildiğine izin vermek için 7,0 'e eklenen sözdizimi. Aşağıdaki örnek gibi kodu
sunar:
public class B
{
public B(int i, out int j)
{
j = i;
}
}

public class D : B
{
public D(int i) : base(i, out var j)
{
Console.WriteLine($"The value of 'j' is {j}");
}
}

Geliştirilmiş aşırı yükleme adayları


Her sürümde, aşırı yükleme çözümleme kuralları belirsiz Yöntem etkinleştirmeleri "belirgin" bir seçeneğe sahip
olduğu durumlara göre güncelleştirilir. Bu sürüm, derleyicinin açık seçimi seçmesini sağlamaya yardımcı olmak için
üç yeni kural ekler:
1. Bir yöntem grubu hem örnek hem de statik üye içerdiğinde, yöntem bir örnek alıcısı veya bağlamı olmadan
çağrılırsa, derleyici örnek üyelerini atar. Yöntem bir örnek alıcısıyla çağrılırsa derleyici statik üyeleri atar. Alıcı
olmadığında, derleyici statik bir bağlamda yalnızca statik üyeleri ve statik ve örnek üyelerini içerir. Alıcı bir örnek
veya tür ındexattributes, derleyici her ikisini de içerir. Örtük bir this örnek alıcısının kullanılabileceği statik bir
bağlam, statik üyeler gibi hiçbir this tanımlanmadığı üyelerin gövdesini ve alan başlatıcıları ve Oluşturucu
başlatıcıları gibi this kullanılamayacak yerleri içerir.
2. Bir yöntem grubu, tür bağımsız değişkenleri kısıtlamalarını karşılamadığı bazı genel yöntemler içerdiğinde, bu
üyeler aday kümesinden kaldırılır.
3. Bir yöntem grubu dönüştürmesi için, dönüş türü, temsilcinin dönüş türüyle eşleşmeyen aday Yöntemler
kümeden kaldırılır.
Bu değişikliği yalnızca, hangi yöntemin daha iyi olduğundan emin olduğunuzda belirsiz yöntem aşırı yüklemeleri
için daha az derleyici hatası bulacağınız için fark edeceksiniz.

Yeni derleyici seçenekleri


Yeni derleyici seçenekleri, programlar için C# yeni derlemeyi ve DevOps senaryolarını destekler.
Ortak veya açık kaynak imzalama
-publicsign derleyici seçeneği derleyicinin bir ortak anahtar kullanarak derlemeyi imzalamasını ister. Derleme
imzalanmış olarak işaretlenir, ancak imza ortak anahtardan alınır. Bu seçenek, açık kaynaklı projelerden ortak
anahtar kullanarak imzalı derlemeler oluşturmanıza olanak sağlar.
Daha fazla bilgi için bkz. -publicsign derleyici seçeneği makalesi.
pathmap
-pathmap derleyici seçeneği, derleyicinin kaynak yollarını eşlenen kaynak yollarla derleme ortamından
değiştirmesini söyler. -pathmap seçeneği, derleyici tarafından PDB dosyalarına veya CallerFilePathAttributeyönelik
olarak yazılan kaynak yolunu denetler.
Daha fazla bilgi için bkz. -pathmap derleyici seçeneği makalesi.
C# 7,2 sürümündeki yenilikler
23.10.2019 • 6 minutes to read • Edit Online

C#7,2, çok sayıda yararlı özellik ekleyen başka bir nokta sürümüdür. Bu yayın için bir tema gereksiz kopyaları veya
ayırmaları önleyerek değer türleriyle daha verimli çalışıyor.
Kalan özellikler küçük, tam özellikli özelliklerdir.
C#7,2, derleyici dili sürümünü seçmek için dil sürümü seçimi yapılandırma öğesini kullanır.
Bu sürümdeki yeni dil özellikleri şunlardır:
Güvenli verimli kod yazma teknikleri
Başvuru semantiğinin kullanıldığı değer türleriyle çalışmayı sağlayan sözdizimi geliştirmelerinden oluşan
bir bileşim.
Girintili olmayan adlandırılmış bağımsız değişkenler
Adlandırılmış bağımsız değişkenlerin ardından konumsal bağımsız değişkenler gelebilir.
Sayısal sabit değerlerde önde gelen alt çizgiler
Sayısal değişmez değerler artık, yazdırılan rakamlardan önce önde gelen alt çizgileri olabilir.
private protected erişim değiştiricisi
private protected Erişim değiştiricisi aynı derlemede türetilmiş sınıflar için erişim imkanı sunar.
Koşullu ref ifadeler
Koşullu ifadenin ( ?: ) sonucu artık bir başvuru olabilir.
Bu makalenin geri kalanında her özelliğe bir genel bakış sunulmaktadır. Her bir özellik için, arkasında yatan bir
düşünme olduğunu öğrenirsiniz. Söz dizimini öğrenirsiniz. dotnet try Genel aracı kullanarak ortamınızdaki bu
özellikleri keşfedebilirsiniz:
1. DotNet-TRY küresel aracını yükler.
2. DotNet/TRY -Samples deposunu kopyalayın.
3. TRY -Samples deposu için geçerli dizini csharp7 alt dizinine ayarlayın.
4. dotnet try öğesini çalıştırın.

Güvenli verimli kod geliştirmeleri


7,2 ' de tanıtılan dil özellikleri, başvuru semantiğinin kullanıldığı sırada değer türleriyle çalışmanıza olanak sağlar.
Başvuru türleri kullanılarak ilişkili bellek ayırmalarını oluşturmadan değer türlerini kopyalamayı en aza indirerek
performansı artırmak için tasarlanmıştır. Özellikler şunlardır:
Bir bağımsız değişkenin başvuruya göre geçirilmesini, ancak çağrılan yöntem tarafından değiştirilmediğinden
emin olmak için parametrelerde değiştirici. in Bir bağımsız değişkene
değiştiricieklemek,kaynakileuyumlubirdeğişiklik in olur.
Yöntem ref readonly üzerinde değiştirici, bir yöntemin değerini başvuruya göre döndürdüğünü ancak bu
nesneye yazma izni olmadığını belirtmek için döndürür. Değiştirici eklemek, döndürme bir değere atanmışsa,
kaynak ile uyumlu bir değişiklikolur. ref readonly Değiştirici varolan ref bir return ifadesine eklendiğinde
uyumsuz bir değişiklik vardır. readonly Çağrıcıların ref , readonly değiştiricisini içermesi için yerel
değişkenlerin bildirimini güncelleştirmesi gerekir.
Bir yapının sabit olduğunu ve onun üye yöntemlerine bir in parametre olarak geçirilmesi gerektiğini
göstermek için bildirimi. readonly struct Değiştirici, readonly var olan bir struct bildirimine eklendiğinde, ikili
uyumlu bir değişiklikbulunur.
Bir yapı türünün doğrudan yönetilen belleğe eriştiğini ve her zaman yığın ayrılması gerektiğini göstermek için
bildirimi. ref struct Değiştirici varolan struct bir bildirime eklendiğinde uyumsuz bir değişiklik vardır. ref
Bir ref struct sınıfın üyesi olamaz veya yığın üzerinde ayrılabileceği diğer konumlarda kullanılabilir.
Bu değişiklikler hakkında daha fazla bilgi için yazma güvenli verimli kod' a erişebilirsiniz.

Girintili olmayan adlandırılmış bağımsız değişkenler


Yöntem çağrıları artık, adlandırılmış bağımsız değişkenler doğru konumlarda olduğunda Konumsal bağımsız
değişkenlerden önce gelen adlandırılmış bağımsız değişkenleri kullanabilir. Daha fazla bilgi için bkz. adlandırılmış
ve isteğe bağlı bağımsız değişkenler.

Sayısal sabit değerlerde önde gelen alt çizgiler


7,0 ' de C# basamak ayırıcıları için destek uygulanması, _ öğesinin sabit değerin ilk karakteri olmasını izin
vermedi. Onaltılık ve ikili sayısal değişmez değerler artık ile _ başlayabilir.
Örneğin:

int binaryValue = 0b_0101_0101;

özel korumalı erişim değiştiricisi


Yeni bir bileşik erişim değiştiricisi: private protected bir üyeye, aynı derlemede belirtilen sınıf veya türetilmiş
sınıfları içeren bir üyeye erişilebildiğini gösterir. Aynı derlemede bulunan türetilmiş sınıfların veya sınıfların
erişimine private protected izinverdiğinden,aynıderlemedebelirtilentüretilmiştürlereerişimikısıtlar.
protected internal

Daha fazla bilgi için bkz. dil başvurusunda erişim değiştiriciler .

Koşullu ref ifadeler


Son olarak, koşullu ifade bir değer sonucu yerine bir başvuru sonucu üretebilir. Örneğin, iki diziden birindeki ilk
öğeye başvuru almak için aşağıdakini yazın:

ref var r = ref (arr != null ? ref arr[0] : ref otherArr[0]);

Değişken r , arr veya içindekiilkdeğerebirbaşvurudur. otherArr


Daha fazla bilgi için bkz. dil başvurusunda koşullu işleç (?:) .
C# 7,1 sürümündeki yenilikler
23.10.2019 • 5 minutes to read • Edit Online

C#7,1, C# dilin ilk nokta sürümüdür. Dil için artan bir sürüm temposunda işaretler. Yeni özellikleri daha erken
kullanabilirsiniz, her yeni özellik için idealdir. C#7,1, derleyiciyi belirtilen dilin sürümüyle eşleşecek şekilde
yapılandırma yeteneğini ekler. Bu sayede, dil sürümlerini yükseltme kararına araçları yükseltme kararını ayırmanızı
sağlayabilirsiniz.
C#7,1, dil sürümü seçimi yapılandırma öğesini, üç yeni dil özelliğini ve yeni derleyici davranışını ekler.
Bu sürümdeki yeni dil özellikleri şunlardır:
async``Main yöntemi
Bir uygulama için giriş noktası async değiştiriciye sahip olabilir.
default değişmez değer ifadeleri
Hedef türü çıkarsanamıyor varsayılan değer ifadelerinde varsayılan değişmez ifadeleri kullanabilirsiniz.
Gösterilen demet öğesi adları
Kayıt düzeni öğelerinin adları, birçok durumda demet başlatmasıyla çıkarsanamıyor.
Genel tür parametrelerinde model eşleştirme
Türü genel bir tür parametresi olan değişkenlerde model eşleşme ifadeleri kullanabilirsiniz.
Son olarak, derleyici iki seçeneğe -refout sahiptir ve -refonly bu, Başvuru derleme üretiminidenetler.
En son özellikleri bir nokta sürümünde kullanmak için, Derleyici dil sürümünü yapılandırmanız ve sürümü
seçmeniz gerekir.
Bu makalenin geri kalanında her özelliğe bir genel bakış sunulmaktadır. Her bir özellik için, arkasında yatan bir
düşünme olduğunu öğrenirsiniz. Söz dizimini öğrenirsiniz. dotnet try Genel aracı kullanarak ortamınızdaki bu
özellikleri keşfedebilirsiniz:
1. DotNet-TRY küresel aracını yükler.
2. DotNet/TRY -Samples deposunu kopyalayın.
3. TRY -Samples deposu için geçerli dizini csharp7 alt dizinine ayarlayın.
4. dotnet try 'i çalıştırın.

Zaman uyumsuz ana


Zaman uyumsuz Main yöntemi, yöntekinizdeki await Main kullanmanıza olanak sağlar. Daha önce yazmanız
gerekir:

static int Main()


{
return DoAsyncWork().GetAwaiter().GetResult();
}

Artık şunu yazabilirsiniz:


static async Task<int> Main()
{
// This could also be replaced with the body
// DoAsyncWork, including its await expressions:
return await DoAsyncWork();
}

Programınız çıkış kodu döndürmezse, şunu Main Taskdöndüren bir yöntem bildirebilirsiniz:

static async Task Main()


{
await SomeAsyncMethod();
}

Programlama kılavuzundaki zaman uyumsuz ana makaledeki ayrıntılar hakkında daha fazla bilgi edinebilirsiniz.

Varsayılan değişmez değer ifadeleri


Varsayılan değişmez değer ifadeleri varsayılan değer ifadelerine yönelik bir geliştirmedir. Bu ifadeler varsayılan
değere bir değişken başlatır. Daha önce yazdığınız yer:

Func<string, bool> whereClause = default(Func<string, bool>);

Artık başlatmanın sağ tarafındaki türü atlayabilirsiniz:

Func<string, bool> whereClause = default;

Daha fazla bilgi için varsayılan işleç makalesinin varsayılan değişmez değeri bölümüne bakın.

Gösterilen demet öğesi adları


Bu özellik 7,0 ' de C# tanıtılan tanımlama grupları özelliği için küçük bir geliştirmedir. Bir tanımlama grubunu
başlattığınızda, atamanın sağ tarafında kullanılan değişkenler demet öğeleri için istediğiniz adlarla aynıdır:

int count = 5;
string label = "Colors used in the map";
var pair = (count: count, label: label);

Kayıt düzeni öğelerinin adları 7,1 içinde C# kayıt kümesini başlatmak için kullanılan değişkenlerden
çıkarsanamıyor:

int count = 5;
string label = "Colors used in the map";
var pair = (count, label); // element names are "count" and "label"

Bu özellik hakkında daha fazla bilgi için Tanımlama grupları makalesinde bulabilirsiniz.

Genel tür parametrelerinde model eşleştirme


7,1 ile C# başlayarak, is ve switch tür deseninin model ifadesi bir genel tür parametresinin türüne sahip olabilir.
Bu, ya da struct class türünde olabilecek türler denetlenirken ve kutulamayı önlemek istediğiniz durumlarda
yararlı olabilir.
Başvuru derlemesi oluşturma
Yalnızca başvuru derlemelerüreten iki yeni derleyici seçeneği vardır: -refout ve -refonly. Bağlantılı makaleler, bu
seçenekleri ve başvuru derlemelerini daha ayrıntılı bir şekilde açıklamaktadır.
C# 7,0 sürümündeki yenilikler
23.10.2019 • 24 minutes to read • Edit Online

C#7,0, C# dile bir dizi yeni özellik ekler:


out değişkenlerinin
Değerleri, kullanıldığı out yönteme bağımsız değişken olarak satır içi olarak bildirebilirsiniz.
Demetler
Birden çok ortak alan içeren hafif, adlandırılmamış türler oluşturabilirsiniz. Derleyiciler ve IDE araçları bu
türlerin semantiğini anlayın.
Atılanlar
Atama, atanan değer hakkında endişelenmezseniz atamalar içinde kullanılan geçici, salt yazılır
değişkenlerdir. Bunlar, tanımlama grupları ve Kullanıcı tanımlı türler oluştururken ve parametreleri ile
out Yöntemler çağrılırken faydalıdır.
Desen Eşleştirme
Bu türlerin üyelerinin rastgele türlerini ve değerlerini temel alarak dallanma mantığı oluşturabilirsiniz.
ref Yereller ve döndürür
Yöntem yerel değişkenleri ve dönüş değerleri diğer depolamaya başvuru olabilir.
Yerel Işlevler
Kendi kapsamını ve görünürlüğünü sınırlamak için işlevleri diğer işlevlerde iç içe geçirebilirsiniz.
Daha fazla ifade-Bodied Üyeler
İfadeler kullanılarak yazılabilir üyelerin listesi artmıştır.
throw İfadelerde
Daha önce izin verilmeyen kod yapılarında özel durumlar oluşturabilir, çünkü throw bir deyimidir.
Genelleştirilmiş zaman uyumsuz dönüş türleri
Değiştiriciyle belirtilen yöntemler async , Task ve ' Task<T> a ek olarak başka türler döndürebilir.
Sayısal sabit değer sözdizimi geliştirmeleri
Yeni belirteçler Sayısal sabitler için okunabilirliği geliştirir.
Bu makalenin geri kalanında her özelliğe bir genel bakış sunulmaktadır. Her bir özellik için, arkasında yatan bir
düşünme olduğunu öğrenirsiniz. Söz dizimini öğrenirsiniz. dotnet try Genel aracı kullanarak ortamınızdaki bu
özellikleri keşfedebilirsiniz:
1. DotNet-TRY küresel aracını yükler.
2. DotNet/TRY -Samples deposunu kopyalayın.
3. TRY -Samples deposu için geçerli dizini csharp7 alt dizinine ayarlayın.
4. dotnet try 'i çalıştırın.

out değişkenlerinin
Bu sürümde, parametreleri destekleyen out mevcut sözdizimi geliştirilmiştir. Artık değişkenleri, ayrı out bir
bildirim bildirimi yazmak yerine bir yöntem çağrısının bağımsız değişken listesinde bildirebilirsiniz:
if (int.TryParse(input, out int result))
Console.WriteLine(result);
else
Console.WriteLine("Could not parse input");

Yukarıda gösterildiği gibi, açıklık için out değişkenin türünü belirtmek isteyebilirsiniz. Ancak, dil örtük olarak
yazılmış bir yerel değişken kullanmayı destekler:

if (int.TryParse(input, out var answer))


Console.WriteLine(answer);
else
Console.WriteLine("Could not parse input");

Kodu daha kolay okunabilir.


Yukarıdaki diğer bir satırda değil, kullandığınız yerde çıkış değişkenini bildirirsiniz.
İlk değer atamaya gerek yoktur.
Yöntemi bir yöntem out çağrısında kullanıldığı yerde bildirerek, yanlışlıkla onu atanmadan
kullanamazsınız.

Demetler
C#, tasarım amacını açıklamak için kullanılan sınıflar ve yapılar için zengin bir sözdizimi sağlar. Ancak bazen zengin
söz dizimi çok az avantajlı ek iş gerektirir. Genellikle birden fazla veri öğesi içeren basit bir yapıya ihtiyacı olan
Yöntemler yazabilirsiniz. Bu senaryoları desteklemek için, ' ye C#eklenmiştir. Tanımlama grupları, veri üyelerini
temsil etmek için birden çok alan içeren hafif veri yapılarıdır. Alanlar doğrulanmaz ve kendi yöntemlerinizi
tanımlayamazsınız

NOTE
Tanımlama grupları 7,0 'den C# önce kullanılabilir, ancak verimsiz ve dil desteği yoktu. Bu, demet öğelerine yalnızca olarak
Item1 başvurulabilir, Item2 vb. anlamına gelir. C#7,0, tanımlama grupları için dil desteğini tanıtır ve bu, yeni, daha verimli
demet türleri kullanarak bir kayıt düzeni alanları için anlamsal adlar sağlar.

Her üyeye bir değer atayarak ve isteğe bağlı olarak tanımlama grubu üyelerinin her birine anlamsal adlar
sağlayarak bir tanımlama grubu oluşturabilirsiniz:

(string Alpha, string Beta) namedLetters = ("a", "b");


Console.WriteLine($"{namedLetters.Alpha}, {namedLetters.Beta}");

Kayıt düzeni Alpha ve Beta olarak adlandırılan alanları içerir. namedLetters Bu adlar yalnızca derleme sırasında
bulunur ve korunmaz, örneğin, çalışma zamanında yansıma kullanarak tanımlama grubu incelenirken.
Tanımlama grubu atamasında, atamanın sağ tarafındaki alanların adlarını da belirtebilirsiniz:

var alphabetStart = (Alpha: "a", Beta: "b");


Console.WriteLine($"{alphabetStart.Alpha}, {alphabetStart.Beta}");

Bir yöntemden döndürülen bir tanımlama grubunun üyelerinin paketini kaldırmak istediğiniz zamanlar olabilir. Bu,
kayıt grubundaki her bir değer için ayrı değişkenler bildirerek yapabilirsiniz. Bu paketten çıkarılması , kayıt
düzeninin kaldırılması olarak adlandırılır:
(int max, int min) = Range(numbers);
Console.WriteLine(max);
Console.WriteLine(min);

Ayrıca, .NET 'teki herhangi bir tür için benzer bir deme sağlayabilirsiniz. Bir Deconstruct yöntemi sınıfının bir üyesi
olarak yazarsınız. Bu Deconstruct Yöntem, ayıklamak istediğiniz her out bir özellik için bir dizi bağımsız değişken
sağlar. Ve X Point koordinatlarınıçıkaranbirDeconstructoryöntemisağlayanbusınıfı Y göz önünde bulundurun:

public class Point


{
public Point(double x, double y)
=> (X, Y) = (x, y);

public double X { get; }


public double Y { get; }

public void Deconstruct(out double x, out double y) =>


(x, y) = (X, Y);
}

Bir tanımlama grubu Point 'na atayarak tek tek alanları ayıklayabilirsiniz:

var p = new Point(3.14, 2.71);


(double X, double Y) = p;

Tanımlama grupları makalesindekitanımlama grupları hakkında ayrıntılı bilgi edinebilirsiniz.

Atılanlar
Genellikle, bir tanımlama grubu oluştururken veya parametreler ile out bir yöntemi çağırırken, değeri
ilgilenmediğiniz ve kullanmayı planlamadığınız bir değişken tanımlamaya zorlanır. C#Bu senaryoyu işlemek için
atma desteği ekler. Bir atma, adı _ (alt çizgi karakteri) olan salt yazılır bir değişkendir; atmayı planladığınız tüm
değerleri tek bir değişkene atayabilirsiniz. Bir atma atanmamış değişken gibidir; atama ifadesinden ayrı olarak,
atma kodda kullanılamaz.
Atma, aşağıdaki senaryolarda desteklenir:
Tanımlama grupları veya Kullanıcı tanımlı türler kaldırılıyor.
Out parametreleri ile Yöntemler çağrılırken.
WITH ve Switch deyimleriyle bir kalıp eşleştirme işleminde.
Bir atamanın değerini bir atma olarak açıkça tanımlamak istediğinizde tek başına tanımlayıcı olarak.
Aşağıdaki örnek, iki farklı QueryCityDataForYears yıl için şehir için veri içeren 6 demet döndüren bir yöntemi
tanımlar. Örnekteki yöntem çağrısı yalnızca yöntemi tarafından döndürülen iki popülasyon değeriyle ilgilidir ve bu
nedenle, kayıt düzeni oluşturulduğunda, kayıt düzeninde kalan değerleri atma olarak değerlendirir.
using System;
using System.Collections.Generic;

public class Example


{
public static void Main()
{
var (_, _, _, pop1, _, pop2) = QueryCityDataForYears("New York City", 1960, 2010);

Console.WriteLine($"Population change, 1960 to 2010: {pop2 - pop1:N0}");


}

private static (string, double, int, int, int, int) QueryCityDataForYears(string name, int year1, int
year2)
{
int population1 = 0, population2 = 0;
double area = 0;

if (name == "New York City")


{
area = 468.48;
if (year1 == 1960)
{
population1 = 7781984;
}
if (year2 == 2010)
{
population2 = 8175133;
}
return (name, area, year1, population1, year2, population2);
}

return ("", 0, 0, 0, 0, 0);


}
}
// The example displays the following output:
// Population change, 1960 to 2010: 393,149

Daha fazla bilgi için bkz. atma.

Desen eşleştirme
Model eşleştirme , nesne türünden farklı özelliklerde Yöntem gönderimi uygulamanıza olanak sağlayan bir özelliktir.
Büyük olasılıkla nesne türüne göre Yöntem gönderimi hakkında zaten bilgi sahibisiniz. Nesne odaklı
programlamada, sanal ve geçersiz kılma yöntemleri, nesne türünü temel alarak yöntem gönderme uygulamak için
dil sözdizimi sağlar. Temel ve türetilmiş sınıflar farklı uygulamalar sağlar. Desen eşleştirme ifadeleri, devralma
hiyerarşisi aracılığıyla ilgili olmayan türler ve veri öğeleri için benzer dağıtım düzenlerini kolayca
uygulayabileceğiniz şekilde bu kavramı genişletir.
Model eşleştirme, is ifadeleri ve switch ifadeleri destekler. Her biri, nesnenin aranan düzene karşılayıp
karşılamadığını tespit etmek için bir nesne ve özelliklerini inceleyerek sağlar. Modele ek kurallar when belirtmek
için anahtar sözcüğünü kullanırsınız.
Model ifadesi, bir nesneyi türü hakkında sorgulamak ve sonucu bir yönergede atamak için tanıdık is işleci
genişletir. is Aşağıdaki kod, bir değişkenin bir int olduğunu denetler ve varsa, geçerli Sum 'a ekler:

if (input is int count)


sum += count;

Önceki küçük örnek, is ifadeye yönelik geliştirmeleri gösterir. Aynı zamanda değer türlerine ve başvuru türlerine
karşı test edebilirsiniz ve başarılı sonucu doğru türdeki yeni bir değişkene atayabilirsiniz.
Anahtar eşleştirme ifadesinde, switch zaten C# dilin bir parçası olan bir tanıdık sözdizimi vardır. Güncelleştirilmiş
switch ifadesinin çeşitli yeni yapıları vardır:
Bir switch ifadenin yöneten türü artık, bu türlerden birine karşılık gelen tamsayı türleri, Enum türleri string
veya null olabilen bir türle sınırlı değildir. Herhangi bir tür kullanılabilir.
switch Her case etikette ifadenin türünü test edebilirsiniz. is İfadesinde olduğu gibi, bu türe yeni bir
değişken atayabilirsiniz.
O değişkende daha fazla when test koşullarına bir yan tümce ekleyebilirsiniz.
case Etiketlerin sırası artık önemlidir. Eşleştirilecek ilk dal yürütülür; diğerleri atlanır.

Aşağıdaki kod bu yeni özellikleri göstermektedir:

public static int SumPositiveNumbers(IEnumerable<object> sequence)


{
int sum = 0;
foreach (var i in sequence)
{
switch (i)
{
case 0:
break;
case IEnumerable<int> childSequence:
{
foreach(var item in childSequence)
sum += (item > 0) ? item : 0;
break;
}
case int n when n > 0:
sum += n;
break;
case null:
throw new NullReferenceException("Null found in sequence");
default:
throw new InvalidOperationException("Unrecognized type");
}
}
return sum;
}

case 0: tanıdık sabit bir örüntü.


case IEnumerable<int> childSequence: bir tür deseninin.
case int n when n > 0: , ek when bir koşula sahip bir tür düzendir.
case null: null desenli bir değer.
default: tanıdık varsayılan durumdur.

' De C#örüntüme göre desenler eşleştirmesi hakkında daha fazla bilgi edinebilirsiniz.

Ref Yereller ve geri dönüşler


Bu özellik, tarafından kullanılan ve başka bir yerde tanımlanan değişkenlere başvuru döndüren algoritmaların
yapılmasını sağlar. Bir örnek büyük matrislerle çalışıyor ve belirli özelliklere sahip tek bir konum buluyor. Aşağıdaki
yöntem, matriste bu depolama için bir başvuru döndürür:
public static ref int Find(int[,] matrix, Func<int, bool> predicate)
{
for (int i = 0; i < matrix.GetLength(0); i++)
for (int j = 0; j < matrix.GetLength(1); j++)
if (predicate(matrix[i, j]))
return ref matrix[i, j];
throw new InvalidOperationException("Not found");
}

Aşağıdaki kodda gösterildiği gibi, dönüş değerini bir ref olarak bildirebilir ve matriste bu değeri değiştirebilirsiniz:

ref var item = ref MatrixSearch.Find(matrix, (val) => val == 42);


Console.WriteLine(item);
item = 24;
Console.WriteLine(matrix[4, 2]);

C# Dil, ref yerelleri yanlış kullanmanızı ve şunu döndürdüğünü koruyan çeşitli kurallara sahiptir:
ref Anahtar sözcüğünü Yöntem imzasına ve bir yöntemindeki tüm return deyimlere eklemeniz gerekir.
Bu, yöntem boyunca başvuruya göre döndürülen yöntemi temizler.
Bir ref return değer değişkenine ref veya bir değişkene atanabilir.
Çağıran, dönüş değerinin kopyalanıp kopyalanmadığını denetler. Dönüş değerini atarken değiştiricinin
atlanması, çağıranın depolama için bir başvuru değil, değer kopyasının istediğini gösterir. ref
Bir ref yerel değişkene standart bir yöntem dönüş değeri atayamazsınız.
Şunun gibi deyimler izin vermez ref int i = sequence.Count();
Ömrü, yönteminin yürütülmesinden daha fazla genişlemeyen bir ref değişkene geri dönemez.
Bu, yerel bir değişkene veya benzer kapsama sahip bir değişkene bir başvuru döndüremeyeceğiniz
anlamına gelir.
ref Yereller ve geri dönüş, zaman uyumsuz yöntemlerle kullanılamaz.
Zaman uyumsuz yöntem döndürüldüğünde, derleyici başvurulan değişkenin son değerine ayarlandığını
bilemez.
Ref Yereller ve ref işlevinin eklenmesi, değerleri kopyalamayı önleyerek veya birden çok kez başvuru işlemleri
gerçekleştirerek daha etkili olan algoritmaların kullanılmasına izin verir.
Dönüş ref değerine ekleme, kaynak ile uyumlu bir değişikdir. Varolan kod derlenir, ancak ref dönüş değeri
atandığında kopyalanır. Çağıranlar, döndürmeyi bir başvuru olarak depolamak için dönüş değeri ref için
depolamayı yerel bir değişkene güncelleştirmelidir.
Daha fazla bilgi için bkz. ref anahtar sözcüğü makalesi.

Yerel işlevler
Sınıfların pek çok tasarımı yalnızca bir konumdan çağrılan yöntemleri içerir. Bu ek özel yöntemler her bir yöntemi
küçük ve odaklanmış olarak tutar. Yerel işlevler , yöntemleri başka bir yöntem bağlamı içinde bildirmenize olanak
tanır. Yerel işlevler, sınıfının okuyucularının, yerel yöntemin yalnızca bildirildiği bağlamdan çağrıldığını görmesini
kolaylaştırır.
Yerel işlevler için iki yaygın kullanım durumu vardır: genel Yineleyici yöntemleri ve genel zaman uyumsuz
yöntemler. Her iki yöntem türü, programcılar tarafından daha sonra oluşabilecek hataları raporlayan kodu oluşturur.
Yineleyici metotlarda, tüm özel durumlar yalnızca döndürülen sırayı belirten kod çağrılırken izlenir. Zaman
uyumsuz metotlarda, tüm özel durumlar yalnızca döndürülen geri Task beklendiğinde gözlemlenir. Aşağıdaki
örnek, yerel bir işlev kullanarak Yineleyici uygulamasından parametre doğrulamayı ayırmayı gösterir:
public static IEnumerable<char> AlphabetSubset3(char start, char end)
{
if (start < 'a' || start > 'z')
throw new ArgumentOutOfRangeException(paramName: nameof(start), message: "start must be a letter");
if (end < 'a' || end > 'z')
throw new ArgumentOutOfRangeException(paramName: nameof(end), message: "end must be a letter");

if (end <= start)


throw new ArgumentException($"{nameof(end)} must be greater than {nameof(start)}");

return alphabetSubsetImplementation();

IEnumerable<char> alphabetSubsetImplementation()
{
for (var c = start; c < end; c++)
yield return c;
}
}

Bağımsız değişken doğrulamasından doğan özel durumların, async zaman uyumsuz iş başlamadan önce
oluşturulması için yöntemler ile aynı yöntem kullanılabilir:

public Task<string> PerformLongRunningWork(string address, int index, string name)


{
if (string.IsNullOrWhiteSpace(address))
throw new ArgumentException(message: "An address is required", paramName: nameof(address));
if (index < 0)
throw new ArgumentOutOfRangeException(paramName: nameof(index), message: "The index must be non-
negative");
if (string.IsNullOrWhiteSpace(name))
throw new ArgumentException(message: "You must supply a name", paramName: nameof(name));

return longRunningWorkImplementation();

async Task<string> longRunningWorkImplementation()


{
var interimResult = await FirstWork(address);
var secondResult = await SecondStep(index, name);
return $"The results are {interimResult} and {secondResult}. Enjoy.";
}
}

NOTE
Yerel işlevler tarafından desteklenen tasarımlardan bazıları lambda ifadelerikullanılarak da gerçekleştirilebilir. Aralarındaki
farklar hakkında daha fazla bilgi edinebilirsiniz

Daha fazla ifade-Bodied Üyeler


C#6 eklenen ifade-üye işlevleri için Bodied Üyeler ve salt okunurdur özellikleri. C#7,0, ifade olarak uygulanabilecek
izin verilen üyeleri genişletir. 7,0 C# ' de, Özellikler ve Dizin oluşturucularüzerinde oluşturucular, sonlandırıcılarve
get ve set erişimciler uygulayabilirsiniz. Aşağıdaki kod, her birinin örneklerini gösterir:
// Expression-bodied constructor
public ExpressionMembersExample(string label) => this.Label = label;

// Expression-bodied finalizer
~ExpressionMembersExample() => Console.Error.WriteLine("Finalized!");

private string label;

// Expression-bodied get / set accessors.


public string Label
{
get => label;
set => this.label = value ?? "Default label";
}

NOTE
Bu örnekte sonlandırıcısı gerekmez, ancak söz dizimini göstermek için gösterilir. Yönetilmeyen kaynakları serbest bırakmak
gerekmedikçe, sınıfınıza sonlandırıcıyı uygulamamalısınız. Ayrıca, SafeHandle yönetilmeyen kaynakları doğrudan yönetmek
yerine sınıfını kullanmayı göz önünde bulundurmanız gerekir.

İfade için bu yeni konumlar-Bodied Üyeler C# dilin önemli bir kilometre taşını temsil eder: Bu özellikler, açık
kaynaklı Roslyn projesinde çalışan topluluk üyeleri tarafından uygulanmıştır.
Bir yöntemi bir ifade ile değiştirmek, ikili uyumlu bir değişiklikolur.

Throw ifadeleri
' C#De throw , her zaman bir beyan olmuştur. Bir ifade değil, bir deyim olduğundan, bunu kullanamadığı C#
yapılar vardı. throw Bu dahil edilen Koşullu ifadeler, null birleştirme ifadeleri ve bazı lambda ifadeleri. İfade
bululmuş üyelerin eklenmesi, throw ifadelerin yararlı olacağı daha fazla konum ekler. Bu yapıtın herhangi birini
yazmak için 7,0, C# throw ifadelerinitanıtır.
Bu ek, daha fazla ifade tabanlı kod yazmayı kolaylaştırır. Hata denetimi için ek deyimlere ihtiyacınız yoktur.

Genelleştirilmiş zaman uyumsuz dönüş türleri


Zaman uyumsuz Task metotlardan bir nesne döndürmek, belirli yollarda performans sorunlarını ortaya çıkarabilir.
Task bir başvuru türüdür, bu nedenle bu bir nesne ayırma anlamına gelir. async Değiştirici ile belirtilen bir
yöntemin önbelleğe alınmış bir sonuç döndürdüğü veya zaman uyumlu olarak tamamladığı durumlarda, ek
ayırmalar kodun performans açısından kritik bölümlerinde önemli bir zaman maliyeti olabilir. Bu ayırmalar sıkı
Döngülerde gerçekleşirse maliyetli hale gelebilir.
Yeni dil özelliği Task , zaman uyumsuz yöntem dönüş türlerinin, Task<T> ve ile void sınırlı olmadığı anlamına gelir.
Döndürülen türün zaman uyumsuz düzene uygun olması gerekir, yani bir GetAwaiter yönteme erişilebilir olması
gerekir. Tek bir somut örnek olarak, ValueTask bu yeni dil özelliğinden kullanım sağlamak için tür .NET Framework
'e eklenmiştir:

public async ValueTask<int> Func()


{
await Task.Delay(100);
return 5;
}
NOTE
Türü kullanabilmek için NuGet paketini System.Threading.Tasks.Extensions eklemeniz gerekir. ValueTask<TResult>

Bu geliştirme, en çok bir Task performans kritik kodunda ayırmayı önlemek için kitaplık yazarları için yararlıdır.

Sayısal sabit değer sözdizimi geliştirmeleri


Hatalı okuma sayısal sabitleri, ilk kez okurken kodu daha zor hale getirir. Bit maskeleri veya diğer sembolik değerler
yanlış anlama eğilimindedir. C#7,0, tasarlanan kullanım için en okunabilir biçimde sayı yazmak için iki yeni özellik
içerir: ikili sabit değerlerve basamak ayırıcıları.
Bit maskeleri oluştururken veya bir sayının ikili gösteriminin en çok okunabilen kodu yaptığı durumlarda bu süreler
için bu sayıyı binary olarak yazın:

public const int Sixteen = 0b0001_0000;


public const int ThirtyTwo = 0b0010_0000;
public const int SixtyFour = 0b0100_0000;
public const int OneHundredTwentyEight = 0b1000_0000;

Sabitin başlangıcında, 0b sayının bir ikili sayı olarak yazıldığını gösterir. İkili sayılar uzun sürebilir, bu nedenle, ikili
Sabitte yukarıda gösterildiği gibi, _ bir rakam ayırıcısı olarak girerek bit düzenlerini görmeyi daha kolay hale
getirirsiniz. Sayı ayırıcısı, sabit içinde herhangi bir yerde görünebilir. 10 tabanında numara için bu, binlerce ayırıcı
olarak kullanılması yaygındır:

public const long BillionsAndBillions = 100_000_000_000;

Rakam ayırıcısı, decimal float , ve double türleri ile birlikte kullanılabilir:

public const double AvogadroConstant = 6.022_140_857_747_474e23;


public const decimal GoldenRatio = 1.618_033_988_749_894_848_204_586_834_365_638_117_720_309_179M;

Birlikte çalışarak, sayısal sabitleri çok daha okunaklı bir şekilde bildirebilirsiniz.
6 ' daki C# yenilikler
23.10.2019 • 15 minutes to read • Edit Online

Uygulamasının C# 6,0 sürümü, geliştiricilerin üretkenliğini artıran birçok özellik içeriyordu. Bu özelliklerin genel
etkisi, daha okunaklı olan daha kısa kodlar yazmanızı de ister. Söz dizimi birçok yaygın uygulama için daha az
sertifika içerir. Tasarım amacını daha az seremle görmek daha kolaydır. Bu özellikleri iyi öğrenin ve daha üretken
olacak daha fazla kod yazmanız ve daha fazla okunabilir kod yazmanız gerekir. Özelliklerden daha fazlasını, dilin
yapılarından daha fazla odaklanabilirsiniz.
Bu makalenin geri kalanında, her bir özelliği keşfetmeye yönelik bir bağlantı ile bu özelliklerin her biri için bir genel
bakış sunulmaktadır. Ayrıca öğreticiler bölümünde 6 ' da etkileşimli bir araştırmayla ilgili C# özellikleri
inceleyebilirsiniz.

Salt okunurdur otomatik Özellikler


Salt okuma otomatik özellikleri , sabit türler oluşturmak için daha kısa bir sözdizimi sağlar. Auto özelliğini yalnızca
bir get erişimcisi ile bildirirsiniz:

public string FirstName { get; }


public string LastName { get; }

FirstName Ve LastName özellikleri yalnızca aynı sınıfın oluşturucusunun gövdesinde ayarlanabilir:

public Student(string firstName, string lastName)


{
if (IsNullOrWhiteSpace(lastName))
throw new ArgumentException(message: "Cannot be blank", paramName: nameof(lastName));
FirstName = firstName;
LastName = lastName;
}

Başka bir yöntemde LastName ayarlamaya çalışmak, CS0200 derleme hatası oluşturur:

public class Student


{
public string LastName { get; }

public void ChangeName(string newLastName)


{
// Generates CS0200: Property or indexer cannot be assigned to -- it is read only
LastName = newLastName;
}
}

Bu özellik, sabit türler oluşturmak için gerçek dil desteğini sunar ve daha kısa ve uygun otomatik özellik
sözdizimini kullanır.
Bu söz dizimini eklemek erişilebilir bir yöntemi kaldırmazsa, ikili uyumlu bir değişiklikolur.

Otomatik-özellik başlatıcıları
Otomatik Özellik başlatıcıları , otomatik özellik için ilk değeri özellik bildiriminin bir parçası olarak bildirmenize
olanak tanır.

public ICollection<double> Grades { get; } = new List<double>();

Üye Grades , bildirildiği yerde başlatılır. Bu, başlatmayı tam olarak bir kez gerçekleştirmeyi kolaylaştırır. Başlatma,
özellik bildiriminin bir parçasıdır ve bu, depolama ayırmasının nesneler için Student ortak arabirimle daha kolay
olmasını sağlar.

İfade-Bodied işlev üyeleri


Yazdığınız birçok üye tek deyimler olabilecek tek ifadelerdir. Bunun yerine Expression-Bodied üyesi yazın.
Yöntemler ve salt okunurdur özellikleri için geçerlidir. Örneğin, bir geçersiz kılma ToString() genellikle harika bir
adaydır:

public override string ToString() => $"{LastName}, {FirstName}";

Bu sözdizimini salt okuma özellikleri için de kullanabilirsiniz:

public string FullName => $"{FirstName} {LastName}";

Varolan bir üyenin bir ifade ile değiştirilmesi, ikili uyumlu bir değişiklikolur.

statik kullanma
Statik geliştirme kullanımı , tek bir sınıfın statik yöntemlerini içeri aktarmanızı sağlar. Kullanmakta olduğunuz sınıfı
belirtirsiniz:

using static System.Math;

Math Herhangi bir örnek yöntemi içermez. Statik ve örnek yöntemlerine using static sahip bir sınıf için sınıf '
statik yöntemleri içeri aktarmak için de kullanabilirsiniz. En yararlı örneklerden Stringbiri şunlardır:

using static System.String;

NOTE
Statik bir using ifadesinde tam sınıf adını System.String kullanmanız gerekir. Bunun yerine string anahtar sözcüğünü
kullanamazsınız.

Bir static using deyimden içeri aktarıldığında, genişletme yöntemleri yalnızca uzantı yöntemi çağırma sözdizimi
kullanılarak çağrıldığında kapsamdadır. Statik bir yöntem olarak çağrıldığında kapsamda değildir. Bunu genellikle
LINQ sorgularında görürsünüz. Enumerable YaQueryableda içeri aktararak LINQ deseninin içeri aktarabilirsiniz.

using static System.Linq.Enumerable;

Uzantı yöntemlerini, genellikle uzantı yöntemi çağırma ifadelerini kullanarak çağırabilirsiniz. Statik yöntem çağrısı
sözdizimini kullanarak çağırdığınız nadir bir durumda sınıf adı ekleme belirsizlik çözümleniyor.
Yönerge static using , iç içe geçmiş türleri de içeri aktarır. Herhangi bir iç içe geçmiş türe, nitelik olmadan
başvurabilirsiniz.
Null-koşullu işleçler
Null koşullu işleç , null denetimleri çok daha kolay ve akıcı hale getirir. Üye erişimini . bununla ?. değiştirin:

var first = person?.FirstName;

Önceki örnekte, değişken first , kişi nesnesi null ise atanır null . Aksi takdirde, FirstName özelliğin değeri
atanır. En önemlisi, ?. Bu kod satırının person , değişkeni ise, null bir NullReferenceException olarak
yaramayacağı anlamına gelir. Bunun yerine, kısa devreler ve döndürür null . Dizi veya Dizin Oluşturucu erişimi
için null koşullu bir işleç de kullanabilirsiniz. Dizin [] ifadesinde ?[] ile değiştirin.
Aşağıdaki ifade, person değerinden bağımsız string olarak bir döndürür. Bu yapıyı genellikle, null özelliklerden
biri olduğunda varsayılan değerleri atamak için null birleşim işleciyle kullanırsınız. Kısa devre null ifadesi
olduğunda döndürülen değer tam ifadeyle eşleşecek şekilde yazılır.

first = person?.FirstName ?? "Unspecified";

Yöntemleri koşullu olarak çağırmak ?. için de kullanabilirsiniz. Null koşullu işleçle üye işlevlerinin en yaygın
kullanımı, güvenli temsilcileri (veya olay işleyicilerini) null güvenle çağırmadır. Üyeye erişmek için ?. işlecini
kullanarak temsilcinin Invoke yöntemini çağıracaksınız. Temsilci desenleri makalesinde bir örnek görebilirsiniz.
?. İşlecinin kuralları, işlecin sol tarafının yalnızca bir kez değerlendirildiğinden emin olur. Olay işleyicilerini
kullanarak aşağıdaki örnek dahil olmak üzere birçok deyim sunar:

// preferred in C# 6:
this.SomethingHappened?.Invoke(this, eventArgs);

Sol tarafının yalnızca bir kez değerlendirilmesinin yanı sıra, yöntemin sol tarafındaki Yöntem çağrıları dahil
herhangi bir ifadeyi kullanmanıza de olanak sağlar. ?.

Dize ilişkilendirme
6 C# ile yeni dize ilişkilendirme özelliği bir dizeye ifade eklemenizi sağlar. Dizeyi yalnızca ile $ önyüz ve sıra
sayıları yerine ve { } arasında ifadeleri kullanın:

public string FullName => $"{FirstName} {LastName}";

Bu örnek, değiştirilen ifadeler için özellikleri kullanır. Herhangi bir ifadeyi kullanabilirsiniz. Örneğin, ilişkilendirme
'nin bir parçası olarak bir öğrencinin sınıf noktası ortalamasını hesaplamanız gerekir:

public string GetGradePointPercentage() =>


$"Name: {LastName}, {FirstName}. G.P.A: {Grades.Average():F2}";

Yukarıdaki kod satırı, değeri Grades.Average() iki ondalık basamakla kayan noktalı sayı olarak biçimlendirir.
Genellikle, belirli bir kültür kullanılarak üretilen dizeyi biçimlendirmeniz gerekebilir. Dize ilişkilendirme tarafından
üretilen nesnenin örtük olarak öğesine System.FormattableStringdönüştürülebileceği olguyu kullanırsınız.
FormattableString Örnek, bileşik biçim dizesini ve ifadeleri dizelere dönüştürmeden önce değerlendirme
sonuçlarını içerir. Bir dizeyi biçimlendirirken kültürü belirtmek için
yönteminikullanın.FormattableString.ToString(IFormatProvider) Aşağıdaki örnek, Almanya (de-DE ) kültürünü
kullanarak bir dize üretir. (Varsayılan olarak, Almanya kültürü ondalık ayırıcı için ', ' karakterini ve binlik ayırıcı
olarak '. ' karakterini kullanır.)

FormattableString str = $"Average grade is {s.Grades.Average()}";


var gradeStr = str.ToString(new System.Globalization.CultureInfo("de-DE"));

Dize ilişkilendirmeyi kullanmaya başlamak için etkileşimli öğreticide dize ilişkilendirme C# , dize ilişkilendirme
makalesi ve öğreticideki dize ilişkilendirme C# bölümüne bakın.

Özel durum filtreleri


Özel durum filtreleri , belirli bir catch yan tümcesinin ne zaman uygulanacağını tespit eden yan tümcelerdir. Özel
durum filtresi için kullanılan ifade olarak true değerlendirilirse, catch yan tümcesi bir özel durum üzerinde normal
işlemesini gerçekleştirir. İfade olarak false değerlendirilirse, catch yan tümce atlanır. Bir kullanım, bir catch yan
tümcenin özel durumu işleyebilmesine izin vermek için bir özel durumla ilgili bilgileri incelemektir:

public static async Task<string> MakeRequest()


{
WebRequestHandler webRequestHandler = new WebRequestHandler();
webRequestHandler.AllowAutoRedirect = false;
using (HttpClient client = new HttpClient(webRequestHandler))
{
var stringTask = client.GetStringAsync("https://docs.microsoft.com/en-us/dotnet/about/");
try
{
var responseText = await stringTask;
return responseText;
}
catch (System.Net.Http.HttpRequestException e) when (e.Message.Contains("301"))
{
return "Site Moved";
}
}
}

nameof İfade
NameOf ifadesinin bir sembolün adı olarak değerlendirilir. Bir değişken, özellik veya üye alanı için her ihtiyaç
duyduğunuzda, araçların çalışmasını sağlamak için harika bir yoldur. İçin nameof en yaygın kullanımlardır bir özel
duruma neden olan bir simgenin adını sağlamaktır:

if (IsNullOrWhiteSpace(lastName))
throw new ArgumentException(message: "Cannot be blank", paramName: nameof(lastName));

Başka bir kullanım, INotifyPropertyChanged arabirimini uygulayan XAML tabanlı uygulamalardır:


public string LastName
{
get { return lastName; }
set
{
if (value != lastName)
{
lastName = value;
PropertyChanged?.Invoke(this,
new PropertyChangedEventArgs(nameof(LastName)));
}
}
}
private string lastName;

Catch ve finally bloklarında await


C#5 ' te ifadeler yerleştirebileceğiniz await yerde çeşitli sınırlamalar vardı. 6 C# ile artık await catch veya
ifadelerindekullanabilirsiniz. finally Bu, genellikle günlük senaryolarıyla kullanılır:

public static async Task<string> MakeRequestAndLogFailures()


{
await logMethodEntrance();
var client = new System.Net.Http.HttpClient();
var streamTask = client.GetStringAsync("https://localHost:10000");
try {
var responseText = await streamTask;
return responseText;
} catch (System.Net.Http.HttpRequestException e) when (e.Message.Contains("301"))
{
await logError("Recovered from redirect", e);
return "Site Moved";
}
finally
{
await logMethodExit();
client.Dispose();
}
}

finally İçinde await destekeklemek catch için uygulama ayrıntıları ve yan tümceleri, davranışın zaman uyumlu
kod davranışıyla tutarlı olmasını sağlamaktır. catch catch Or
yantümcesindeyürütülenkodoluşturduğunda,yürütmesonrakiçevresindekibloktauygunbiryantümcearar. finally
Geçerli bir özel durum varsa, bu özel durum kaybedilir. Aynı durum, catch ve finally yan tümcelerinde beklenen
ifadelerle aynıdır: için uygun catch bir aranır ve varsa geçerli özel durum kaybolur.

NOTE
Bu davranış catch finally , yeni özel durumlar oluşturmamaya özen gösterin.

Dizin oluşturucular kullanarak ilişkilendirilebilir koleksiyonları başlatma


Dizin başlatıcıları , koleksiyon başlatıcılarının Dizin kullanımıyla daha tutarlı olmasını sağlayan iki özellikten biridir. '
In C#önceki sürümlerinde, anahtar ve değer çiftleri etrafında küme ayraçları ekleyerek sıra stili
Dictionary<TKey,TValue>koleksiyonlarıyla koleksiyon başlatıcıları kullanabilirsiniz:
private Dictionary<int, string> messages = new Dictionary<int, string>
{
{ 404, "Page not Found"},
{ 302, "Page moved, but left a forwarding address."},
{ 500, "The web server can't come out to play today."}
};

Bunları, erişilebilir Add yöntemin birden Dictionary<TKey,TValue> fazla bağımsız değişken kabul ettiği
koleksiyonlar ve diğer türlerle birlikte kullanabilirsiniz. Yeni sözdizimi, koleksiyona bir dizin kullanılarak atamayı
destekler:

private Dictionary<int, string> webErrors = new Dictionary<int, string>


{
[404] = "Page not Found",
[302] = "Page moved, but left a forwarding address.",
[500] = "The web server can't come out to play today."
};

Bu özellik, çeşitli sürümlere yönelik dizi kapsayıcılarına benzer bir sözdizimi kullanılarak ilişkilendirilebilir
kapsayıcıların başlatılabileceği anlamına gelir.

Koleksiyon Add başlatıcılarında uzantı yöntemleri


Koleksiyon başlatmayı daha kolay hale getiren başka bir özellik, Add yöntemi için bir genişletme yöntemi
kullanma olanağıdır. Bu özellik Visual Basic eşlik için eklendi. Özelliği, en çok, anlamsal olarak yeni öğeler eklemek
için farklı bir ada sahip bir yöntemi olan bir özel koleksiyon sınıfınız olduğunda yararlıdır.

Geliştirilmiş aşırı yükleme çözümlemesi


Bu son özellik, büyük olasılıkla fark edilmeyecek bir özelliktir. C# Derleyicinin önceki sürümünde lambda ifadeleri
içeren bazı Yöntem çağrıları bulunursa oluşturulan yapılar vardı. Şu yöntemi göz önünde bulundurun:

static Task DoThings()


{
return Task.FromResult(0);
}

Önceki sürümlerinde C#, Yöntem grubu sözdizimini kullanarak bu yöntemi çağırmak başarısız olur:

Task.Run(DoThings);

Önceki derleyici ve Task.Run(Action) Task.Run(Func<Task>()) arasında doğru şekilde ayırt edilemedi. Önceki
sürümlerde bağımsız değişken olarak bir lambda ifadesi kullanmanız gerekir:

Task.Run(() => DoThings());

6 C# derleyicisi, daha iyi bir Task.Run(Func<Task>()) seçim olduğunu doğru şekilde belirler.
Belirleyici derleyici çıkışı
-deterministic Seçeneği derleyiciye aynı kaynak dosyaların birbirini izleyen derlemeler için bayt için aynı çıkış
derlemesi oluşturmasını söyler.
Varsayılan olarak, her derleme her derlemede benzersiz çıktı üretir. Derleyici, bir zaman damgası ve rastgele
sayıdan oluşturulan bir GUID ekler. Bu seçeneği, derlemeler genelinde tutarlılığı sağlamak üzere bayt için bayt
çıkışı karşılaştırmak istiyorsanız kullanın.
Daha fazla bilgi için, bkz. belirleyici derleyici seçeneği makalesi.
C# geçmişi
8.11.2019 • 15 minutes to read • Edit Online

Bu makalede, C# dilin her bir ana sürümünün geçmişi sağlanmaktadır. C# Takım yenilik yapın ve yeni özellikler
eklemeye devam etmektedir. Gelecek sürümler için kabul edilen özellikler dahil olmak üzere ayrıntılı dil özelliği
durumu GitHub 'daki DotNet/Roslyn deposunda bulunabilir.

IMPORTANT
C# Dil, C# belirtimin bazı özellikler için standart kitaplık olarak tanımladığı tür ve yöntemlere dayanır. .NET platformu bu
türleri ve yöntemleri bir dizi pakete sunar. Özel durum işleme bir örnektir. Oluşturulan nesnenin Exceptiontüretildiğinden emin
olmak için her throw deyimi veya ifadesi denetlenir. Benzer şekilde, yakalanan türün Exceptiontürediğinden emin olmak için
her catch denetlenir. Her sürümde yeni gereksinimler eklenebilir. Eski ortamlarda en son dil özelliklerini kullanmak için, belirli
kitaplıkları yüklemeniz gerekebilir. Bu bağımlılıklar, her belirli sürüm için sayfasında belgelenmiştir. Bu bağımlılıkta arka plan için
dil ve kitaplık arasındaki ilişkiler hakkında daha fazla bilgi edinebilirsiniz.

C# Yapı araçları, varsayılan dil sürümü olan en son ana dil sürümünü göz önünde bulundurun. Bu bölümdeki diğer
makalelerde ayrıntılı olarak açıklanan ana yayınlar arasında nokta yayınları olabilir. En son özellikleri bir nokta
sürümünde kullanmak için, Derleyici dil sürümünü yapılandırmanız ve sürümü seçmeniz gerekir. 7,0 sonrasında C#
üç nokta yayını vardı:
C# 7,3:
C#7,3, Visual Studio 2017 sürüm 15,7 ve .NET Core 2,1 SDKile başlayarak kullanılabilir.
C# 7,2:
C#7,2, Visual Studio 2017 sürüm 15,5 ve .NET Core 2,0 SDKile başlayarak kullanılabilir.
C# 7,1:
C#7,1, Visual Studio 2017 sürüm 15,3 ve .NET Core 2,0 SDKile başlayarak kullanılabilir.

C#sürüm 1,0
Geri dönerek Visual Studio .NET 2002 ile C# yayınlanan sürüm 1,0, Java gibi çok sayıda görünür. ECMA için
belirtilen tasarım hedeflerinin bir parçasıolarak, "basit, modern, genel amaçlı nesne yönelimli bir dil" olarak arar. Bu
sırada, Java gibi, bu erken tasarım hedefleri elde ettiği anlamına gelir.
Ancak şimdi C# 1,0 ' ye geri bakarsanız, kendinizi biraz daha bulabilirsiniz. Yerleşik zaman uyumsuz özellikleri ve
izin verilen genel türler etrafında bulunan bazı nesnelerin bazı nesnelerin bazı özelliklerini ele alır. Aslında, genel
türleri tamamen ele edindi. Ve LINQ? Henüz kullanılamıyor. Bu eklemelerin gelmesi birkaç yıl sürer.
C#sürüm 1,0, bugün ile karşılaştırıldığında özelliklerden çıkarılır. Kendinize bazı ayrıntılı kodlar yazmaktır. Ancak
yine de bir yere başlamanız gerekir. C#sürüm 1,0, Windows platformunda Java için önemli bir alternatiftir.
1,0 'nin C# önemli özellikleri dahildir:
Sınıflar
Yapılar
Arabirimler
Olaylar
Veri Erişimi
Temsilciler
İfadeler
Deyimler
Öznitelikler

C#sürüm 1,2
C#sürüm 1,2, Visual Studio .NET 2003 ile birlikte gönderilir. Dilde birkaç küçük geliştirmeler vardı. Çoğu önemli, bu
IEnumerator IDisposableuygulandığında IEnumerator Dispose olarak adlandırılan foreach döngüsünde
oluşturulan kod, bu sürüm ile başdır.

C#sürüm 2,0
Şimdi ilginç şeyler almaya başlamıştır. Visual Studio 2005 ile birlikte 2005 ' de yayınlanan bazı C# önemli 2,0
özelliklere göz atalım:
Genel Türler
Kısmi türler
Anonim Yöntemler
Null yapılabilir değer türleri
Yineleyiciler
Kovaryans ve değişken sapması
Diğer C# 2,0 özellikleri mevcut özelliklere özellikler eklemiştir:
Alıcı/ayarlayıcı ayrı erişilebilirlik
Yöntem grubu dönüştürmeleri (Temsilciler)
Statik sınıflar
Temsilci çıkarımı
C# Genel bir nesne YÖNELIMLI (OO ) dil olarak başlamışsa, sürüm 2,0, C# bir acelendeki olarak değiştirilmiştir.
Bunların altındaysa, önemli geliştirici sorun noktalarından sonra gitirler. Ve bunları önemli bir şekilde yaptıktan
sonra.
Genel türler ile türler ve Yöntemler, tür güvenliğini korurken rastgele bir tür üzerinde çalışabilir. Örneğin, bir
List<T> olması, List<string> veya List<int> sahip olmanızı ve bu dizelerde veya tamsayılarla tür kullanımı
güvenli işlemler gerçekleştirmenizi sağlar. Genel türleri kullanmak, her işlem için Object ArrayList veya kümeden
türetilen ListInt oluşturma işleminden daha iyidir.
C#sürüm 2,0, yineleyiciler tarafından getirildi. Yineleyiciler, succinctly almak için bir List (veya diğer sıralanabilir
türler) içindeki tüm öğeleri bir foreach döngüsüyle incelemenizi sağlar. Dilin birinci sınıf parçası olarak yineleyiciler
olması, dilin okunabilirliğini ve kişilerin kod hakkında neden olma yeteneğini önemli ölçüde geliştirmiştir.
Ancak, C# Java ile biraz catch oynamaya devam eder. Java, genel türler ve yineleyiciler içeren sürümleri zaten
yayımlamıştır. Ancak yakında gelişmeye devam eden diller olarak değişir.

C#sürüm 3,0
C#sürüm 3,0, Visual Studio 2008 ile birlikte 2007 geldi, ancak dil özelliklerinin tam bot 'ı .NET Framework sürüm
3,5 ile gelmiş olabilir. Bu sürüm, büyümesi için büyük bir değişiklik işaretledi C#. Gerçekten anlaşılabilir C#
programlama dili olarak oluşturulmuştur. Bu sürümdeki bazı önemli özelliklere göz atalım:
Otomatik uygulanan özellikler
Anonim türler
Sorgu ifadeleri
Lambda ifadeleri
İfade ağaçları
Uzantı yöntemleri
Örtük olarak yazılan yerel değişkenler
Kısmi Yöntemler
Nesne ve koleksiyon başlatıcıları
Geriye dönük olarak, bu özelliklerin çoğu hem kaçınılmazdır hem de ınseparablegörünmektedir. Hepsi stratejik
olarak bir araya gelerek. Genellikle C# sürümün Killer özelliğinin, dil Ile tümleşik sorgu (LINQ ) olarak da bilinen
sorgu ifadesi olması düşünüldük.
Daha fazla kızılmış bir görünüm, LINQ 'ın oluşturulduğu temel olarak ifade ağaçları, lambda ifadeleri ve anonim
türler inceler. Ancak her iki durumda da 3,0 C# , Devrim niteliğinde bir kavram olarak sunulur. C#3,0, bir karma
nesne odaklı/işlevsel dili açmak C# için ön hazırlıkları başlattık 'un düzenlenmesine başlamıştır.
Özellikle, koleksiyonlar üzerinde işlemler gerçekleştirmek için diğer şeyler arasında SQL stili, bildirime dayalı
sorgular yazabilirsiniz. Bir tamsayılar listesinin ortalamasını hesaplamak için for döngüsü yazmak yerine, bunu
list.Average() gibi yapabilirsiniz. Sorgu ifadelerinin ve genişletme yöntemlerinin birleşimi, tam olarak çok daha
akıllı bir şekilde kullanıma sunulacaktır.
İnsanların gerçekten bir kavram ve kavramı tümleştirmeleri için zaman sürdü, ancak bu, yavaş yavaş bir şekilde
yapılır. Şimdi, daha sonra kod daha kısa, basit ve işlevsel.

C#sürüm 4,0
C#Visual Studio 2010 ile yayınlanan sürüm 4,0, sürüm 3,0 çığır durumuna kadar zor bir zamana sahip olurdu.
Sürüm 3,0 ile, C# dili Java 'nın gölgimiyle ve belirgin bir şekilde daha sıkıca taşımıştı. Dil hızlı bir şekilde şık hale
geliyor.
Sonraki sürümde bazı ilginç yeni özellikler tanıtıldı:
Dinamik bağlama
Adlandırılmış/isteğe bağlı bağımsız değişkenler
Genel birlikte değişken ve değişken karşıtı
Gömülü birlikte çalışma türleri
Gömülü birlikte çalışma türleri bir dağıtım sorun alleviated. Genel Kovaryans ve değişken Varyans, genel türler
kullanmak için daha fazla güç sunar, ancak bu, büyük olasılıkla çerçeve ve kitaplık yazarları tarafından en çok
teşekkürler. Adlandırılmış ve isteğe bağlı parametreler birçok yöntem aşırı yüklemesini ortadan kaldırmanıza ve
kolaylık sağlamanıza olanak tanır. Ancak bu özelliklerden hiçbiri tam olarak paradigma değiştirme değildir.
Ana Özellik dynamic anahtar kelimesinin sunumiydi. C# Sürüm 4,0 ' de tanıtılan dynamic anahtar sözcüğü
derleme zamanı yazma sırasında derleyiciyi geçersiz kılabilme özelliği. Dinamik anahtar sözcüğünü kullanarak
JavaScript gibi dinamik olarak belirlenmiş dillere benzer yapılar oluşturabilirsiniz. Bir dynamic x = "a string"
oluşturup daha sonra ne olması gerektiğini sıralamak için onu çalışma zamanına bırakarak bu bir oluşturabilirsiniz.
Dinamik bağlama, hataları olası ve ayrıca dil dahilinde harika bir güç sağlar.

C#sürüm 5,0
C#Visual Studio 2012 ile yayınlanan sürüm 5,0, dilin odaklanmış bir sürümüdür. Bu sürüm için neredeyse tüm çaba
başka bir çığır dil kavramıyla karşılaştık: zaman uyumsuz programlama için async ve await modeli. Ana özellikler
listesi aşağıda verilmiştir:
Zaman uyumsuz Üyeler
Arayan bilgileri öznitelikleri
Ayrıca Bkz.
Kod projesi: 5,0 içinde C# çağıran bilgi öznitelikleri
Çağıran bilgileri özniteliği, bir çok ortak yansıma kodu için kod olmadan çalıştırdığınız bağlam hakkındaki bilgileri
kolayca almanızı sağlar. Tanılama ve günlüğe kaydetme görevlerinde birçok kullanımı vardır.
Ancak async ve await bu sürümün gerçek yıldızlardır. Bu özellikler 2012 ' de geldiğinde, C# ilk sınıf katılımcı
olarak dile zaman uyumlu hale getirerek oyunu yeniden değiştirdi. Uzun süre çalışan işlemlerle ve geri çağırmaların
Web 'leri uygulamasına sahip olduğunuzda, büyük olasılıkla bu dil özelliğini sevtiniz.

C#sürüm 6,0
3,0 ve 5,0 sürümleriyle, C# nesne yönelimli bir dile önemli yeni özellikler ekledik. Visual Studio 2015 ile yayınlanan
sürüm 6,0 ' de, baskın bir Killer özelliği yapmaktan sonra, daha üretken bir şekilde programlama yapan C# daha
küçük birçok özelliği serbest bırakacaktır. Bunlardan bazıları şunlardır:
Statik içeri aktarmalar
Özel durum filtreleri
Otomatik Özellik başlatıcıları
İfade gövdeli Üyeler
Null yayıcı
Dize ilişkilendirme
NameOf işleci
Dizin başlatıcıları
Diğer yeni özellikler şunlardır:
Catch/finally bloklarında await
Yalnızca alıcı özellikleri için varsayılan değerler
Bu özelliklerin her biri kendi sağında ilginç olur. Ancak bunları tamamen gözden geçirin, ilginç bir model
görürsünüz. Bu sürümde, C# kodu daha terse ve okunabilir hale getirmek için dilin ortak olduğunu ortadan
kaldırdık. Bu nedenle, temiz ve basit kod fanları için bu dil sürümü çok büyük bir kazanmıştı.
Bunlar, kendi kendine geleneksel bir dil özelliği olmasa da, bu sürümle birlikte başka bir şey gerçekleştirmektedir.
Hizmet olarak derleyicisiniserbest bırakılanlar. C# Derleyici artık ' de C#yazılmıştır ve bu derleyicisini programlama
çabalarınızın bir parçası olarak kullanabilirsiniz.

C#sürüm 7,0
En son ana sürüm, Visual C# Studio 2017 ile yayınlanan sürüm 7,0 ' dir. Bu sürümde, 6,0 ' de, ancak hizmet olarak
derleyici olmayan bir dizi C# ve seyrek şey vardır. Yeni özelliklerden bazıları şunlardır:
Out değişkenleri
Tanımlama grupları ve ayrıştırma
Desen eşleştirme
Yerel işlevler
Genişletilmiş ifade gövdeli Üyeler
Ref Yereller ve geri dönüşler
Dahil edilen diğer özellikler:
Atılanlar
İkili sabit değerler ve basamak ayırıcıları
Throw ifadeleri
Bu özelliklerin tümü, geliştiriciler için seyrek erişimli yeni özellikler sunar ve her zamankinden sonra bile temizleyici
kodu yazma fırsatına sahiptir. Vurgu, out anahtar sözcüğüyle birlikte kullanılacak değişkenlerin bildirimini ve kayıt
düzeni aracılığıyla birden çok dönüş değerine izin vererek bir vurgulanmasını sağlar.
Ancak C# , daha geniş bir kullanıma yerleştirmekte. .NET Core artık herhangi bir işletim sistemini hedeflemiştir ve
bu durumda, hem bulutta hem de taşınabilirlik konusunda gözleriniz vardır. Bu yeni özellikler, yeni özelliklerle
birlikte gelmenin yanı sıra dil tasarımcıları 'nın düşüncelerini ve zamanını tamamen kaplar.
İlk olarak_Nıdidıetrich ve Patrick Smacchia,_ nbağlı blog 'da yayımlanan Makale .
Dil özellikleri ve kitaplık türleri arasındaki ilişkileri
23.10.2019 • 3 minutes to read • Edit Online

C# Belirli türlerini ve belirli erişilebilir üyeler üzerinde bu türleri için standart bir kitaplığı dil tanımı gerektirir.
Derleyici için birçok farklı dil özelliklerini bu gerekli türleri ve üyeleri kullanan kod oluşturur. Gerektiğinde, burada
bu tür veya üyeler henüz dağıtılmamış ortamları için kod yazma, dil daha yeni sürümleri için gerekli türleri içeren
NuGet paketleri vardır.
Bu bağımlılık standart kitaplığı işlevlerini bir parçası olmuştur C# ilk sürümünden bu yana dili. Bu sürümde, dahil
edilen örnekler:
Exception -Tüm derleyicinin ürettiği özel durumlar için kullanılır.
String - C# string türüdür ilişkin bir eşanlam String.
Int32 -, eş anlamlı int .
Bu ilk sürüm basit: derleyici ve standart kitaplık birlikte birlikte ve her yalnızca bir sürümü vardı.
Sonraki sürümlerde C# bazen yeni türleri veya üyeleri için bağımlılıklar ekledik. Örnekler: INotifyCompletion,
CallerFilePathAttribute ve CallerMemberNameAttribute. C#7.0 devam bu bir bağımlılık ekleyerek ValueTuple
uygulamak için diziler dil özelliğidir.
Dil Tasarım ekibi, türler ve üyeler uyumlu standart kitaplığa gerekli'nın yüzey alanını en aza indirmek için çalışır. Bu
hedefe burada yeni kitaplık özellikleri diline sorunsuz bir şekilde eklenen temiz bir tasarıma karşı dengelenir.
Gelecekteki sürümlerinde yeni özellikler olacaktır C# yeni türler ve üyeler standart Kitaplığı'nda gerektirir. Bu
bağımlılıkları çalışmanızı yönetmek nasıl anlamak önemlidir.

Bağımlılıklarınızı yönetme
C#derleme araçları artık .NET kitaplıklarına desteklenen platformlarda sürüm döngüsü'nden birbirinden
ayrılmıştır. Aslında, farklı .NET kitaplıkları farklı yayın döngülerine sahiptir: .NET Core birlikte gelen ayrı bir
zamanlamaya ve kitaplık güncelleştirmeleri sevk her hedef platform için Xamarin araçları ile Xamarin sürümleri,
Windows üzerinde .NET Framework, bir Windows güncelleştirmesi yayımlanır.
Çoğu zaman, bu değişiklikler fark yoktur. Ancak, daha yeni bir sürümüyle .NET kitaplıkları gerektiren özellikleri
olmayan dil henüz bu platform üzerinde çalışırken, bu yeni türler sağlamak için NuGet paketlerini başvuru.
Uygulamanızın desteklediği yeni framework yüklemeleri ile güncelleştirilir platformu olarak ek başvuru
kaldırabilirsiniz.
Bu ayrım bile karşılık gelen framework olmayabilir makineler hedeflenirken yeni dil özellikleri kullanabileceğiniz
anlamına gelir.
C# geliştiricileri için sürüm ve güncelleştirme konuları
23.10.2019 • 3 minutes to read • Edit Online

C# dili için yeni özellikler eklendikçe uyumluluk çok önemli bir hedeftir. Hemen hemen tüm durumlarda, herhangi
bir sorun olmadan yeni bir derleyici sürümü ile mevcut kodu yeniden derlenmesi.
Yeni dil özellikleri bir kitaplıkta benimsediğinizde, daha fazla dikkat gerekli olabilir. Yeni bir kitaplık en yeni
sürümünde bulunan özellikler ile oluşturduğunuz ve derleyicinin önceki sürümleri kullanılarak oluşturulan
uygulamaları sağlamak için kullanabilmesi. Veya varolan bir kitaplığını yükseltme ve kullanıcılarınızın çoğu
sürümler henüz yükseltilmemiş. Yeni özellikler benimseme hakkında kararlar gibi uyumluluk iki çeşidi göz önünde
bulundurmanız gerekir: kaynak uyumlu ve uyumlu ikili.

İkili uyumlu değişiklikleri


Değişiklikler kitaplığınıza uyumlu ikili zaman güncelleştirilmiş kitaplığınızı kullanılabilir uygulamaları ve
kitaplıkları kullanan derlenmeden. Bağımlı derlemelerin yeniden oluşturulması için gerekli değildir ve herhangi bir
kaynak kod değişikliği gereklidir. İkili uyumlu değişiklikleri de kaynak uyumlu değişikliklerdir.

Kaynak uyumlu değişiklikleri


Değişiklikler kitaplığınıza kaynak uyumlu zaman uygulamaları ve kitaplıkları, kitaplığı kullanan kaynak kod
değişikliği gerektirmez, ancak kaynak düzgün çalışması için yeni sürümü karşı derlenmesi gerekiyor.

Uyumsuz değişiklikleri
Bir değişiklik ne ise kaynak uyumlu ya da uyumlu ikili, bağımlı kitaplıkları ve uygulamaları kaynak kodu
değişiklikleri birlikte yeniden derleme gereklidir.

Kitaplığınızı değerlendir
Bu uyumluluk kavramları için kendi iç uygulama kitaplığınızın ortak ve korunan bildirimleri etkiler. Herhangi bir
yeni özellik dahili olarak kullandığı her zaman uyumlu ikili.
İkili uyumlu değişiklikleri genel bildirimleri eski sözdizimi olarak aynı derlenmiş kodunu üretir yeni söz dizimi
sağlar. Örneğin, bir ifade gövdeli üyesine bir yöntemi değiştirme olduğu bir uyumlu ikili değiştirin:
Özgün kod:

public double CalculateSquare(double value)


{
return value * value;
}

Yeni kod:

public double CalculateSquare(double value) => value * value;

Kaynak uyumlu değişikliğine neden söz dizimi genel bir üyenin, ancak mevcut çağrı siteleri bir şekilde uyumlu
olarak derlenmiş kodunu değiştirir. Örneğin, bir yöntem imzasının değiştirilmesi bir değer parametresi tarafından
bir in başvuruya göre kaynak uyumlu parametredir, ancak ikili uyumlu:
Özgün kod:

public double CalculateSquare(double value) => value * value;

Yeni kod:

public double CalculateSquare(in double value) => value * value;

Yenilikler makaleleri ortak bildirimleri etkileyen bir özellik ile tanışın kaynak uyumlu ya da ikili uyumlu olup
olmadığını unutmayın.
Türler (C# Programlama Kılavuzu)
29.11.2019 • 19 minutes to read • Edit Online

Türler, değişkenler ve değerler


C#türü kesin belirlenmiş bir dildir. Her değişken ve sabitin, bir değeri değerlendiren her ifadeyi olduğu gibi bir türü
vardır. Her yöntem imzası her giriş parametresi ve dönüş değeri için bir tür belirtir. .NET sınıf kitaplığı, dosya
sistemi, ağ bağlantıları, koleksiyon ve nesne dizileri ve tarihler gibi çok çeşitli mantıksal yapıları temsil eden daha
karmaşık türler ve yerleşik sayısal türlerin bir kümesini tanımlar. Tipik C# bir program, sınıf kitaplığından türleri ve
programın sorunlu etki alanına özgü kavramları modelleyebilir Kullanıcı tanımlı türleri kullanır.
Bir tür içinde depolanan bilgiler şunları içerebilir:
Türün bir değişkeninin gerektirdiği depolama alanı.
Temsil ettiği maksimum ve en düşük değerler.
İçerdiği Üyeler (Yöntemler, alanlar, olaylar vb.).
Devraldığı temel tür.
Değişkenlere yönelik belleğin çalışma zamanında ayrılabileceği konum.
İzin verilen işlem türleri.
Derleyici, kodunuzda gerçekleştirilen tüm işlemlerin tür açısından güvenliolduğundan emin olmak için tür bilgilerini
kullanır. Örneğin, inttüründe bir değişken bildirirseniz, derleyici değişkeni toplama ve çıkarma işlemlerinde
kullanmanıza izin verir. Booltüründe bir değişkende aynı işlemleri gerçekleştirmeye çalışırsanız, derleyici aşağıdaki
örnekte gösterildiği gibi bir hata oluşturur:

int a = 5;
int b = a + 2; //OK

bool test = true;

// Error. Operator '+' cannot be applied to operands of type 'int' and 'bool'.
int c = a + test;

NOTE
C ve C++ geliştiricilerle, bool 'un C# int'e dönüştürülebilir olmadığına dikkat edin.

Derleyici, tür bilgilerini yürütülebilir dosyaya meta veriler olarak katıştırır. Ortak dil çalışma zamanı (CLR ), bellek
ayırdığı ve geri kazanır daha fazla güvence altına almak için çalışma zamanında bu meta verileri kullanır.
Değişken bildirimlerinde türleri belirtme
Bir programda bir değişken veya sabit belirttiğinizde, onun türünü belirtmeniz veya var anahtar sözcüğünü
kullanarak derleyicinin türü saymasına izin vermelisiniz. Aşağıdaki örnek, hem yerleşik sayısal türler hem de
Kullanıcı tanımlı karmaşık türler kullanan bazı değişken bildirimlerini gösterir:
// Declaration only:
float temperature;
string name;
MyClass myClass;

// Declaration with initializers (four examples):


char firstLetter = 'C';
var limit = 3;
int[] source = { 0, 1, 2, 3, 4, 5 };
var query = from item in source
where item <= limit
select item;

Yöntem parametrelerinin türleri ve dönüş değerleri Yöntem imzasında belirtilmiştir. Aşağıdaki imza, giriş bağımsız
değişkeni olarak bir int gerektiren ve bir dize döndüren bir yöntemi gösterir:

public string GetName(int ID)


{
if (ID < names.Length)
return names[ID];
else
return String.Empty;
}
private string[] names = { "Spencer", "Sally", "Doug" };

Bir değişken oluşturulduktan sonra, yeni bir türle yeniden bildirilemez ve belirtilen türle uyumlu olmayan bir değer
atanamaz. Örneğin, bir int bildiremez ve bunu bir true Boolean değeri atayabilirsiniz. Ancak, değerler başka türlere
dönüştürülebilir (örneğin, yeni değişkenlere atandığında veya yöntem bağımsız değişkenleri olarak geçirildiğinde).
Veri kaybına neden olmayan bir tür dönüştürmesi , derleyici tarafından otomatik olarak gerçekleştirilir. Veri kaybına
neden olabilecek bir dönüştürme, kaynak kodda bir tür dönüştürme gerektirir.
Daha fazla bilgi için bkz. atama ve tür dönüştürmeleri.

Yerleşik türler
C#tamsayılar, kayan nokta değerleri, Boole ifadeleri, metin karakterleri, ondalık değerler ve diğer veri türlerini
temsil etmek için standart bir yerleşik sayısal türler kümesi sağlar. Ayrıca, yerleşik string ve object türleri vardır.
Bunlar, herhangi bir C# programda kullanabilmeniz için kullanılabilir. Yerleşik türler hakkında daha fazla bilgi için
bkz. Yerleşik türler Için başvuru tabloları.

Özel türler
Kendi özel türlerinizi oluşturmak için struct, Class, Interfaceve enum yapılarını kullanırsınız. .NET sınıf kitaplığı,
Microsoft tarafından kendi uygulamalarınızda kullanabileceğiniz özel türlerin bir koleksiyonudur. Varsayılan olarak,
sınıf kitaplığındaki en sık kullanılan türler her C# programda kullanılabilir. Diğerleri yalnızca tanımlandıkları
derlemeye açıkça bir proje başvurusu eklediğinizde kullanılabilir hale gelir. Derleyicinin derlemeye bir başvurusu
olduktan sonra, kaynak kodda o derlemede belirtilen türlerin değişkenlerini (ve sabitleri) bildirebilirsiniz. Daha fazla
bilgi için bkz. .NET sınıf kitaplığı.

Ortak tür sistemi


.NET 'teki tür sistemi hakkında iki temel noktayı anlamak önemlidir:
Devralma ilkesini destekler. Türler, temel türlerolarak adlandırılan diğer türlerden türetilebilir. Türetilmiş tür,
yöntemleri, özellikleri ve temel türün diğer üyelerini devralır (bazı kısıtlamalarla). Temel tür başka bir türden
türetebilir, bu durumda türetilmiş tür, devralma hiyerarşisindeki her iki temel türün üyelerini devralır.
System.Int32 (C# anahtar sözcük: int) gibi yerleşik sayısal türler dahil olmak üzere tüm türler, sonunda
System.Object (C# anahtar sözcük: nesne) olan tek bir temel türden türetilir. Bu Birleşik tür hiyerarşisine
ortak tür sistemi (Cts) denir. ' De C#devralma hakkında daha fazla bilgi için bkz. Devralma.
CTS içindeki her tür, bir değer türü veya bir başvuru türüolarak tanımlanır. Bu, .NET sınıf kitaplığı 'ndaki tüm
özel türleri ve ayrıca kendi Kullanıcı tanımlı türlerinizi içerir. Struct anahtar sözcüğünü kullanarak
tanımladığınız türler değer türleridir; Tüm yerleşik sayısal türler structs . Sınıf anahtar sözcüğünü
kullanarak tanımladığınız türler başvuru türleridir. Başvuru türleri ve değer türlerinde farklı derleme zamanı
kuralları ve farklı çalışma zamanı davranışları vardır.
Aşağıdaki çizimde, CTS 'deki değer türleri ve başvuru türleri arasındaki ilişki gösterilmektedir.
Aşağıdaki görüntüde, CTS 'deki değer türleri ve başvuru türleri gösterilmektedir:

NOTE
En yaygın olarak kullanılan türlerin System ad alanında düzenlendiğini görebilirsiniz. Ancak, bir türün bulunduğu ad alanının,
bir değer türü veya başvuru türü olup olmadığı bir ilişkisi yoktur.

Değer türleri
Değer türleri, System.Objecttüretilen System.ValueTypetüretilir. System.ValueType türetilen türlerin CLR 'de özel
davranışı vardır. Değer türü değişkenleri doğrudan değerlerini içerir, bu da belleğin, değişkenin bildirildiği bağlamda
satır içi olarak ayrıldığı anlamına gelir. Değer türü değişkenler için ayrı bir yığın ayırma veya çöp toplama ek yükü
yoktur.
Değer türlerinin iki kategorisi vardır: struct ve enum.
Yerleşik sayısal türler yapı birimleridir ve erişebileceğiniz özelliklere ve yöntemlere sahiptirler:

// Static method on type byte.


byte b = byte.MaxValue;

Ancak bunları, basit olmayan türler gibi bu değerlere bildirir ve bunlara atanır:
byte num = 0xA;
int i = 5;
char c = 'Z';

Değer türleri korumalıdır, yani örneğin, bir türü System.Int32türetemezsiniz ve Kullanıcı tanımlı herhangi bir
sınıftan veya yapıdan devralacak bir struct tanımlayamazsınız, çünkü bir struct yalnızca
System.ValueTypedevralabilir. Ancak, bir struct bir veya daha fazla arabirim uygulayabilir. Yapı türünü, uygulayan
herhangi bir arabirim türüne çevirebilirsiniz; Bu, bir kutulama işleminin yapıyı yönetilen yığında bir başvuru türü
nesnesinin içine sarmasına neden olur. Kutulama işlemleri, bir System.Object veya herhangi bir arabirim türünü
giriş parametresi olarak alan bir yönteme bir değer türü geçirdiğinizde oluşur. Daha fazla bilgi için bkz. kutulama ve
kutudançıkarma.
Kendi özel değer türlerinizi oluşturmak için struct anahtar sözcüğünü kullanırsınız. Genellikle, bir yapı aşağıdaki
örnekte gösterildiği gibi küçük bir ilgili değişkenler kümesi için kapsayıcı olarak kullanılır:

public struct Coords


{
public int x, y;

public Coords(int p1, int p2)


{
x = p1;
y = p2;
}
}

Yapılar hakkında daha fazla bilgi için bkz. yapılar. .NET 'teki değer türleri hakkında daha fazla bilgi için bkz. değer
türleri.
Değer türlerinin diğer kategorisi sabit listesi' dir. Enum, adlandırılmış integral sabitleri kümesini tanımlar. Örneğin,
.NET sınıf kitaplığındaki System.IO.FileMode numaralandırması, bir dosyanın nasıl açılacağını belirten adlandırılmış
sabit tamsayılar kümesi içerir. Aşağıdaki örnekte gösterildiği gibi tanımlanmıştır:

public enum FileMode


{
CreateNew = 1,
Create = 2,
Open = 3,
OpenOrCreate = 4,
Truncate = 5,
Append = 6,
}

System.IO.FileMode.Create sabiti 2 değerine sahiptir. Ancak ad, kaynak kodu okuyan insanlar için çok daha anlamlı
olur ve bu nedenle sabit değişmez sayılar yerine Numaralandırmaların kullanılması daha iyidir. Daha fazla bilgi için
bkz. System.IO.FileMode.
Tüm numaralandırmalar System.ValueTypedevralan System.Enumdevralır. Yapılar için uygulanan tüm kurallar,
numaralandırmalar için de geçerlidir. Numaralandırmalar hakkında daha fazla bilgi için bkz. numaralandırma türleri.
Başvuru türleri
Class, Delegate, array veya Interface olarak tanımlanan bir tür, bir başvuru türüdür. Çalışma zamanında, bir başvuru
türünde bir değişken bildirdiğinizde, New işlecini kullanarak açıkça bir nesne oluşturana veya başka bir new yerde
oluşturulmuş bir nesne (örneğin, ' de gösterildiği gibi) Aşağıdaki örnek:
MyClass mc = new MyClass();
MyClass mc2 = mc;

Bir arabirim, kendisini uygulayan bir sınıf nesnesiyle birlikte başlatılmalıdır. MyClass IMyInterface uygularsa,
aşağıdaki örnekte gösterildiği gibi bir IMyInterface örneği oluşturursunuz:

IMyInterface iface = new MyClass();

Nesne oluşturulduğunda, bellek yönetilen yığında ayrılır ve değişken yalnızca nesnenin konumuna bir başvuru
içerir. Yönetilen yığında bulunan türler, her ikisi de ayrıldıklarında ve çöp toplamaolarak bilinen clr 'nin otomatik
bellek yönetimi işlevselliği tarafından geri kazanıyorsa ek yük gerektirir. Ancak çöp toplama da yüksek oranda
iyileştirilmiştir ve çoğu senaryoda bir performans sorunu oluşturmaz. Çöp toplama hakkında daha fazla bilgi için
bkz. Otomatik bellek yönetimi.
Tüm diziler, öğeleri değer türleri olsa bile başvuru türlerdir.Diziler, System.Array sınıfından dolaylı olarak türetilir,
ancak aşağıdaki örnekte gösterildiği gibi bunları tarafından C#verilen Basitleştirilmiş sözdizimi ile bildirir ve
kullanabilirsiniz:

// Declare and initialize an array of integers.


int[] nums = { 1, 2, 3, 4, 5 };

// Access an instance property of System.Array.


int len = nums.Length;

Başvuru türleri devralmayı tamamen destekler. Bir sınıf oluşturduğunuzda, korumalıolarak tanımlanmayan diğer bir
arabirim veya sınıftan kalıtımla alabilir ve diğer sınıflar sınıfınızdan devralınabilir ve sanal yöntemlerinizi geçersiz
kılabilir. Kendi sınıflarınızı oluşturma hakkında daha fazla bilgi için bkz. sınıflar ve yapılar. Devralma ve sanal
yöntemler hakkında daha fazla bilgi için bkz. Devralma.

Değişmez değer türleri


' C#De, değişmez değerler derleyicisinden bir tür alır. Sayının sonuna bir harf ekleyerek sayısal bir sabit değerin
nasıl yazılması gerektiğini belirtebilirsiniz. Örneğin, 4,56 değerinin bir float olarak değerlendirilip
değerlendirilmeyeceğini belirtmek için, sayının sonuna bir "f" veya "F" ekleyin: 4.56f . Hiçbir harf eklenyoksa,
derleyici değişmez değer için bir tür çıkarması olur. Hangi türlerin harf sonekleriyle belirtibileceği hakkında daha
fazla bilgi için bkz. değer türlerindebağımsız türler için başvuru sayfaları.
Değişmez değerler yazıldığı ve tüm türler System.Objectsonunda sonuç olarak türettiğinden, aşağıdaki gibi bir kod
yazabilir ve derleyebilirsiniz:

string s = "The answer is " + 5.ToString();


// Outputs: "The answer is 5"
Console.WriteLine(s);

Type type = 12345.GetType();


// Outputs: "System.Int32"
Console.WriteLine(type);

Genel türler
Bir tür, istemci kodunun türün bir örneğini oluşturduğunda sağladığı gerçek tür ( somut tür) için yer tutucu olarak
görev yapan bir veya daha fazla tür parametresiyle bildirilemez. Bu tür türler Genel türlerolarak adlandırılır.
Örneğin, System.Collections.Generic.List<T> .NET türü, kuralına göre bir tür parametresine sahiptir. Türün bir
örneğini oluşturduğunuzda, listenin içereceği nesnelerin türünü (örneğin, dize) belirtirsiniz:

List<string> stringList = new List<string>();


stringList.Add("String example");
// compile time error adding a type other than a string:
stringList.Add(4);

Tür parametresinin kullanımı, her öğeyi nesneyedönüştürmek zorunda kalmadan her türlü öğe türünü tutmak için
aynı sınıfı yeniden kullanmayı mümkün kılar. Derleyici, koleksiyon öğelerinin belirli türünü bildiğinden ve derleme
zamanında bir hata tetikleyebildiğinden, genel koleksiyon sınıfları kesin türü belirtilmiş koleksiyonlar olarak
adlandırılır. stringList Örneğin, önceki örnek. Daha fazla bilgi için bkz. Genel türler.

Örtük türler, anonim türler ve null yapılabilir değer türleri


Daha önce belirtildiği gibi, var anahtar sözcüğünü kullanarak yerel bir değişkeni (sınıf üyelerini değil) örtük olarak
yazabilirsiniz. Değişken hala derleme zamanında bir tür alır, ancak tür derleyici tarafından sağlanır.Daha fazla bilgi
için bkz. örtülü olarak yazılan yerel değişkenler.
Bazı durumlarda, yöntem sınırlarını depolamayı veya geçişi istemediğiniz ilgili değerlerin basit kümeleri için
adlandırılmış bir tür oluşturmak uygun değildir. Bu amaçla anonim türler oluşturabilirsiniz. Daha fazla bilgi için bkz.
anonim türler.
Sıradan değer türlerinin değeri nullolamaz. Ancak, türden sonra bir ? ekleyerek null yapılabilir değer türleri
oluşturabilirsiniz. Örneğin int? , nulldeğeri de olan bir int türüdür. Null yapılabilir değer türleri
System.Nullable<T>genel yapı türü örnekleridir. Null olabilen değer türleri, genellikle sayısal değerlerin null
olabileceği veritabanlarına ve veritabanlarından veri geçirirken faydalıdır. Daha fazla bilgi için bkz. Nullable değer
türleri.

İlgili bölümler
Daha fazla bilgi için aşağıdaki konulara bakın:
Tür Değiştirme ve Tür Dönüştürmeler
Kutulama ve Kutudan Çıkarma
Tür dinamiği kullanma
Değer Türleri
Başvuru Türleri
Sınıflar ve Yapılar
Anonim Tipler
Genel Türler

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir kaynaktır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
XML Veri Türlerini Dönüştürme
Integral türleri
Boş değer atanabilir başvuru türleri
8.11.2019 • 12 minutes to read • Edit Online

C#8,0, başvuru türü değişkenlerinin özellikleri hakkında önemli deyimler etkinleştirmenizi sağlayan null
yapılabilir başvuru türleri ve null yapılamayan başvuru türleri tanıtır:
Başvurunun null olması gerekir. Değişkenlerin null olması beklenen durumlarda derleyici, bu değişkenlerin
null olmadığını denetlemeden önce bu değişkenlere başvurmasının güvenli olmasını sağlayan kuralları zorlar:
Değişken null olmayan bir değere başlatılmalıdır.
Değişkene hiçbir şekilde null değeri atanamaz.
Başvuru null olabilir. Değişkenler null olabilir, derleyici null bir başvuruyu doğru bir şekilde kontrol
aldığınızdan emin olmak için farklı kurallar uygular:
Değişken yalnızca derleyici değerin null olmadığını garanti edemediğinde başvuru yapılabilir.
Bu değişkenler varsayılan null değeri ile başlatılabilir ve diğer kodda null değeri atanabilir.
Bu yeni özellik, tasarım amacını değişken bildiriminden belirlenemediği önceki sürümlerde C# başvuru
değişkenlerinin işlenmesine göre önemli avantajlar sağlar. Derleyici, başvuru türleri için null başvuru özel
durumlarına karşı güvenlik sağlamadı:
Başvuru nullolabilir. Bir başvuru türü null olarak başlatıldığında veya daha sonra null değeri atandığında
hiçbir uyarı verilmez.
Başvurunun null olmadığı varsayılır. Başvuru türleri başvurulduğunu derleyici hiçbir uyarı vermez. (Null
olabilen başvurular sayesinde, null olabilen bir değişkene başvuru yaptığınızda Derleyici uyarıları yayınlar).
Null yapılabilir başvuru türleri eklenmesiyle, amacınızı daha net bir şekilde bildirebilirsiniz. null değeri, bir
değişkenin bir değere başvurmadığından emin olmanın doğru yoludur. Bu özelliği, tüm null değerlerini
kodınızdan kaldırmak için kullanmayın. Bunun yerine, amacınızı derleyiciye ve kodunuzu okuyan diğer
geliştiricilere bildirmeniz gerekir. Amacınızı bildirerek, derleyici bu amaca tutarsız bir kod yazdığınızda size
bildirir.
Null yapılabilir bir başvuru türü , null yapılabilir değer türleriyleaynı söz dizimi kullanılarak belirtilmiştir:
değişkenin türüne bir ? eklenir. Örneğin, aşağıdaki değişken bildirimi null olabilen bir dize değişkenini temsil
eder, name :

string? name;

? tür adına eklenmemiş olan herhangi bir değişken null yapılamayan bir başvuru türüdür. Bu özellik, bu
özelliği etkinleştirdiğinizde var olan koddaki tüm başvuru türü değişkenlerini içerir.
Derleyici, null olabilen bir başvurunun boş olmayan olarak bilinmesinin bilinmediğini anlamak için statik analizi
kullanır. Null olduğunda, null olabilen bir başvuruya başvuru yaptığınızda derleyici sizi uyarır. Bir değişken
adından sonra, ! null-forverme işlecini kullanarak bu davranışı geçersiz kılabilirsiniz. Örneğin, name değişkeni
null olmadığını, ancak derleyici bir uyarı verir, derleyicinin analizini geçersiz kılmak için aşağıdaki kodu
yazabilirsiniz:

name!.Length;

Türlerin null olabilme sayısı


Herhangi bir başvuru türü, uyarıların ne zaman oluşturulacağını açıklayan dört adet nulldeğer içerebilir:
Null atanabilir olmayan: null bu türdeki değişkenlere atanamaz. Bu tür değişkenlerin, başvuru yapılmadan
önce null olarak işaretli olması gerekmez.
Nullable: null, bu türdeki değişkenlere atanabilir. Bu türdeki değişkenlerin başvurusunun kaldırılması, önce
null denetlenmeksizin bir uyarıya neden olur.
Zorunluluvou: bu,C# 8,0 öncesi durumundadır. Bu tür değişkenlere başvuru yapılmadan başvuru yapılabilir
veya atanabilir.
Bilinmiyor: Bu, genellikle kısıtlamaların, türün null yapılabilir veya null değeratanabilir olması gerektiğini
bildirmeyecek tür parametreleri içindir.
Değişken bildirimindeki bir türün null olabilme değeri, değişkenin bildirildiği null yapılabilir bağlam tarafından
denetlenir.

Null yapılabilir bağlamlar


Null yapılabilir bağlamlar, derleyicinin başvuru türü değişkenlerini nasıl yorumlayacağını öğrenmek için ayrıntılı
denetimi etkinleştirir. Belirli bir kaynak çizginin null yapılabilir ek açıklama bağlamı etkin veya devre dışı.
ÖncedenC# 8,0 derleyicisini, tüm kodunuzu devre dışı bırakılmış bir null yapılabilir bağlamda derleme olarak
düşünebilirsiniz: herhangi bir başvuru türü null olabilir. Null yapılabilir uyarılar bağlamı da etkinleştirilebilir
veya devre dışı bırakılabilir. Null yapılabilir uyarılar bağlamı, akış analizini kullanarak derleyici tarafından
oluşturulan uyarıları belirtir.
. Csproj dosyanızdaki Nullable öğesi kullanılarak bir proje için Nullable ek açıklama bağlamı ve null yapılabilir
uyarı bağlamı ayarlanabilir. Bu öğe, derleyicinin türlerin null olduğunu ve hangi uyarıların oluşturulduğunu nasıl
yorumlayacağını yapılandırır. Geçerli ayarlar şunlardır:
enable : null yapılabilir ek açıklama bağlamı etkindir. Null yapılabilir uyarı bağlamı etkin.
Örneğin, string olan bir başvuru türü değişkenleri null değer atanamaz. Tüm null değer alabilirlik
uyarıları etkin.
warnings : Nullable ek açıklama bağlamı devre dışı. Null yapılabilir uyarı bağlamı etkin.
Bir başvuru türü değişkenleri, zorunluluvou. Tüm null değer alabilirlik uyarıları etkin.
annotations : null yapılabilir ek açıklama bağlamı etkindir. Null yapılabilir uyarı bağlamı devre dışı.
Bir başvuru türü değişkenleri, örneğin dizesi null değer atanamaz. Tüm null değer alabilirlik uyarıları
devre dışı bırakıldı.
disable : Nullable ek açıklama bağlamı devre dışı. Null yapılabilir uyarı bağlamı devre dışı.
Başvuru türündeki değişkenler, daha önceki sürümlerinde olduğu gibi, zorunluluvou 'lardır C#. Tüm
null değer alabilirlik uyarıları devre dışı bırakıldı.
Örnek:

<Nullable>enable</Nullable>

Ayrıca, aynı bağlamlarını projenizde her yerde ayarlamak için yönergeleri de kullanabilirsiniz:
#nullable enable : null yapılabilir ek açıklama bağlamını ve null yapılabilir uyarı bağlamını etkinolarak
ayarlar.
#nullable disable : null yapılabilir ek açıklama bağlamını ve null yapılabilir uyarı bağlamını devre dışıolarak
ayarlar.
#nullable restore : null yapılabilir ek açıklama bağlamını ve null yapılabilir uyarı bağlamını proje ayarlarına
geri yükler.
#nullable disable warnings : null yapılabilir uyarı bağlamını devre dışıolarak ayarlayın.
#nullable enable warnings : null yapılabilir uyarı bağlamını etkinolarak ayarlayın.
#nullable restore warnings : proje ayarlarına Nullable uyarı bağlamını geri yükler.
#nullable disable annotations : null yapılabilir ek açıklama bağlamını devre dışıolarak ayarlayın.
#nullable enable annotations : null yapılabilir ek açıklama bağlamını etkinolarak ayarlayın.
#nullable restore annotations : ek açıklama uyarı bağlamını proje ayarlarına geri yükler.

Varsayılan olarak, null yapılabilir ek açıklama ve uyarı bağlamları devre dışıdır. Bu, mevcut kodunuzun değişiklik
yapılmadan ve yeni bir uyarı oluşturmadan derlendiğini gösterir.

Null yapılabilir ek açıklama bağlamı


Derleyici, devre dışı bırakılmış bir null yapılabilir ek açıklama bağlamında aşağıdaki kuralları kullanır:
Etkin olamayan başvuruları devre dışı bir bağlamda bildiremezsiniz.
Tüm başvuru değişkenleri null 'a atanabilir.
Başvuru türü değişkenine başvurulduğunu bir uyarı oluşturulmaz.
Null-forverme işleci devre dışı bir bağlamda kullanılamaz.
Davranışı önceki sürümleriyle aynıdır C#.
Derleyici, etkinleştirilmiş bir null yapılabilir ek açıklama bağlamında aşağıdaki kuralları kullanır:
Başvuru türündeki herhangi bir değişken null atanamaz bir başvurudur.
Null olamayan herhangi bir başvuruya, güvenli bir şekilde başvurulmalıdır.
Herhangi bir null yapılabilir başvuru türü (değişken bildiriminde bulunan türden sonra ? tarafından
belirtilen) null olabilir. Statik analiz, başvurunun başvurulduğunu null dışında bir değer olarak bilinmeyeceğini
belirler. Aksi takdirde, derleyici sizi uyarır.
Null yapılabilir bir başvurunun null olmadığını bildirmek için null-forverme işlecini kullanabilirsiniz.
Etkin bir null yapılabilir ek açıklama bağlamında, bir başvuru türüne eklenen ? karakteri null olabilen bir
başvuru türübildirir. İfadenin null olmadığını bildirmek için ! null-forverme işleci bir ifadeye eklenebilir.

Null yapılabilir uyarı bağlamı


Null yapılabilir uyarı bağlamı null yapılabilir ek açıklama bağlamından farklıdır. Yeni ek açıklamalar devre dışı
bırakıldığında bile uyarılar etkinleştirilebilir. Derleyici, herhangi bir başvurunun null durumunu belirlemede
statik akış analizini kullanır. Null yapılabilir uyarı bağlamı devre dışı bırakılmadıysanull durumu null ya da
null olabilir . Derleyici nullolduğunu tespit ettiğinizde bir başvuruya başvuru yaparsanız, derleyici sizi uyarır.
Derleyici iki koşuldan birini belirleyemediği takdirde başvurunun durumu null olabilir :
1. Değişken, null olmayan bir değere kesin olarak atandı.
2. Değişken veya ifade, kendisine başvurulmadan önce null değere karşı denetlendi.
Null yapılabilir uyarı bağlamı etkin olduğunda, derleyici bir değişken veya ifadeye, belki de null bir durumda
her başvuru yaptığınızda uyarılar oluşturur. Ayrıca, null olabilen bir tür veya ifade, etkin bir Nullable ek açıklama
bağlamında null yapılamayan bir başvuru türüne atandığında uyarılar oluşturulur.

Ayrıca bkz.
Taslak Nullable başvuru türleri belirtimi
Null yapılabilir başvurular öğreticisine giriş
Var olan bir kod temelinin Nullable başvurulara geçirilmesi
Kitaplıkları null yapılabilir başvuru türleri kullanacak
şekilde güncelleştirme ve arayanlara null olabilecek
kuralları iletişim kurma
27.11.2019 • 30 minutes to read • Edit Online

Null yapılabilir başvuru türlerinin eklenmesi, her değişken için null bir değere izin verilip verilmeyeceğini veya
beklenmediğini bildirebilmeniz anlamına gelir. Ayrıca, bağımsız değişkenin ve dönüş değerlerinin null durumlarını
tamamen anlatmak için AllowNull , DisallowNull , MaybeNull , NotNull , NotNullWhen , MaybeNullWhen ve
NotNullWhenNotNull gibi çeşitli öznitelikler de uygulayabilirsiniz. Bu, kod yazarken harika bir deneyim sağlar. Null
atanabilir olmayan bir değişken null olarak ayarlanmayabilir, uyarılar alırsınız. Nullable bir değişken, başvuru
yapılmadan önce null olarak işaretli değilse uyarılar alırsınız. Kitaplıklarınızın güncelleştirilmesi zaman alabilir,
ancak ödeme bu duruma göre yapılır. null değere izin verildiğinde ya da yasaklanmış olduğunda derleyiciye daha
fazla bilgi SAĞLARSANıZ, API 'nizin kullanıcıları daha iyi uyarıları alır. Tanıdık bir örnekle başlayalım. Kitaplığınızın
bir kaynak dizesini almak için aşağıdaki API 'ye sahip olduğunu düşünün:

bool TryGetMessage(string key, out string message)

Yukarıdaki örnek, .NET 'teki tanıdık Try* modelini izler. Bu API için iki başvuru bağımsız değişkeni vardır: key ve
message parametresi. Bu API, bu bağımsız değişkenlerin nulldurumuyla ilgili aşağıdaki kurallara sahiptir:

Çağıranlar, keybağımsız değişkeni olarak null iletmemelidir.


Çağıranlar, message bağımsız değişkeni olarak null değeri olan bir değişken geçirebilir.
TryGetMessage yöntemi true döndürürse message değeri null değildir. Dönüş değeri false, message değeri
(ve null durumu) null ise.

key kuralı, değişken türü ile tamamen ifade edilebilir: key null yapılamayan bir başvuru türü olmalıdır. message
parametresi daha karmaşıktır. Bağımsız değişken olarak null izin verir, ancak başarıyı, out bağımsız değişkeninin
null olmadığını garanti eder. Bu senaryolar için beklentileri betimleyen daha zengin bir sözlük gerekir.
Boş değer atanabilir başvurular için kitaplığınızın güncelleştirilmesi, bazı değişkenlerde ve tür adlarından daha fazla
Sprink ? gerektirir. Yukarıdaki örnek, API 'lerinizi incelemeniz ve her giriş bağımsız değişkeni için beklentilerinizi
göz önünde bulundurmanız gerektiğini gösterir. Dönüş değeri için garantiler ve yöntemin dönüşi üzerinde
herhangi bir out veya ref bağımsız değişkeni göz önünde bulundurun. Sonra bu kuralları derleyiciye iletmeyin
ve bu kurallar tarafından çağıranlar olmadığında Derleyici uyarılar sağlar.
Bu iş zaman alır. Diğer gereksinimleri ve teslim edilebilirleri dengelarken, kitaplığınızı veya uygulamanızı null
yapılabilir hale getirme stratejileriyle başlayalım. Devam eden geliştirmeyi nasıl dengeleyebilirsiniz, null yapılabilir
başvuru türleri etkinleştiriliyor. Genel tür tanımları için zorluk öğrenirsiniz. Tek tek API 'lerde ön ve son koşulları
betimleyen öznitelikler uygulamayı öğreneceksiniz.

Null yapılabilir bir strateji seçin


İlk seçenek, null yapılabilir başvuru türlerinin varsayılan olarak açık veya kapalı olması gerekip gerekmediğini
belirtir. İki stratejileriniz vardır:
Tüm proje için null yapılabilir başvuru türlerini etkinleştirin ve devre dışı olan kodda devre dışı bırakın.
Yalnızca Nullable başvuru türleri için açıklama eklenmiş kod için null yapılabilir başvuru türlerini etkinleştirin.
İlk strateji, null yapılabilir başvuru türleri için güncelleştirdiğinizde, kitaplığa başka özellikler eklerken en iyi şekilde
kullanılır. Tüm yeni geliştirmeler null yapılabilir. Mevcut kodu güncelleştirdiğinizde bu sınıflarda null yapılabilir
başvuru türlerini etkinleştirirsiniz.
Bu ilk stratejiyi izleyerek şunları yapın:
1. Csproj dosyalarınıza <Nullable>enable</Nullable> öğesini ekleyerek projenin tamamına ait null yapılabilir
türleri etkinleştirin.
2. #nullable disable pragma öğesini projenizdeki her kaynak dosyaya ekleyin.
3. Her dosya üzerinde çalışırken, pragmayı kaldırın ve tüm uyarıları çözün.
Bu ilk stratejide, her dosyaya pragma eklemek için daha fazla yukarı iş vardır. Avantajı, projeye eklenen her yeni kod
dosyasının null yapılabilir olmasını sağlar. Herhangi bir yeni iş, null yapılabilir. yalnızca var olan kodun
güncellenmesi gerekiyor.
İkinci strateji, kitaplığın genellikle kararlı olması ve geliştirmenin ana odağının null yapılabilir başvuru türlerini
benimsemeniz durumunda daha iyi bir şekilde çalışacaktır. API 'Leri not yazarken null yapılabilir başvuru türlerini
açabilirsiniz. İşiniz bittiğinde, tüm proje için null yapılabilir başvuru türlerini etkinleştirirsiniz.
Bu ikinci stratejiyi izleyerek şunları yapın:
1. #nullable enable pragma 'ı, null yapılabilir yapmak istediğiniz dosyaya ekleyin.
2. Tüm uyarıları çözün.
3. Tüm kitaplığı null yapılabilir olarak farkında olana kadar bu ilk iki adıma devam edin.
4. Csproj dosyalarınıza <Nullable>enable</Nullable> öğesini ekleyerek projenin tamamına ait null yapılabilir
türleri etkinleştirin.
5. Artık gerekli olmadığı için #nullable enable pragmaları kaldırın.
Bu ikinci stratejinin daha az iş ön ucu vardır. Zorunluluğunu getirir, yeni bir dosya oluşturduğunuz ilk görevin
pragmasını eklemek ve null yapılabilir olduğunu fark edevidir. Takımınızdaki herhangi bir geliştirici unutur, bu yeni
kod artık tüm kod Nullable olarak uyumlu hale getirmek için iş kapsamındedir.
Seçtiğiniz bu Stratejiler, projenizde ne kadar etkin geliştirme gerçekleştireceğinize bağlıdır. Projeniz ne kadar fazla
olgun ve kararlı, ikinci strateji daha iyidir. Daha fazla geliştirmekte olan özellikler, ilk strateji daha iyidir.

Null yapılabilir uyarılar, son değişiklikleri mi göstermelidir?


Null yapılabilir başvuru türlerini etkinleştirmeden önce, değişkenler null yapılabilir zorunluluvouolarak
değerlendirilir. Null yapılabilir başvuru türlerini etkinleştirdikten sonra, bu değişkenlerin hepsi null değer
atanamaz. Bu değişkenler null olmayan değerlere başlatılamıyorsa, derleyici uyarılar verebilir.
Büyük olasılıkla başka bir uyarı kaynağı, değer başlatılmamış olduğunda değerler döndürür.
Derleyici uyarılarını adresleyen ilk adım, parametre üzerinde ? ek açıklamaları ve bağımsız değişkenlerin veya
dönüş değerlerinin null olabileceğini göstermek için dönüş türlerini kullanmaktır. Başvuru değişkenleri null
olmamalı, özgün bildirim doğru olur. Bunu yaparken hedefiniz yalnızca uyarıları düzeltemedi. Daha önemli hedef,
derleyicinin olası null değerler için amacınızı anlaması sağlamaktır. Uyarıları incelerken, kitaplığınız için bir sonraki
önemli kararına ulaşabilirsiniz. Tasarım amacınızı daha net bir şekilde iletmek için API imzalarını değiştirmeyi
düşünmek istiyor musunuz? Daha önce incelenen TryGetMessage yöntemi için daha iyi bir API imzası şu olabilir:

string? TryGetMessage(string key);

Dönüş değeri başarılı veya başarısız olduğunu gösterir ve değer bulunursa değeri taşır. Çoğu durumda, API
imzalarını değiştirmek, null değerleri nasıl ilettikleri iyileştirebilirler.
Ancak, genel kitaplıklar veya büyük Kullanıcı temellerine sahip kitaplıklar için herhangi bir API imza değişikliğine
giriş yapmayı tercih edebilirsiniz. Bu durumlar ve diğer yaygın desenler için, bir bağımsız değişken veya dönüş
değeri null olduğunda daha net bir şekilde tanımlanacak öznitelikler uygulayabilirsiniz. API 'nizin yüzeyini
değiştirmeyi göz önünde bulundurmayın, büyük olasılıkla tür ek açıklamalarını bağımsız değişkenler veya dönüş
değerleri için null değerleri tanımlamak için yeterli değildir. Bu örneklerde, bir API 'yi daha net bir şekilde
anlatmak için öznitelikler uygulayabilirsiniz.

Öznitelikler tür ek açıklamalarını Genişlet


Değişkenlerin null durumu hakkında ek bilgileri ifade etmek için çeşitli öznitelikler eklenmiştir. 8 ' den önce C#
yazdığınız tüm kod null yapılabilir başvuru türleri olarak null zorunluluvouidi. Yani herhangi bir başvuru türü
değişkeni null olabilir, ancak null denetimleri gerekli değildir. Kodunuz Nullable olarak farkındaolduktan sonra bu
kurallar değişir. Başvuru türleri asla null değer olmamalı ve null yapılabilir başvuru türleri başvurulmadan önce
null karşı denetlenmelidir.

API 'nizin kuralları TryGetValue API senaryosuyla gördüğünüz gibi büyük olasılıkla daha karmaşıktır. Birçok API
'niz, değişkenlerin null veya ne zaman oluşturulabileceğine ilişkin daha karmaşık kurallara sahiptir. Bu
durumlarda, bu kuralları ifade etmek için aşağıdaki özniteliklerden birini kullanacaksınız:
AllowNull: null yapılamayan bir giriş bağımsız değişkeni null olabilir.
Disallownull: null olabilen bir giriş bağımsız değişkeni hiçbir şekilde null olmamalıdır.
MaybeNull: null yapılamayan bir dönüş değeri null olabilir.
NotNull: null olabilen bir dönüş değeri hiçbir şekilde null olmaz.
MaybeNullWhen: yöntem belirtilen bool değerini döndürdüğünde null yapılamayan bir giriş bağımsız
değişkeni null olabilir.
Notnullne zaman: yöntem belirtilen bool değerini döndürdüğünde null olabilen bir giriş bağımsız değişkeni
null olmaz.
Notnullifnotnull: belirtilen parametrenin bağımsız değişkeni null değilse, dönüş değeri null olamaz.
Yukarıdaki açıklamalar, her bir özniteliğin yaptığı işe yönelik hızlı bir başvurudur.Aşağıdaki her bölümde davranışı
ve anlamı daha kapsamlı bir şekilde açıklanmıştır.
Bu özniteliklerin eklenmesi, derleyiciye API 'nizin kuralları hakkında daha fazla bilgi verir. Kodu çağırma özelliği,
null yapılabilir etkin bir bağlamda derlenirse, derleyici bu kuralları ihlal ettiklerinde çağıranları uyarır. Bu öznitelikler,
uygulamanızda ek denetimleri etkinleştirmez.

Önkoşulları belirtin: AllowNull ve DisallowNull


Makul bir varsayılan değere sahip olduğu için hiçbir süre null döndürmediği bir okuma/yazma özelliği düşünün.
Çağıranlar, bu varsayılan değere ayarlarken ayarlanan erişimciye null geçer. Örneğin, bir sohbet odasında ekran
adı isteyen bir mesajlaşma sistemi düşünün. Hiçbiri sağlanmazsa, sistem rastgele bir ad üretir:

public string ScreenName


{
get => screenName;
set => screenName = value ?? GenerateRandomScreenName();
}
private string screenName;

Önceki kodu null olabilir bir zorunluluvou bağlamında derlerken her şey iyidir. Null yapılabilir başvuru türlerini
etkinleştirdikten sonra, ScreenName özelliği null yapılamayan bir başvuru haline gelir. Bu, get erişimcisi için
doğrudur: hiçbir süre null döndürmez. Çağıranlar null için döndürülen özelliği denetmek zorunda değildir.
Ancak şimdi özelliği null olarak ayarlamak bir uyarı oluşturur. Bu tür bir kodu desteklemeye devam etmek için,
aşağıdaki kodda gösterildiği gibi, System.Diagnostics.CodeAnalysis.AllowNullAttribute özniteliğini özelliğine
eklersiniz:

[AllowNull]
public string ScreenName
{
get => screenName;
set => screenName = value ?? GenerateRandomScreenName();
}
private string screenName = GenerateRandomScreenName();

Bu makalede açıklanan bu ve diğer öznitelikleri kullanmak için System.Diagnostics.CodeAnalysis için bir using
yönergesi eklemeniz gerekebilir. Özniteliği, set erişimcisine değil, özelliğine uygulanır. AllowNull özniteliği ön
koşullarıbelirtir ve yalnızca girişler için geçerlidir. get erişimcisinin dönüş değeri var, ancak giriş bağımsız
değişkeni yok. Bu nedenle AllowNull özniteliği yalnızca set erişimcisi için geçerlidir.
Yukarıdaki örnekte, bir bağımsız değişkende AllowNull özniteliği eklenirken ne aranacağı gösterilmektedir:
1. Bu değişken için genel sözleşme, null olmaması ve null yapılamayan bir başvuru türü istemeniz gerekir.
2. Giriş değişkeninin null olması, en sık kullanılan kullanımlar olmasa da senaryolar vardır.
Çoğu kez bu özniteliğe özellikler veya in , out ve ref bağımsız değişkenleri için ihtiyaç duyarsınız. AllowNull
özniteliği, genellikle null olmayan bir değişken olduğunda en iyi seçenektir, ancak önkoşul olarak null izin
vermeniz gerekir.
DisallowNull kullanmaya yönelik senaryolar ile karşıtlık: Bu özniteliği, null yapılabilir bir türdeki bir giriş
değişkeninin null olmaması gerektiğini belirtmek için kullanırsınız. null varsayılan değer olduğu ancak
istemciler yalnızca null olmayan bir değere ayarlayabileceği bir özelliği düşünün. Aşağıdaki kodu göz önünde
bulundurun:

public string ReviewComment


{
get => _comment;
set => _comment = value ?? throw new ArgumentNullException(nameof(value), "Cannot set to null");
}
string _comment;

Yukarıdaki kod, tasarımınızı ReviewComment null , ancak null olarak ayarlayabilmenin en iyi yoludur. Bu kod null
yapılabilir olduğunda, bu kavramı System.Diagnostics.CodeAnalysis.DisallowNullAttributekullanarak çağıranlara
daha net bir şekilde ifade edebilirsiniz:

[DisallowNull]
public string? ReviewComment
{
get => _comment;
set => _comment = value ?? throw new ArgumentNullException(nameof(value), "Cannot set to null");
}
string? _comment;

Null yapılabilir bir bağlamda, ReviewComment get erişimcisi null varsayılan değerini döndürebilir. Derleyici, erişim
öncesinde denetlenmesi gerektiğini uyarır. Ayrıca, arayanlara, null gibi görünse de, çağıranlar açıkça null olarak
ayarlanmamalıdır. DisallowNull özniteliği bir ön koşulde belirtir, get erişimcisini etkilemez. Aşağıdaki özellikleri
gözlemlerseniz DisallowNull özniteliğini kullanmayı seçmeniz gerekir:
1. Değişken, genellikle ilk örneklendiği zaman çekirdek senaryolarda null olabilir.
2. Değişken açıkça null olarak ayarlanmamalıdır.
Bu durumlar, başlangıçta null yükümlülüğüoluşturulan kodda ortaktır. Nesne özelliklerinin iki ayrı başlatma işlemi
olarak ayarlanmış olması olabilir. Bazı özelliklerin bazı zaman uyumsuz çalışma tamamlandıktan sonra ayarlanmış
olması olabilir.
AllowNull ve DisallowNull öznitelikleri, değişkenlerde önkoşulların Bu değişkenlerde boş değer atanabilir
açıklamalarıyla eşleşmeyebilir belirtmenize olanak tanır. Bunlar, API 'nizin özellikleri hakkında daha ayrıntılı bilgi
sağlar. Bu ek bilgiler, arayanların API 'nizi doğru şekilde kullanmasına yardımcı olur.Aşağıdaki öznitelikleri
kullanarak önkoşulları belirtdüğünü unutmayın:
AllowNull: null yapılamayan bir giriş bağımsız değişkeni null olabilir.
Disallownull: null olabilen bir giriş bağımsız değişkeni hiçbir şekilde null olmamalıdır.

Son koşulları belirtin: MaybeNull ve NotNull


Aşağıdaki imzaya sahip bir yönteminiz olduğunu varsayalım:

public Customer FindCustomer(string lastName, string firstName)

Aranan ad bulunamadığı zaman null döndürmek için bunun gibi bir yöntem yazmış oldunuz. null , kaydın
bulunamadığını açıkça gösterir. Bu örnekte, büyük ihtimalle Customer dönüş türünü Customer? olarak
değiştirirsiniz. Dönüş değerinin null yapılabilir bir başvuru türü olarak bildirilmesi, bu API 'nin amacını açıkça
belirtir.
Genel tanımlar ve null değer verilebilme kapsamında, tekniği genel yöntemlerle çalışmayan nedenler için. Benzer
bir kalıbı izleyen genel bir yönteminiz olabilir:

public T Find<T>(IEnumerable<T> sequence, Func<T, bool> match)

Dönüş değerinin T? belirtemezsiniz. Bu yöntem, Aranan öğe bulunamadığında null döndürür. T? bir dönüş
türü bildiremiyoruz, bu ek açıklamayı Yöntem döndürecek şekilde MaybeNull ekleyin:

[return: MaybeNull]
public T Find<T>(IEnumerable<T> sequence, Func<T, bool> match)

Yukarıdaki kod, arayanlara sözleşmenin null yapılamayan bir tür gösterdiği anlamına gelir, ancak dönüş değeri
gerçekten null olabilir. API 'niz null yapılamayan bir tür olması gerektiğinde (genellikle genel bir tür parametresi)
MaybeNull özniteliğini kullanın, ancak null döndürüldüğünden örnek olabilir.

Bir dönüş değeri veya out ya da ref bağımsız değişkeninin tür null yapılabilir bir tür olmasına rağmen null
olmadığını belirtebilirsiniz. Bir dizinin birçok öğe tutabilecek kadar büyük olmasını sağlayan bir yöntemi düşünün.
Giriş bağımsız değişkeninin kapasitesi yoksa, yordam yeni bir dizi ayırır ve var olan tüm öğeleri buna kopyalar.
Giriş bağımsız değişkeni null , yordam yeni depolama alanı ayırır. Yeterli kapasite varsa, yordam hiçbir şey
yapmaz:

public void EnsureCapacity<T>(ref T[] storage, int size)

Bu yordamı aşağıdaki şekilde çağırabilirsiniz:

// messages has the default value (null) when EnsureCapacity is called:


EnsureCapacity<string>(ref messages, 10);
// messages is not null.
EnsureCapacity<string>(messages, 50);
Null başvuru türlerini etkinleştirdikten sonra, önceki kodun uyarı olmadan derlendiğinden emin olmak istersiniz.
Yöntem döndüğünde, storage bağımsız değişkeninin null olmadığı garanti edilir. Ancak, null başvurusuyla
EnsureCapacity çağırmak kabul edilebilir. storage null yapılabilir bir başvuru türü yapabilirsiniz ve NotNull koşul
sonrası parametre bildirimine ekleyebilirsiniz:

public void EnsureCapacity<T>([NotNull]ref T[]? storage, int size)

Yukarıdaki kod, mevcut sözleşmeyi çok açık bir şekilde ifade eder: çağıranlar null değeri olan bir değişken
geçirebilir, ancak dönüş değeri hiçbir şekilde null olmamalıdır. NotNull özniteliği, null bağımsız değişken olarak
geçirilebilecek ref ve out bağımsız değişkenleri için en yararlı seçenektir, ancak yöntemin döndürdüğü bağımsız
değişkenin null olmaması garanti edilir.
Aşağıdaki öznitelikleri kullanarak koşulsuz Sonkoşulları belirtirsiniz:
MaybeNull: null yapılamayan bir dönüş değeri null olabilir.
NotNull: null olabilen bir dönüş değeri hiçbir şekilde null olmaz.

Koşullu koşulları belirtin: NotNullWhen , MaybeNullWhen ve


NotNullIfNotNull
Büyük olasılıkla string yöntemi String.IsNullOrEmpty(String)hakkında bilgi sahibisiniz. Bu yöntem, bağımsız
değişken null veya boş bir dize olduğunda true döndürür. Bu bir null denetim biçimidir: çağıranların null olması
gerekmez; Yöntem false döndürürse bağımsız değişkeni denetleyin. Bu null yapılabilir bir yöntemi gibi bir yöntem
oluşturmak için bağımsız değişkenini null yapılabilir bir türe ayarlarsınız ve NotNullWhen özniteliği ekleyebilirsiniz:

bool IsNullOrEmpty([NotNullWhen(false)]string? value);

Bu, derleyiciye dönüş değerinin false olduğu herhangi bir kodun null denetimli olması gerektiğini bildirir.
Özniteliğin eklenmesi derleyicinin statik analizine IsNullOrEmpty gerekli null denetimi gerçekleştirmesini bildirir:
false döndürdüğünde, giriş bağımsız değişkeni null değildir.

string? userInput = GetUserInput();


if (!string.IsNullOrEmpty(userInput))
{
int messageLength = userInput.Length; // no null check needed.
}
// null check needed on userInput here.

String.IsNullOrEmpty(String) yöntemine .NET Core 3,0 için yukarıda gösterildiği gibi açıklama eklenir. Kod
tabanınızda, null değerler için nesnelerin durumunu kontrol eden benzer yöntemlere sahip olabilirsiniz. Derleyici
özel null denetim yöntemlerini tanımaz ve ek açıklamaları kendiniz eklemeniz gerekir. Özniteliğini eklediğinizde,
derleyicinin statik analizi, sınanan değişkenin null olarak işaretli olduğunu bilir.
Bu öznitelikler için başka bir kullanım Try* öründir. ref ve out değişkenlerine yönelik Sonkoşulları, dönüş
değeri üzerinden iletilir. Daha önce gösterilen bu yöntemi göz önünde bulundurun:

bool TryGetMessage(string key, out string message)

Yukarıdaki yöntem tipik bir .NET deyimidir OM: dönüş değeri, message bulunan değere ayarlanmış olup
olmadığını veya hiçbir ileti bulunamazsa varsayılan değere ayarlandığını gösterir. Yöntem true döndürürse,
message değeri null değildir; Aksi takdirde, yöntemi null olarak message ayarlar.
NotNullWhen özniteliğini kullanarak bu deyimden iletişim kurabilirsiniz. Null yapılabilir başvuru türleri için imzayı
güncelleştirdiğinizde message bir string? yapın ve bir öznitelik ekleyin:

bool TryGetMessage(string key, [NotNullWhen(true)] out string? message)

Yukarıdaki örnekte, TryGetMessage true döndürüldüğünde message değeri null değil olarak bilinir. Kod
tabanınızda benzer yöntemlere aynı şekilde açıklama eklemek gerekir: bağımsız değişkenler null olabilir ve
Yöntem true döndürdüğünde null olmadığı bilinmektedir.
Ayrıca ihtiyacınız olabilecek bir son öznitelik vardır. Bazen bir dönüş değerinin null durumu, bir veya daha fazla giriş
bağımsız değişkenlerinin null durumuna bağlıdır. Bu yöntemler, belirli giriş bağımsız değişkenleri null
olmadığında null olmayan bir değer döndürür. Bu yöntemlere doğru şekilde açıklama eklemek için
NotNullIfNotNull özniteliğini kullanırsınız. Aşağıdaki yöntemi göz önünde bulundurun:

string GetTopLevelDomainFromFullUrl(string url);

url bağımsız değişkeni null değilse, çıktı null olmaz. Null yapılabilir başvurular etkinleştirildikten sonra, bu imza
doğru şekilde çalışarak API 'niz hiçbir şekilde null girişi kabul etmez. Ancak, giriş null ise, dönüş değeri de null
olabilir. Bu nedenle, imzayı aşağıdaki kodla değiştirebilirsiniz:

string? GetTopLevelDomainFromFullUrl(string? url);

Bu da çalışır, ancak arayanlara ek null denetimleri uygulamaya zorlayacaktır. Sözleşme, dönüş değerinin yalnızca
url giriş bağımsız değişkeni null olduğunda null olacaktır. Bu sözleşmeyi ifade etmek için, aşağıdaki kodda
gösterildiği gibi bu yönteme açıklama ekleyebilirsiniz:

[return: NotNullIfNotNull("url")]
string? GetTopLevelDomainFromFullUrl(string? url);

Dönüş değerine ve bağımsız değişkenine, null``? olduğunu belirten açıklanmalıdır. Öznitelik, url bağımsız
değişkeni null olmadığında döndürülen değerin null olmaması gerektiğini açıklığa kavuşturmaz.
Şu öznitelikleri kullanarak koşullu Sonkoşulları belirtirsiniz:
MaybeNullWhen: yöntem belirtilen bool değerini döndürdüğünde null yapılamayan bir giriş bağımsız
değişkeni null olabilir.
Notnullne zaman: yöntem belirtilen bool değerini döndürdüğünde null olabilen bir giriş bağımsız değişkeni
null olmaz.
Notnullifnotnull: belirtilen parametrenin giriş bağımsız değişkeni null değilse, dönüş değeri null olamaz.

Genel tanımlar ve null değer alabilirlik


Genel türlerin ve genel yöntemlerin null durumuna doğru bir şekilde iletişim kurmak için özel bakım yapılması
gerekir. Bu, null olabilen bir değer türünün ve null olabilen bir başvuru türünün temelde farklı olduğu gerçekten
farklıdır. int? , Nullable<int> için bir eş anladır, ancak derleyici tarafından eklenen bir özniteliğe sahip string?
string . Sonuç olarak, T bir class veya bir struct olup olmadığını bilmeden derleyicinin T? için doğru kodu
oluşturabileceği bir sonucudur.
Bu, kapalı bir genel türün tür bağımsız değişkeni olarak null yapılabilir bir tür (değer türü veya başvuru türü)
kullanmayacağınız anlamına gelmez. Hem List<string?> hem de List<int?> List<T> geçerli örneklerdir.
Ne anlama geliyor, bir genel sınıfta veya yöntem bildiriminde kısıtlama olmadan T? kullanmayacağınız anlamına
gelir. Örneğin, Enumerable.FirstOrDefault<TSource>(IEnumerable<TSource>) T? döndürecek şekilde
değiştirilmez. struct veya class kısıtlamasını ekleyerek bu sınırlamayı aşabilirsiniz. Bu kısıtlamalardan biri ile
derleyici, hem T hem de T? için nasıl kod üretireceğini bilir.
Genel tür bağımsız değişkeni için kullanılan türleri null yapılamayan türler olacak şekilde kısıtlamak isteyebilirsiniz.
Bunu, bu tür bağımsız değişkenine notnull kısıtlamasını ekleyerek yapabilirsiniz. Bu kısıtlama uygulandığında tür
bağımsız değişkeni null yapılabilir bir tür olmamalıdır.

Sonuçlar
Null yapılabilir başvuru türleri eklemek, null olabilecek değişkenlere yönelik API beklentilerinizi tanımlayan bir
başlangıç sözlüğü sağlar. Ek öznitelikler, değişkenlerin null durumunu ön koşullar ve Postconditions olarak
tanımlamaya yönelik daha zengin bir sözlük sağlar. Bu öznitelikler beklentilerinizi daha net bir şekilde anlatır ve API
'lerinizi kullanan geliştiriciler için daha iyi bir deneyim sağlar.
Bir null yapılabilir bağlam için kitaplıkları güncelleştirdiğinizde, API 'lerinizi kullanıcılarına doğru kullanım için bu
öznitelikleri ekleyin. Bu öznitelikler, giriş bağımsız değişkenlerinin ve dönüş değerlerinin Null durumunu tam olarak
açıklamanıza yardımcı olur:
AllowNull: null yapılamayan bir giriş bağımsız değişkeni null olabilir.
Disallownull: null olabilen bir giriş bağımsız değişkeni hiçbir şekilde null olmamalıdır.
MaybeNull: null yapılamayan bir dönüş değeri null olabilir.
NotNull: null olabilen bir dönüş değeri hiçbir şekilde null olmaz.
MaybeNullWhen: yöntem belirtilen bool değerini döndürdüğünde null yapılamayan bir giriş bağımsız
değişkeni null olabilir.
Notnullne zaman: yöntem belirtilen bool değerini döndürdüğünde null olabilen bir giriş bağımsız değişkeni
null olmaz.
Notnullifnotnull: belirtilen parametrenin giriş bağımsız değişkeni null değilse, dönüş değeri null olamaz.
Ad Alanları (C# Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Ad alanları, C# programlamada iki şekilde çok fazla kullanılır. İlk olarak .NET Framework, aşağıdaki gibi birçok
sınıfını düzenlemek için ad alanlarını kullanır:

System.Console.WriteLine("Hello World!");

System bir ad alanıdır ve Console bu ad alanındaki bir sınıftır. using Anahtar sözcüğü, aşağıdaki örnekte olduğu
gibi, tüm adı gerekli olmaması için kullanılabilir:

using System;

Console.WriteLine("Hello");
Console.WriteLine("World!");

Daha fazla bilgi için bkz. using yönergesi.


İkincisi, kendi ad alanlarınızı bildirmek daha büyük programlama projelerindeki sınıf ve yöntem adlarının kapsamını
denetlemenize yardımcı olabilir. Aşağıdaki örnekte olduğu gibi bir ad alanı bildirmek için Namespace anahtar
sözcüğünü kullanın:

namespace SampleNamespace
{
class SampleClass
{
public void SampleMethod()
{
System.Console.WriteLine(
"SampleMethod inside SampleNamespace");
}
}
}

Ad alanının adı geçerli C# bir tanımlayıcı adıolmalıdır.

Ad alanlarına genel bakış


Ad alanları aşağıdaki özelliklere sahiptir:
Büyük kod projelerini düzenler.
. İşleci kullanılarak sınırlandırılır.
using Yönergesi, her sınıf için ad alanının adını belirtmek için gereksinimi obviates.
Ad alanı "root" ad alanıdır: global::System her zaman .net System ad alanına başvurur. global

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin ad alanları bölümüne bakın.
Ayrıca bkz.
C# Programlama Kılavuzu
Ad Alanlarını Kullanma
Nasıl yapılır: My Namespace 'i kullanma
Tanımlayıcı adları
using Yönergesi
:: İşleç
Türler, değişkenler ve değerler
29.11.2019 • 10 minutes to read • Edit Online

C#türü kesin belirlenmiş bir dildir. Her değişken ve sabitin, bir değeri değerlendiren her ifadeyi olduğu gibi bir türü
vardır. Her yöntem imzası her giriş parametresi ve dönüş değeri için bir tür belirtir. .NET Framework sınıf kitaplığı,
dosya sistemi, ağ bağlantıları, koleksiyon ve nesne dizileri ve tarihler gibi çok çeşitli mantıksal yapıları temsil eden
daha karmaşık türler ve yerleşik sayısal türlerin bir kümesini tanımlar. Tipik C# bir program, sınıf kitaplığından
türleri ve programın sorunlu etki alanına özgü kavramları modelleyebilir Kullanıcı tanımlı türleri kullanır.
Bir tür içinde depolanan bilgiler şunları içerebilir:
Türün bir değişkeninin gerektirdiği depolama alanı.
Temsil ettiği maksimum ve en düşük değerler.
İçerdiği Üyeler (Yöntemler, alanlar, olaylar vb.).
Devraldığı temel tür.
Değişkenlere yönelik belleğin çalışma zamanında ayrılabileceği konum.
İzin verilen işlem türleri.
Derleyici, kodunuzda gerçekleştirilen tüm işlemlerin tür açısından güvenliolduğundan emin olmak için tür
bilgilerini kullanır. Örneğin, inttüründe bir değişken bildirirseniz, derleyici değişkeni toplama ve çıkarma
işlemlerinde kullanmanıza izin verir. Booltüründe bir değişkende aynı işlemleri gerçekleştirmeye çalışırsanız,
derleyici aşağıdaki örnekte gösterildiği gibi bir hata oluşturur:

int a = 5;
int b = a + 2; //OK

bool test = true;

// Error. Operator '+' cannot be applied to operands of type 'int' and 'bool'.
int c = a + test;

NOTE
C ve C++ geliştiricilerle, bool 'un C# int'e dönüştürülebilir olmadığına dikkat edin.

Derleyici, tür bilgilerini yürütülebilir dosyaya meta veriler olarak katıştırır. Ortak dil çalışma zamanı (CLR ), bellek
ayırdığı ve geri kazanır daha fazla güvence altına almak için çalışma zamanında bu meta verileri kullanır.

Değişken bildirimlerinde türleri belirtme


Bir programda bir değişken veya sabit belirttiğinizde, onun türünü belirtmeniz veya var anahtar sözcüğünü
kullanarak derleyicinin türü saymasına izin vermelisiniz. Aşağıdaki örnek, hem yerleşik sayısal türler hem de
Kullanıcı tanımlı karmaşık türler kullanan bazı değişken bildirimlerini gösterir:
// Declaration only:
float temperature;
string name;
MyClass myClass;

// Declaration with initializers (four examples):


char firstLetter = 'C';
var limit = 3;
int[] source = { 0, 1, 2, 3, 4, 5 };
var query = from item in source
where item <= limit
select item;

Yöntem parametrelerinin türleri ve dönüş değerleri Yöntem imzasında belirtilmiştir. Aşağıdaki imza, giriş bağımsız
değişkeni olarak bir int gerektiren ve bir dize döndüren bir yöntemi gösterir:

public string GetName(int ID)


{
if (ID < names.Length)
return names[ID];
else
return String.Empty;
}
private string[] names = { "Spencer", "Sally", "Doug" };

Bir değişken oluşturulduktan sonra, yeni bir türle yeniden bildirilemez ve belirtilen türle uyumlu olmayan bir değer
atanamaz. Örneğin, bir int bildiremez ve bunu bir true Boolean değeri atayabilirsiniz. Ancak, değerler başka
türlere dönüştürülebilir (örneğin, yeni değişkenlere atandığında veya yöntem bağımsız değişkenleri olarak
geçirildiğinde). Veri kaybına neden olmayan bir tür dönüştürmesi , derleyici tarafından otomatik olarak
gerçekleştirilir. Veri kaybına neden olabilecek bir dönüştürme, kaynak kodda bir tür dönüştürme gerektirir.
Daha fazla bilgi için bkz. atama ve tür dönüştürmeleri.

Yerleşik türler
C#tamsayılar, kayan nokta değerleri, Boole ifadeleri, metin karakterleri, ondalık değerler ve diğer veri türlerini
temsil etmek için standart bir yerleşik sayısal türler kümesi sağlar. Ayrıca yerleşik dize ve nesne türleri de vardır.
Bunlar, herhangi bir C# programda kullanabilmeniz için kullanılabilir. Yerleşik türler hakkında daha fazla bilgi için
bkz. Yerleşik türler Için başvuru tablosu.

Özel türler
Kendi özel türlerinizi oluşturmak için struct, Class, Interfaceve enum yapılarını kullanırsınız. .NET Framework sınıf
kitaplığı, Microsoft tarafından kendi uygulamalarınızda kullanabileceğiniz özel türlerin bir koleksiyonudur.
Varsayılan olarak, sınıf kitaplığındaki en sık kullanılan türler her C# programda kullanılabilir. Diğerleri yalnızca
tanımlandıkları derlemeye açıkça bir proje başvurusu eklediğinizde kullanılabilir hale gelir. Derleyicinin derlemeye
bir başvurusu olduktan sonra, kaynak kodda o derlemede belirtilen türlerin değişkenlerini (ve sabitleri)
bildirebilirsiniz.

Genel türler
Bir tür, istemci kodunun türün bir örneğini oluşturduğunda sağladığı gerçek tür ( somut tür) için yer tutucu olarak
görev yapan bir veya daha fazla tür parametresiyle bildirilemez. Bu tür türler Genel türlerolarak adlandırılır.
Örneğin .NET Framework tür List<T>, kuralına göre bir tür parametresine sahiptir ve tadı verilir. Türün bir örneğini
oluşturduğunuzda, listenin içereceği nesnelerin türünü (örneğin, dize) belirtirsiniz:
List<string> strings = new List<string>();

Tür parametresinin kullanımı, her öğeyi nesneyedönüştürmek zorunda kalmadan her türlü öğe türünü tutmak için
aynı sınıfı yeniden kullanmayı mümkün kılar. Derleyici, koleksiyon öğelerinin belirli türünü bildiğinden ve derleme
zamanında bir hata tetikleyebildiğinden, genel koleksiyon sınıfları kesin türü belirtilmiş koleksiyonlar olarak
adlandırılır. strings Örneğin, önceki örnek. Daha fazla bilgi için bkz. Genel türler.

Örtülü türler, anonim türler ve demet türleri


Daha önce belirtildiği gibi, var anahtar sözcüğünü kullanarak yerel bir değişkeni (sınıf üyelerini değil) örtük olarak
yazabilirsiniz. Değişken hala derleme zamanında bir tür alır, ancak tür derleyici tarafından sağlanır.Daha fazla bilgi
için bkz. örtülü olarak yazılan yerel değişkenler.
Bazı durumlarda, yöntem sınırlarını depolamayı veya geçişi istemediğiniz ilgili değerlerin basit kümeleri için
adlandırılmış bir tür oluşturmak uygun değildir. Bu amaçla anonim türler oluşturabilirsiniz. Daha fazla bilgi için bkz.
anonim türler.
Bir yöntemden birden fazla değer döndürmek, yaygın bir yöntemdir. Tek bir yöntem çağrısında birden çok değer
döndüren demet türleri oluşturabilirsiniz. Daha fazla bilgi için bkz. tanımlamabilgileri.

Ortak tür sistemi


.NET Framework sistem hakkında iki temel noktayı anlamak önemlidir:
Devralma ilkesini destekler. Türler, temel türlerolarak adlandırılan diğer türlerden türetilebilir. Türetilmiş tür,
yöntemleri, özellikleri ve temel türün diğer üyelerini devralır (bazı kısıtlamalarla). Temel tür başka bir türden
türetebilir, bu durumda türetilmiş tür, devralma hiyerarşisindeki her iki temel türün üyelerini devralır. Int32
(C# anahtar sözcük: int ) gibi yerleşik sayısal türler dahil olmak üzere tüm türler, sonundaObject(C# anahtar
sözcük: object ) olan tek bir temel türden türetilir. Bu Birleşik tür hiyerarşisine ortak tür sistemi (Cts) denir. '
De C#devralma hakkında daha fazla bilgi için bkz. Devralma.
CTS içindeki her tür, bir değer türü veya bir başvuru türüolarak tanımlanır. Bu, .NET Framework sınıf
kitaplığındaki tüm özel türleri ve ayrıca kendi Kullanıcı tanımlı türlerinizi içerir. Struct anahtar sözcüğünü
kullanarak tanımladığınız türler değer türleridir; Tüm yerleşik sayısal türler yapılar' dur. Değer türleri
hakkında daha fazla bilgi için bkz. yapılar. Sınıf anahtar sözcüğünü kullanarak tanımladığınız türler başvuru
türleridir. Başvuru türleri hakkında daha fazla bilgi için bkz. sınıflar. Başvuru türleri ve değer türlerinde farklı
derleme zamanı kuralları ve farklı çalışma zamanı davranışları vardır.

Ayrıca bkz.
Yapılar
Sınıflar
Sınıflar (C# Programlama Kılavuzu)
23.10.2019 • 8 minutes to read • Edit Online

Başvuru türleri
Sınıf olarak tanımlanan bir tür, başvuru türüdür. Çalışma zamanında, bir başvuru türünde bir değişken
bildirdiğinizde, New işlecini kullanarak sınıfın bir örneğini açıkça oluşturana veya onu oluşturulmuş bir uyumlu
türdeki nesne atayan sürece değişken null değerini içerir diğer bir yerde, aşağıdaki örnekte gösterildiği gibi:

//Declaring an object of type MyClass.


MyClass mc = new MyClass();

//Declaring another object of the same type, assigning it the value of the first object.
MyClass mc2 = mc;

Nesne oluşturulduğunda, söz konusu nesne için yönetilen yığında yeterli bellek ayrılır ve değişken yalnızca
belirtilen nesnenin konumuna bir başvuru içerir. Yönetilen yığında bulunan türler, her ikisi de ayrıldıklarında ve çöp
toplamaolarak bilinen clr 'nin otomatik bellek yönetimi işlevselliği tarafından geri kazanıyorsa ek yük gerektirir.
Ancak çöp toplama da yüksek oranda iyileştirilmiştir ve çoğu senaryoda bir performans sorunu oluşturmaz. Çöp
toplama hakkında daha fazla bilgi için bkz. Otomatik bellek yönetimi ve çöp toplama.

Sınıfları Bildirme
Sınıflar, aşağıdaki örnekte gösterildiği gibi, Class anahtar sözcüğü ve ardından benzersiz bir tanımlayıcı kullanılarak
bildirilenler:

//[access modifier] - [class] - [identifier]


public class Customer
{
// Fields, properties, methods and events go here...
}

class Anahtar sözcüğü öncesinde erişim düzeyidir. Bu durumda genel kullanıldığından, herkes bu sınıfın
örneklerini oluşturabilir. Sınıfın adı class anahtar sözcüğünü izler. Sınıfın adı geçerli C# bir tanımlayıcı adıolmalıdır.
Tanımın geri kalanı, davranışın ve verilerin tanımlandığı sınıf gövdesidir. Bir sınıftaki alanlar, özellikler, Yöntemler ve
olaylar topluca sınıf üyeleriolarak adlandırılır.

Nesneler oluşturma
Bazen birbirinin yerine kullanıldıkları halde bir sınıf ve bir nesne farklı şeylerdir. Bir sınıf nesne türünü tanımlar,
ancak nesnenin kendisi değildir. Bir nesne, bir sınıfı temel alan somut bir varlıktır ve bazen bir sınıfın örneği olarak
adlandırılır.
Nesneler Yeni anahtar sözcüğü kullanılarak, ardından nesnenin temel aldığı sınıfın adı tarafından oluşturulabilir ve
şöyle olur:

Customer object1 = new Customer();

Bir sınıfın bir örneği oluşturulduğunda, nesnesine bir başvuru, programcıya geri geçirilir. Önceki örnekte, object1
temel alan Customer bir nesnesine başvurudur. Bu başvuru yeni nesneye başvurur ancak nesne verilerinin kendisini
içermez. Aslında, herhangi bir nesne oluşturmadan bir nesne başvurusu oluşturabilirsiniz:

Customer object2;

Bir nesneye başvurmayan bu gibi nesne başvuruları oluşturmanızı önermeyiz, çünkü bu başvuru, bu tür bir
başvuruya erişim denemesi çalışma zamanında başarısız olur. Ancak, bu tür bir başvuru, yeni bir nesne oluşturarak
ya da bunun gibi var olan bir nesneye atanarak bir nesneye başvurmak için kullanılabilir:

Customer object3 = new Customer();


Customer object4 = object3;

Bu kod, her ikisi de aynı nesneye başvuran iki nesne başvurusu oluşturur. Bu nedenle, nesne üzerinde yapılan
object3 tüm değişiklikler sonraki object4 kullanımlarda yansıtılır. Sınıfları temel alan nesneler başvuruya göre
başvurulduğu için sınıflar başvuru türleri olarak bilinir.

Sınıf devralma
Sınıflar, nesne odaklı programlamanın temel bir özelliği olan devralmayıtamamen destekler. Bir sınıf
oluşturduğunuzda, korumalıolarak tanımlanmayan diğer bir arabirim veya sınıftan kalıtımla alabilir ve diğer sınıflar
sınıfınızdan devralınabilir ve sınıf sanal yöntemlerini geçersiz kılabilir.
Devralma bir türetmekullanılarak gerçekleştirilir. Bu, bir sınıfın veri ve davranış devraldığı temel sınıf kullanılarak
bildirildiği anlamına gelir. Bir temel sınıf, bir iki nokta üst üste eklenerek ve türetilmiş sınıf adından sonra temel
sınıfın adı aşağıdaki gibi olarak belirtilir:

public class Manager : Employee


{
// Employee fields, properties, methods and events are inherited
// New Manager fields, properties, methods and events go here...
}

Bir sınıf bir temel sınıf bildiriyorsa, oluşturucular hariç, taban sınıfın tüm üyelerini devralır. Daha fazla bilgi için bkz.
Devralma.
Aksine C++, içindeki C# bir sınıf yalnızca bir temel sınıftan doğrudan devralınabilir. Ancak, bir temel sınıfın kendisi
başka bir sınıftan devraldığı için, bir sınıf dolaylı olarak birden fazla temel sınıfı devralınabilir. Ayrıca, bir sınıf
doğrudan birden fazla arabirim uygulayabilir. Daha fazla bilgi için bkz. arabirimler.
Bir sınıf, soyutolarak bildirilemez. Soyut bir sınıf imza tanımına sahip ancak uygulamaya sahip olmayan soyut
yöntemler içerir. Soyut sınıfların örneği oluşturulamıyor. Yalnızca soyut yöntemleri uygulayan türetilmiş sınıflar
aracılığıyla kullanılabilir. Buna karşılık, korumalı bir sınıf diğer sınıfların bundan türemesine izin vermez. Daha fazla
bilgi için bkz. soyut ve korumalı sınıflar ve sınıf üyeleri.
Sınıf tanımları, farklı kaynak dosyalar arasında bölünebilir. Daha fazla bilgi için bkz. kısmi sınıflar ve Yöntemler.

Örnek
Aşağıdaki örnek, bir Otomatik uygulanan özellik, bir yöntem ve Oluşturucu olarak adlandırılan özel bir yöntem
içeren bir ortak sınıf tanımlar. Daha fazla bilgi için bkz. Özellikler, Yöntemlerve oluşturucular konuları. Daha sonra
sınıfının örnekleri new anahtar sözcüğüyle oluşturulur.
using System;

public class Person


{
// Constructor that takes no arguments:
public Person()
{
Name = "unknown";
}

// Constructor that takes one argument:


public Person(string name)
{
Name = name;
}

// Auto-implemented readonly property:


public string Name { get; }

// Method that overrides the base class (System.Object) implementation.


public override string ToString()
{
return Name;
}
}
class TestPerson
{
static void Main()
{
// Call the constructor that has no parameters.
var person1 = new Person();
Console.WriteLine(person1.Name);

// Call the constructor that has one parameter.


var person2 = new Person("Sarah Jones");
Console.WriteLine(person2.Name);
// Get the string representation of the person2 instance.
Console.WriteLine(person2);

Console.WriteLine("Press any key to exit.");


Console.ReadKey();
}
}
// Output:
// unknown
// Sarah Jones
// Sarah Jones

C# Dil Belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir kaynaktır.

Ayrıca bkz.
C# Programlama Kılavuzu
Nesne Odaklı Programlama
Çok biçimlilik
Tanımlayıcı adları
Üyeler
Yöntemler
Oluşturucular
Sonlandırıcılar
Nesneler
Yapılar
8.11.2019 • 4 minutes to read • Edit Online

Struct bir değer türüdür. Bir struct oluşturulduğunda, yapının atandığı değişken yapının gerçek verilerini barındırır.
Yapı yeni bir değişkene atandığında, kopyalanır. Bu nedenle, yeni değişken ve özgün değişken aynı verilerin iki ayrı
kopyasını içerir. Bir kopyada yapılan değişiklikler diğer kopyayı etkilemez.
Değer türü değişkenleri doğrudan değerlerini içerir, bu da belleğin, değişkenin bildirildiği bağlamda satır içi olarak
ayrıldığı anlamına gelir. Değer türü değişkenler için ayrı bir yığın ayırma veya çöp toplama ek yükü yoktur.
Değer türlerinin iki kategorisi vardır: struct ve enum.
Yerleşik sayısal türler yapı birimleridir ve erişebileceğiniz özelliklere ve yöntemlere sahiptirler:

// Static method on type Byte.


byte b = Byte.MaxValue;

Ancak bunları, basit olmayan türler gibi bu değerlere bildirir ve bunlara atanır:

byte num = 0xA;


int i = 5;
char c = 'Z';

Değer türleri korumalıdır, yani örneğin, bir türü Int32türetemezsiniz ve Kullanıcı tanımlı herhangi bir sınıftan veya
yapıdan devralacak bir struct tanımlayamazsınız, çünkü bir struct yalnızca ValueTypedevralabilir. Ancak, bir struct
bir veya daha fazla arabirim uygulayabilir. Bir yapı türünü arabirim türüne çevirebilirsiniz; Bu, bir kutulama
işleminin yapıyı yönetilen yığında bir başvuru türü nesnesinin içine sarmasına neden olur. Paketleme işlemleri, bir
Object giriş parametresi olarak alan bir yönteme bir değer türü geçirdiğinizde oluşur. Daha fazla bilgi için bkz.
kutulama ve kutudançıkarma.
Kendi özel değer türlerinizi oluşturmak için struct anahtar sözcüğünü kullanırsınız. Genellikle, bir yapı aşağıdaki
örnekte gösterildiği gibi küçük bir ilgili değişkenler kümesi için kapsayıcı olarak kullanılır:

public struct Coords


{
public int x, y;

public Coords(int p1, int p2)


{
x = p1;
y = p2;
}
}

.NET Framework değer türleri hakkında daha fazla bilgi için bkz. ortak tür sistemi.
Yapılar sınıflarla aynı sözdiziminin çoğunu paylaşır, ancak yapılar sınıflardan daha sınırlıdır:
Bir struct bildiriminde, const veya static olarak belirtilemediği sürece alanlar başlatılamaz.
Struct parametresiz bir Oluşturucu (parametresiz bir Oluşturucu) veya sonlandırıcısı bildiremez.
Yapılar atamaya kopyalanır. Bir yapı yeni bir değişkene atandığında, tüm veriler kopyalanır ve yeni kopyada
yapılan değişiklikler özgün kopyanın verilerini değiştirmez. Bu, sözlük < dize, myStruct > gibi değer
türlerinin koleksiyonlarıyla çalışırken unutmamak önemlidir.
Yapılar, değer türlerdir ve sınıflardır başvuru türleridir.
Sınıfların aksine, yapılar new işleci kullanılmadan oluşturulabilir.
Yapılar, parametreleri olan oluşturucular bildirebilir.
Yapı, başka bir struct veya sınıftan devralınabilir ve bir sınıfın temeli olamaz. Tüm yapılar, Objectdevralan
ValueTypedoğrudan devralır.
Bir struct, arabirimler uygulayabilir.

Boş değer atanabilen değer türleri


Sıradan değer türlerinin değeri nullolamaz. Ancak, türden sonra bir ? ekleyerek null yapılabilir değer türleri
oluşturabilirsiniz. Örneğin int? , nulldeğeri de olan bir int türüdür. Null yapılabilir değer türleri
Nullable<T>genel yapı türü örnekleridir. Null olabilen değer türleri, genellikle sayısal değerlerin null veya tanımsız
olabileceği veritabanlarına veri geçirirken faydalıdır. Daha fazla bilgi için bkz. Nullable değer türleri.

Ayrıca bkz.
Sınıflar
Temel Türler
C#demet türleri
30.10.2019 • 32 minutes to read • Edit Online

C#tanımlama grupları, hafif bir sözdizimi kullanarak tanımladığınız türlerdir. Daha basit bir sözdizimi, sayıya
göre dönüştürme kuralları (kardinalite olarak adlandırılır) ve öğe türleri ve kopyalar, eşitlik testleri ve atamalar
için tutarlı kurallar vardır. Zorunluluğunu getirir olarak, tanımlama grupları devralma ile ilişkili nesne odaklı
bazı deyimleri desteklemez. 7,0 sürümündeki yenilikler makalesindeki tanımlama bilgileri bölümüne genel
bakış alabilirsiniz. C#
Bu makalede, C# 7,0 ve sonraki sürümlerde tanımlama gruplarını ve bunları kullanmanın farklı yollarını ve
tanımlama grupları ile çalışmaya yönelik ilk Kılavuzu düzenleyen dil kurallarını öğreneceksiniz.

NOTE
Yeni tanımlama grubu özellikleri ValueTuple türleri gerektirir. Türü içermeyen platformlarda kullanabilmek için, NuGet
paketini System.ValueTuple ' i eklemeniz gerekir.
Bu, çerçeveye teslim edilen türleri kullanan diğer dil özelliklerine benzerdir. Örnek olarak, INotifyCompletion
arabirimine bağlı async ve await ve IEnumerable<T> ' e bağlı LINQ verilebilir. Bununla birlikte, .NET daha fazla
platforma bağımlı olduğu için teslim mekanizması değişiyor. .NET Framework, dil derleyicisi ile aynı temposunda her
zaman yollanmayabilir. Yeni dil özellikleri yeni türlere dayandığınızda, bu türler dil Özellikleri sevk edildiğinde NuGet
paketleri olarak kullanılabilir olacaktır. Bu yeni türler .NET Standard API 'sine eklendikçe ve Framework 'ün bir parçası
olarak teslim edildiğinde, NuGet paket gereksinimi kaldırılır.

Yeni demet desteği ekleme nedenlerinden başlayalım. Yöntemler tek bir nesne döndürür. Tanımlama grupları
bu tek nesnede birden çok değeri daha kolay paketlemenize olanak tanır.
.NET Framework zaten genel Tuple sınıfları var. Ancak, bu sınıfların iki önemli sınırlaması vardı. Biri için,
Tuple sınıfları özellikleri Item1 , Item2 vb. olarak adlandırılır. Bu adlar hiçbir anlam bilgisi içermez. Bu Tuple
türlerinin kullanılması, özelliklerin her birinin anlamını karşılayarak iletişim kurmasına imkan vermez. Yeni dil
özellikleri, bir tanımlama grubu içindeki öğeler için anlamsal anlamlı adlar bildirme ve kullanma imkanı sağlar.
Tuple sınıfları, başvuru türleri olduklarından daha fazla performans sorunlarına neden olur. Tuple
türlerinden birini kullanmak nesneleri ayırmayı gösterir. Etkin yollarda birçok küçük nesne ayırmak
uygulamanızın performansı üzerinde ölçülebilir bir etkiye sahip olabilir. Bu nedenle, tanımlama birimleri için
dil desteği yeni ValueTuple yapılarını kullanır.
Bu eksiklikleri önlemek için, birden çok öğeyi yürütmek üzere class veya struct oluşturabilirsiniz. Ne yazık
ki, sizin için daha fazla çalışma ve tasarım amacınızı gizler. struct veya class yapmak, hem veri hem de
davranışla bir tür tanımlamanız gerektiğini gösterir. Birçok kez yalnızca birden çok değeri tek bir nesnede
depolamak istiyorsunuz.
Dil özellikleri ve ValueTuple genel yapıları, bu demet türlerine herhangi bir davranış (Yöntem)
ekleyemeyeceği kuralını zorlar. Tüm ValueTuple türleri değişebilir yapılar. Her üye alanı bir ortak alandır.
Böylece çok hafif hale gelir. Bununla birlikte, bu, her ne kadar önemli olduğu durumlarda başlıkların
kullanılması gerektiği anlamına gelir.
Tanımlama grupları, class ve struct türlerinden daha basit ve daha esnek veri kapsayıcılarıdır. Bu
farklılıkları keşfedelim.

Adlandırılmış ve adlandırılmamış diziler


ValueTuple yapısı, var olan Tuple türlerinde tanımlanan özelliklere benzer şekilde Item1 , Item2 , Item3 , vb.
adlı alanlara sahiptir. Bu adlar, adlandırılmamış tanımlama gruplarıiçin kullanabileceğiniz tek adlardır. Bir
tanımlama grubu için alternatif alan adı sağlamadığınızda, adlandırılmamış bir tanımlama grubu
oluşturdunuz:

var unnamed = ("one", "two");

Önceki örnekteki tanımlama grubu, değişmez sabitler kullanılarak başlatılmış ve 7,1 içinde C# demet alan adı
tahminleri kullanılarak oluşturulan öğe adlarına sahip olmayacaktır.
Ancak, bir tanımlama grubu başlattığınızda, her bir alana daha iyi adlar veren yeni dil özellikleri
kullanabilirsiniz. Bunun yapılması adlandırılmış bir tanımlama grubuoluşturur. Adlandırılmış tanımlama
gruplarının hala Item1 , Item2 , Item3 vb. adlı öğeleri vardır. Ancak, adlandırmış olduğunuz öğelerin herhangi
biri için eş anlamlıları da vardır. Her öğe için ad belirterek adlandırılmış bir tanımlama grubu oluşturursunuz.
Bir yol, kayıt kümesi başlatmasının parçası olarak adları belirtmektir:

var named = (first: "one", second: "two");

Adlandırılmış tanımlama gruplarını etkin bir şekilde kullanabilmeniz için bu eş anlamlılar derleyici ve dil
tarafından işlenir. Ides ve düzenleyiciler, Roslyn API 'Lerini kullanarak bu anlam adlarını okuyabilir.
Adlandırılmış bir tanımlama grubunun öğelerine aynı derlemenin herhangi bir yerindeki anlam adlarıyla
başvurabilirsiniz. Derleyici, derlenmiş çıktıyı oluştururken Item* eşdeğerleriyle tanımladığınız adların yerini
alır. Derlenen Microsoft ara dili (MSIL ), bu öğeleri verdiğiniz adları içermez.
7,1 ' C# den başlayarak, kayıt düzeni için alan adları, kayıt düzeni başlatmak için kullanılan değişkenlerden
bulunabilir. Bu, demet yansıtma başlatıcıları olarak adlandırılır. Aşağıdaki kod, accumulation adlı count
(bir tamsayı) ve sum (çift) içeren bir tanımlama grubu oluşturur.

var sum = 12.5;


var count = 5;
var accumulation = (count, sum);

Derleyici, ortak Yöntemler veya özelliklerden döndürülen tanımlama grupları için oluşturduğunuz adları
iletmelidir. Bu durumlarda, derleyici yöntemine bir TupleElementNamesAttribute özniteliği ekler. Bu öznitelik,
kayıt grubundaki her öğeye verilen adları içeren TransformNames liste özelliği içerir.

NOTE
Visual Studio gibi geliştirme araçları da bu meta verileri okur ve meta veri alanı adlarını kullanarak IntelliSense ve diğer
özellikleri sağlar.

Adlandırılmış tanımlama gruplarını birbirlerine atamaya yönelik kuralları anlamak için yeni tanımlama bilgileri
ve ValueTuple türü temel temellerini anlamak önemlidir.

Demet projeksiyon başlatıcıları


Genel olarak, demet yansıtma başlatıcıları, bir demet başlatma bildiriminin sağ tarafındaki değişken veya alan
adlarını kullanarak çalışır. Açık bir ad verilirse, bu, yansıtılan herhangi bir adın önüne geçer. Örneğin, aşağıdaki
başlatıcıda öğeler explicitFieldOne ve explicitFieldTwo ' dir localVariableOne ve localVariableTwo :
var localVariableOne = 5;
var localVariableTwo = "some text";

var tuple = (explicitFieldOne: localVariableOne, explicitFieldTwo: localVariableTwo);

Açık bir adın sağlanmadığı herhangi bir alan için, geçerli bir örtük ad yansıtıldır. Açıkça veya örtük olarak
anlamsal adlar sağlama gereksinimi yoktur. Aşağıdaki başlatıcıda, değeri "her şeye yanıt" olan, değeri 42 ve
stringContent olan Item1 alan adlarına sahiptir:

var stringContent = "The answer to everything";


var mixedTuple = (42, stringContent);

Aday alan adlarının demet alanı üzerinde yansıtılmamaları gereken iki koşul vardır:
1. Aday adı, ayrılmış bir tanımlama grubu adı olduğunda. Örnekler arasında Item3 , ToString veya Rest
sayılabilir.
2. Aday adı, başka bir demet alan adının bir yinelemesi olduğunda açık veya kapalı olur.
Bu koşullar belirsizlik kullanmaktan kaçının. Bu adlar, bir tanımlama grubu içindeki bir alanın alan adları olarak
kullanıldıklarında belirsizliğe neden olur. Bu koşullardan hiçbiri derleme zamanı hatalarına neden olur. Bunun
yerine, yansıtılan adlara sahip öğeler kendileri için öngörülen semantik adlara sahip değildir. Aşağıdaki
örneklerde bu koşullar gösterilmektedir:

var ToString = "This is some text";


var one = 1;
var Item1 = 5;
var projections = (ToString, one, Item1);
// Accessing the first field:
Console.WriteLine(projections.Item1);
// There is no semantic name 'ToString'
// Accessing the second field:
Console.WriteLine(projections.one);
Console.WriteLine(projections.Item2);
// Accessing the third field:
Console.WriteLine(projections.Item3);
// There is no semantic name 'Item1`.

var pt1 = (X: 3, Y: 0);


var pt2 = (X: 3, Y: 4);

var xCoords = (pt1.X, pt2.X);


// There are no semantic names for the fields
// of xCoords.

// Accessing the first field:


Console.WriteLine(xCoords.Item1);
// Accessing the second field:
Console.WriteLine(xCoords.Item2);

Bu durumlar derleyici hatalarına neden olmaz çünkü demet alan adı projeksiyonu kullanılabilir olmadığında,
7,0 ile C# yazılan koda yönelik bir değişiklik olacaktır.

Eşitlik ve tanımlama grupları


7,3 ile C# başlayarak, demet türleri == ve != işleçlerini destekler. Bu işleçler, sol bağımsız değişkenin her bir
üyesini sırasıyla doğru bağımsız değişkenin her bir üyesiyle karşılaştırarak çalışır. Bu karşılaştırmalar kısa
devre. Bir çift eşit olmadığı anda üyelerin değerlendirilmesi durdurulur. Aşağıdaki kod örnekleri == kullanır,
ancak karşılaştırma kuralları hepsi != ' e uygulanır. Aşağıdaki kod örneği iki tamsayı çifti için bir eşitlik
karşılaştırması gösterir:

var left = (a: 5, b: 10);


var right = (a: 5, b: 10);
Console.WriteLine(left == right); // displays 'true'

Demet eşitlik testlerini daha uygun hale getirmek için çeşitli kurallar vardır. Tanımlama grubu eşitliği, aşağıdaki
kodda gösterildiği gibi, tanımlama gruplarının biri null yapılabilir bir tanımlama grubu ise yükseltilmemiş
dönüştürmeleri gerçekleştirir:

var left = (a: 5, b: 10);


var right = (a: 5, b: 10);
(int a, int b)? nullableTuple = right;
Console.WriteLine(left == nullableTuple); // Also true

Tanımlama grubu eşitliği, her iki başlığın de her bir üyesinde örtük dönüştürmeler de gerçekleştirir. Bunlar,
yükseltilmemiş dönüştürmeleri, genişleyen dönüşümler veya diğer örtük dönüştürmeler içerir. Aşağıdaki
örneklerde, tamsayı 2 kayıt düzeninin, tamsayıdan Long 'a örtük dönüştürme nedeniyle uzun 2 tanımlama
grubu ile karşılaştırılabilmesinin gösterilmektedir:

// lifted conversions
var left = (a: 5, b: 10);
(int? a, int? b) nullableMembers = (5, 10);
Console.WriteLine(left == nullableMembers); // Also true

// converted type of left is (long, long)


(long a, long b) longTuple = (5, 10);
Console.WriteLine(left == longTuple); // Also true

// comparisons performed on (long, long) tuples


(long a, int b) longFirst = (5, 10);
(int a, long b) longSecond = (5, 10);
Console.WriteLine(longFirst == longSecond); // Also true

Demet üyelerinin adları, eşitlik için testlere katılmaz. Ancak, işlenenden biri açık adlara sahip bir demet sabit
değeri ise, bu adlar diğer işlenenin adlarıyla eşleşmezse, derleyici uyarı CS8383 oluşturur. Her iki işlenenin de
demet sabit değerleri olduğu durumlarda, aşağıdaki örnekte gösterildiği gibi uyarı sağ işlenende olur:

(int a, string b) pair = (1, "Hello");


(int z, string y) another = (1, "Hello");
Console.WriteLine(pair == another); // true. Member names don't participate.
Console.WriteLine(pair == (z: 1, y: "Hello")); // warning: literal contains different member names

Son olarak, tanımlama grupları iç içe diziler içerebilir. Tanımlama grubu eşitliği, aşağıdaki örnekte gösterildiği
gibi, iç içe geçmiş diziler aracılığıyla her bir işlenenin "şeklini" karşılaştırır:

(int, (int, int)) nestedTuple = (1, (2, 3));


Console.WriteLine(nestedTuple == (1, (2, 3)) );

Farklı şekilleri olduğunda, eşitlik (veya eşitsizlik) için iki tanımlama grubunu karşılaştırmak üzere bir derleme
zamanı hatası. Derleyici, iç içe geçmiş tanımlama gruplarının kendisini karşılaştırmak için denenmez.

Atama ve tanımlama grupları


Dil, her bir sağ taraftaki öğenin örtük olarak karşılık gelen sol taraftaki öğesine dönüştürülebileceği, aynı
sayıda öğeye sahip demet türleri arasında atamayı destekler. Diğer dönüşümler atamalar için kabul edilmez.
Farklı şekillerde bir tanımlama grubu atamak için bir derleme zamanı hatası vardır. Derleyici, iç içe geçmiş
tanımlama gruplarının atamasını atamak için denenmez. Demet türleri arasında izin verilen atama türlerine
bakalım.
Aşağıdaki örneklerde kullanılan değişkenleri göz önünde bulundurun:

// The 'arity' and 'shape' of all these tuples are compatible.


// The only difference is the field names being used.
var unnamed = (42, "The meaning of life");
var anonymous = (16, "a perfect square");
var named = (Answer: 42, Message: "The meaning of life");
var differentNamed = (SecretConstant: 42, Label: "The meaning of life");

İlk iki değişken, unnamed ve anonymous öğeler için belirtilen semantik adlara sahip değildir. Alan adları Item1
ve Item2 ' dir. Son iki değişken, named ve differentName öğeler için verilen semantik adlara sahiptir. Bu iki
başlık, öğeler için farklı adlara sahiptir.
Bu başlıkların dördü, aynı sayıda öğeye sahiptir (' kardinalite ' olarak adlandırılır) ve bu öğelerin türleri aynıdır.
Bu nedenle, bu atamaların hepsi çalışır:

unnamed = named;

named = unnamed;
// 'named' still has fields that can be referred to
// as 'answer', and 'message':
Console.WriteLine($"{named.Answer}, {named.Message}");

// unnamed to unnamed:
anonymous = unnamed;

// named tuples.
named = differentNamed;
// The field names are not assigned. 'named' still has
// fields that can be referred to as 'answer' and 'message':
Console.WriteLine($"{named.Answer}, {named.Message}");

// With implicit conversions:


// int can be implicitly converted to long
(long, string) conversion = named;

Başlıkların adlarının atanmadığından emin olun. Öğelerin değerleri, kayıt düzeni içindeki öğelerin sırasını
izleyerek atanır.
Farklı türlerin veya öğe sayılarının başlıkları atanamaz:

// Does not compile.


// CS0029: Cannot assign Tuple(int,int,int) to Tuple(int, string)
var differentShape = (1, 2, 3);
named = differentShape;

Yöntem dönüş değerleri olarak tanımlama grubu


Tanımlama grupları için en yaygın kullanımdan biri yöntem dönüş değeri olarak belirlenir. Bir örnek adım
adım inceleyelim. Bir dizi sayı için standart sapmayı hesaplayan bu yöntemi göz önünde bulundurun:
public static double StandardDeviation(IEnumerable<double> sequence)
{
// Step 1: Compute the Mean:
var mean = sequence.Average();

// Step 2: Compute the square of the differences between each number


// and the mean:
var squaredMeanDifferences = from n in sequence
select (n - mean) * (n - mean);
// Step 3: Find the mean of those squared differences:
var meanOfSquaredDifferences = squaredMeanDifferences.Average();

// Step 4: Standard Deviation is the square root of that mean:


var standardDeviation = Math.Sqrt(meanOfSquaredDifferences);
return standardDeviation;
}

NOTE
Bu örnekler düzeltilmeyen örnek standart sapmayı hesaplar. Düzeltilen örnek standart sapma formülü, Average
genişletme yöntemi olduğundan, kare farklarının toplamını N yerine (N-1) değerine böler. Standart sapma için bu
formüller arasındaki farklılıklar hakkında daha fazla ayrıntı için bir istatistik metnine danışın.

Yukarıdaki kod, standart sapma için textbook formülünü izler. Doğru yanıtı üretir ancak bu, verimsiz bir
uygulama. Bu yöntem, diziyi iki kez numaralandırır: ortalamayı üretmek için bir kez ve ortalamanın farkının
ortalamasının ortalamasını üretmek için bir kez. (LINQ sorgularının geç değerlendirildiğini unutmayın. bu
nedenle, ortalama farklar ve bu farkların ortalaması yalnızca bir numaralandırma yapar.)
Dizinin yalnızca bir listesini kullanarak standart sapmayı hesaplayan alternatif bir formül vardır. Bu hesaplama,
diziyi numaralandırdığından iki değer üretir: dizideki tüm öğelerin toplamı ve her bir değerin kare toplamı:

public static double StandardDeviation(IEnumerable<double> sequence)


{
double sum = 0;
double sumOfSquares = 0;
double count = 0;

foreach (var item in sequence)


{
count++;
sum += item;
sumOfSquares += item * item;
}

var variance = sumOfSquares - sum * sum / count;


return Math.Sqrt(variance / count);
}

Bu sürüm, diziyi tam olarak bir kez numaralandırır. Ancak yeniden kullanılabilir kod değildir. Çalışmaya devam
ederseniz, birçok farklı istatistiksel hesaplamaların dizideki öğelerin sayısını, sıranın toplamını ve dizi
karelerinin toplamını kullanmasını göreceksiniz. Bu yöntemi yeniden düzenleme ve bu değerlerin üçünü de
üreten bir yardımcı program yöntemi yazma. Üç değer de bir tanımlama grubu olarak döndürülebilir.
Bu yöntemi, numaralandırma sırasında hesaplanan üç değerin bir kayıt düzeninde depolanması için
güncelleştirelim. Bu sürümü oluşturur:
public static double StandardDeviation(IEnumerable<double> sequence)
{
var computation = (Count: 0, Sum: 0.0, SumOfSquares: 0.0);

foreach (var item in sequence)


{
computation.Count++;
computation.Sum += item;
computation.SumOfSquares += item * item;
}

var variance = computation.SumOfSquares - computation.Sum * computation.Sum / computation.Count;


return Math.Sqrt(variance / computation.Count);
}

Visual Studio 'nun yeniden düzenleme desteği, çekirdek istatistik işlevlerinin özel bir yönteme
ayıklanabilmesini kolaylaştırır. Bu, Sum , SumOfSquares ve Count ' ün üç değeri ile demet türünü döndüren
private static yöntemi sağlar:

public static double StandardDeviation(IEnumerable<double> sequence)


{
(int Count, double Sum, double SumOfSquares) computation = ComputeSumAndSumOfSquares(sequence);

var variance = computation.SumOfSquares - computation.Sum * computation.Sum / computation.Count;


return Math.Sqrt(variance / computation.Count);
}

private static (int Count, double Sum, double SumOfSquares) ComputeSumAndSumOfSquares(IEnumerable<double>


sequence)
{
var computation = (count: 0, sum: 0.0, sumOfSquares: 0.0);

foreach (var item in sequence)


{
computation.count++;
computation.sum += item;
computation.sumOfSquares += item * item;
}

return computation;
}

Dil, el ile birkaç hızlı düzenleme yapmak istiyorsanız kullanabileceğiniz birkaç seçenek sağlar. İlk olarak, var
bildirimini kullanarak ComputeSumAndSumOfSquares yöntem çağrısından kayıt düzeni sonucunu başlatabilirsiniz.
ComputeSumAndSumOfSquares yöntemi içinde üç ayrı değişken de oluşturabilirsiniz. Son sürüm aşağıdaki kodda
gösterilmiştir:
public static double StandardDeviation(IEnumerable<double> sequence)
{
var computation = ComputeSumAndSumOfSquares(sequence);

var variance = computation.SumOfSquares - computation.Sum * computation.Sum / computation.Count;


return Math.Sqrt(variance / computation.Count);
}

private static (int Count, double Sum, double SumOfSquares) ComputeSumAndSumOfSquares(IEnumerable<double>


sequence)
{
double sum = 0;
double sumOfSquares = 0;
int count = 0;

foreach (var item in sequence)


{
count++;
sum += item;
sumOfSquares += item * item;
}

return (count, sum, sumOfSquares);


}

Bu son sürüm, bu üç değere veya bunların herhangi bir alt kümesine ihtiyacı olan herhangi bir yöntem için
kullanılabilir.
Dil, bu demet döndürme yöntemlerinde öğelerin adlarını yönetmenin diğer seçeneklerini destekler.
Dönüş değeri bildiriminden alan adlarını kaldırabilir ve adlandırılmamış bir tanımlama grubu
döndürebilirsiniz:

private static (double, double, int) ComputeSumAndSumOfSquares(IEnumerable<double> sequence)


{
double sum = 0;
double sumOfSquares = 0;
int count = 0;

foreach (var item in sequence)


{
count++;
sum += item;
sumOfSquares += item * item;
}

return (sum, sumOfSquares, count);


}

Bu kayıt düzeninin alanları Item1 , Item2 ve Item3 olarak adlandırılır. Metotlardan döndürülen başlıkların
öğelerine anlam isimleri sağlamanız önerilir.
LINQ sorguları yazarken, tanımlama gruplarının yararlı olabilecek başka bir IOM. Son öngörülen sonuç,
seçilen nesnelerin özelliklerinin tümünü değil, genellikle bazılarını içerir.
Genellikle sorgunun sonuçlarını anonim bir tür bir nesne dizisine proje olarak projecekti. Bu çok sayıda
kısıtlama sunuyordu, öncelikle anonim türler bir yöntem için dönüş türünde kolaylıkla adlandırılamadığından.
Sonuç türü olarak object veya dynamic kullanmanın alternatifleri, önemli performans maliyetleriyle birlikte
geldi.
Bir demet türü dizisinin döndürülmesi kolaydır ve öğelerin adları ve türleri derleme zamanında ve IDE araçları
aracılığıyla kullanılabilir. Örneğin, bir ToDo uygulaması düşünün. Yapılacaklar listesindeki tek bir girişi
göstermek için aşağıdakine benzer bir sınıf tanımlayabilirsiniz:

public class ToDoItem


{
public int ID { get; set; }
public bool IsDone { get; set; }
public DateTime DueDate { get; set; }
public string Title { get; set; }
public string Notes { get; set; }
}

Mobil uygulamalarınız, yalnızca başlığı görüntüleyen geçerli ToDo öğelerinin Compact formunu
destekleyebilir. Bu LINQ sorgusu, yalnızca KIMLIĞI ve başlığı içeren bir projeksiyon oluşturacak. Bir
tanımlama grubu sırası döndüren bir yöntem tasarımın iyi olduğunu ifade eder:

internal IEnumerable<(int ID, string Title)> GetCurrentItemsMobileList()


{
return from item in AllItems
where !item.IsDone
orderby item.DueDate
select (item.ID, item.Title);
}

NOTE
7,1 C# ' de demet projeksiyonları, anonim türlerde özellik adlandırmasına benzer şekilde, öğeleri kullanarak, adlandırılmış
tanımlama grupları oluşturmanıza imkan tanır. Yukarıdaki kodda, sorgu projeksiyonundaki select deyimleri, ID ve
Title öğelerine sahip bir tanımlama grubu oluşturur.

Adlandırılmış tanımlama grubu, imzanın bir parçası olabilir. Derleyicinin ve IDE araçlarının, sonucu doğru
şekilde kullandığınızı, statik denetim sağlamasına imkan tanır. Adlandırılmış tanımlama grubu statik tür
bilgilerini de taşır, bu nedenle, sonuçlarla çalışmak için yansıma veya dinamik bağlama gibi pahalı çalışma
süresi özelliklerinin kullanılmasına gerek yoktur.

Ayrıştırma
Bir yöntem tarafından döndürülen kayıt grubunu kaldırarak bir kayıt grubundaki tüm öğelerin paketini
kaldırabilirsiniz. Başlıkların çıkarılması için üç farklı yaklaşım vardır. İlk olarak, her bir alanın türünü parantez
içindeki her bir öğe için ayrı değişkenler oluşturmak üzere açıkça bildirebilirsiniz:

public static double StandardDeviation(IEnumerable<double> sequence)


{
(int count, double sum, double sumOfSquares) = ComputeSumAndSumOfSquares(sequence);

var variance = sumOfSquares - sum * sum / count;


return Math.Sqrt(variance / count);
}

Ayrıca, parantez dışında var anahtar sözcüğünü kullanarak bir kayıt grubundaki her bir alan için örtük olarak
yazılan değişkenler de bildirebilirsiniz:
public static double StandardDeviation(IEnumerable<double> sequence)
{
var (sum, sumOfSquares, count) = ComputeSumAndSumOfSquares(sequence);

var variance = sumOfSquares - sum * sum / count;


return Math.Sqrt(variance / count);
}

Ayrıca, parantez içindeki tüm değişken bildirimleri veya var anahtar sözcüğünü kullanmak da geçerlidir.

(double sum, var sumOfSquares, var count) = ComputeSumAndSumOfSquares(sequence);

Kayıt grubundaki her alan aynı türde olsa bile, parantez dışında belirli bir tür kullanamazsınız.
Mevcut bildirimlerle de tanımlama gruplarını kaldırabilirsiniz:

public class Point


{
public int X { get; set; }
public int Y { get; set; }

public Point(int x, int y) => (X, Y) = (x, y);


}

WARNING
Parantez içindeki bildirimlerle mevcut bildirimleri karıştıramazsınız. Örneğin, aşağıdakilere izin verilmez:
(var x, y) = MyMethod(); . X , parantez içinde bildirildiği ve y daha önce başka bir yerde BILDIRILDIĞI için bu hata
CS8184 oluşturur.

Kullanıcı tanımlı türleri kaldırma


Herhangi bir demet türü, yukarıda gösterilen şekilde kaldırılabilir. Kullanıcı tanımlı herhangi bir tür (sınıflar,
yapılar veya hatta arabirimler) üzerinde oluşturmayı etkinleştirmek de kolaydır.
Tür yazarı, türü oluşturan veri öğelerini temsil eden herhangi bir sayıda out değişkenine değer atayan bir
veya daha fazla Deconstruct yöntemi tanımlayabilir. Örneğin, aşağıdaki Person türü, bir kişi nesnesini ilk adı
ve soyadı temsil eden öğelere oluşturan bir Deconstruct yöntemi tanımlar:

public class Person


{
public string FirstName { get; }
public string LastName { get; }

public Person(string first, string last)


{
FirstName = first;
LastName = last;
}

public void Deconstruct(out string firstName, out string lastName)


{
firstName = FirstName;
lastName = LastName;
}
}

Deyapý yöntemi, FirstName ve LastName özelliklerini temsil eden Person ' dan iki dizeye atamayı sağlar:
var p = new Person("Althea", "Goodwin");
var (first, last) = p;

Yazmayan türler için bile, oluşturmayı etkinleştirebilirsiniz. Deconstruct yöntemi, bir nesnenin erişilebilir veri
üyelerini paketten uygulayan bir genişletme yöntemi olabilir. Aşağıdaki örnekte, Person türünden türetilmiş
bir Student türü ve FirstName , LastName ve GPA temsil eden üç değişkene Student oluşturan bir
genişletme yöntemi gösterilmektedir:

public class Student : Person


{
public double GPA { get; }
public Student(string first, string last, double gpa) :
base(first, last)
{
GPA = gpa;
}
}

public static class Extensions


{
public static void Deconstruct(this Student s, out string first, out string last, out double gpa)
{
first = s.FirstName;
last = s.LastName;
gpa = s.GPA;
}
}

Student nesnesi artık iki adet erişilebilir Deconstruct yöntemine sahiptir: Student türleri için belirtilen
genişletme yöntemi ve Person türü üyesi. Her ikisi de kapsamdadır ve bir Student ' ı iki değişkene veya
üçüne ayırmayı sağlar. Üç değişkene bir öğrenci atarsanız, ilk ad, soyadı ve GPA döndürülür. İki değişkene bir
öğrenci atarsanız, yalnızca ad ve soyadı döndürülür.

var s1 = new Student("Cary", "Totten", 4.5);


var (fName, lName, gpa) = s1;

Bir sınıfta veya sınıf hiyerarşisinde birden çok Deconstruct yöntemi tanımlamayı dikkatli olmanız gerekir. Aynı
sayıda out parametresi olan birden çok Deconstruct yöntemi hızla belirsizlikleri neden olabilir. Çağıranlar
istenen Deconstruct yöntemini kolayca çağıramayabilir.
Bu örnekte, belirsiz bir çağrı için en az şans vardır çünkü Person için Deconstruct yöntemi iki çıkış
parametresine sahip ve Student için Deconstruct yönteminin üç tane vardır.
Yinelenenleri kaldırma işleçleri, test eşitliğine katılmaz. Aşağıdaki örnek, CS0019 derleyici hatası oluşturur:

Person p = new Person("Althea", "Goodwin");


if (("Althea", "Goodwin") == p)
Console.WriteLine(p);

Deconstruct yöntemi, Person nesne p iki dize içeren bir kayıt türüne dönüştürebilir, ancak eşitlik testleri
bağlamında geçerli değildir.

Out parametreleri olarak tanımlama grubu


Tanımlama grupları, out parametreleri olarakkullanılabilir. Daha önce ayrıştırma bölümünde bahsedilen
belirsizlik ile karıştırılmamalıdır. Bir yöntem çağrısında, yalnızca demet 'in şeklini açıklamanız gerekir:
Dictionary<int, (int, string)> dict = new Dictionary<int, (int, string)>();
dict.Add(1, (234, "First!"));
dict.Add(2, (345, "Second"));
dict.Add(3, (456, "Last"));

// TryGetValue already demonstrates using out parameters


dict.TryGetValue(2, out (int num, string place) pair);

Console.WriteLine($"{pair.num}: {pair.place}");

/*
* Output:
* 345: Second
*/

Alternatif olarak, adlandırılmamış bir tanımlama grubu kullanabilir ve alanlarına Item1 ve Item2 olarak
başvurabilirsiniz:

dict.TryGetValue(2, out (int, string) pair);


// ...
Console.WriteLine($"{pair.Item1}: {pair.Item2}");

Sonuç
Adlandırılmış tanımlama grupları için yeni dil ve kitaplık desteği, birden çok öğeyi depolayan ancak sınıflar ve
yapılar için davranış tanımlamadığınız veri yapılarını kullanan tasarımlarla çalışmayı çok daha kolay hale
getirir. Bu türler için tanımlama gruplarını kullanmak kolaydır. Daha ayrıntılı class veya struct sözdizimini
kullanarak tür yazmak zorunda kalmadan statik tür denetimi avantajlarından yararlanın. Bu sayede bile,
private veya internal olan yardımcı program yöntemleri için en iyi seçenektir. Ortak yöntemleriniz birden
çok öğeye sahip bir değer döndürzaman class veya struct tür Kullanıcı tanımlı türler oluşturun.
Demetleri ve diğer türleri ayrıştırma
31.10.2019 • 15 minutes to read • Edit Online

Kayıt düzeni, bir yöntem çağrısından birden çok değer almanın hafif bir yolunu sağlar. Ancak, tanımlama grubunu
aldıktan sonra ayrı öğelerini işlemeniz gerekir. Bu işlem, aşağıdaki örnekte gösterildiği gibi, öğe temelinde tek
yapmanız gereken bir öğedir. QueryCityData yöntemi 3 tanımlama grubu döndürür ve öğelerinden her biri ayrı bir
işlemde bir değişkene atanır.

using System;

public class Example


{
public static void Main()
{
var result = QueryCityData("New York City");

var city = result.Item1;


var pop = result.Item2;
var size = result.Item3;

// Do something with the data.


}

private static (string, int, double) QueryCityData(string name)


{
if (name == "New York City")
return (name, 8175133, 468.48);

return ("", 0, 0);


}
}

Bir nesneden birden çok alan ve özellik değeri alınması eşit bir şekilde olabilir: üye üye temelinde bir değişkene bir
alan veya özellik değeri atamanız gerekir.
C# 7,0 ' den başlayarak, bir tanımlama grubundan birden çok öğe alabilir veya tek bir Yapı işlemindeki bir
nesneden birden çok alan, özellik ve hesaplanan değer alabilirsiniz. Bir tanımlama grubu oluştururken, öğelerini
ayrı değişkenlere atarsınız. Bir nesneyi kaldırdığınızda, seçili değerleri ayrı değişkenlere atarsınız.

Kayıt düzeni kaldırma


C#, tek bir işlemde bir kayıt grubundaki tüm öğeleri paketlemenizi sağlayan tanımlama grupları için yerleşik destek
özellikleri. Bir kayıt düzeni oluşturmak için genel sözdizimi, bir tanımlama sözdizimine benzer. bir atama ifadesinin
sol tarafında parantez içine atanacak olan değişkenleri çevrelemektir. Örneğin, aşağıdaki ifade 4 kayıt öğelerinin
öğelerini dört ayrı değişkene atar:

var (name, address, city, zip) = contact.GetAddressInfo();

Tanımlama grubu oluşturmanın üç yolu vardır:


Her alanın türünü parantez içinde açık bir şekilde bildirebilirsiniz. Aşağıdaki örnek, QueryCityData metodu
tarafından döndürülen 3 kayıt düzeni oluşturmak için bu yaklaşımı kullanır.
public static void Main()
{
(string city, int population, double area) = QueryCityData("New York City");

// Do something with the data.


}

Her değişkenin türünü karşılayan C# var anahtar sözcüğünü kullanabilirsiniz. var anahtar sözcüğünü
parantezlerin dışında yerleştirebilirsiniz. Aşağıdaki örnek, QueryCityData yöntemi tarafından döndürülen 3
kayıt düzeni oluştururken tür çıkarımı kullanır.

public static void Main()


{
var (city, population, area) = QueryCityData("New York City");

// Do something with the data.


}

var anahtar sözcüğünü, parantez içindeki değişken bildirimlerinin herhangi biri veya tümü ile ayrı ayrı de
kullanabilirsiniz.

public static void Main()


{
(string city, var population, var area) = QueryCityData("New York City");

// Do something with the data.


}

Bu, kısabera ve önerilmez.


Son olarak, tanımlama grubunu zaten önceden tanımlanmış değişkenler halinde oluşturabilirsiniz.

public static void Main()


{
string city = "Raleigh";
int population = 458880;
double area = 144.8;

(city, population, area) = QueryCityData("New York City");

// Do something with the data.


}

Kayıt grubundaki her alan aynı türde olsa bile, parantez dışında belirli bir tür belirtemezsiniz. Bu bir derleyici hatası
oluşturur CS8136, "Deinşaat" var (...) ' formu, ' var ' için belirli bir türe izin vermez. ".
Ayrıca, kayıt düzeni öğelerinin her birini bir değişkene atamanız gerektiğini unutmayın. Herhangi bir öğeyi
atlarsanız, derleyici CS8132 hatasını üretir, "' x ' öğelerinden oluşan bir demet ' y ' değişkenlerine parçalanamaz."
Bir oluşturma 'nın sol tarafındaki mevcut değişkenlere bildirimleri ve atamaları karıştırmayacağınızı unutmayın.
Derleyici hata CS8184 oluşturuyor, "bir oluşturma, sol taraftaki bildirimleri ve ifadeleri karıştıramaz." üyeler yeni
tanımlanan ve mevcut değişkenleri içerenleri içerir.

Kayıt düzeni öğeleri atma ile kaldırılıyor


Genellikle bir kayıt düzeni oluştururken yalnızca bazı öğelerin değerleriyle ilgileniyorsunuz. 7,0 ' C# den itibaren,
değerlerini yok saymayı C#seçtiğiniz salt yazılır değişkenler olan atmadesteğinden yararlanabilirsiniz. Atma bir
atamadaki alt çizgi karakteriyle ("_") belirtilir. İstediğiniz sayıda değeri atabilirsiniz; tümü, _ tek bir atma tarafından
temsil edilir.
Aşağıdaki örnek, atma ile başlıkların kullanımını gösterir. QueryCityDataForYears yöntemi, şehir adı, alanı, bir yıl, bu
yıl için şehir popülasyonu, ikinci yıl ve bu ikinci yıl için şehir popülasyonu olan 6 tanımlama grubu döndürür. Örnek,
bu iki yıl arasındaki popülasyondaki değişikliği gösterir. Kayıt kümesinden kullanılabilen veriler, şehir alanıyla
ilgilentik ve tasarım zamanında şehir adını ve iki tarihi biliyoruz. Sonuç olarak, yalnızca kayıt düzeninde depolanan
iki popülasyon değeri ile ilgileniyoruz ve kalan değerlerini atma olarak işleyebilir.

using System;
using System.Collections.Generic;

public class Example


{
public static void Main()
{
var (_, _, _, pop1, _, pop2) = QueryCityDataForYears("New York City", 1960, 2010);

Console.WriteLine($"Population change, 1960 to 2010: {pop2 - pop1:N0}");


}

private static (string, double, int, int, int, int) QueryCityDataForYears(string name, int year1, int
year2)
{
int population1 = 0, population2 = 0;
double area = 0;

if (name == "New York City")


{
area = 468.48;
if (year1 == 1960)
{
population1 = 7781984;
}
if (year2 == 2010)
{
population2 = 8175133;
}
return (name, area, year1, population1, year2, population2);
}

return ("", 0, 0, 0, 0, 0);


}
}
// The example displays the following output:
// Population change, 1960 to 2010: 393,149

Kullanıcı tanımlı türleri kaldırma


C#, kayıt olmayan türler oluşturmak için yerleşik destek sunmaz. Ancak, bir sınıfın yazarı, bir struct veya Interface
olarak, bir veya daha fazla Deconstruct yöntemi uygulayarak tür örneklerinin çıkarılması için izin verebilirsiniz.
Yöntemi void döndürür ve kaldırılacak her değer, yöntem imzasında bir Out parametresi ile belirtilir. Örneğin, bir
Person sınıfının aşağıdaki Deconstruct yöntemi birinci, orta ve son adı döndürür:

public void Deconstruct(out string fname, out string mname, out string lname)

Daha sonra, aşağıdaki gibi bir atamayla p adlı Person sınıfının bir örneğini kaldırabilirsiniz:

var (fName, mName, lName) = p;


Aşağıdaki örnek, bir Person nesnesinin özelliklerinin çeşitli birleşimlerini döndürmek için Deconstruct yöntemini
aşırı yükler. Tek tek aşırı yükleme dönüşü:
Ad ve soyadı.
Birinci, son ve orta ad.
Ad, soyadı, şehir adı ve durum adı.

using System;

public class Person


{
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public string City { get; set; }
public string State { get; set; }

public Person(string fname, string mname, string lname,


string cityName, string stateName)
{
FirstName = fname;
MiddleName = mname;
LastName = lname;
City = cityName;
State = stateName;
}

// Return the first and last name.


public void Deconstruct(out string fname, out string lname)
{
fname = FirstName;
lname = LastName;
}

public void Deconstruct(out string fname, out string mname, out string lname)
{
fname = FirstName;
mname = MiddleName;
lname = LastName;
}

public void Deconstruct(out string fname, out string lname,


out string city, out string state)
{
fname = FirstName;
lname = LastName;
city = City;
state = State;
}
}

public class Example


{
public static void Main()
{
var p = new Person("John", "Quincy", "Adams", "Boston", "MA");

// Deconstruct the person object.


var (fName, lName, city, state) = p;
Console.WriteLine($"Hello {fName} {lName} of {city}, {state}!");
}
}
// The example displays the following output:
// Hello John Adams of Boston, MA!
Bir nesneden yaygın olarak ayıklanan veri gruplarını yansıtmak için Deconstruct yöntemini aşırı yükleyebilirsiniz.
Bu, benzersiz ve belirsiz imzalara sahip Deconstruct yöntemleri tanımlamaya dikkat etmeniz gerekir. Aynı sayıda
out parametresine sahip birden çok Deconstruct yöntemi ya da farklı bir düzende aynı sayıda out parametresi
olabilir karışıklıklara neden olabilir.
Aşağıdaki örnekteki aşırı yüklenmiş Deconstruct yöntemi, olası bir karışıklık kaynağını göstermektedir. İlk aşırı
yükleme, Person nesnenin adı, ikinci adı, soyadı ve yaşını bu sırayla döndürür. İkinci aşırı yükleme yalnızca yıllık
gelirle birlikte ad bilgilerini döndürür, ancak birinci, orta ve soyadı farklı bir sıralardır. Bu, bir Person örneği
oluştururken bağımsız değişkenlerin sırasını karıştırmayı kolaylaştırır.

using System;

public class Person


{
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public string City { get; set; }
public string State { get; set; }
public DateTime DateOfBirth { get; set; }
public Decimal AnnualIncome { get; set; }

public void Deconstruct(out string fname, out string mname, out string lname, out int age)
{
fname = FirstName;
mname = MiddleName;
lname = LastName;
age = DateTime.Now.Year - DateOfBirth.Year;

if (DateTime.Now.DayOfYear - (new DateTime(DateTime.Now.Year, DateOfBirth.Month,


DateOfBirth.Day)).DayOfYear < 0)
age--;
}

public void Deconstruct(out string lname, out string fname, out string mname, out decimal income)
{
fname = FirstName;
mname = MiddleName;
lname = LastName;
income = AnnualIncome;
}
}

Kullanıcı tanımlı bir türü atma ile kaldırma


Tanımlama gruplarıile yaptığınız gibi, bir Deconstruct yöntemi tarafından döndürülen seçili öğeleri yoksaymak için
atarsa ' u kullanabilirsiniz. Her atma "_" adlı bir değişken tarafından tanımlanır ve tek bir ayrıştırma işlemi birden
çok atma içerebilir.
Aşağıdaki örnek, bir Person nesnesini dört dizeye (ilk ve son adlar, şehir ve eyalet) oluşturur, ancak son adı ve
durumu atar.

// Deconstruct the person object.


var (fName, _, city, _) = p;
Console.WriteLine($"Hello {fName} of {city}!");
// The example displays the following output:
// Hello John of Boston!

Uzantı yöntemiyle kullanıcı tanımlı bir tür kaldırma


Bir sınıf, yapı veya arabirim yazmadıysanız, ilgilendiğiniz değerleri döndürmek için bir veya daha fazla Deconstruct
uzantısı yöntemi uygulayarak bu türdeki nesneleri yine de oluşturabilirsiniz.
Aşağıdaki örnek, System.Reflection.PropertyInfo sınıfı için iki Deconstruct uzantısı yöntemini tanımlar. İlki,
özelliğin özelliklerini gösteren, türü, statik mi, örnek mi olduğunu, salt okunurdur ve dizine eklenip
eklenmeyeceğini içeren bir değerler kümesi döndürür. İkincisi, özelliğin erişilebilirliğini gösterir. Get ve set
erişimcilerinin erişilebilirliği farklı olabileceğinden, Boole değerleri özelliğin ayrı Get ve set erişimcilerine sahip olup
olmadığını ve varsa aynı erişilebilirliği içerip içermediğini gösterir. Yalnızca bir erişimci varsa veya hem Get hem de
set erişimcisinin aynı erişilebilirliği varsa access değişkeni, özelliğin erişilebilirliğini bir bütün olarak gösterir. Aksi
takdirde, Get ve set erişimcilerinin erişilebilirliği getAccess ve setAccess değişkenleriyle belirtilir.

using System;
using System.Collections.Generic;
using System.Reflection;

public static class ReflectionExtensions


{
public static void Deconstruct(this PropertyInfo p, out bool isStatic,
out bool isReadOnly, out bool isIndexed,
out Type propertyType)
{
var getter = p.GetMethod;

// Is the property read-only?


isReadOnly = ! p.CanWrite;

// Is the property instance or static?


isStatic = getter.IsStatic;

// Is the property indexed?


isIndexed = p.GetIndexParameters().Length > 0;

// Get the property type.


propertyType = p.PropertyType;
}

public static void Deconstruct(this PropertyInfo p, out bool hasGetAndSet,


out bool sameAccess, out string access,
out string getAccess, out string setAccess)
{
hasGetAndSet = sameAccess = false;
string getAccessTemp = null;
string setAccessTemp = null;

MethodInfo getter = null;


if (p.CanRead)
getter = p.GetMethod;

MethodInfo setter = null;


if (p.CanWrite)
setter = p.SetMethod;

if (setter != null && getter != null)


hasGetAndSet = true;

if (getter != null)
{
if (getter.IsPublic)
getAccessTemp = "public";
else if (getter.IsPrivate)
getAccessTemp = "private";
else if (getter.IsAssembly)
getAccessTemp = "internal";
else if (getter.IsFamily)
getAccessTemp = "protected";
else if (getter.IsFamilyOrAssembly)
else if (getter.IsFamilyOrAssembly)
getAccessTemp = "protected internal";
}

if (setter != null)
{
if (setter.IsPublic)
setAccessTemp = "public";
else if (setter.IsPrivate)
setAccessTemp = "private";
else if (setter.IsAssembly)
setAccessTemp = "internal";
else if (setter.IsFamily)
setAccessTemp = "protected";
else if (setter.IsFamilyOrAssembly)
setAccessTemp = "protected internal";
}

// Are the accessibility of the getter and setter the same?


if (setAccessTemp == getAccessTemp)
{
sameAccess = true;
access = getAccessTemp;
getAccess = setAccess = String.Empty;
}
else
{
access = null;
getAccess = getAccessTemp;
setAccess = setAccessTemp;
}
}
}

public class Example


{
public static void Main()
{
Type dateType = typeof(DateTime);
PropertyInfo prop = dateType.GetProperty("Now");
var (isStatic, isRO, isIndexed, propType) = prop;
Console.WriteLine($"\nThe {dateType.FullName}.{prop.Name} property:");
Console.WriteLine($" PropertyType: {propType.Name}");
Console.WriteLine($" Static: {isStatic}");
Console.WriteLine($" Read-only: {isRO}");
Console.WriteLine($" Indexed: {isIndexed}");

Type listType = typeof(List<>);


prop = listType.GetProperty("Item",
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance |
BindingFlags.Static);
var (hasGetAndSet, sameAccess, accessibility, getAccessibility, setAccessibility) = prop;
Console.Write($"\nAccessibility of the {listType.FullName}.{prop.Name} property: ");

if (!hasGetAndSet | sameAccess)
{
Console.WriteLine(accessibility);
}
else
{
Console.WriteLine($"\n The get accessor: {getAccessibility}");
Console.WriteLine($" The set accessor: {setAccessibility}");
}
}
}
// The example displays the following output:
// The System.DateTime.Now property:
// PropertyType: DateTime
// Static: True
// Read-only: True
// Indexed: False
//
// Accessibility of the System.Collections.Generic.List`1.Item property: public

Ayrıca bkz.
Atılanlar
Demetler
Arabirimler (C# Programlama Kılavuzu)
31.10.2019 • 7 minutes to read • Edit Online

Bir arabirim, soyut olmayan bir sınıfın veya yapının uygulanması gereken ilgili işlevler grubu için tanımlar içerir.
Arabirimleri kullanarak, örneğin, bir sınıftaki birden çok kaynaktan davranış ekleyebilirsiniz. Dil, sınıfların birden çok
C# devralınmasını desteklemediğinden bu özellik önemlidir. Bunlara ek olarak, başka bir struct veya sınıftan
gerçekten devralmadıklarından yapılar için devralmayı taklit etmek istiyorsanız bir arabirim kullanmanız gerekir.
Arabirim anahtar sözcüğünü kullanarak bir arabirim tanımlarsınız. Aşağıdaki örnekte gösterildiği gibi.

interface IEquatable<T>
{
bool Equals(T obj);
}

Yapının adı geçerli C# bir tanımlayıcı adıolmalıdır. Kural gereği, arabirim adları büyük I başlar.
IEquatable<T> arabirimini uygulayan herhangi bir sınıf veya yapı, arabirimin belirttiği imzayla eşleşen bir Equals
yöntemi tanımı içermelidir. Sonuç olarak, sınıfının bir örneğinin aynı sınıfın başka bir örneğine eşit olup olmadığını
belirleyebildiği bir Equals yöntemi içermesi için IEquatable<T> uygulayan bir sınıf üzerinde sayım yapabilirsiniz.
IEquatable<T> tanımı Equals için bir uygulama sağlamaz. Bir sınıf veya yapı birden çok arabirim uygulayabilir,
ancak bir sınıf yalnızca tek bir sınıftan devralınabilir.
Soyut sınıflar hakkında daha fazla bilgi için bkz. soyut ve korumalı sınıflar ve sınıf üyeleri.
Arabirimler Yöntemler, özellikler, olaylar, Dizin oluşturucular veya bu dört üye türlerinin herhangi bir birleşimini
içerebilir. Örneklere bağlantılar için Ilgili bölümlerbölümüne bakın. Arabirim, sabitler, alanlar, işleçler, örnek
oluşturucular, sonlandırıcılar veya türler içeremez. Arabirim üyeleri otomatik olarak geneldir ve erişim değiştiricileri
içeremez. Üyeler de statikolamaz.
Bir arabirim üyesini uygulamak için, uygulama sınıfının karşılık gelen üyesi ortak, statik değil olmalıdır ve arabirim
üyesiyle aynı ada ve imzaya sahip olmalıdır.
Bir sınıf veya yapı bir arabirim uygularsa, sınıf veya yapı, arabirimin tanımladığı tüm Üyeler için bir uygulama
sağlamalıdır. Arabirimin kendisi bir sınıf veya yapının, temel sınıf işlevini devraldığı şekilde devraldığı bir işlevsellik
sağlamaz. Ancak, bir temel sınıf bir arabirim uygularsa, taban sınıftan türetilmiş herhangi bir sınıf bu uygulamayı
devralır.
Aşağıdaki örnek, IEquatable<T> arabiriminin bir uygulamasını gösterir. Uygulama sınıfı Car , Equals yönteminin
bir uygulamasını sağlamalıdır.
public class Car : IEquatable<Car>
{
public string Make {get; set;}
public string Model { get; set; }
public string Year { get; set; }

// Implementation of IEquatable<T> interface


public bool Equals(Car car)
{
return this.Make == car.Make &&
this.Model == car.Model &&
this.Year == car.Year;
}
}

Bir sınıfın özellikleri ve Dizin oluşturucular, bir arabirimde tanımlı bir özellik veya Dizin Oluşturucu için ek
erişimciler tanımlayabilir. Örneğin, bir arabirim bir Get erişimcisine sahip bir özellik bildirebilir. Arabirimini
uygulayan sınıf, hem get hem de set erişimcisi ile aynı özelliği bildirebilir. Ancak, özellik veya Dizin Oluşturucu açık
uygulama kullanıyorsa, erişimcilerinin eşleşmesi gerekir. Açık uygulama hakkında daha fazla bilgi için bkz. Açık
arabirim uygulama ve arabirim özellikleri.
Arabirimler, diğer arabirimlerden devralınabilir. Bir sınıf, devraldığı temel sınıflar veya diğer arabirimlerin devraldığı
arabirimler aracılığıyla birden çok kez arabirim içerebilir. Ancak, sınıfı bir arabirimin uygulamasını yalnızca bir kez ve
yalnızca sınıf sınıfın tanımının bir parçası olarak bildirir ( class ClassName : InterfaceName ). Arabirimi uygulayan bir
temel sınıf devralmış olduğunuz için arabirim devralınmışsa, taban sınıf arabirimin üyelerinin uygulanmasını sağlar.
Ancak, türetilen sınıf devralınan uygulamayı kullanmak yerine herhangi bir sanal arabirim üyesini yeniden
uygulayabilir.
Bir temel sınıf, sanal Üyeler kullanarak arabirim üyeleri de uygulayabilir. Bu durumda, türetilmiş bir sınıf sanal
üyeleri geçersiz kılarak arabirim davranışını değiştirebilir. Sanal üyeler hakkında daha fazla bilgi için bkz. çok
biçimlilik.

Arabirimler Özeti
Bir arabirim aşağıdaki özelliklere sahiptir:
Bir arabirim, yalnızca soyut üyelere sahip bir soyut temel sınıf gibidir. Arabirimi uygulayan herhangi bir sınıf
veya yapının tüm üyelerini uygulaması gerekir.
Arabirim doğrudan başlatılamaz. Üyeleri, arabirimini uygulayan herhangi bir sınıf veya yapı tarafından uygulanır.
Arabirimler olay, Dizin oluşturucular, Yöntemler ve özellikler içerebilir.
Arabirimler yöntemlerin uygulanmasını içermez.
Bir sınıf veya yapı, birden çok arabirim uygulayabilir. Bir sınıf bir temel sınıfı devralınabilir ve ayrıca bir veya daha
fazla arabirim uygulayabilir.

Bu bölümde
Belirtik Arabirim Kullanma
Bir arabirime özgü bir sınıf üyesinin nasıl oluşturulacağını açıklar.
Nasıl yapılır: Arabirim Üyelerini Açıkça Uygulama
Arabirimlerin üyelerini açıkça nasıl uygulayacağınızı gösteren bir örnek sağlar.
Nasıl yapılır: İki Arabirimin Üyelerini Açıkça Uygulama
Devralma ile arabirimlerin üyelerini açıkça nasıl uygulayabileceğinizi gösteren bir örnek sağlar.

İlgili bölümler
Arabirim Özellikleri
Arabirimlerdeki Dizin Oluşturucular
Nasıl yapılır: arabirim olaylarını uygulama
Sınıflar ve Yapılar
Devralma
Yöntemler
Çok biçimlilik
Soyut ve Korumalı Sınıflar ve Sınıf Üyeleri
Veri Erişimi
Olaylar
Dizin Oluşturucular

öne çıkan kitap bölümü


Öğrenme C# 3,0 ' deki arabirimler: C# 3,0 temelleri ana

Ayrıca bkz.
C# Programlama Kılavuzu
Devralma
Tanımlayıcı adları
Yöntemler
31.10.2019 • 33 minutes to read • Edit Online

Yöntemi, bir dizi deyim içeren bir kod bloğudur. Program, metodu çağırarak ve gerekli Yöntem bağımsız
değişkenlerini belirterek deyimlerin yürütülmesine neden olur. ' C#De, her yürütülen yönerge bir yöntem
bağlamında gerçekleştirilir. Main yöntemi her C# uygulamanın giriş noktasıdır ve program başlatıldığında ortak
dil çalışma zamanı (CLR ) tarafından çağrılır.

NOTE
Bu konuda adlandırılmış yöntemler ele alınmaktadır. Anonim işlevler hakkında daha fazla bilgi için bkz. Anonim işlevler.

Yöntem imzaları
Yöntemler bir class veya struct belirtilen belirterek belirtilir:
public veya private gibi isteğe bağlı erişim düzeyi. Varsayılan, private değeridir.
abstract veya sealed gibi isteğe bağlı değiştiriciler.
Dönüş değeri veya yöntem None ise void .
Yöntem adı.
Herhangi bir yöntem parametresi. Yöntem parametreleri parantez içine alınır ve virgülle ayrılır. Boş parantezler,
yöntemin hiçbir parametre gerektirmediğini belirtir.
Bu parçalar birlikte yöntem imzasını oluşturur.

NOTE
Bir yöntemin dönüş türü, yöntem aşırı yüklemesi amaçları için yöntemin imzasının bir parçası değildir. Ancak, bir temsilci ve
işaret ettiği yöntem arasındaki uyumluluğun belirlenmesi sırasında yönteminin imzasının bir parçasıdır.

Aşağıdaki örnek, beş yöntem içeren Motorcycle adlı bir sınıfı tanımlar:

using System;

abstract class Motorcycle


{
// Anyone can call this.
public void StartEngine() {/* Method statements here */ }

// Only derived classes can call this.


protected void AddGas(int gallons) { /* Method statements here */ }

// Derived classes can override the base class implementation.


public virtual int Drive(int miles, int speed) { /* Method statements here */ return 1; }

// Derived classes can override the base class implementation.


public virtual int Drive(TimeSpan time, int speed) { /* Method statements here */ return 0; }

// Derived classes must implement this.


public abstract double GetTopSpeed();
}
Motorcycle sınıfının aşırı yüklenmiş bir yöntemi içerdiğini unutmayın Drive . İki yöntem aynı ada sahiptir, ancak
parametre türlerine göre farklılaştıralınmalıdır.

Yöntem çağırma
Yöntemler örnek veya statikolabilir. Örnek yöntemini çağırmak için bir nesnesi örneği oluşturabilir ve yöntemi bu
nesnede çağırabilirsiniz. örnek yöntemi Bu örnek ve verileri üzerinde çalışır. Yöntemin ait olduğu türün adına
başvurarak statik bir yöntem çağırılır; statik yöntemler örnek verilerinde çalışmaz. Bir nesne örneği aracılığıyla
statik bir yöntemi çağırma girişimi bir derleyici hatası oluşturur.
Bir yöntemi çağırmak, bir alana erişme gibidir. Nesne adından sonra (bir örnek yöntemi arıyorsanız) veya tür adı
(bir static yöntemi çağırırken), bir nokta, yöntemin adı ve parantez ekleyin. Bağımsız değişkenler parantez içinde
listelenir ve virgülle ayrılır.
Yöntem tanımı, gerekli parametrelerin adlarını ve türlerini belirtir. Bir çağıran yöntemini çağırdığında, her bir
parametre için bağımsız değişken olarak adlandırılan somut değerler sağlar. Bağımsız değişkenlerin parametre
türüyle uyumlu olması gerekir, ancak çağıran kodda bir tane kullanılırsa bağımsız değişken adının, yönteminde
tanımlanan parametre ile aynı olması gerekmez. Aşağıdaki örnekte Square yöntemi iadlı int türünde tek bir
parametre içerir. İlk yöntem çağrısı Square metodu, int türünde bir değişken olarak geçirir; İkinci, sayısal bir
sabit; ve üçüncü, bir ifade.

public class Example


{
public static void Main()
{
// Call with an int variable.
int num = 4;
int productA = Square(num);

// Call with an integer literal.


int productB = Square(12);

// Call with an expression that evaluates to int.


int productC = Square(productA * 3);
}

static int Square(int i)


{
// Store input argument in a local variable.
int input = i;
return input * input;
}
}

Yöntem çağırma tarafından kullanılan en yaygın biçim Konumsal bağımsız değişkenler; Yöntem parametreleriyle
aynı sırada bağımsız değişkenler sağlar. Bu nedenle Motorcycle sınıfının yöntemleri aşağıdaki örnekte olduğu gibi
çağrılabilir. Örneğin, Drive metoduna yapılan çağrı, yöntemin sözdiziminde iki parametreye karşılık gelen iki
bağımsız değişken içerir. Birincisi miles parametresinin değeri olur, ikinci değer speed parametresinin değeridir.
class TestMotorcycle : Motorcycle
{
public override double GetTopSpeed()
{
return 108.4;
}

static void Main()


{

TestMotorcycle moto = new TestMotorcycle();

moto.StartEngine();
moto.AddGas(15);
moto.Drive(5, 20);
double speed = moto.GetTopSpeed();
Console.WriteLine("My top speed is {0}", speed);
}
}

Bir yöntemi çağırırken Konumsal bağımsız değişkenler yerine adlandırılmış bağımsız değişkenler de
kullanabilirsiniz. Adlandırılmış bağımsız değişkenler kullanılırken, ardından iki nokta üst üste (":") ve bağımsız
değişken ile parametre adını belirtirsiniz. Yöntem için bağımsız değişkenler tüm gerekli bağımsız değişkenler
bulunduğu sürece herhangi bir sırada görünebilir. Aşağıdaki örnek, TestMotorcycle.Drive yöntemini çağırmak için
adlandırılmış bağımsız değişkenleri kullanır. Bu örnekte, adlandırılmış bağımsız değişkenler metodun parametre
listesinden ters sırada geçirilir.

using System;

class TestMotorcycle : Motorcycle


{
public override int Drive(int miles, int speed)
{
return (int) Math.Round( ((double)miles) / speed, 0);
}

public override double GetTopSpeed()


{
return 108.4;
}

static void Main()


{

TestMotorcycle moto = new TestMotorcycle();


moto.StartEngine();
moto.AddGas(15);
var travelTime = moto.Drive(speed: 60, miles: 170);
Console.WriteLine("Travel time: approx. {0} hours", travelTime);
}
}
// The example displays the following output:
// Travel time: approx. 3 hours

Bir yöntemi, hem Konumsal bağımsız değişkenleri hem de adlandırılmış bağımsız değişkenleri kullanarak
çağırabilirsiniz. Ancak, Konumsal bağımsız değişken adlandırılmış bir bağımsız değişkeni izleyemez. Aşağıdaki
örnek, bir Konumsal bağımsız değişken ve bir adlandırılmış bağımsız değişken kullanarak önceki örnekteki
TestMotorcycle.Drive yöntemini çağırır.

var travelTime = moto.Drive(170, speed: 55);


Devralınan ve geçersiz kılınan Yöntemler
Bir tür içinde açıkça tanımlanan üyelere ek olarak, bir tür, temel sınıflarında tanımlanan üyeleri devralır. Yönetilen
tür sistemindeki tüm türler Object sınıfından doğrudan veya dolaylı olarak devraldığı için, tüm türler üyelerini
(Equals(Object), GetType()ve ToString()gibi) alırlar. Aşağıdaki örnek, bir Person sınıfını tanımlar, iki Person
nesnesini başlatır ve iki nesnenin eşit olup olmadığını belirleyen Person.Equals yöntemini çağırır. Ancak Equals
yöntemi, Person sınıfında tanımlı değildir; Objectdevralınır.

using System;

public class Person


{
public String FirstName;
}

public class Example


{
public static void Main()
{
var p1 = new Person();
p1.FirstName = "John";
var p2 = new Person();
p2.FirstName = "John";
Console.WriteLine("p1 = p2: {0}", p1.Equals(p2));
}
}
// The example displays the following output:
// p1 = p2: False

Türler, override anahtar sözcüğünü kullanarak devralınan üyeleri geçersiz kılabilir ve geçersiz kılınan yöntem için
bir uygulama sağlar. Yöntem imzası, geçersiz kılınan metodun ile aynı olmalıdır. Aşağıdaki örnek, Equals(Object)
yönteminin geçersiz kılınmasının dışında, önceki bir gibidir. (İki yöntem tutarlı sonuçlar sağlamaya yönelik olduğu
için GetHashCode() yöntemini de geçersiz kılar.)
using System;

public class Person


{
public String FirstName;

public override bool Equals(object obj)


{
var p2 = obj as Person;
if (p2 == null)
return false;
else
return FirstName.Equals(p2.FirstName);
}

public override int GetHashCode()


{
return FirstName.GetHashCode();
}
}

public class Example


{
public static void Main()
{
var p1 = new Person();
p1.FirstName = "John";
var p2 = new Person();
p2.FirstName = "John";
Console.WriteLine("p1 = p2: {0}", p1.Equals(p2));
}
}
// The example displays the following output:
// p1 = p2: True

Parametreleri geçirme
İçindeki C# türler, değer türleri ya da başvuru türleridir. Yerleşik değer türlerinin bir listesi için bkz. türler ve
değişkenler. Varsayılan olarak, değer türleri ve başvuru türleri değere göre bir yönteme geçirilir.
Parametreleri değere göre geçirme
Değer türü bir yönteme değere göre geçirildiğinde, nesnesine nesnenin kendisi yerine bir kopyası geçirilir. Bu
nedenle, çağrılan yöntemdeki nesne üzerindeki değişikliklerin, Denetim çağırana döndüğünde özgün nesne
üzerinde hiçbir etkisi olmaz.
Aşağıdaki örnek bir değer türünü değere göre bir yönteme geçirir ve çağrılan yöntem değer türünün değerini
değiştirmeye çalışır. Değer türü olan int türünde bir değişken tanımlar, değerini 20 olarak başlatır ve değişkenin
değerini 30 olarak değiştiren ModifyValue adlı bir yönteme geçirir. Ancak yöntemi döndüğünde, değişkenin değeri
değişmeden kalır.
using System;

public class Example


{
public static void Main()
{
int value = 20;
Console.WriteLine("In Main, value = {0}", value);
ModifyValue(value);
Console.WriteLine("Back in Main, value = {0}", value);
}

static void ModifyValue(int i)


{
i = 30;
Console.WriteLine("In ModifyValue, parameter value = {0}", i);
return;
}
}
// The example displays the following output:
// In Main, value = 20
// In ModifyValue, parameter value = 30
// Back in Main, value = 20

Başvuru türündeki bir nesne bir değere göre yönteme geçirildiğinde, nesnesine bir başvuru değeri ile geçirilir.
Diğer bir deyişle, yöntem nesnenin kendisini değil, nesnenin konumunu gösteren bir bağımsız değişkendir. Bu
başvuruyu kullanarak nesnesinin bir üyesini değiştirirseniz, Denetim çağıran yönteme döndüğünde değişiklik
nesnesine yansıtılır. Ancak, metoduna geçirilen nesnenin değiştirilmesi, Denetim çağırana döndüğünde özgün
nesneyi etkilemez.
Aşağıdaki örnek, SampleRefType adlı bir sınıfı (bir başvuru türü) tanımlar. Bir SampleRefType nesnesi başlatır, value
alanına 44 atar ve nesneyi ModifyObject yöntemine geçirir. Bu örnek temelde önceki örnekle aynı şeyi yapar; bir
bağımsız değişkeni değere göre bir yönteme geçirir. Ancak, bir başvuru türü kullanıldığından, sonuç farklıdır.
obj.value alanına ModifyObject yapılan değişiklik, örnekte gösterildiği gibi, Main yönteminde rt bağımsız
değişkeninin value alanını 33 olarak değiştirir.

using System;

public class SampleRefType


{
public int value;
}

public class Example


{
public static void Main()
{
var rt = new SampleRefType();
rt.value = 44;
ModifyObject(rt);
Console.WriteLine(rt.value);
}

static void ModifyObject(SampleRefType obj)


{
obj.value = 33;
}
}

Parametreleri başvuruya göre geçirme


Bir yöntemde bir bağımsız değişkenin değerini değiştirmek istediğinizde ve denetim çağırma yöntemine
döndüğünde bu değişikliği yansıtmak istediğinizde, parametreyi başvuruya göre geçirirsiniz. Bir parametreyi
başvuruya göre geçirmek için ref veya out anahtar sözcüğünü kullanırsınız. Kopyalamayı önlemek için bir
değeri başvuruya göre geçirebilir, ancak in anahtar sözcüğünü kullanarak değişikliklere devam edebilirsiniz.
Aşağıdaki örnek, değeri ModifyValue metoduna başvuruya göre geçirilme dışında, öncekiyle aynıdır. ModifyValue
yönteminde parametrenin değeri değiştirildiğinde, Denetim çağırana döndüğünde değer değişikliği yansıtılır.

using System;

public class Example


{
public static void Main()
{
int value = 20;
Console.WriteLine("In Main, value = {0}", value);
ModifyValue(ref value);
Console.WriteLine("Back in Main, value = {0}", value);
}

static void ModifyValue(ref int i)


{
i = 30;
Console.WriteLine("In ModifyValue, parameter value = {0}", i);
return;
}
}
// The example displays the following output:
// In Main, value = 20
// In ModifyValue, parameter value = 30
// Back in Main, value = 30

Ref parametreleri tarafından kullanılan ortak bir model, değişkenlerin değerlerini değiştirmeyi içerir. İki değişkeni
başvuruya göre bir yönteme geçirirseniz ve yöntemi içeriğini değiştirir. Aşağıdaki örnek, tamsayı değerlerini
değiştirir.

using System;

public class Example


{
static void Main()
{
int i = 2, j = 3;
System.Console.WriteLine("i = {0} j = {1}" , i, j);

Swap(ref i, ref j);

System.Console.WriteLine("i = {0} j = {1}" , i, j);


}

static void Swap(ref int x, ref int y)


{
int temp = x;
x = y;
y = temp;
}
}
// The example displays the following output:
// i = 2 j = 3
// i = 3 j = 2

Bir başvuru türü parametresinin geçirilmesi, tek öğelerinin veya alanlarının değeri yerine başvurunun kendisinin
değerini değiştirmenize izin verir.
Parametre dizileri
Bazen, yönteminiz için bağımsız değişkenlerin tam sayısını belirttiğiniz gereksinim kısıtlayıcıdır. Bir parametrenin
parametre dizisi olduğunu göstermek için params anahtar sözcüğünü kullanarak, yönteminizin değişken sayıda
bağımsız değişkenle çağrılmasına izin verebilirsiniz. params anahtar sözcüğüyle etiketlenmiş parametre bir dizi
türü olmalıdır ve yöntemin parametre listesindeki son parametre olmalıdır.
Bir çağıran daha sonra yöntemi üç yöntemden birini çağırabilir:
İstenen sayıda öğe içeren uygun türdeki bir diziyi geçirerek.
Uygun türdeki bağımsız değişkenlerin virgülle ayrılmış bir listesini yöntemine geçirerek.
Parametre dizisine bir bağımsız değişken sağlamıyor.
Aşağıdaki örnek, bir parametre dizisinin tüm sesli harfleri döndüren GetVowels adlı bir yöntemi tanımlar. Main
yöntemi yöntemi çağırmanın üç yolunu gösterir. Çağıranlar, params değiştiricisini içeren parametreler için
herhangi bir bağımsız değişken sağlamak için gerekli değildir. Bu durumda, parametresi null .

using System;
using System.Linq;

class Example
{
static void Main()
{
string fromArray = GetVowels(new[] { "apple", "banana", "pear" });
Console.WriteLine($"Vowels from array: '{fromArray}'");

string fromMultipleArguments = GetVowels("apple", "banana", "pear");


Console.WriteLine($"Vowels from multiple arguments: '{fromMultipleArguments}'");

string fromNoValue = GetVowels();


Console.WriteLine($"Vowels from no value: '{fromNoValue}'");
}

static string GetVowels(params string[] input)


{
if (input == null || input.Length == 0)
{
return string.Empty;
}

var vowels = new char[] { 'A', 'E', 'I', 'O', 'U' };


return string.Concat(
input.SelectMany(
word => word.Where(letter => vowels.Contains(char.ToUpper(letter)))));
}
}

// The example displays the following output:


// Vowels from array: 'aeaaaea'
// Vowels from multiple arguments: 'aeaaaea'
// Vowels from no value: ''

İsteğe bağlı parametreler ve bağımsız değişkenler


Yöntem tanımı parametrelerinin gerekli olduğunu veya isteğe bağlı olduğunu belirtebilir. Varsayılan olarak
Parametreler gereklidir. İsteğe bağlı parametreler, parametrenin varsayılan değeri Yöntem tanımına eklenerek
belirtilir. Yöntemi çağrıldığında, isteğe bağlı bir parametre için bir bağımsız değişken sağlanmazsa, bunun yerine
varsayılan değer kullanılır.
Parametrenin varsayılan değeri aşağıdaki tür ifadelerden biri tarafından atanmalıdır:
Sabit dize veya sayı gibi bir sabit.
new ValType() , ValType bir değer türü olduğu form ifadesi. Bunun, türün gerçek üyesi olmayan, değer türünün
örtük parametresiz oluşturucusunu çağırdığına unutmayın.
default(ValType) , ValType bir değer türü olduğu form ifadesi.

Bir yöntem hem gerekli hem de isteğe bağlı parametreleri içeriyorsa, isteğe bağlı parametreler parametre listesinin
sonunda, tüm gerekli parametrelerden sonra tanımlanır.
Aşağıdaki örnek, bir zorunlu ve iki isteğe bağlı parametre içeren ExampleMethod bir yöntemi tanımlar.

using System;

public class Options


{
public void ExampleMethod(int required, int optionalInt = default(int),
string description = "Optional Description")
{
Console.WriteLine("{0}: {1} + {2} = {3}", description, required,
optionalInt, required + optionalInt);
}
}

Birden çok isteğe bağlı bağımsız değişkeni olan bir yöntem Konumsal bağımsız değişkenler kullanılarak çağrılırsa,
çağıran ilk bir bağımsız değişken için bağımsız değişkenin sağlandığı en son bir parametre için bir bağımsız
değişken sağlamalıdır. ExampleMethod yöntemi söz konusu olduğunda, örneğin, çağıran description parametresi
için bir bağımsız değişken sağlarsa, bu da optionalInt parametresi için de sağlamalıdır.
opt.ExampleMethod(2, 2, "Addition of 2 and 2"); geçerli bir yöntem çağrıdır;
opt.ExampleMethod(2, , "Addition of 2 and 0"); "bağımsız değişken eksik" derleyici hatası oluşturur.

Bir yöntem adlandırılmış bağımsız değişkenler veya konumsal ve adlandırılmış bağımsız değişkenlerin bir birleşimi
kullanılarak çağrılırsa, çağıran yöntem çağrısındaki son Konumsal bağımsız değişkeni izleyen tüm bağımsız
değişkenleri atlayabilir.
Aşağıdaki örnek ExampleMethod yöntemini üç kez çağırır. İlk iki yöntem çağıran konum değişkenlerini kullanır. İlki
hem isteğe bağlı bağımsız değişkenleri atlar, ikincisi ise son bağımsız değişkeni atlar. Üçüncü yöntem çağrısı,
gerekli parametre için bir Konumsal bağımsız değişken sağlar, ancak optionalInt bağımsız değişkenini atlayarak
description parametresine bir değer sağlamak için adlandırılmış bir bağımsız değişken kullanır.

public class Example


{
public static void Main()
{
var opt = new Options();
opt.ExampleMethod(10);
opt.ExampleMethod(10, 2);
opt.ExampleMethod(12, description: "Addition with zero:");
}
}
// The example displays the following output:
// Optional Description: 10 + 0 = 10
// Optional Description: 10 + 2 = 12
// Addition with zero:: 12 + 0 = 12

İsteğe bağlı parametrelerin kullanımı, aşırı yükleme çözümlemesinietkiler veya C# derleyicinin hangi belirli aşırı
yüklemeyi bir yöntem çağrısı tarafından çağrılması gerektiğini belirleyen yöntemi aşağıda gösterildiği gibi:
Bir yöntem, Dizin Oluşturucu veya Oluşturucu, parametrelerinden her biri isteğe bağlı veya bir konuma göre,
çağırma deyimindeki tek bir bağımsız değişkene ve bu bağımsız değişken parametre türüne
dönüştürülebileceğinden yürütme için bir adaydır.
Birden fazla aday bulunursa, tercih edilen dönüştürmeler için aşırı yükleme çözümleme kuralları, açıkça
belirtilen bağımsız değişkenlere uygulanır. İsteğe bağlı parametreler için Atlanan bağımsız değişkenler
yoksayılır.
İki aday eşit derecede iyi bir şekilde yarar olursa, tercih, çağrıda bağımsız değişkenlerin atlandığı isteğe bağlı
parametreleri olmayan bir adaya gider. Bu, daha az parametreye sahip adaylar için aşırı yükleme
çözünürlüğünde genel bir tercihin sonucudur.

Döndürülen değerler
Yöntemler çağırana bir değer döndürebilir. Dönüş türü (yöntem adından önce listelenen tür) void değilse, yöntemi
return anahtar sözcüğünü kullanarak değeri döndürebilir. Dönüş türüyle eşleşen bir değişken, sabit veya ifade
gelen return anahtar sözcüğünü içeren bir deyim, bu değeri çağıran yönteme döndürür. Void olmayan bir dönüş
türüne sahip metotlar, bir değer döndürmek için return anahtar sözcüğünü kullanmak için gereklidir. return
anahtar sözcüğü, yöntemin yürütülmesini de durduruyor.
Dönüş türü void ise, değer içermeyen bir return deyimin, metodun yürütülmesini durdurmak için yine de yararlı
olması gerekir. return anahtar sözcüğü olmadan Yöntem, kod bloğunun sonuna ulaştığında yürütmeyi durdurur.
Örneğin, bu iki yöntem tamsayılar döndürmek için return anahtar sözcüğünü kullanır:

class SimpleMath
{
public int AddTwoNumbers(int number1, int number2)
{
return number1 + number2;
}

public int SquareANumber(int number)


{
return number * number;
}
}

Bir yöntemden döndürülen bir değer kullanmak için, çağırma yöntemi yöntemi tek bir değer olan her yerde, aynı
türde bir değer yeterli olacak şekilde kullanabilir. Dönüş değerini bir değişkene de atayabilirsiniz. Örneğin,
aşağıdaki iki kod örneği aynı hedefi yerine getirmektedir:

int result = obj.AddTwoNumbers(1, 2);


result = obj.SquareANumber(result);
// The result is 9.
Console.WriteLine(result);

result = obj.SquareANumber(obj.AddTwoNumbers(1, 2));


// The result is 9.
Console.WriteLine(result);

Bu durumda, bir değeri depolamak için result , yerel bir değişken kullanmak isteğe bağlıdır. Kodun
okunabilirliğini yardımcı olabilir veya metodun tüm kapsamı için bağımsız değişkenin özgün değerini depolamanız
gerekirse gerekli olabilir.
Bazen yönteminizin tek bir değerden fazlasını döndürmesini istersiniz. 7,0 ' C# den başlayarak, kayıt düzeni
türlerini ve demet sabitdeğerlerini kullanarak bunu kolayca yapabilirsiniz. Demet türü, demet öğelerinin veri
türlerini tanımlar. Demet sabit değerleri, döndürülen tanımlama grubunun gerçek değerlerini sağlar. Aşağıdaki
örnekte, (string, string, string, int) GetPersonalInfo yöntemi tarafından döndürülen demet türünü tanımlar.
(per.FirstName, per.MiddleName, per.LastName, per.Age) ifadesi demet değişmez değeri; yöntemi, PersonInfo
nesnesinin yaşı ile birlikte birinci, orta ve son adı döndürür.

public (string, string, string, int) GetPersonalInfo(string id)


{
PersonInfo per = PersonInfo.RetrieveInfoById(id);
return (per.FirstName, per.MiddleName, per.LastName, per.Age);
}

Çağıran daha sonra aşağıdaki gibi kodla döndürülen kayıt grubunu kullanabilir:

var person = GetPersonalInfo("111111111")


Console.WriteLine("{person.Item1} {person.Item3}: age = {person.Item4}");

Adlar, kayıt düzeni türü tanımındaki demet öğelerine de atanabilir. Aşağıdaki örnek, adlandırılmış öğeleri kullanan
GetPersonalInfo yönteminin alternatif bir sürümünü göstermektedir:

public (string FName, string MName, string LName, int Age) GetPersonalInfo(string id)
{
PersonInfo per = PersonInfo.RetrieveInfoById(id);
return (per.FirstName, per.MiddleName, per.LastName, per.Age);
}

GetPersonInfo yöntemine yapılan önceki çağrı, daha sonra aşağıdaki gibi değiştirilebilir:

var person = GetPersonalInfo("111111111");


Console.WriteLine("{person.FName} {person.LName}: age = {person.Age}");

Bir yöntem bir diziyi bağımsız değişken olarak geçirse ve tek tek öğelerin değerini değiştirirse, yöntemin diziyi
döndürmesi gerekli değildir, ancak bunun için uygun stil veya işlevsel akış için bunu seçebilirsiniz. Bunun nedeni C#
, tüm başvuru türlerini değere göre geçirir ve dizi başvurusunun değeri dizi işaretçisidir. Aşağıdaki örnekte,
DoubleValues yönteminde yapılan values dizisinin içeriklerinde yapılan değişiklikler, diziye yönelik bir başvuruya
sahip herhangi bir kod tarafından Observable ' tır.

using System;

public class Example


{
static void Main(string[] args)
{
int[] values = { 2, 4, 6, 8 };
DoubleValues(values);
foreach (var value in values)
Console.Write("{0} ", value);
}

public static void DoubleValues(int[] arr)


{
for (int ctr = 0; ctr <= arr.GetUpperBound(0); ctr++)
arr[ctr] = arr[ctr] * 2;
}
}
// The example displays the following output:
// 4 8 12 16
Uzantı yöntemleri
Genellikle, varolan bir türe bir yöntem eklemenin iki yolu vardır:
Bu tür için kaynak kodu değiştirin. Bu, türün kaynak kodunu sahipsiz olmadığınız takdirde bunu yapamazlar.
Ayrıca, yöntemi desteklemek için herhangi bir özel veri alanı eklerseniz, bu bir büyük değişiklik haline gelir.
Yeni metodu türetilmiş bir sınıfta tanımlayın. Bir yöntem, yapılar ve numaralandırmalar gibi diğer türler için
devralma kullanılarak bu şekilde eklenemez. Ayrıca, korumalı bir sınıfa bir yöntemi "eklemek" için de
kullanılabilir.
Uzantı yöntemleri, türün kendisini değiştirmeden veya yeni yöntemi devralınmış bir tür içinde uygulamadan,
varolan bir türe "eklemenize" olanak sağlar. Uzantı yönteminin, genişlettiği türle aynı derlemede bulunması
gerekmez. Bir uzantı yöntemini bir türün tanımlı üyesi gibi çağırın.
Daha fazla bilgi için bkz. Uzantı yöntemleri.

Zaman uyumsuz yöntemler


Async özelliğini kullanarak, açık geri çağırmaları kullanmadan zaman uyumsuz yöntemleri çağırabilir veya
kodunuzu birden çok yöntemde veya Lambda ifadelerinde el ile böedebilirsiniz.
Zaman uyumsuz değiştiriciyle bir yöntemi işaretlerseniz, yönteminde await işlecini kullanabilirsiniz. Denetim
zaman uyumsuz yöntemde bir await ifadesine ulaştığında, beklenen görev tamamlanmazsa denetim çağırana
döner ve beklenen görev tamamlanana kadar, await anahtar sözcüğüyle yöntemde ilerleme durumu askıya alınır.
Görev tamamlandığında, yürütme yöntemi içinde çalışmaya çalışabilir.

NOTE
Zaman uyumsuz bir yöntem, henüz tamamlanmamış olan ilk beklemiş nesneyle karşılaştığında çağırana döner veya zaman
uyumsuz yöntemin sonuna kadar, hangisi önce gerçekleşiyorsa.

Zaman uyumsuz bir yöntem Task<TResult>, Taskveya void dönüş türüne sahip olabilir. void dönüş türü
öncelikle, bir void dönüş türünün gerekli olduğu olay işleyicilerini tanımlamak için kullanılır. void döndüren
zaman uyumsuz bir yöntem beklenemez ve void döndüren bir yöntemi çağıran yöntemin aldığı özel durumları
yakalayamaz. 7,0 ile C# başlayarak, zaman uyumsuz bir yöntem herhangi bir görev benzeri dönüş türünesahip
olabilir.
Aşağıdaki örnekte DelayAsync , bir tamsayı döndüren Return ifadesine sahip zaman uyumsuz bir yöntemdir.
Zaman uyumsuz bir yöntem olduğundan, yöntem bildirimi Task<int> dönüş türüne sahip olmalıdır. Dönüş türü
Task<int> olduğu için, aşağıdaki int result = await delayTask deyimi gösterdiği gibi, DoSomethingAsync await
ifadesinin değerlendirmesi bir tamsayı oluşturur.
using System;
using System.Diagnostics;
using System.Threading.Tasks;

public class Example


{
// This Click event is marked with the async modifier.
public static void Main()
{
DoSomethingAsync().Wait();
}

private static async Task DoSomethingAsync()


{
int result = await DelayAsync();
Console.WriteLine("Result: " + result);
}

private static async Task<int> DelayAsync()


{
await Task.Delay(100);
return 5;
}

// Output:
// Result: 5
}
// The example displays the following output:
// Result: 5

Zaman uyumsuz bir yöntem hiçbir içinde, refveya Out parametrelerini bildiremez, ancak bu parametrelere sahip
yöntemleri çağırabilir.
Zaman uyumsuz yöntemler hakkında daha fazla bilgi için bkz. Async ve await Ile zaman uyumsuz programlama,
zaman uyumsuz programlarda denetim akışıve zaman uyumsuz dönüş türleri.

İfade gövdeli üyeler


Yalnızca bir ifadenin sonucuyla hemen dönen veya yöntemin gövdesi olarak tek bir deyimi olan yöntem
tanımlarının olması yaygındır. => kullanarak bu tür yöntemleri tanımlamaya yönelik bir sözdizimi kısayolu vardır:

public Point Move(int dx, int dy) => new Point(x + dx, y + dy);
public void Print() => Console.WriteLine(First + " " + Last);
// Works with operators, properties, and indexers too.
public static Complex operator +(Complex a, Complex b) => a.Add(b);
public string Name => First + " " + Last;
public Customer this[long id] => store.LookupCustomer(id);

Yöntem void döndürürse veya zaman uyumsuz bir yöntem ise, yönteminin gövdesi bir deyim ifadesi olmalıdır
(Lambdalar ile aynı). Özellikler ve Dizin oluşturucular için, salt okunurdur ve get erişimci anahtar sözcüğünü
kullanmayın.

Yineleyiciler
Yineleyici, bir koleksiyon üzerinde liste veya dizi gibi özel bir yineleme gerçekleştirir. Bir yineleyici, her öğeyi birer
birer döndürmek için yield return ifadesini kullanır. yield return ifadeye ulaşıldığında, çağıranın sıradaki öğeyi
istemesi için geçerli konum hatırlanır.
Yineleyicinin dönüş türü IEnumerable, IEnumerable<T>, IEnumeratorveya IEnumerator<T>olabilir.
Daha fazla bilgi için bkz. yineleyiciler.

Ayrıca bkz.
Erişim Değiştiricileri
Statik Sınıflar ve Statik Sınıf Üyeleri
Devralma
Soyut ve Korumalı Sınıflar ve Sınıf Üyeleri
params
out
ref
in
Parametreleri Geçirme
Lambda ifadeleri (C# Programlama Kılavuzu)
4.11.2019 • 17 minutes to read • Edit Online

Lambda ifadesi aşağıdaki iki formdan herhangi birinin bir ifadesidir:


Gövdesi olarak bir ifadeye sahip olan ifade lambda :

(input-parameters) => expression

Gövdesi olarak bir ifade bloğuna sahip olan ifade lambda :

(input-parameters) => { <sequence-of-statements> }

Lambda parametre listesini gövdesinden ayırmak için => lambda bildirimi işlecini kullanın. Lambda ifadesi
oluşturmak için, lambda işlecinin sol tarafında (varsa) giriş parametrelerini ve diğer tarafta bir ifade ya da deyim
bloğunu belirtirsiniz.
Herhangi bir lambda ifadesi, bir temsilci türüne dönüştürülebilir. Lambda ifadesinin dönüştürülebileceği temsilci
türü, parametrelerinin ve dönüş değerinin türlerine göre tanımlanır. Lambda ifadesi bir değer döndürmezse,
Action temsilci türlerinden birine dönüştürülebilir; Aksi takdirde, Func temsilci türlerinden birine dönüştürülebilir.
Örneğin, iki parametresi olan ve değer döndüren bir lambda ifadesi bir Action<T1,T2> temsilcisine
dönüştürülemez. Bir parametreye sahip olan ve bir değer döndüren bir lambda ifadesi Func<T,TResult> temsilciye
dönüştürülebilir. Aşağıdaki örnekte, x adlı bir parametreyi belirten x => x * x lambda ifadesi, bir temsilci türü
değişkenine atanmış x kare değeri döndürür:

Func<int, int> square = x => x * x;


Console.WriteLine(square(5));
// Output:
// 25

Aşağıdaki örnekte gösterildiği gibi ifade lambdaları da ifade ağacı türlerine dönüştürülebilir:

System.Linq.Expressions.Expression<Func<int, int>> e = x => x * x;


Console.WriteLine(e);
// Output:
// x => (x * x)

Lambda ifadelerini, örneğin, arka planda yürütülmesi gereken kodu geçirmek için Task.Run(Action) yöntemine bir
bağımsız değişken olarak temsilci türleri veya ifade ağaçları örnekleri gerektiren herhangi bir kodda
kullanabilirsiniz. Aşağıdaki örnekte gösterildiği gibi, LINQ ' de C# yazdığınızda Lambda ifadelerini de
kullanabilirsiniz:

int[] numbers = { 2, 3, 4, 5 };
var squaredNumbers = numbers.Select(x => x * x);
Console.WriteLine(string.Join(" ", squaredNumbers));
// Output:
// 4 9 16 25

System.Linq.Enumerable sınıfında Enumerable.Select yöntemini çağırmak için yöntem tabanlı sözdizimi


kullandığınızda (örneğin, LINQ to Objects ve LINQ to XML, parametre bir temsilci türüdür
System.Func<T,TResult>. System.Linq.Queryable sınıfında Queryable.Select yöntemini çağırdığınızda, örneğin
LINQ to SQL, parametre türü bir ifade ağacı türüdür Expression<Func<TSource,TResult>> . Her iki durumda da,
parametre değerini belirtmek için aynı lambda ifadesini kullanabilirsiniz. Bu, Lambdalar tarafından oluşturulan
nesnelerin türü farklı olsa da, iki Select benzer görünmesini sağlar.

İfade lambdaları
=> işlecinin sağ tarafında bir ifade olan bir lambda ifadesine bir ifade lambdaadı verilir. İfade lambdaları ifade
ağaçlarınınyapımını yaygın olarak kullanır. Bir lambda ifadesi, ifadenin sonucunu verir ve aşağıdaki temel biçimi alır:

(input-parameters) => expression

Parantezler yalnızca lambdanın bir çıktı parametresi varsa isteğe bağlıdır; aksi takdirde bunlar gereklidir.
Boş ayraçlarla sıfır giriş parametrelerini belirtin:

Action line = () => Console.WriteLine();

İki veya daha fazla giriş parametresi, ayraç içinde virgülle ayrılır:

Func<int, int, bool> testForEquality = (x, y) => x == y;

Bazen derleyicinin giriş türlerini çıkarması olanaksızdır. Aşağıdaki örnekte gösterildiği gibi türleri açıkça
belirtebilirsiniz:

Func<int, string, bool> isTooLong = (int x, string s) => s.Length > x;

Giriş parametresi türleri tamamen açık veya tümü örtük olmalıdır; Aksi halde, bir CS0748 derleyici hatası oluşur.
Lambda ifadesinin gövdesi bir yöntem çağrısından oluşabilir. Ancak, SQL Server gibi .NET ortak dil çalışma
zamanının bağlamı dışında değerlendirilen ifade ağaçları oluşturuyorsanız, Lambda ifadelerinde Yöntem çağrılarını
kullanmamalısınız. Yöntemler .NET ortak dil çalışma zamanı bağlamının dışında anlamlı olmayacaktır.

İfade lambdaları
Ayraçlar arasındaki deyimler hariç statement lambda, expression lambda'ya benzer:

(input-parameters) => { <sequence-of-statements> }

Bir lambda deyiminin gövdesi herhangi bir sayıda deyimden oluşabilir; ancak, uygulamada genellikle iki veya üçten
fazla değildir.

Action<string> greet = name =>


{
string greeting = $"Hello {name}!";
Console.WriteLine(greeting);
};
greet("World");
// Output:
// Hello World!
Deyim lambdaları ifade ağaçları oluşturmak için kullanılamaz.

Zaman uyumsuz Lambdalar


Async ve await anahtar sözcüklerini kullanarak zaman uyumsuz işleme içeren lambda ifadeleri ve deyimlerini
kolayca oluşturabilirsiniz. Örneğin, aşağıdaki Windows Forms örnek, zaman uyumsuz bir yöntemi çağıran ve
bekleden bir olay işleyicisi içerir, ExampleMethodAsync .

public partial class Form1 : Form


{
public Form1()
{
InitializeComponent();
button1.Click += button1_Click;
}

private async void button1_Click(object sender, EventArgs e)


{
await ExampleMethodAsync();
textBox1.Text += "\r\nControl returned to Click event handler.\n";
}

private async Task ExampleMethodAsync()


{
// The following line simulates a task-returning asynchronous process.
await Task.Delay(1000);
}
}

Zaman uyumsuz lambda kullanarak aynı olay işleyicisini ekleyebilirsiniz. Bu işleyiciyi eklemek için aşağıdaki örnekte
gösterildiği gibi Lambda parametre listesinden önce bir async değiştiricisi ekleyin:

public partial class Form1 : Form


{
public Form1()
{
InitializeComponent();
button1.Click += async (sender, e) =>
{
await ExampleMethodAsync();
textBox1.Text += "\r\nControl returned to Click event handler.\n";
};
}

private async Task ExampleMethodAsync()


{
// The following line simulates a task-returning asynchronous process.
await Task.Delay(1000);
}
}

Zaman uyumsuz yöntemlerin nasıl oluşturulacağı ve kullanılacağı hakkında daha fazla bilgi için bkz. Async ve await
Ile zaman uyumsuz programlama.

Lambda ifadeleri ve tanımlama grupları


Dil, C# 7,0 ile başlayarak, Tanımlama gruplarıiçin yerleşik destek sağlar. C# Bir lambda ifadesine bağımsız değişken
olarak bir tanımlama grubu sağlayabilirsiniz ve lambda ifadeniz de bir tanımlama grubu döndürebilir. Bazı
durumlarda, C# derleyici demet bileşenleri türlerini belirlemekte tür çıkarımı kullanır.
Bir tanımlama grubu, bileşenlerinin virgülle ayrılmış bir listesini parantez içine alarak tanımlarsınız. Aşağıdaki
örnek, her bir değeri iki katına çıkarır ve çarpma 'un sonucunu içeren üç bileşeni olan bir tanımlama grubu
döndüren bir lambda ifadesine bir dizi sayıyı geçirmek için üç bileşeni olan tanımlama grubunu kullanır.

Func<(int, int, int), (int, int, int)> doubleThem = ns => (2 * ns.Item1, 2 * ns.Item2, 2 * ns.Item3);
var numbers = (2, 3, 4);
var doubledNumbers = doubleThem(numbers);
Console.WriteLine($"The set {numbers} doubled: {doubledNumbers}");
// Output:
// The set (2, 3, 4) doubled: (4, 6, 8)

Normalde, bir tanımlama grubu alanları Item1 , Item2 vb. olarak adlandırılır. Ancak, aşağıdaki örnekte olduğu gibi
adlandırılmış bileşenlerle bir tanımlama grubu tanımlayabilirsiniz.

Func<(int n1, int n2, int n3), (int, int, int)> doubleThem = ns => (2 * ns.n1, 2 * ns.n2, 2 * ns.n3);
var numbers = (2, 3, 4);
var doubledNumbers = doubleThem(numbers);
Console.WriteLine($"The set {numbers} doubled: {doubledNumbers}");

Tanımlama grupları hakkında C# daha fazla bilgi için bkz C# . demet türleri.

Standart sorgu işleçleri ile Lambdalar


Diğer uygulamalar arasında LINQ to Objects, türü genel temsilcilerin Func<TResult> ailesinden olan bir giriş
parametresine sahiptir. Bu temsilciler, giriş parametrelerinin sayısını ve türünü ve temsilcinin dönüş türünü
tanımlamak için tür parametreleri kullanır. Func temsilciler, bir kaynak veri kümesindeki her öğeye uygulanan
Kullanıcı tanımlı ifadeleri kapsüllemek için çok yararlıdır. Örneğin, Func<T,TResult> temsilci türünü göz önünde
bulundurun:

public delegate TResult Func<in T, out TResult>(T arg)

Temsilci, int bir giriş parametresi olduğu ve döndürülen değer bool Func<int, bool> bir örnek olarak
oluşturulabilir. Dönüş değeri her zaman son tür parametresinde belirtilir. Örneğin, Func<int, string, bool> iki giriş
parametresi olan bir temsilciyi, int ve string ve bool dönüş türünü tanımlar. Aşağıdaki Func temsilci
çağrıldığında, giriş parametresinin beş ' a eşit olup olmadığını belirten Boole değeri döndürür:

Func<int, bool> equalsFive = x => x == 5;


bool result = equalsFive(4);
Console.WriteLine(result); // False

Bağımsız değişken türü bir Expression<TDelegate>olduğunda bir lambda ifadesi de sağlayabilirsiniz, örneğin,
Queryable türünde tanımlanan standart sorgu işleçleri. Bir Expression<TDelegate> bağımsız değişkeni
belirttiğinizde, lambda bir ifade ağacına derlenir.
Aşağıdaki örnek Count standart sorgu işlecini kullanır:

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
int oddNumbers = numbers.Count(n => n % 2 == 1);
Console.WriteLine($"There are {oddNumbers} odd numbers in {string.Join(" ", numbers)}");

Derleyici giriş parametresinin türünü çıkarabilir veya bunu açıkça belirtebilirsiniz. Bu belirli lambda ifadesi, ikiye
bölünen 1 ' in geri kalanı olduğunda bu tamsayıları ( n ) sayar.
Aşağıdaki örnek, koşulu karşılamayan dizideki ilk sayı olduğundan, 9 ' dan önce gelen numbers dizisindeki tüm
öğeleri içeren bir dizi üretir:
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
var firstNumbersLessThanSix = numbers.TakeWhile(n => n < 6);
Console.WriteLine(string.Join(" ", firstNumbersLessThanSix));
// Output:
// 5 4 1 3

Aşağıdaki örnek, birden çok giriş parametresini parantez içine alarak belirtir. Yöntemi, değeri dizideki sıra
konumundan daha az olan bir sayıyla karşılaşana kadar numbers dizisindeki tüm öğeleri döndürür:

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
var firstSmallNumbers = numbers.TakeWhile((n, index) => n >= index);
Console.WriteLine(string.Join(" ", firstSmallNumbers));
// Output:
// 5 4

Lambda ifadelerinde tür çıkarımı


Lambda yazarken genellikle giriş parametreleri için bir tür belirtmeniz gerekmez, derleyici lambda gövdesine,
parametre türlerine ve C# dil belirtiminde açıklanan diğer etkenlere göre türü çıkarsabilir. Standart sorgu
işleçlerinin çoğunda ilk giriş kaynak dizisindeki öğelerin türüdür. Bir IEnumerable<Customer> sorguladıktan sonra,
giriş değişkeni bir Customer nesnesi olarak algılanır ve bu, yöntemlerine ve özelliklerine erişiminiz olduğu anlamına
gelir:

customers.Where(c => c.City == "London");

Lambdalar için tür çıkarımı için genel kurallar aşağıdaki gibidir:


Lambda temsilci türüyle aynı sayıda parametre içermelidir.
Lambdadaki her giriş parametresi, denk gelen temsilci parametresine dolaylı olarak dönüştürülebilir
olmalıdır.
Lambdanın (varsa) dönüş değeri örtük olarak temsilcinin dönüş türüne dönüştürülebilir olmalıdır.
Ortak tür sisteminin hiçbir "lambda ifadesi" kavramı olmadığından, lambda ifadelerinin bir tür olmadığını
unutmayın. Ancak, bazen bir lambda ifadesinin "tür" i resmi olarak konuşmak yararlı olabilir. Bu durumlarda tür,
lambda ifadesinin dönüştürüldüğü temsilci türüne veya Expression türüne başvurur.

Lambda ifadelerinde dış değişkenlerin ve değişken kapsamının


yakalanması
Lambdalar, dış değişkenlerebaşvurabilir. Bunlar, lambda ifadesini tanımlayan yöntemde veya lambda ifadesini
içeren türde kapsamda kapsam içinde olan değişkenlerdir. Bu şekilde tutulan değişkenler, aksi halde kapsam dışına
çıkacak ve çöp olarak toplanacak olsalar dahi kullanılmak üzere lambda ifadesinde saklanır. Bir lambda ifadesinde
tüketilebilmesi için öncelikle mutlaka bir harici değişken tayin edilmelidir. Aşağıdaki örnek bu kuralları gösterir:
public static class VariableScopeWithLambdas
{
public class VariableCaptureGame
{
internal Action<int> updateCapturedLocalVariable;
internal Func<int, bool> isEqualToCapturedLocalVariable;

public void Run(int input)


{
int j = 0;

updateCapturedLocalVariable = x =>
{
j = x;
bool result = j > input;
Console.WriteLine($"{j} is greater than {input}: {result}");
};

isEqualToCapturedLocalVariable = x => x == j;

Console.WriteLine($"Local variable before lambda invocation: {j}");


updateCapturedLocalVariable(10);
Console.WriteLine($"Local variable after lambda invocation: {j}");
}
}

public static void Main()


{
var game = new VariableCaptureGame();

int gameInput = 5;
game.Run(gameInput);

int jTry = 10;


bool result = game.isEqualToCapturedLocalVariable(jTry);
Console.WriteLine($"Captured local variable is equal to {jTry}: {result}");

int anotherJ = 3;
game.updateCapturedLocalVariable(anotherJ);

bool equalToAnother = game.isEqualToCapturedLocalVariable(anotherJ);


Console.WriteLine($"Another lambda observes a new value of captured variable: {equalToAnother}");
}
// Output:
// Local variable before lambda invocation: 0
// 10 is greater than 5: True
// Local variable after lambda invocation: 10
// Captured local variable is equal to 10: True
// 3 is greater than 5: False
// Another lambda observes a new value of captured variable: True
}

Lambda ifadelerindeki değişken kapsam için aşağıdaki kurallar geçerlidir:


Tutulan bir değişkenin kullandığı bellek, ona başvuran temsilcinin kullandığı bellek geri kazanılmaya hazır
hale gelinceye kadar geri kazanılmaz.
Bir lambda ifadesi içinde tanıtılan değişkenler kapsayan yöntemde görünmez.
Lambda ifadesi kapsayan yöntemden bir ın, refveya Out parametresini doğrudan yakalayamaz.
Lambda ifadesindeki bir dönüş deyimi kapsayan metodun dönüşmesine neden olmaz.
Bir lambda ifadesi, bu sıçrama deyiminin hedefi lambda ifade bloğunun dışındaysa bir goto, Breakveya
Continue deyimi içeremez. Ayrıca, hedef bloğun içindeyse lambda ifade bloğunun dışında bir sıçrama
deyimine sahip olmak için bir hatadır.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin anonim işlev ifadeleri bölümüne bakın.

öne çıkan kitap bölümü


3,0 tanımlama kitabı, üçüncü sürüm 'de Temsilciler, olaylar ve lambda ifadeleri C# : 3,0 programcılar için C# 250 '
den fazla çözüm

Ayrıca bkz.
C# Programlama Kılavuzu
LINQ (dil ile tümleşik sorgu)
İfade Ağaçları
Yerel işlevler lambda ifadeleriyle karşılaştırılır
Örtük olarak yazılan lambda ifadeleri
Visual Studio 2008 C# örnekleri (bkz. LINQ örnek sorguları dosyaları ve XQuery programı)
Özyinelemeli lambda ifadeleri
Özellikler
30.10.2019 • 14 minutes to read • Edit Online

Özellikler ilk sınıf vatandaşları ' C#dir. Dil, geliştiricilerin tasarım amacını doğru şekilde ifade eden kod yazmasını
sağlayan sözdizimini tanımlar.
Özellikler erişilen alanlar gibi davranır. Ancak, alanların aksine özellikler, bir özelliğe erişildiğinde veya atandığında
yürütülen deyimleri tanımlayan Erişimcilerde uygulanır.

Özellik sözdizimi
Özellikler için sözdizimi, alanlar için doğal bir uzantıdır. Bir alan, depolama konumunu tanımlar:

public class Person


{
public string FirstName;
// remaining implementation removed from listing
}

Bir özellik tanımı, bu özelliğin değerini alan ve atayan bir get ve set erişimcisi için bildirimleri içerir:

public class Person


{
public string FirstName { get; set; }

// remaining implementation removed from listing


}

Yukarıda gösterilen sözdizimi Auto özelliği sözdizimidir. Derleyici, özelliği yedekleyen alan için depolama konumu
oluşturur. Derleyici Ayrıca get ve set erişimcileri gövdesini de uygular.
Bazen bir özelliği, türü için varsayılan değer dışında bir değere başlatmalısınız. C#özelliği için kapanış ayracından
sonra bir değer ayarlayarak bunu yapmanızı mümkün. FirstName özelliği için başlangıç değerini null yerine boş
dize olacak şekilde tercih edebilirsiniz. Aşağıda gösterildiği gibi belirtmeniz gerekir:

public class Person


{
public string FirstName { get; set; } = string.Empty;

// remaining implementation removed from listing


}

Bu makalede daha sonra göreceğiniz gibi, belirli bir başlatma, salt okuma özellikleri için en yararlı seçenektir.
Depolamayı aşağıda gösterildiği gibi kendiniz de tanımlayabilirsiniz:
public class Person
{
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
private string firstName;
// remaining implementation removed from listing
}

Bir özellik uygulamasının tek bir ifade olması halinde, alıcı veya ayarlayıcı için ifade-Bodied Üyeler
kullanabilirsiniz:

public class Person


{
public string FirstName
{
get => firstName;
set => firstName = value;
}
private string firstName;
// remaining implementation removed from listing
}

Bu basitleştirilmiş söz dizimi, bu makale boyunca geçerli olan yerlerde kullanılacaktır.


Yukarıda gösterilen özellik tanımı bir okuma-yazma özelliğidir. Anahtar kelimesinin set erişimcisinde value
dikkat edin. set erişimcisinin her zaman value adlı tek bir parametresi vardır. get erişimcisi, özelliğin türüne
dönüştürülebilir bir değer döndürmelidir (Bu örnekte string ).
Söz dizimi temel bilgileri. Çeşitli farklı tasarım deyimlerini destekleyen birçok farklı çeşitliliğe sahiptir. İnceleyelim
ve her biri için sözdizimi seçeneklerini öğrenelim.

Senaryolar
Yukarıdaki örneklerde, özellik tanımının en basit durumlardan biri gösterildi: doğrulama içermeyen bir okuma-
yazma özelliği. get ve set erişimcilerine istediğiniz kodu yazarak birçok farklı senaryo oluşturabilirsiniz.
Doğrulama
Bir özellik tarafından temsil edilen değerlerin her zaman geçerli olduğundan emin olmak için set erişimcisine
kod yazabilirsiniz. Örneğin, Person sınıfı için bir kural, adın boş veya boşluk olamaz. Şöyle yazın:

public class Person


{
public string FirstName
{
get => firstName;
set
{
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentException("First name must not be blank");
firstName = value;
}
}
private string firstName;
// remaining implementation removed from listing
}
Yukarıdaki örnek, Özellik ayarlayıcısı doğrulamasının parçası olarak bir throw ifadesi kullanılarak
basitleştirilebilir:

public class Person


{
public string FirstName
{
get => firstName;
set => firstName = (!string.IsNullOrWhiteSpace(value)) ? value : throw new ArgumentException("First
name must not be blank");
}
private string firstName;
// remaining implementation removed from listing
}

Yukarıdaki örnekte, ilk adın boş veya boşluk olmaması gerekir kuralını zorlar. Bir geliştirici yazıyorsa

hero.FirstName = "";

Bu atama bir ArgumentException oluşturur. Bir özellik kümesi erişimcisinin void dönüş türüne sahip olması
gerektiğinden, özel durum oluşturarak set erişimcisinde hataları raporlayabilir.
Bu söz dizimini, senaryonuza gereken her şeye genişletebilirsiniz. Farklı özellikler arasındaki ilişkileri
denetleyebilir veya herhangi bir dış koşula göre doğrulayabilirsiniz. Bir özellik C# erişimcisinde geçerli deyimler
geçerlidir.
Salt okunurdur
Bu noktaya kadar, gördüğünüze olan tüm özellik tanımlarının ortak erişimcilere sahip okuma/yazma özellikleri
vardır. Bu, özellikler için tek geçerli erişilebilirlik değildir. Salt okunurdur özellikler oluşturabilir veya set ve Get
erişimcilerine farklı erişilebilirlik sağlayabilirsiniz. Person sınıfınızın yalnızca, bu sınıftaki diğer yöntemlerden
FirstName özelliğinin değerini değiştirmeyi etkinleştirdiğini varsayalım. Set erişimcisine public yerine
erişilebilirlik private verebilirsiniz:

public class Person


{
public string FirstName { get; private set; }

// remaining implementation removed from listing


}

Artık, FirstName özelliğine herhangi bir koddan erişilebilir, ancak yalnızca Person sınıfındaki diğer koddan
atanabilir.
Küme veya Get erişimcilerine herhangi bir kısıtlayıcı erişim değiştiricisi ekleyebilirsiniz. Bireysel erişimciye
yerleştirdiğiniz herhangi bir erişim değiştiricisi, özellik tanımındaki erişim değiştiricisinden daha sınırlı olmalıdır.
FirstName özelliği public olduğundan, küme erişimcisi private olduğundan, yukarıdaki geçerlidir. Bir public
erişimcisi ile private özelliği bildiremezsiniz. Özellik bildirimleri de protected , internal , protected internal
veya hatta private olarak da yapılandırılabilir.
Ayrıca, get erişimcisine daha kısıtlayıcı değiştirici yerleştirmek de geçerlidir. Örneğin, bir public özelliğine sahip
olabilirsiniz, ancak get erişimcisini private olarak kısıtlayabilirsiniz. Bu senaryo uygulamada nadiren yapılır.
Ayrıca, bir özellik üzerinde yapılan değişiklikleri yalnızca bir oluşturucuda veya özellik başlatıcısında
ayarlanabilmesi için kısıtlayabilirsiniz. Person sınıfını şu şekilde değiştirebilirsiniz:
public class Person
{
public Person(string firstName) => this.FirstName = firstName;

public string FirstName { get; }

// remaining implementation removed from listing


}

Bu özellik, en yaygın olarak salt okunurdur özellikler olarak sunulan koleksiyonları başlatmak için kullanılır:

public class Measurements


{
public ICollection<DataPoint> points { get; } = new List<DataPoint>();
}

Hesaplanan özellikler
Bir özelliğin yalnızca bir üye alanının değerini döndürmesi gerekmez. Hesaplanan bir değer döndüren özellikler
oluşturabilirsiniz. İlk ve soyadlarını birleştirerek hesaplanan tam adı döndürmek için Person nesnesini
genişletelim:

public class Person


{
public string FirstName { get; set; }

public string LastName { get; set; }

public string FullName { get { return $"{FirstName} {LastName}"; } }


}

Yukarıdaki örnek, tam ad için biçimlendirilen dizeyi oluşturmak üzere dize ilişkilendirme özelliğini kullanır.
Ayrıca, hesaplanan FullName özelliğini oluşturmak için daha kısa bir yol sağlayan Expression-Bodied üyesinide
kullanabilirsiniz:

public class Person


{
public string FirstName { get; set; }

public string LastName { get; set; }

public string FullName => $"{FirstName} {LastName}";


}

İfade-Bodied Üyeler , tek bir ifade içeren yöntemleri tanımlamak için lambda ifadesi sözdizimini kullanır. Burada,
bu ifade kişi nesnesinin tam adını döndürür.
Önbelleğe alınan değerlendirilen Özellikler
Hesaplanan bir özellik kavramını depolama ile karıştırabilir ve önbelleğe alınmış bir değerlendirilen
Özellikoluşturabilirsiniz. Örneğin, FullName özelliğini, dize biçimlendirmesi yalnızca ilk kez erişildiğinde olacak
şekilde güncelleştirebilirsiniz:
public class Person
{
public string FirstName { get; set; }

public string LastName { get; set; }

private string fullName;


public string FullName
{
get
{
if (fullName == null)
fullName = $"{FirstName} {LastName}";
return fullName;
}
}
}

Yukarıdaki kod bir hata içeriyor. Kod FirstName ya da LastName özelliğinin değerini güncelleştiriyorsa, önceden
değerlendirilen fullName alanı geçersizdir. fullName alanı yeniden hesaplanabilmesi için FirstName ve
LastName özelliğinin set erişimcileri değiştirirsiniz:

public class Person


{
private string firstName;
public string FirstName
{
get => firstName;
set
{
firstName = value;
fullName = null;
}
}

private string lastName;


public string LastName
{
get => lastName;
set
{
lastName = value;
fullName = null;
}
}

private string fullName;


public string FullName
{
get
{
if (fullName == null)
fullName = $"{FirstName} {LastName}";
return fullName;
}
}
}

Bu son sürüm FullName özelliğini yalnızca gerektiğinde değerlendirir. Daha önce hesaplanan sürüm geçerliyse,
kullanılır. Başka bir durum değişikliği önceden hesaplanan sürümü geçersiz kılar, yeniden hesaplanır.Bu sınıfı
kullanan geliştiricilerin uygulamanın ayrıntılarını bilmeleri gerekmez. Bu iç değişikliklerden hiçbiri kişi nesnesinin
kullanımını etkilemez. Bu, bir nesnenin veri üyelerini açığa çıkarmak için özellikleri kullanmanın temel nedenidir.
Öznitelikleri otomatik uygulanan özelliklere iliştirme
7,3 ile C# başlayarak, alan öznitelikleri otomatik uygulanan özelliklerde derleyicinin ürettiği yedekleme alanına
iliştirilebilir. Örneğin, benzersiz bir tamsayı Id özelliği ekleyen Person sınıfına bir düzeltme düşünün. Otomatik
uygulanan bir özellik kullanarak Id özelliğini yazarsınız, ancak tasarımınız Id özelliğini kalıcı hale getirmeyi
çağırmıyor. NonSerializedAttribute, yalnızca alanlara eklenebilir, ancak özelliklere eklenebilir. Aşağıdaki örnekte
gösterildiği gibi, özniteliğinde field: belirticisini kullanarak Id özelliğinin yedekleme alanına
NonSerializedAttribute ekleyebilirsiniz:

public class Person


{
public string FirstName { get; set; }

public string LastName { get; set; }

[field:NonSerialized]
public int Id { get; set; }

public string FullName => $"{FirstName} {LastName}";


}

Bu teknik, otomatik uygulanan özelliğindeki yedekleme alanına eklediğiniz tüm öznitelikler için geçerlidir.
INotifyPropertyChanged uygulama
Bir özellik erişimcisine kod yazmanız gereken son senaryo, veri bağlama istemcilerine bir değerin değiştiğini
bildirmek için kullanılan INotifyPropertyChanged arabirimini desteklemelidir. Bir özelliğin değeri değiştiğinde,
nesne değişikliği belirtmek için INotifyPropertyChanged.PropertyChanged olayını oluşturur. Veri bağlama
kitaplıkları, sırasıyla, bu değişikliğe göre görüntüleme öğelerini güncelleştirir. Aşağıdaki kod, bu kişi sınıfının
FirstName özelliği için INotifyPropertyChanged nasıl uygulanacağını gösterir.

public class Person : INotifyPropertyChanged


{
public string FirstName
{
get => firstName;
set
{
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentException("First name must not be blank");
if (value != firstName)
{
PropertyChanged?.Invoke(this,
new PropertyChangedEventArgs(nameof(FirstName)));
}
firstName = value;
}
}
private string firstName;

public event PropertyChangedEventHandler PropertyChanged;


// remaining implementation removed from listing
}

?. işlecine null Conditional işlecidenir. İşlecin sağ tarafını değerlendirmeden önce null başvurusunu denetler.
Nihai sonuç, PropertyChanged olayına abone olmadığında, olayı yükseltmek için kodun yürütülmeyeceğini
unutmayın. Bu durumda bu denetim olmadan bir NullReferenceException oluşturur. Daha fazla bilgi için bkz.
events . Bu örnek ayrıca, özellik adı sembolünden metin gösterimine dönüştürmek için yeni nameof işlecini
kullanır. nameof kullanmak özelliğin adını yanlış yazmış olduğunuz hataları azaltabilir.
Yeniden INotifyPropertyChanged uygulamak, gereken senaryoları desteklemek için Erişimcilerde kod
yazabileceğiniz bir durum örneğidir.

Toplam
Özellikler, bir sınıf veya nesne içindeki akıllı alanların bir biçimidir. Nesnenin dışından, nesne içindeki alanlar gibi
görünürler. Ancak, özellikler tam C# işlevsellik paleti kullanılarak uygulanabilir. Doğrulama, farklı erişilebilirlik, geç
değerlendirme ya da senaryolarınızın ihtiyaç duyduğu herhangi bir gereksinim sağlayabilirsiniz.
Dizin Oluşturucular
30.10.2019 • 14 minutes to read • Edit Online

Dizin oluşturucular özelliklere benzerdir. Birçok şekilde, Dizin oluşturucular Özelliklerile aynı dil özelliklerinde yapı
oluşturur. Dizin oluşturucular dizinli özellikleri etkinleştirir: bir veya daha fazla bağımsız değişken kullanılarak
başvurulan Özellikler. Bu bağımsız değişkenler, bazı değer toplamasına bir dizin sağlar.

Dizin Oluşturucu sözdizimi


Bir dizin oluşturucuya bir değişken adı ve köşeli ayraçlar aracılığıyla erişirsiniz. Dizin Oluşturucu bağımsız
değişkenlerini köşeli ayraç içine yerleştirebilirsiniz:

var item = someObject["key"];


someObject["AnotherKey"] = item;

Özellik adı olarak this anahtar sözcüğünü kullanarak Dizin oluşturucular bildirir ve bağımsız değişkenleri köşeli
ayraç içinde bildirir. Bu bildirim, önceki paragrafta gösterilen kullanımla eşleşir:

public int this[string key]


{
get { return storage.Find(key); }
set { storage.SetAt(key, value); }
}

Bu ilk örnekte, Özellikler ve Dizin oluşturucular için sözdizimi arasındaki ilişkiyi görebilirsiniz. Bu benzerleme
vurguladı, Dizin oluşturucular için sözdizimi kurallarının çoğunu taşır. Dizin oluşturucular geçerli erişim
değiştiricilerine sahip olabilir (genel, korunan dahili, korunan, iç, özel veya özel korumalı). Mühürlü, sanal veya
soyut olabilir. Özelliklerde olduğu gibi, bir dizin oluşturucuda get ve set erişimcileri için farklı erişim değiştiricileri
belirtebilirsiniz. Salt yazılır Dizin oluşturucular da (set erişimcisini atlayarak) veya salt yazılır Dizin oluşturucular
(Get erişimcisini atlayarak) belirtebilirsiniz.
Özelliklerle birlikte çalışarak, dizin oluşturucularının bulunduğu neredeyse her şeyi uygulayabilirsiniz. Bu kuralın
tek istisnası Otomatik uygulanan özelliklerdir. Derleyici, Dizin Oluşturucu için her zaman doğru depolama alanı
oluşturamıyor.
Bir öğe kümesindeki bir öğeye başvuruda bulunmak için bağımsız değişkenlerin varlığı, dizin oluşturucularının
özelliklerini ayırır. Her bir 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. Bir sınıf tanımında bir veya daha fazla Dizin Oluşturucu
kullanabileceğiniz farklı senaryolar araştıralım.

Senaryolar
API 'sinin, bu koleksiyonun bağımsız değişkenlerini tanımladığınız bazı koleksiyonları modellediğinde, bu Dizin
oluşturucuyu yazmanız gerekir. Dizin oluşturucular, .NET Core Framework 'ün parçası olan koleksiyon türleri ile
doğrudan eşleşmeyebilir veya eşleşmeyebilir. Bir koleksiyonun modellenmesi ek olarak, türü başka sorumluluklara
sahip olabilir. Dizin oluşturucular, bu soyutlamalarda değerlerinin nasıl depolandığını veya hesaplanmadığını
belirten iç ayrıntıları açığa çıkarmadan, türün soyutlamada eşleşen API 'yi sağlamanıza olanak tanır.
Dizin oluşturucularkullanmanın bazı yaygın senaryolarından bazılarını inceleyelim. Dizin oluşturucular için örnek
klasöreerişebilirsiniz. İndirme yönergeleri için bkz. örnekler ve öğreticiler.
Diziler ve vektörler
Dizin oluşturucular oluşturmak için en yaygın senaryolardan biri, türü bir diziyi veya bir vektörü modellediğinde
olur. Sıralı bir veri listesini modellemek için bir Dizin Oluşturucu oluşturabilirsiniz.
Kendi dizin oluşturucuyu oluşturmanın avantajı, bu koleksiyonun depolama alanını gereksinimlerinize uyacak
şekilde tanımlayabilmeniz. Aynı anda belleğe yüklenecek çok büyük geçmiş verileri modelleyen bir senaryoyu
düşünün. Kullanım temelinde koleksiyonun bölümlerini yüklemeniz ve kaldırmanız gerekir. Aşağıdaki örnek, bu
davranışı modelleyen bir örnektir. Bu, kaç veri noktasının var olduğunu bildirir. İsteğe bağlı verilerin bölümlerini
tutacak sayfalar oluşturur. Daha yeni istekler için gereken sayfalar için yer açmak üzere sayfaları bellekten kaldırır.

public class DataSamples


{
private class Page
{
private readonly List<Measurements> pageData = new List<Measurements>();
private readonly int startingIndex;
private readonly int length;
private bool dirty;
private DateTime lastAccess;

public Page(int startingIndex, int length)


{
this.startingIndex = startingIndex;
this.length = length;
lastAccess = DateTime.Now;

// 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 => dirty;


public DateTime LastAccess => lastAccess;
}

private readonly int totalSize;


private readonly List<Page> pagesInMemory = new List<Page>();

public DataSamples(int totalSize)


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ümesinin bellek içi bir koleksiyona yüklenmesinin iyi nedenleri olduğu durumlarda, herhangi bir
koleksiyon sıralamasını modellemek için bu tasarım deyimlerini takip edebilirsiniz. Page sınıfının, ortak arabirimin
parçası olmayan özel bir iç içe sınıf olduğunu unutmayın. Bu ayrıntılar, bu sınıfın tüm kullanıcılarından gizlenir.
sözlüğü
Diğer bir yaygın senaryo, bir sözlüğü veya eşlemeyi modellemenize gerek duyduğunuzda olur. Bu senaryo,
yazdığınız değerleri anahtar temelinde, genellikle 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 ifadelerine 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 Action temsilcisine eşleyen ArgsActions sınıfı ve
bu seçenekle karşılaştığında her Action yürütmek için ArgsActions kullanan bir ArgsProcessor .

public class ArgsProcessor


{
private readonly ArgsActions actions;

public ArgsProcessor(ArgsActions actions)


{
this.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 Dictionary<string, Action>();

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 koleksiyona yakından eşlenir. get , verilen bir seçeneğin
yapılandırılıp yapılandırılmadığını belirler. Bu durumda, bu seçenekle ilişkili Action döndürür. Aksi takdirde, hiçbir
şey olmayan bir Action döndürür. Ortak erişimci bir set erişimcisi içermez. Bunun yerine, seçenekleri ayarlamak
için genel bir yöntem kullanan tasarım.
Ç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ıtlanmaz. İki örneğe bakalım.
İlk örnek, bir Mandeli kümesi için değerler üreten bir sınıfı gösterir. Küme arkasında matematik hakkında daha fazla
bilgi için Bu makaleyiokuyun. Dizin Oluşturucu X, Y düzleinde bir noktayı tanımlamak için iki Double Double
kullanır. Get erişimcisi, bir noktanın küme içinde olmadığı belirlenene kadar yineleme sayısını hesaplar. En fazla
yineleme ulaşılırsa, nokta ayarlanmıştır ve sınıfın Maxyinelemelerde değeri döndürülür. (Bilgisayar tarafından
üretilen görüntüler Mandeli kümesi için populartı kümesi, bir noktanın kümenin dışında olduğunu belirlemek için
gereken yineleme sayısı için renkleri tanımlar.
public class Mandelbrot
{
readonly private int maxIterations;

public Mandelbrot(int maxIterations)


{
this.maxIterations = 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))
{
var newX = x * x - y * y + x0;
y = 2 * x * y + y0;
x = newX;
iterations++;
}
return iterations;
}
}
}

Mandelbrot kümesi, gerçek sayı değerleri için her (x, y) koordinatının değerlerini tanımlar. Bu, sonsuz sayıda değer
içerebilen bir sözlük tanımlar. Bu nedenle, küme arkasında depolama yok. Bunun yerine, kod get erişimcisini
çağırdığında, bu sınıf her bir noktanın değerini hesaplar. Kullanılan temeldeki depolama alanı yok.
Dizin oluşturucunun, farklı türlerde birden çok bağımsız değişken aldığı dizin oluşturucularının bir son kullanımını
inceleyelim. Geçmiş sıcaklık verilerini yöneten bir programı düşünün. Bu Dizin Oluşturucu, bu konum için yüksek
ve düşük sıcaklıkları ayarlamak veya almak üzere bir şehir ve bir tarih kullanır:
using DateMeasurements =
System.Collections.Generic.Dictionary<System.DateTime, IndexersSamples.Common.Measurements>;
using CityDataMeasurements =
System.Collections.Generic.Dictionary<string, System.Collections.Generic.Dictionary<System.DateTime,
IndexersSamples.Common.Measurements>>;

public class HistoricalWeatherData


{
readonly CityDataMeasurements storage = new CityDataMeasurements();

public Measurements this[string city, DateTime date]


{
get
{
var cityData = default(DateMeasurements);

if (!storage.TryGetValue(city, out cityData))


throw new ArgumentOutOfRangeException(nameof(city), "City not found");

// strip out any time portion:


var index = date.Date;
var measure = default(Measurements);
if (cityData.TryGetValue(index, out measure))
return measure;
throw new ArgumentOutOfRangeException(nameof(date), "Date not found");
}
set
{
var cityData = default(DateMeasurements);

if (!storage.TryGetValue(city, out cityData))


{
cityData = new DateMeasurements();
storage.Add(city, cityData);
}

// Strip out any time portion:


var index = date.Date;
cityData[index] = value;
}
}
}

Bu örnek, hava durumu verilerini iki farklı bağımsız değişkenle eşleyen bir dizin oluşturucu oluşturur: bir şehir (bir
string tarafından temsil edilir ) ve Tarih (bir DateTime tarafından temsil edilir ). İç depolama iki boyutlu sözlüğü
temsil etmek için iki Dictionary sınıfı kullanır. Ortak API artık temeldeki depolamayı temsil etmektedir. Bunun
yerine, dizin oluşturucularının dil özellikleri, temeldeki depolamanın farklı çekirdek koleksiyon türlerini kullanması
gerekir ancak, soyutlamasını temsil eden bir ortak arabirim oluşturmanıza olanak sağlar.
Bu kodun, bazı geliştiricilere alışkın olabilecek iki bölümü vardır. Bu iki using deyimi:

using DateMeasurements = System.Collections.Generic.Dictionary<System.DateTime,


IndexersSamples.Common.Measurements>;
using CityDataMeasurements = System.Collections.Generic.Dictionary<string,
System.Collections.Generic.Dictionary<System.DateTime, IndexersSamples.Common.Measurements>>;

oluşturulan genel tür için bir diğer ad oluşturun. Bu deyimler daha sonra kodu daha sonra
Dictionary<DateTime, Measurements> ve Dictionary<string, Dictionary<DateTime, Measurements> > genel yapımı
yerine daha açıklayıcı DateMeasurements ve CityDateMeasurements adlarını kullanacak şekilde etkinleştirir. Bu yapı,
= işaretinin sağ tarafında tam nitelikli tür adlarının kullanılmasını gerektirir.

İkinci yöntem, koleksiyonlara dizin eklemek için kullanılan herhangi bir DateTime nesnesinin zaman kısımlarını bir
kez çıkaramadır. .NET Framework yalnızca tarih türü içermez. Geliştiriciler DateTime türünü kullanır, ancak bu
gündeki herhangi bir DateTime nesnesinin eşit olduğundan emin olmak için Date özelliğini kullanın.

Toplam
Sınıfınıza, bu özelliğin tek bir değer değil, her tekil öğenin bir dizi bağımsız değişken tarafından tanımlandığı bir
değer koleksiyonu olmak üzere her zaman bir özellik benzeri öğe oluşturmanız gerekir. Bu bağımsız değişkenler
koleksiyondaki hangi öğeye başvurulduğunu benzersiz şekilde tanımlayabilir. Dizin oluşturucular, bir üyenin sınıfın
dışından bir veri öğesi gibi davranılabileceği, ancak içindeki bir yöntem gibi ele alındığı Özelliklerkavramını
genişletir. Dizin oluşturucular, bağımsız değişkenlerin bir öğe kümesini temsil eden özellikte tek bir öğe bulmasına
izin verir.
Atma- C# kılavuz
31.10.2019 • 10 minutes to read • Edit Online

7,0 ile C# başlayarak, C# uygulama kodunda kasıtlı olarak kullanılmamış olan geçici ve kukla değişkenler olan
atma 'yı destekler. Atma, atanmamış değişkenlere eşdeğerdir; Bunlar bir değere sahip değildir. Yalnızca tek bir
atma değişkeni olduğundan ve bu değişkene ayrılan depolama alanı bulunmayabilir, atma işlemi bellek
ayırmalarını azaltabilir. Kodunuzun amacını açık hale yaptığından, okunabilirliği ve bakım yapamazı geliştirir.
Bir değişkenin, adı olarak alt çizgi ( _ ) atayarak bir atma olduğunu belirtirsiniz. Örneğin, aşağıdaki yöntem çağrısı,
ilk ve ikinci değerlerin dıştığı 3 tanımlama grubu döndürür ve alan , daha önce bildirildiği bir değişken
Getcityınformationtarafından döndürülen karşılık gelen üçüncü bileşene ayarlanır:

(_, _, area) = city.GetCityInformation(cityName);

7,0 C# ' de, atma aşağıdaki bağlamlarda atamalar içinde desteklenir:


Kayıt düzeni ve nesne oluşturma.
Ve anahtarıile eşleşen model.
out parametreli yöntemlere çağrılar.
Kapsamda _ olmadığında tek başına _ .
_ geçerli bir atıldığında, değerini alma veya atama işleminde kullanma girişimi, "_' adı geçerli bağlamda yok"
hatasını üretir. Bunun nedeni _ bir değer atanmamıştır ve hatta bir depolama konumu atanmayabilir. Gerçek bir
değişkense, önceki örnekte olduğu gibi birden fazla değeri atlamadınız.

Demet ve nesne oluşturmayı kaldırma


Atma, uygulama kodunuz bazı demet öğeleri kullandığında ancak diğerlerini yoksaytığında tanımlama grupları ile
çalışırken özellikle yararlıdır. Örneğin, aşağıdaki QueryCityDataForYears yöntemi, şehir adı, alanı, yıl, bu yıl için şehir
popülasyonu, ikinci yıl ve bu ikinci yıl için şehir popülasyonu olan 6 tanımlama grubu döndürür. Örnek, bu iki yıl
arasındaki popülasyondaki değişikliği gösterir. Kayıt kümesinden kullanılabilen veriler, şehir alanıyla ilgilentik ve
tasarım zamanında şehir adını ve iki tarihi biliyoruz. Sonuç olarak, yalnızca kayıt düzeninde depolanan iki
popülasyon değeri ile ilgileniyoruz ve kalan değerlerini atma olarak işleyebilir.
using System;
using System.Collections.Generic;

public class Example


{
public static void Main()
{
var (_, _, _, pop1, _, pop2) = QueryCityDataForYears("New York City", 1960, 2010);

Console.WriteLine($"Population change, 1960 to 2010: {pop2 - pop1:N0}");


}

private static (string, double, int, int, int, int) QueryCityDataForYears(string name, int year1, int
year2)
{
int population1 = 0, population2 = 0;
double area = 0;

if (name == "New York City")


{
area = 468.48;
if (year1 == 1960)
{
population1 = 7781984;
}
if (year2 == 2010)
{
population2 = 8175133;
}
return (name, area, year1, population1, year2, population2);
}

return ("", 0, 0, 0, 0, 0);


}
}
// The example displays the following output:
// Population change, 1960 to 2010: 393,149

Atma ile tanımlama gruplarını kaldırma hakkında daha fazla bilgi için bkz. tanımlama gruplarını ve diğer türleri
kaldırma.
Bir sınıf, yapı veya arabirimin Deconstruct yöntemi, bir nesneden belirli bir veri kümesini almanıza ve
oluşturmanıza da olanak sağlar. Yalnızca ayrıştırılmış değerlerin yalnızca bir alt kümesiyle çalışmayı
düşünüyorsanız, atma ' yı kullanabilirsiniz. Aşağıdaki örnek, bir Person nesnesini dört dizeye (ilk ve son adlar,
şehir ve eyalet) ayırır, ancak son adı ve durumu atar.
using System;

public class Person


{
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public string City { get; set; }
public string State { get; set; }

public Person(string fname, string mname, string lname,


string cityName, string stateName)
{
FirstName = fname;
MiddleName = mname;
LastName = lname;
City = cityName;
State = stateName;
}

// Return the first and last name.


public void Deconstruct(out string fname, out string lname)
{
fname = FirstName;
lname = LastName;
}

public void Deconstruct(out string fname, out string mname, out string lname)
{
fname = FirstName;
mname = MiddleName;
lname = LastName;
}

public void Deconstruct(out string fname, out string lname,


out string city, out string state)
{
fname = FirstName;
lname = LastName;
city = City;
state = State;
}
}

public class Example


{
public static void Main()
{
var p = new Person("John", "Quincy", "Adams", "Boston", "MA");

// <Snippet1>
// Deconstruct the person object.
var (fName, _, city, _) = p;
Console.WriteLine($"Hello {fName} of {city}!");
// The example displays the following output:
// Hello John of Boston!
// </Snippet1>
}
}
// The example displays the following output:
// Hello John Adams of Boston, MA!

Kullanıcı tanımlı türleri atma ile kaldırma hakkında daha fazla bilgi için bkz. tanımlama gruplarını ve diğer türleri
kaldırma.
switch ve is ile eşleşen desenler
Atma stili , ın ve anahtar anahtar sözcükleriyle birlikte eşleşen düzende kullanılabilir. Her ifade her zaman atma
düzeniyle eşleşir.
Aşağıdaki örnek, bir nesnenin bir IFormatProvider uygulama verip içermediğini ve nesnenin null olup olmadığını
test etmek için ,, bir nesnesinin bir ProvidesFormatInfo yöntemini tanımlar. Ayrıca, başka bir türdeki null olmayan
nesneleri işlemek için de atma modelini kullanır.

using System;
using System.Globalization;

public class Example


{
public static void Main()
{
object[] objects = { CultureInfo.CurrentCulture,
CultureInfo.CurrentCulture.DateTimeFormat,
CultureInfo.CurrentCulture.NumberFormat,
new ArgumentException(), null };
foreach (var obj in objects)
ProvidesFormatInfo(obj);
}

private static void ProvidesFormatInfo(object obj)


{
switch (obj)
{
case IFormatProvider fmt:
Console.WriteLine($"{fmt} object");
break;
case null:
Console.Write("A null object reference: ");
Console.WriteLine("Its use could result in a NullReferenceException");
break;
case object _:
Console.WriteLine("Some object type without format information");
break;
}
}
}
// The example displays the following output:
// en-US object
// System.Globalization.DateTimeFormatInfo object
// System.Globalization.NumberFormatInfo object
// Some object type without format information
// A null object reference: Its use could result in a NullReferenceException

Out parametreleri ile yöntemlere çağrılar


Kullanıcı tanımlı bir türü (bir sınıf, yapı veya arabirim örneği) oluşturmak için Deconstruct yöntemi çağrılırken,
bağımsız out bağımsız değişkenlerin değerlerini atabilirsiniz. Ancak, Out parametresiyle herhangi bir yöntemi
çağırırken out bağımsız değişkenlerin değerini de atabilirsiniz.
Aşağıdaki örnek, bir tarihin dize temsilinin geçerli kültür içinde geçerli olup olmadığını belirlemek için DateTime.
Trypari (dize, Out DateTime) yöntemini çağırır. Örnek yalnızca tarih dizesini doğrulamaya ve tarihi ayıklamak için
ayrıştırılmaya karşı düşünüldüğünde, yönteme out bağımsız değişkeni atılır.
using System;

public class Example


{
public static void Main()
{
string[] dateStrings = {"05/01/2018 14:57:32.8", "2018-05-01 14:57:32.8",
"2018-05-01T14:57:32.8375298-04:00", "5/01/2018",
"5/01/2018 14:57:32.80 -07:00",
"1 May 2018 2:57:32.8 PM", "16-05-2018 1:00:32 PM",
"Fri, 15 May 2018 20:10:57 GMT" };
foreach (string dateString in dateStrings)
{
if (DateTime.TryParse(dateString, out _))
Console.WriteLine($"'{dateString}': valid");
else
Console.WriteLine($"'{dateString}': invalid");
}
}
}
// The example displays output like the following:
// '05/01/2018 14:57:32.8': valid
// '2018-05-01 14:57:32.8': valid
// '2018-05-01T14:57:32.8375298-04:00': valid
// '5/01/2018': valid
// '5/01/2018 14:57:32.80 -07:00': valid
// '1 May 2018 2:57:32.8 PM': valid
// '16-05-2018 1:00:32 PM': invalid
// 'Fri, 15 May 2018 20:10:57 GMT': invalid

Tek başına atma


Yok saymayı seçtiğiniz herhangi bir değişkeni belirtmek için tek başına atmayı kullanabilirsiniz. Aşağıdaki örnek,
zaman uyumsuz bir işlem tarafından döndürülen Task nesnesini yoksaymak için tek başına atmayı kullanır. Bu,
işlemin tamamlanana kadar yaptığı özel durumu gizlemeyi etkiler.
using System;
using System.Threading.Tasks;

public class Example


{
public static void Main()
{
ExecuteAsyncMethods().Wait();
}

private static async Task ExecuteAsyncMethods()


{
Console.WriteLine("About to launch a task...");
_ = Task.Run(() => { var iterations = 0;
for (int ctr = 0; ctr < int.MaxValue; ctr++)
iterations++;
Console.WriteLine("Completed looping operation...");
throw new InvalidOperationException();
});
await Task.Delay(5000);
Console.WriteLine("Exiting after 5 second delay");
}
}
// The example displays output like the following:
// About to launch a task...
// Completed looping operation...
// Exiting after 5 second delay

_ de geçerli bir tanımlayıcı olduğunu unutmayın. Desteklenen bir bağlam dışında kullanıldığında _ , atma olarak
kabul edilir ancak geçerli bir değişken olarak değerlendirilir. _ adlı bir tanımlayıcı zaten kapsamda ise, tek başına
bir atma olarak _ kullanılması şu şekilde olabilir:
İstenen atma değeri atanarak, kapsam içi _ değişkeninin değerini yanlışlıkla değiştirme. Örneğin:

private static void ShowValue(int _)


{
byte[] arr = { 0, 0, 1, 2 };
_ = BitConverter.ToInt32(arr, 0);
Console.WriteLine(_);
}
// The example displays the following output:
// 33619968

Tür güvenliğini ihlal eden bir derleyici hatası. Örneğin:

private static bool RoundTrips(int _)


{
string value = _.ToString();
int newValue = 0;
_ = Int32.TryParse(value, out newValue);
return _ == newValue;
}
// The example displays the following compiler error:
// error CS0029: Cannot implicitly convert type 'bool' to 'int'

Derleyici hatası CS0136, "Bu ad bir yerel veya parametre tanımlamak için kapsayan bir yerel kapsamda
kullanıldığından,"_' adlı bir yerel veya parametre bu kapsamda bildirilemez. " Örneğin:
public void DoSomething(int _)
{
var _ = GetValue(); // Error: cannot declare local _ when one is already in scope
}
// The example displays the following compiler error:
// error CS0136:
// A local or parameter named '_' cannot be declared in this scope
// because that name is used in an enclosing local scope
// to define a local or parameter

Ayrıca bkz.
Demetleri ve diğer türleri ayrıştırma
is anahtar sözcüğü
switch anahtar sözcüğü
Genel Türler (C# Programlama Kılavuzu)
30.10.2019 • 5 minutes to read • Edit Online

Genel türler, sınıf veya yöntem istemci kodu tarafından bildirilene ve örneklendirilene kadar bir veya daha fazla
türün belirtimini erteleme sınıfları ve yöntemleri tasarlamak için .NET Framework parametre türü kavramını ortaya
çıkarabilir. Örneğin, bir genel tür parametresi kullanarak T , diğer istemci kodunun, çalışma zamanı yayınları veya
paketleme işlemlerinin maliyetini ya da riskini göstermeden, burada gösterildiği gibi, kullanabileceği tek bir sınıf
yazabilirsiniz:

// Declare the generic class.


public class GenericList<T>
{
public void Add(T input) { }
}
class TestGenericList
{
private class ExampleClass { }
static void Main()
{
// Declare a list of type int.
GenericList<int> list1 = new GenericList<int>();
list1.Add(1);

// Declare a list of type string.


GenericList<string> list2 = new GenericList<string>();
list2.Add("");

// Declare a list of type ExampleClass.


GenericList<ExampleClass> list3 = new GenericList<ExampleClass>();
list3.Add(new ExampleClass());
}
}

Genel sınıflar ve Yöntemler, yeniden kullanılabilirlik, tür güvenliği ve verimliliği genel olmayan karşılıklarının bir
şekilde birleştirir. Genel türler, koleksiyonlarla ve bunlarla çalışan yöntemlerle en sık kullanılır.
System.Collections.Generic ad alanı, genel tabanlı birkaç koleksiyon sınıfı içerir. ArrayList gibi genel olmayan
koleksiyonlar önerilmez ve uyumluluk amacıyla korunur. Daha fazla bilgi için bkz. .net 'Teki genel türler.
Kuşkusuz, özel genel türler ve Yöntemler oluşturarak tür açısından güvenli ve verimli bir şekilde kendi
Genelleştirilmiş çözümlerinizi ve tasarım düzenlerini sağlayabilirsiniz. Aşağıdaki kod örneğinde, tanıtım amacıyla
basit bir genel bağlantılı liste sınıfı gösterilmektedir. (Çoğu durumda, kendinizinkini oluşturmak yerine .NET
Framework sınıf kitaplığı tarafından sunulan List<T> sınıfını kullanmanız gerekir.) Tür parametresi T , somut bir
türün genellikle listede depolanan öğenin türünü belirtmek için kullanıldığı çeşitli konumlarda kullanılır. Aşağıdaki
yollarla kullanılır:
AddHead yönteminde bir yöntem parametresinin türü olarak.
İç içe Node sınıfındaki Data özelliğinin dönüş türü olarak.
Özel üyenin türü, iç içe yerleştirilmiş sınıfta data .
T iç içe Node sınıfı için kullanılabilir olduğunu unutmayın. GenericList<T> , GenericList<int> gibi somut bir türle
başlatıldığında T her oluşumu int ile yerine geçer.
// type parameter T in angle brackets
public class GenericList<T>
{
// The nested class is also generic on T.
private class Node
{
// T used in non-generic constructor.
public Node(T t)
{
next = null;
data = t;
}

private Node next;


public Node Next
{
get { return next; }
set { next = value; }
}

// T as private member data type.


private T data;

// T as return type of property.


public T Data
{
get { return data; }
set { data = value; }
}
}

private Node head;

// constructor
public GenericList()
{
head = null;
}

// T as method parameter type:


public void AddHead(T t)
{
Node n = new Node(t);
n.Next = head;
head = n;
}

public IEnumerator<T> GetEnumerator()


{
Node current = head;

while (current != null)


{
yield return current.Data;
current = current.Next;
}
}
}

Aşağıdaki kod örneği, istemci kodunun tamsayılar listesini oluşturmak için genel GenericList<T> sınıfını nasıl
kullandığını gösterir. Yalnızca tür bağımsız değişkenini değiştirerek aşağıdaki kod, dizelerin veya diğer özel türün
listesini oluşturmak için kolayca değiştirilebilir:
class TestGenericList
{
static void Main()
{
// int is the type argument
GenericList<int> list = new GenericList<int>();

for (int x = 0; x < 10; x++)


{
list.AddHead(x);
}

foreach (int i in list)


{
System.Console.Write(i + " ");
}
System.Console.WriteLine("\nDone");
}
}

Genel bakışa genel bakış


Kod yeniden kullanımını en üst düzeye çıkarmak için genel türleri kullanın, güvenlik ve performans yazın.
Genel türlerin en yaygın kullanımı koleksiyon sınıfları oluşturmaktır.
.NET Framework sınıf kitaplığı, System.Collections.Generic ad alanında birkaç yeni genel koleksiyon sınıfı içerir.
Bunlar, System.Collections ad alanındaki ArrayList gibi sınıflar yerine mümkün olduğunda kullanılmalıdır.
Kendi genel arabirimlerinizi, sınıflarınızı, yöntemlerinizi, olaylarınızı ve temsilcilerinizi oluşturabilirsiniz.
Genel sınıflar, belirli veri türlerindeki yöntemlere erişimi etkinleştirmek için kısıtlanabilir.
Genel veri türünde kullanılan türlerle ilgili bilgiler, yansıma kullanılarak çalışma zamanında elde edilebilir.

İlgili bölümler
Genel Tür Parametreleri
Tür Parametrelerindeki Kısıtlamalar
Genel Sınıflar
Genel Arabirimler
Genel Yöntemler
Genel Temsilciler
C++ Şablonları ve C# Genel Türleri Arasındaki Farklar
Genel Türler ve Yansıma
Çalışma Zamanındaki Genel Türler

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi.

Ayrıca bkz.
System.Collections.Generic
C# Programlama Kılavuzu
Türler
<typeparam >
<typeparamref >
.NET 'teki genel türler
Yineleyiciler
30.10.2019 • 9 minutes to read • Edit Online

Yazdığınız neredeyse her programın, bir koleksiyon üzerinde yineleme yapması gerekir. Bir koleksiyondaki her
öğeyi inceleyen bir kod yazacaksınız.
Ayrıca, bu sınıfın öğeleri için bir yineleyici üreten Yöntemler olan yineleyici yöntemleri de oluşturacaksınız. Bunlar
için kullanılabilir:
Bir koleksiyondaki her öğe için bir eylem gerçekleştirme.
Özel bir koleksiyon numaralandırılıyor.
LINQ veya diğer kitaplıkları genişletme.
Yineleyici yöntemler aracılığıyla veri akışının etkin olduğu bir veri işlem hattı oluşturma.
C# Dil bu senaryolara yönelik özellikler sağlar. Bu makale, bu özelliklere genel bir bakış sağlar.
Bu öğreticide birden çok adım vardır. Her adımdan sonra, uygulamayı çalıştırabilir ve ilerleme durumunu
görebilirsiniz. Ayrıca, bu konu için Tamamlanan örneği görüntüleyebilir veya indirebilirsiniz . İndirme yönergeleri
için bkz. örnekler ve öğreticiler.

Foreach ile yineleme


Bir koleksiyonun numaralandırılması basittir: foreach anahtar sözcüğü bir koleksiyonu numaralandırır ve
koleksiyondaki her öğe için katıştırılmış deyimin bir kez yürütülmesini ister:

foreach (var item in collection)


{
Console.WriteLine(item.ToString());
}

Hepsi bu kadar çok. Bir koleksiyonun tüm içeriğini yinelemek için foreach deyimleri yeterlidir. foreach deyimleri
de Magic değildir, ancak. Bir koleksiyonu yinelemek için gereken kodu oluşturmak üzere .NET Core kitaplığı 'nda
tanımlanan iki genel arabirimi kullanır: IEnumerable<T> ve IEnumerator<T> . Bu mekanizma aşağıda daha ayrıntılı
olarak açıklanmıştır.
Bu arabirimlerin her ikisi de genel olmayan ortaklarınıza sahiptir: IEnumerable ve IEnumerator . Genel sürümler
modern kod için tercih edilir.

Yineleyici yöntemleriyle listeleme kaynakları


Dilin harika bir özelliği, C# bir numaralandırma için kaynak oluşturan Yöntemler oluşturmanıza olanak sağlar.
Bunlar Yineleyici Yöntemlerolarak adlandırılır. Yineleyici yöntemi, istek sırasında nesnelerin bir dizide nasıl
oluşturulacağını tanımlar. Bir yineleyici yöntemi tanımlamak için yield return bağlamsal anahtar sözcükleri
kullanırsınız.
0 ile 9 arasındaki tamsayıların sırasını oluşturmak için bu yöntemi yazabilirsiniz:
public IEnumerable<int> GetSingleDigitNumbers()
{
yield return 0;
yield return 1;
yield return 2;
yield return 3;
yield return 4;
yield return 5;
yield return 6;
yield return 7;
yield return 8;
yield return 9;
}

Yukarıdaki kodda, bir yineleyici yönteminde birden çok ayrık yield return deyimi kullanabileceğiniz olguyu
vurgulamak için farklı yield return deyimleri gösterilmektedir. Bir yineleyici yönteminin kodunu basitleştirmek
için diğer dil yapılarını kullanabilirsiniz (ve genellikle bunu yapabilirsiniz). Aşağıdaki yöntem tanımı, tam olarak aynı
sayı dizisini üretir:

public IEnumerable<int> GetSingleDigitNumbers()


{
int index = 0;
while (index < 10)
yield return index++;
}

Bir veya başka bir karar vermeniz gerekmez. Yönteminizin ihtiyaçlarını karşılamak için gereken sayıda
yield return deyimlerine sahip olabilirsiniz:

public IEnumerable<int> GetSingleDigitNumbers()


{
int index = 0;
while (index < 10)
yield return index++;

yield return 50;

index = 100;
while (index < 110)
yield return index++;
}

Bu temel sözdizimidir. Bir yineleyici yöntemi yazacağınız gerçek bir dünya örneğini ele alalım. IoT projesinde
olduğunuzu ve cihaz sensörleri çok büyük bir veri akışı üretdiğinizi düşünün. Veriler hakkında fikir almak için, her
n. veri öğesini örnek bir yöntem yazabilirsiniz. Bu küçük yineleyici yöntemi, Eli:

public static IEnumerable<T> Sample(this IEnumerable<T> sourceSequence, int interval)


{
int index = 0;
foreach (T item in sourceSequence)
{
if (index++ % interval == 0)
yield return item;
}
}

Yineleyici metotlarda önemli bir kısıtlama vardır: aynı yöntemde hem bir return deyimin hem de bir
yield return deyiminiz olamaz. Aşağıdakiler derlenmeyecektir:
public IEnumerable<int> GetSingleDigitNumbers()
{
int index = 0;
while (index < 10)
yield return index++;

yield return 50;

// generates a compile time error:


var items = new int[] {100, 101, 102, 103, 104, 105, 106, 107, 108, 109 };
return items;
}

Bu kısıtlama normalde bir sorun değildir. Yöntemi boyunca yield return veya özgün yöntemi birden çok metoda
ayırarak, bazı return ve yield return kullanarak bir seçiminiz vardır.
Son yöntemi yield return her yerde kullanmak için biraz daha değiştirebilirsiniz:

public IEnumerable<int> GetSingleDigitNumbers()


{
int index = 0;
while (index < 10)
yield return index++;

yield return 50;

var items = new int[] {100, 101, 102, 103, 104, 105, 106, 107, 108, 109 };
foreach (var item in items)
yield return item;
}

Bazen doğru yanıt, bir yineleyici yöntemini iki farklı yönteme bölmek olur. return ve yield return kullanan bir
ikincisi. Boole bağımsız değişkenine göre boş bir koleksiyon veya ilk 5 tek sayı döndürmek isteyebileceğiniz bir
durum düşünün. Bu iki yöntem olarak yazabilirsiniz:

public IEnumerable<int> GetSingleDigitOddNumbers(bool getCollection)


{
if (getCollection == false)
return new int[0];
else
return IteratorMethod();
}

private IEnumerable<int> IteratorMethod()


{
int index = 0;
while (index < 10)
{
if (index % 2 == 1)
yield return index;
index++;
}
}

Yukarıdaki yöntemlere bakın. İlki, boş bir koleksiyon ya da ikinci yöntem tarafından oluşturulan Yineleyici
döndürmek için standart return ifadesini kullanır. İkinci yöntem, istenen diziyi oluşturmak için yield return
ifadesini kullanır.

foreach daha derin inceleyin


foreach deyimi, bir koleksiyonun tüm öğelerinde yinelemek için IEnumerable<T> ve IEnumerator<T> arabirimlerini
kullanan standart bir deyim halinde genişletilir. Ayrıca, geliştiricilerin kaynakları düzgün bir şekilde
yönetmediğinden yaptığı hataları da en aza indirir.
Derleyici, ilk örnekte gösterilen foreach döngüsünü bu yapı ile benzer bir şekilde çevirir:

IEnumerator<int> enumerator = collection.GetEnumerator();


while (enumerator.MoveNext())
{
var item = enumerator.Current;
Console.WriteLine(item.ToString());
}

Yukarıdaki yapı, C# derleyicinin 5 ve üzeri sürümü itibariyle oluşturulan kodu temsil eder. Sürüm 5 ' ten önce
item değişken farklı bir kapsama sahipti:

// C# versions 1 through 4:
IEnumerator<int> enumerator = collection.GetEnumerator();
int item = default(int);
while (enumerator.MoveNext())
{
item = enumerator.Current;
Console.WriteLine(item.ToString());
}

Bu, önceki davranış lambda ifadeleri içeren hataların tanılanması için hafif ve zor bir yol olabileceğinden
değiştirildi. Lambda ifadeleri hakkında daha fazla bilgi için bkz. lambda ifadeleri.
Derleyici tarafından oluşturulan tam kod biraz daha karmaşıktır ve GetEnumerator() tarafından döndürülen
nesnenin IDisposable arabirimini uyguladığı durumları işler. Tam genişletme şu şekilde kod üretir:

{
var enumerator = collection.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
var item = enumerator.Current;
Console.WriteLine(item.ToString());
}
} finally
{
// dispose of enumerator.
}
}

Numaralandırıcının elden çıkarılma şekli enumerator türünün özelliklerine bağlıdır. Genel durumda finally yan
tümcesi şu şekilde genişletilir:

finally
{
(enumerator as IDisposable)?.Dispose();
}

Ancak, enumerator türü korumalı bir tür ise ve enumerator türünden IDisposable öğesine örtük dönüştürme
yoksa, finally yan tümcesi boş bir bloğa genişletilir:
finally
{
}

enumerator türünden IDisposable örtük bir dönüştürme varsa ve enumerator null yapılamayan bir değer türü ise,
finally yan tümcesi şu şekilde genişletilir:

finally
{
((IDisposable)enumerator).Dispose();
}

Ktam, tüm bu ayrıntıları anımsamanız gerekmez. foreach deyimleri sizin için tüm bu nusları işler. Derleyici bu
yapıların herhangi biri için doğru kodu oluşturacaktır.
Temsilcilere Giriş
30.10.2019 • 4 minutes to read • Edit Online

Temsilciler, .NET ' te bir geç bağlama mekanizması sağlar. Geç bağlama, çağıranın, algoritmanın bir kısmını
uygulayan en az bir yöntem sağladığı bir algoritma oluşturduğunuz anlamına gelir.
Örneğin, bir astronomi uygulamasındaki yıldızın bir listesini sıralamayı düşünün. Bu yıldızları Dünya uzaklığına
veya yıldızın büyüklüğüne göre ya da algılanan parlaklığını göre sıralamayı tercih edebilirsiniz.
Tüm bu durumlarda, Sort () yöntemi temelde aynı şeyi yapar: listedeki öğeleri, bazı karşılaştırmaya göre düzenler.
İki yıldızı karşılaştıran kod, sıralama sıralarında her biri için farklıdır.
Bu tür çözümler yazılımda yarı bir yüzyıl için kullanılmıştır. C# Dil temsilcisi kavramı ilk sınıf dil desteğini sağlar ve
kavram etrafında güvenlik yazın.
Bu serinin ilerleyen kısımlarında göreceğiniz gibi, bu gibi algoritmalar C# için yazdığınız kod tür güvenlidir ve
türlerin bağımsız değişkenlerle ve dönüş türleriyle eşleşmesini sağlamak için dilin ve derleyicinin yararlanır.

Temsilciler için dil tasarımı hedefleri


Dil tasarımcıları, son olarak temsilci haline gelen özellik için birkaç amaç numaralandırmış.
Ekip, herhangi bir geç bağlama algoritması için kullanılabilecek ortak bir dil yapısı istedi. Bu, geliştiricilerin tek bir
kavram öğrenmesine ve aynı kavramı birçok farklı yazılım sorunu üzerinde kullanmasına olanak sağlar.
İkincisi, takım hem tek hem çok noktaya yayın yöntemi çağrılarını desteklemek istedi. (Çok noktaya yayın
temsilcileri, birden çok yöntem çağrısı zincirlenen temsilcidir. Bu serinin ilerleyen kısımlarındaörnekleri
görürsünüz.)
Ekip, geliştiricilerin tüm C# yapılar için beklediği tür güvenliğini desteklemek için temsilciler istedi.
Son olarak, takım bir olay deseninin temsilcilerin veya herhangi bir geç bağlama algoritmasının çok faydalı olduğu
belirli bir model olduğunu kabul eder. Ekip, temsilcilerle ilgili kodun .NET olay deseninin temelini
sağlayabildiğinden emin olmak istedi.
Bu çalışmanın sonucu, C# ve .net sürümündeki temsilci ve olay desteiydi. Bu bölümdeki diğer makaleler dil
özelliklerini, kitaplık desteğini ve temsilcilerle çalışırken kullanılan yaygın deyimleri kapsar.
delegate anahtar sözcüğünü ve ürettiği kodu öğrenirsiniz. System.Delegate sınıftaki özellikler ve bu özelliklerin
nasıl kullanıldığı hakkında bilgi edineceksiniz. Tür güvenli temsilciler oluşturmayı ve temsilciler aracılığıyla
çağrılabilecek Yöntemler oluşturmayı öğreneceksiniz. Ayrıca lambda ifadeleri kullanarak temsilcilerle ve olaylarla
nasıl çalışacağınızı öğreneceksiniz. Temsilcilerin LINQ için yapı taşlarından birine nerede geldiğini görürsünüz.
Temsilcilerin .NET olay deseninin temelini ve bunların nasıl farklı olduğunu öğrenirsiniz.
Genel olarak, temsilcilerin .NET 'teki programlama kapsamında nasıl bir parçası olduğunu ve Framework API
'Leriyle çalıştığını göreceksiniz.
Haydi başlayın.
Next
System. Delegate ve delegate anahtar sözcüğü
4.11.2019 • 10 minutes to read • Edit Online

Öncekini
Bu makale, temsilcileri destekleyen .NET Framework içindeki sınıfları ve bunların delegate anahtar kelimesiyle
nasıl eşlendiğini kapsar.

Temsilci türlerini tanımlama


' Delegate ' anahtar sözcüğüyle başlayalım, çünkü bu aslında temsilcilerle çalışırken kullanacağınız şeydir.
delegate anahtar sözcüğünü kullandığınızda derleyicinin oluşturduğu kod, Delegate ve MulticastDelegate
sınıflarının üyelerini çağıran yöntem çağrılarına eşlenir.
Yöntem imzasını tanımlamaya benzer bir sözdizimi kullanarak bir temsilci türü tanımlarsınız. Yalnızca delegate
anahtar sözcüğünü tanımına eklersiniz.
Bizim örneğimizde List. Sort () yöntemini kullanmaya devam edelim. İlk adım, karşılaştırma temsilcisi için bir tür
oluşturmaktır:

// From the .NET Core library

// Define the delegate type:


public delegate int Comparison<in T>(T left, T right);

Derleyici, kullanılan imzayla eşleşen System.Delegate türetilen bir sınıf oluşturur (Bu durumda, bir tamsayı
döndüren ve iki bağımsız değişkeni olan bir yöntem). Bu temsilcinin türü Comparison . Comparison temsilci türü
genel bir tür. Genel türler hakkında daha fazla bilgi için burayabakın.
Sözdiziminin bir değişken bildirmiş gibi görünebileceğini ancak gerçekten bir türbildirdiğine dikkat edin. Sınıf
içinde doğrudan ad alanları içinde veya genel ad alanında temsilci türleri tanımlayabilirsiniz.

NOTE
Temsilci türlerinin (veya diğer türlerin) doğrudan genel ad alanında bildirilmesi önerilmez.

Derleyici Ayrıca bu yeni tür için ekleme ve kaldırma işleyicileri üretir. bu sayede, bu sınıfın istemcileri bir örneğin
çağrı listesinden Yöntem ekleyebilir ve kaldırabilir. Derleyici, eklenen veya kaldırılan yöntemin imzasının, yöntemi
bildirirken kullanılan imza ile eşleştiğinden zorlanır.

Temsilci örneklerini bildirme


Temsilciyi tanımladıktan sonra, bu türün bir örneğini oluşturabilirsiniz. İçindeki C#tüm değişkenler gibi, temsilci
örneklerini doğrudan bir ad alanında veya genel ad alanında bildiremezsiniz.

// inside a class definition:

// Declare an instance of that type:


public Comparison<T> comparator;

Değişkenin türü, daha önce tanımlanan temsilci türü Comparison<T> . Değişkenin adı comparator .
Yukarıdaki kod parçacığı, bir sınıf içinde bir üye değişkeni bildirdi. Yerel değişkenler veya yöntemler için bağımsız
değişkenler olan temsilci değişkenlerini de bildirebilirsiniz.

Temsilcileri çağırma
Bu temsilciyi çağırarak bir temsilcinin çağırma listesindeki yöntemleri çağırabilirsiniz. Sort() yönteminin içinde,
hangi nesnelerin yerleştirileceği sırayı belirleyen kod karşılaştırma yöntemini çağırır:

int result = comparator(left, right);

Yukarıdaki satırda kod, temsilciye iliştirilmiş yöntemi çağırır . Değişkeni bir yöntem adı olarak değerlendirir ve
normal Yöntem çağrısı söz dizimini kullanarak çağırılır.
Bu kod satırı güvenli olmayan bir varsayımına neden olur: temsilciye bir hedefin eklendiğinden emin olmaz. Hiçbir
hedef iliştirilmişse, yukarıdaki satır NullReferenceException oluşturulmasına neden olur. Bu sorunu gidermek için
kullanılan ıoms, basit bir null denetiminden daha karmaşıktır ve bu serininilerleyen kısımlarında ele alınmıştır.

Çağırma hedeflerini atama, ekleme ve kaldırma


Temsilci türünün tanımlanması ve temsilci örneklerinin nasıl bildirildiği ve çağrıldığı.
List.Sort() yöntemini kullanmak isteyen geliştiricilerin imza, temsilci türü tanımıyla eşleşen bir yöntem
tanımlaması gerekir ve bunu sıralama yöntemi tarafından kullanılan temsilciye atar. Bu atama, yöntemi bu temsilci
nesnesinin çağırma listesine ekler.
Dizelerin bir listesini uzunluğuna göre sıralamak istediğinizi varsayalım. Karşılaştırma işleviniz aşağıdaki gibi
olabilir:

private static int CompareLength(string left, string right) =>


left.Length.CompareTo(right.Length);

Yöntemi özel bir yöntem olarak bildirilmiştir. Bu çok güzel. Bu yöntemin ortak arayüzün bir parçası olmasını
istemeyebilirsiniz. Bir temsilciye eklendiğinde karşılaştırma yöntemi olarak yine de kullanılabilir. Çağıran kod bu
yöntemi temsilci nesnesinin hedef listesine iliştirilir ve bu temsilci aracılığıyla erişebilir.
Bu ilişkiyi, List.Sort() yöntemine geçirerek oluşturursunuz:

phrases.Sort(CompareLength);

Yöntem adının parantez olmadan kullanıldığına dikkat edin. Yöntemin bağımsız değişken olarak kullanılması,
derleyicinin Yöntem başvurusunu temsilci çağırma hedefi olarak kullanılabilecek bir başvuruya dönüştürmesini ve
bu yöntemi bir çağırma hedefi olarak iliştirmesine söyler.
Ayrıca, Comparison<string> türünde bir değişken bildirerek ve ödev yaparak da açık olabilirsiniz:

Comparison<string> comparer = CompareLength;


phrases.Sort(comparer);

' De, bir temsilci hedefi olarak kullanılan yöntemin küçük bir yöntem olduğu durumlarda, atamayı gerçekleştirmek
için lambda ifadesi sözdizimini kullanmak yaygındır:
Comparison<string> comparer = (left, right) => left.Length.CompareTo(right.Length);
phrases.Sort(comparer);

Temsilci hedefleri için lambda ifadelerinin kullanılması, sonraki bölümdedaha fazla ele alınmıştır.
Sort () örneği genellikle temsilciye tek bir hedef yöntemi iliştirir. Ancak, temsilci nesneleri, temsilci nesnesine
eklenmiş birden çok Target yöntemi olan çağrı listelerini destekler.

Temsilci ve MulticastDelegate sınıfları


Yukarıda açıklanan dil desteği, genellikle temsilcilerle çalışmanız gereken özellikleri ve desteği sağlar. Bu özellikler
.NET Core Framework 'te iki sınıf üzerine kurulmuştur: Delegate ve MulticastDelegate.
System.Delegate sınıfı ve tek bir doğrudan alt sınıfı olan System.MulticastDelegate , temsilciler oluşturmak,
yöntemleri temsilci hedefleri olarak kaydetmek ve temsilci hedefi olarak kaydedilen tüm yöntemleri çağırmak için
çerçeve desteği sağlar.
Her ne kadar System.Delegate ve System.MulticastDelegate sınıfları kendilerine temsilci türleri değildir. Bunlar,
tüm özel temsilci türleri için temel sağlar. Aynı dil tasarım süreci, Delegate veya MulticastDelegate türetilen bir
sınıfı bildiremezsiniz. C# Dil kuralları bunu yasaklar.
Bunun yerine, C# derleyici, temsilci türlerini bildirmek için C# language anahtar sözcüğünü kullandığınızda
MulticastDelegate türetilen bir sınıfın örneklerini oluşturur.

Bu tasarım, C# ve .net ilk sürümünde köklerine sahiptir. Tasarım ekibi için bir hedef, temsilci kullanılırken dilin tür
güvenliğini zorlamasını sağlamaktır. Bu, temsilcilerin doğru tür ve bağımsız değişken sayısıyla çağrılmasını
sağlamaktır. Ve herhangi bir dönüş türü, derleme zamanında doğru şekilde belirtilmiştir. Temsilciler, genel türler
'den önce olan 1,0 .NET sürümünün bir parçası idi.
Bu tür güvenliğini zorlamak için en iyi yol, derleyicinin kullanılan yöntem imzasını temsil eden somut temsilci
sınıfları oluşturmasına yöneliktir.
Türetilmiş sınıfları doğrudan oluşturamasanız bile, bu sınıflarda tanımlanan yöntemleri kullanacaksınız.
Temsilcilerle çalışırken kullanacağınız en yaygın yöntemlerle başlayalım.
Anımsanması gereken ilk, en önemli olgu, birlikte çalıştığınız her temsilcinin MulticastDelegate türetilir. Çok
noktaya yayın temsilcisi, bir temsilci aracılığıyla çağrıldığında birden fazla yöntem hedefinin çağrılabileceği
anlamına gelir. Özgün tasarım, yalnızca bir hedef yöntemin iliştirilebileceği ve çağrılabildiği temsilciler arasında
ayrım yapmayı ve birden çok hedef metodun iliştirilebileceği ve çağrılabileceği temsilcileri arasında ayrım yapmayı
düşünüder. Bu ayrım, ilk düşünmeden uygulamada daha az yararlı olacaktır. İki farklı sınıf zaten oluşturuldu ve ilk
genel sürümünden bu yana çerçevede vardı.
Temsilcilerle en iyi şekilde kullanacağınız Yöntemler Invoke() ve / EndInvoke()``BeginInvoke() . Invoke() , belirli
bir temsilci örneğine eklenmiş olan tüm yöntemleri çağırır. Yukarıda gördüğünüz gibi genellikle temsilci
değişkeninde Yöntem çağrısı söz dizimini kullanarak temsilciler çağırılır. Bu serinin ilerleyen
kısımlarındagöreceğiniz gibi, bu yöntemlerle doğrudan çalışan desenler vardır.
Artık dil sözdizimini ve temsilcileri destekleyen sınıfları gördüğünüze göre, türü kesin belirlenmiş temsilcilerin ne
kullanıldığını, oluşturulduğunu ve çağırılacağını incelim.
Next
Kesin Tür Belirtilmiş Temsilciler
30.10.2019 • 4 minutes to read • Edit Online

Öncekini
Önceki makalede, delegate anahtar sözcüğünü kullanarak belirli temsilci türleri oluşturduğunuz gördünüz.
Soyut temsilci sınıfı, gevşek bağlantısı ve çağırma için altyapıyı sağlar. Somut temsilci türleri, bir temsilci nesnesi
için çağırma listesine eklenen yöntemler için tür güvenliğini benimseme ve zorlama açısından çok daha yararlı hale
gelir. delegate anahtar sözcüğünü kullandığınızda ve somut bir temsilci türü tanımladığınızda, derleyici bu
yöntemleri oluşturur.
Uygulamada, bu, farklı bir yöntem imzasına ihtiyacınız olduğunda yeni temsilci türleri oluşturulmasına neden olur.
Bu iş bir süre sonra sıkıcı olabilir. Her yeni özellik yeni temsilci türleri gerektirir.
Ktam, bu gerekli değildir. .NET Core Framework, temsilci türlerine ihtiyacınız olduğunda yeniden kullanabileceğiniz
çeşitli türler içerir. Bunlar, yeni yöntem bildirimlerine ihtiyacınız olduğunda özelleştirmeler bildirebilmeniz için
genel tanımlardır.
Bu türlerin ilki Action türüdür ve çeşitli çeşitlerdir:

public delegate void Action();


public delegate void Action<in T>(T arg);
public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2);
// Other variations removed for brevity.

Genel tür bağımsız değişkeninde in değiştirici, Kovaryans hakkındaki makalede ele alınmıştır.
Action<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16>gibi 16 ' ya kadar bağımsız değişken içeren
Action temsilcisinin çeşitlemeleri vardır. Bu tanımların her bir temsilci bağımsız değişkeni için farklı genel
bağımsız değişkenler kullanması önemlidir: Bu, size en fazla esneklik sağlar. Yöntem bağımsız değişkenlerinin aynı
olması gerekir, ancak aynı türde olabilir.
Void dönüş türüne sahip herhangi bir temsilci türü için Action türlerinden birini kullanın.
Framework Ayrıca değer döndüren temsilci türleri için kullanabileceğiniz çeşitli genel temsilci türleri içerir:

public delegate TResult Func<out TResult>();


public delegate TResult Func<in T1, out TResult>(T1 arg);
public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);
// Other variations removed for brevity

Sonuç genel tür bağımsız değişkeninde out değiştirici, Kovaryans hakkındaki makalede ele alınmıştır.
Func<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,TResult>gibi 16 ' ya kadar giriş bağımsız
değişkeni olan Func temsilcisinin çeşitlemeleri vardır. Sonucun türü her zaman kuralına göre tüm Func
bildirimlerinde son tür parametresidir.
Bir değer döndüren herhangi bir temsilci türü için Func türlerinden birini kullanın.
Ayrıca özelleştirilmiş bir Predicate<T> tek bir değer üzerinde bir test döndüren temsilcinin türü:

public delegate bool Predicate<in T>(T obj);


Herhangi bir Predicate türü için yapısal olarak eşdeğer Func türünün var olduğunu fark edebilirsiniz:

Func<string, bool> TestForString;


Predicate<string> AnotherTestForString;

Bu iki tür denk olduğunu düşünebilirsiniz. Bunlar değildir. Bu iki değişken birbirlerinin yerine kullanılamaz. Bir tür
değişkenine diğer tür atanamaz. C# Tür sistemi, yapıyı değil, tanımlı türlerin adlarını kullanır.
.NET Core kitaplığındaki tüm bu temsilci türü tanımları, oluşturduğunuz ve temsilci gerektiren yeni bir özellik için
yeni bir temsilci türü tanımlamanız gerekmeyen anlamına gelir. Bu genel tanımlar çoğu durumda ihtiyacınız olan
tüm temsilci türlerini sağlamalıdır. Gerekli tür parametreleriyle bu türlerden birini basitçe örnekleyebilirsiniz. Genel
hale getirilebilir algoritmalar söz konusu olduğunda, bu Temsilciler genel türler olarak kullanılabilir.
Bu süre zamandan tasarruf etmelidir ve temsilcilerle çalışmak için oluşturmanız gereken yeni tür sayısını en aza
indirir.
Sonraki makalede, uygulama ortamında temsilcilerle çalışmaya yönelik birkaç ortak desen görürsünüz.
Next
Temsilciler için Ortak Desenler
4.11.2019 • 13 minutes to read • Edit Online

Öncekini
Temsilciler, bileşenler arasında çok az sayıda bağlantısı olan yazılım tasarımlarını sağlayan bir mekanizma sağlar.
Bu tür bir tasarıma yönelik harika bir örnek LINQ 'dir. LINQ sorgu Ifade deseninin tüm özellikleri için temsilcileri
temel alır. Şu basit örneği göz önünde bulundurun:

var smallNumbers = numbers.Where(n => n < 10);

Bu, sayı dizisini yalnızca 10 ' dan küçük bir değere filtreler. Where yöntemi, bir dizinin hangi öğelerin filtreyi
geçiğini belirleyen bir temsilci kullanır. Bir LINQ sorgusu oluşturduğunuzda, bu belirli amaçla temsilci
uygulamasını sağlarsınız.
WHERE yönteminin prototipi:

public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source, Func<TSource, bool>


predicate);

Bu örnek, LINQ 'ın parçası olan tüm yöntemlerle yinelenir. Bunlar, belirli sorguyu yöneten kod için temsilcileri
kullanır. Bu API tasarım deseninin öğrenilmesinde ve anlaşılması çok güçlü bir araçtır.
Bu basit örnek, temsilcilerin bileşenler arasında çok az eşlenme gerektirdiğini gösterir. Belirli bir taban sınıftan
türetilen bir sınıf oluşturmanız gerekmez. Belirli bir arabirim uygulamanız gerekmez. Tek gereksinim, her
seferinde görev için temel olan bir yöntemin uygulanmasını sağlamaktır.

Temsilcilerle kendi bileşenlerinizi oluşturma


Temsilcilere dayalı bir tasarım kullanarak bir bileşen oluşturarak bu örneği oluşturalım.
Büyük bir sistemde günlük iletilerinde kullanılabilecek bir bileşen tanımlayalim. Kitaplık bileşenleri, birden çok
farklı platformda birçok farklı ortamda kullanılabilir. Bileşende günlükleri yöneten çok sayıda ortak özellik vardır.
Sistemdeki herhangi bir bileşenden iletileri kabul etmesi gerekir. Bu iletiler, çekirdek bileşenin yönetebileceği
farklı önceliklere sahip olacaktır. İletilerde, son Arşivlenen form zamandamgaları olmalıdır. Daha gelişmiş
senaryolar için, iletileri kaynak bileşene göre filtreleyebilirsiniz.
Özelliğin her zaman değiştirecek bir özelliği vardır: iletiler yazıldığı yer. Bazı ortamlarda, bunlar hata konsoluna
yazılabilir. Diğer bir deyişle, bir dosya. Diğer olanaklar veritabanı depolama, işletim sistemi olay günlükleri veya
diğer belge depolama alanı içerir.
Ayrıca, farklı senaryolarda kullanılabilecek çıkış bileşimleri de vardır. Konsola ve bir dosyaya ileti yazmak
isteyebilirsiniz.
Temsilcilere dayalı bir tasarım harika bir esneklik sağlar ve gelecekte eklenebilecek depolama mekanizmalarını
desteklemeyi kolaylaştırır.
Bu tasarımın altında, birincil günlük bileşeni sanal olmayan, hatta kapalı bir sınıf olabilir. İletileri farklı depolama
medyasına yazmak için herhangi bir temsilci kümesini takabilirsiniz. Çok noktaya yayın temsilcileri için yerleşik
destek, iletilerin birden çok konuma (bir dosya ve bir konsol) yazılması gerektiği senaryoları desteklemeyi
kolaylaştırır.
Ilk uygulama
Küçük bir başlangıç: ilk uygulama yeni iletileri kabul edecek ve ekli temsilciden yazacak. Konsola ileti yazan bir
temsilciyle başlayabilirsiniz.

public static class Logger


{
public static Action<string> WriteMessage;

public static void LogMessage(string msg)


{
WriteMessage(msg);
}
}

Yukarıdaki statik sınıf, kullanılabilecek en basit şeydir. Konsola ileti yazan Yöntem için tek bir uygulama yazmaları
gerekir:

public static class LoggingMethods


{
public static void LogToConsole(string message)
{
Console.Error.WriteLine(message);
}
}

Son olarak, bir temsilciyi, günlükçü içinde belirtilen WriteMessage temsilcisine ekleyerek yedeklemeniz gerekir:

Logger.WriteMessage += LoggingMethods.LogToConsole;

Uygulamalarından
Bizim örneğimiz oldukça basittir, ancak temsilcilerin bulunduğu tasarımların bazı önemli yönergelerinden
bazılarını göstermektedir.
Çekirdek çerçevede tanımlanan temsilci türlerinin kullanılması, kullanıcıların temsilcilerle çalışmasını kolaylaştırır.
Yeni türler tanımlamanız gerekmez ve kitaplığınızı kullanan geliştiricilerin yeni, özelleştirilmiş temsilci türleri
öğrenmelerine gerek yoktur.
Kullanılan arabirimler olabildiğince az ve esnek olarak kullanılabilir: yeni bir çıktı günlükçüsü oluşturmak Için bir
yöntem oluşturmanız gerekir. Bu yöntem bir statik yöntem veya bir örnek yöntemi olabilir. Herhangi bir erişim
sahibi olabilir.

Çıktıyı biçimlendirme
Bu ilk sürümü biraz daha sağlam hale gedelim ve ardından diğer günlük mekanizmalarını oluşturmaya
başlayalim.
Daha sonra, günlük sınıfınızın daha yapılandırılmış iletiler oluşturması için LogMessage() yöntemine birkaç
bağımsız değişken ekleyelim:
public enum Severity
{
Verbose,
Trace,
Information,
Warning,
Error,
Critical
}

public static class Logger


{
public static Action<string> WriteMessage;

public static void LogMessage(Severity s, string component, string msg)


{
var outputMsg = $"{DateTime.Now}\t{s}\t{component}\t{msg}";
WriteMessage(outputMsg);
}
}

Daha sonra, günlük çıktısına gönderilen iletileri filtrelemek için bu Severity bağımsız değişkenini kullanalım.

public static class Logger


{
public static Action<string> WriteMessage;

public static Severity LogLevel {get;set;} = Severity.Warning;

public static void LogMessage(Severity s, string component, string msg)


{
if (s < LogLevel)
return;

var outputMsg = $"{DateTime.Now}\t{s}\t{component}\t{msg}";


WriteMessage(outputMsg);
}
}

Uygulamalarından
Günlük altyapısına yeni özellikler eklediniz. Günlükçü bileşeni herhangi bir çıkış mekanizmasına çok esnek bir
şekilde bağlanmış olduğundan, bu yeni özellikler, günlükçü temsilcisini uygulayan kodun herhangi bir etkisi
olmadan eklenebilir.
Bunu oluştururken, bu gevşek bir şekilde, diğer konumlarda herhangi bir değişiklik yapmadan sitenin parçalarını
güncelleştirme konusunda daha fazla esneklik sağlayabilme hakkında daha fazla örnek görürsünüz. Aslında daha
büyük bir uygulamada, günlükçü çıkış sınıfları farklı bir derlemede olabilir, hatta yeniden oluşturulması gerekmez.

Ikinci bir çıkış altyapısı oluşturma


Günlük bileşeni de birlikte geliyor. İletileri bir dosyaya kaydeden bir çıkış altyapısı ekleyelim. Bu, biraz daha ilgili
çıkış altyapısı olacaktır. Dosya işlemlerini kapsülleyen bir sınıf olur ve her yazma işleminden sonra dosyanın her
zaman kapatılmasını sağlar. Bu, her ileti oluşturulduktan sonra tüm verilerin diske temizlendiğinden emin
olmanızı sağlar.
Dosya tabanlı günlükçü şu şekildedir:
public class FileLogger
{
private readonly string logPath;
public FileLogger(string path)
{
logPath = path;
Logger.WriteMessage += LogMessage;
}

public void DetachLog() => Logger.WriteMessage -= LogMessage;


// make sure this can't throw.
private void LogMessage(string msg)
{
try
{
using (var log = File.AppendText(logPath))
{
log.WriteLine(msg);
log.Flush();
}
}
catch (Exception)
{
// Hmm. We caught an exception while
// logging. We can't really log the
// problem (since it's the log that's failing).
// So, while normally, catching an exception
// and doing nothing isn't wise, it's really the
// only reasonable option here.
}
}
}

Bu sınıfı oluşturduktan sonra, onu örnekleyebilirsiniz ve LogMessage metodunu günlükçü bileşenine iliştirir:

var file = new FileLogger("log.txt");

Bu ikisi birbirini dışlamalı değildir. Her iki günlük yöntemini iliştirebilir ve konsola ve bir dosyaya ileti
oluşturabilirsiniz:

var fileOutput = new FileLogger("log.txt");


Logger.WriteMessage += LoggingMethods.LogToConsole; // LoggingMethods is the static class we utilized
earlier

Daha sonra aynı uygulamada bile, temsilcilerden birini sisteme başka herhangi bir sorun olmadan
kaldırabilirsiniz:

Logger.WriteMessage -= LoggingMethods.LogToConsole;

Uygulamalarından
Şimdi günlüğe kaydetme alt sistemi için ikinci bir çıkış işleyicisi eklediniz. Bu, dosya sistemini doğru şekilde
desteklemeye yönelik bir bit daha daha altyapı gerektirir. Temsilci bir örnek yöntemidir. Aynı zamanda özel bir
yöntemdir. Temsilci altyapısı temsilcileri bağlayabildiğinden, daha fazla erişilebilirlik gerekmez.
İkinci olarak, temsilci tabanlı tasarım, ek kod olmadan birden çok çıktı yöntemi sunar. Birden çok çıkış yöntemini
desteklemek için ek altyapı oluşturmanız gerekmez. Bunlar, çağırma listesinde yalnızca başka bir yöntem haline
gelir.
Dosya günlüğü çıkış yönteminde koda özel bir dikkat ödeyin. Özel durum oluşturmadığından emin olmak için
kodlanır. Her zaman kesinlikle gerekli olmasa da, genellikle iyi bir uygulamadır. Temsilci yöntemlerinden biri bir
özel durum oluşturursa, Çağrılı kalan temsilciler çağrılmaz.
Son bir notta, dosya günlükçüsü, her günlük iletisindeki dosyayı açıp kapatarak kaynaklarını yönetmesi gerekir.
Dosyayı açık tutmayı ve siz bitirdiğinizde dosyayı kapatmak için IDisposable 'yi uygulamayı seçebilirsiniz. Her iki
yöntemin da avantajları ve dezavantajları vardır. Her ikisi de sınıflar arasında biraz daha fazla eşlenme oluşturur.
Her iki senaryoyu desteklemek için günlükçü sınıfındaki kodların hiçbirinin güncellenmesi gerekmez.

Null temsilcileri işleme


Son olarak, LogMessage yöntemini, hiçbir çıkış mekanizması seçili olmadığında bu durumlar için sağlam olacak
şekilde güncelleştirlim. WriteMessage temsilcisinin ekli bir çağırma listesi olmadığında geçerli uygulama bir
NullReferenceException oluşturur. Hiçbir yöntem ekli olmadığında sessizce devam eden bir tasarım tercih
edebilirsiniz. Bu, Delegate.Invoke() yöntemiyle birlikte boş koşullu işleç kullanılarak kolaydır:

public static void LogMessage(string msg)


{
WriteMessage?.Invoke(msg);
}

Sol işlenen (Bu durumda WriteMessage ) null olduğunda, null koşullu işleç ( ?. ) kısa devrelerinin boş olması, bir
iletiyi günlüğe kaydetmek için denenmediği anlamına gelir.
System.Delegate veya System.MulticastDelegate belgelerinde listelenen Invoke() yöntemini
bulamayamayacağız. Derleyici, belirtilen herhangi bir temsilci türü için tür güvenli Invoke yöntemi oluşturur. Bu
örnekte, Invoke tek bir string bağımsız değişkeni alır ve void dönüş türü vardır.

Uygulamaların Özeti
Diğer yazarlar ve diğer özelliklerle genişletilebilen bir günlük bileşeni Beginnings ' yi gördünüz. Tasarımdaki
temsilcileri kullanarak bu farklı bileşenler çok esnek bir şekilde bağlanmış. Bu, çeşitli avantajlar sağlar. Yeni çıkış
mekanizmaları oluşturmak ve bunları sisteme eklemek çok kolaydır. Bu diğer mekanizmaların yalnızca bir
yöntemi olmalıdır: günlük iletisini yazan yöntem. Yeni özellikler eklendiğinde çok dayanıklı bir tasarımdır.
Herhangi bir yazıcı için gereken sözleşme, bir yöntemi uygulamaktır. Bu yöntem bir statik veya örnek yöntemi
olabilir. Ortak, özel veya başka bir yasal erişim olabilir.
Günlükçü sınıfı, önemli değişikliklere bildirmeden herhangi bir sayıda geliştirme veya değişiklik yapabilir. Her
sınıf gibi, değişiklikleri bozmadan genel API 'yi değiştiremezsiniz. Ancak, günlükçü ve herhangi bir çıkış motoru
arasındaki kuponu yalnızca temsilci aracılığıyla aldığından, başka hiçbir tür (arabirimler veya temel sınıflar gibi)
dahil değildir. Kuponu mümkün olduğunca küçük.
Next
Olaylara giriş
25.11.2019 • 5 minutes to read • Edit Online

Öncekini
Olaylar, bir geç bağlama mekanizması gibi bir temsilcidir. Aslında, olaylar, temsilciler için dil desteği üzerine
kurulmuştur.
Olaylar, bir şeyin meydana geldiği bir nesnenin (sistemdeki tüm ilgi bileşenlerine) bir yoludur. Başka herhangi bir
bileşen olaya abone olabilir ve bir olay ortaya çıktığında bildirim alabilir.
Büyük olasılıkla bazı programlarınızdaki olayları kullandınız. Birçok grafik sisteminde kullanıcı etkileşimini
raporlamak için bir olay modeli vardır. Bu olaylar, fare hareketini, düğme basışlarını ve benzer etkileşimleri rapor
edecektir. Bu en yaygın bir deyişle, olayların kullanıldığı tek senaryo değildir.
Sınıflarınız için oluşturulması gereken olayları tanımlayabilirsiniz. Olaylarla çalışırken dikkat edilmesi gereken
önemli bir nokta, belirli bir olay için kayıtlı herhangi bir nesne olmayabilir. Bir dinleyici yapılandırılmadığında
olayları tetiklememeleri için kodunuzu yazmanız gerekir.
Bir olaya abone olmak Ayrıca iki nesne (olay kaynağı ve olay havuzu) arasında bir Ida oluşturur. Olay havuzunun
artık olaylarla ilgilenmemesi durumunda olay kaynağından abone olmaması gerekir.

Olay desteği için tasarım hedefleri


Olaylar için dil tasarımı bu hedefleri hedefler:
Bir olay kaynağı ve olay havuzu arasında çok az sayıda bağlantısı etkinleştirin. Bu iki bileşen aynı kuruluş
tarafından yazılamaz ve tamamen farklı zamanlamalarda bile güncelleştirilemeyebilir.
Bir olaya abone olmak ve aynı olaydan aboneliği kaldırmak çok basittir.
Olay kaynakları birden çok olay abonesini desteklemelidir. Ayrıca, ekli olay abonesi olmadan da destek
sağlamalıdır.
Olayların hedeflerinin temsilcilerle ilgili hedeflere çok benzediğinden emin olabilirsiniz. Bu nedenle, olay dili
desteğinin temsilci dili desteği üzerine kurulmuştur.

Olaylar için dil desteği


Olayları tanımlama ve olayları abone olma sözdizimi, temsilcilerin sözdizimi uzantısıdır.
Bir olayı tanımlamak için event anahtar sözcüğünü kullanırsınız:

public event EventHandler<FileListArgs> Progress;

Olayın türü (Bu örnekteki EventHandler<FileListArgs> ) bir temsilci türü olmalıdır. Bir olayı bildirirken izlemeniz
gereken birçok kural vardır. Genellikle, olay temsilci türünün void dönüşü vardır. Olay bildirimleri bir fiil veya bir
fiil ifadesi olmalıdır. Olay gerçekleşen bir şeyi raporladığında geçmiş zaman hali kullanın. Gerçekleşmeyen bir şeyi
raporlamak için, mevcut bir zaman hali fiilini (örneğin, Closing ) kullanın. Genellikle, var zaman hali kullanımı,
sınıfınızın bazı özelleştirme davranışlarını desteklediğini gösterir. En yaygın senaryolardan biri iptali destekliyoruz.
Örneğin, Closing bir olay, kapatma işleminin devam edip edemeyeceğini belirten bir bağımsız değişken içerebilir.
Diğer senaryolar, olay bağımsız değişkenlerinin özelliklerini güncelleştirerek çağıranların davranış değiştirmesine
olanak sağlayabilir. Algoritmanın yapması önerilen sonraki eylemi belirten bir olay oluşturabilirsiniz. Olay
işleyicisi, olay bağımsız değişkeninin özelliklerini değiştirerek farklı bir eylemi zorunlu kılabilir.
Olayı yükseltmek istediğinizde, temsilci çağırma sözdizimini kullanarak olay işleyicilerini çağırabilirsiniz:

Progress?.Invoke(this, new FileListArgs(file));

Temsilcilerhakkında bölümünde açıklandığı gibi,?. işleci, bu olaya abone olmadığında olayı yapmayı
denediğinizden emin olmanızı kolaylaştırır.
+= işlecini kullanarak bir olaya abone olursunuz:

EventHandler<FileListArgs> onProgress = (sender, eventArgs) =>


Console.WriteLine(eventArgs.FoundFile);

fileLister.Progress += onProgress;

Handler yöntemi, yukarıda gösterildiği gibi genellikle ' on ' önekini ve olay adını izler.
-= işlecini kullanarak aboneliğinizi kaldırabilirsiniz:

fileLister.Progress -= onProgress;

Olay işleyicisini temsil eden ifade için yerel bir değişken bildirdiğim unutulmamalıdır. Bu sayede abonelik
kaldırma, işleyiciyi kaldırır. Bunun yerine, lambda ifadesinin gövdesini kullandıysanız, hiçbir şey iliştirilmemiş hiçbir
şey olmayan bir işleyiciyi kaldırmaya çalışıyorsunuz.
Sonraki makalede, tipik olay desenleri ve bu örnekteki farklı Çeşitlemeler hakkında daha fazla bilgi edineceksiniz.
Next
Standart .NET olay desenleri
30.10.2019 • 13 minutes to read • Edit Online

Öncekini
.NET olayları genellikle bilinen birkaç deseni izler. Bu desenlerin standartlaştırılacağı geliştiriciler, geliştiricilerin
herhangi bir .NET olay programına uygulanabilecek standart desenlerle ilgili bilgi sahibi olabileceği anlamına gelir.
Standart bir olay kaynağı oluşturmak ve kodunuzda standart olayları abone olmak ve işlemek için ihtiyacınız olan
tüm bilgilere sahip olacak şekilde bu standart desenleri ilerlim.

Olay temsilcisi Imzaları


.NET olay temsilcisi için standart imza:

void OnEventRaised(object sender, EventArgs args);

Dönüş türü void. Olaylar temsilcilere dayalıdır ve çok noktaya yayın temsilcileriniz. Bu, herhangi bir olay kaynağı
için birden çok aboneyi destekler. Bir yöntemden tek dönüş değeri, birden çok olay abonelerine ölçeklenmez. Olay
kaynağı, olay oluşturulduktan sonra hangi dönüş değeri görebilir? Bu makalenin ilerleyen kısımlarında, olay
kaynağına rapor veren olay abonelerini destekleyen olay protokollerini nasıl oluşturacağınız hakkında bilgi
edineceksiniz.
Bağımsız değişken listesi iki bağımsız değişken içerir: gönderici ve olay bağımsız değişkenleri. sender derleme
zaman türü System.Object , ancak her zaman doğru olacak şekilde daha fazla türetilmiş bir tür bildiğiniz halde
olabilir. Kurala göre object kullanın.
İkinci bağımsız değişken genellikle System.EventArgs türetilmiş bir türdür. (Bir sonraki bölümde bu kural artık
zorlanmadığını göreceksiniz.) Olay türü herhangi bir ek bağımsız değişken gerekmiyorsa, her iki bağımsız
değişkeni de sağlamanız gerekir. Olaylarınızın ek bilgi içermediğini belirtmek için kullanmanız gereken
EventArgs.Empty özel bir değer vardır.

Bir dizinde veya bir kalıbı izleyen alt dizinlerindeki dosyaları listeleyen bir sınıf oluşturalım. Bu bileşen, bulunan her
dosya için, düzeniyle eşleşen bir olay oluşturur.
Bir olay modelinin kullanılması bazı tasarım avantajları sağlar. Aranan bir dosya bulunduğunda farklı eylemler
gerçekleştiren birden çok olay dinleyicisi oluşturabilirsiniz. Farklı dinleyicileri birleştirmek daha sağlam algoritmalar
oluşturabilir.
Aranan bir dosyayı bulmak için ilk olay bağımsız değişkeni bildirimi aşağıda verilmiştir:

public class FileFoundArgs : EventArgs


{
public string FoundFile { get; }

public FileFoundArgs(string fileName)


{
FoundFile = fileName;
}
}

Bu tür küçük, salt veri türü gibi görünse de, kuralı izlemeniz ve bir başvuru ( class ) türü yapmanız gerekir. Diğer
bir deyişle, bağımsız değişken nesnesi başvuruya göre geçirilir ve verilerin tüm güncelleştirmeleri tüm aboneler
tarafından görüntülenir. İlk sürüm, sabit bir nesnedir. Olay bağımsız değişkeni türünde özellikleri sabit hale
getirmek için tercih etmelisiniz. Bu şekilde, bir abone, başka bir abonenin onları görebilmesi için değerleri
değiştiremez. (Aşağıda göreceğiniz şekilde bunun için özel durumlar vardır.)
Sonra, FileSearcher sınıfında olay bildirimini oluşturuyoruz. EventHandler<T> türünden yararlanmak, başka bir tür
tanımı oluşturmanız gerekmediği anlamına gelir. Yalnızca genel bir özelleştirme kullanırsınız.
Bir düzeniyle eşleşen dosyaları aramak ve bir eşleşme bulunduğunda doğru olayı yükseltmek için FileSearcher
sınıfını dolduralım.

public class FileSearcher


{
public event EventHandler<FileFoundArgs> FileFound;

public void Search(string directory, string searchPattern)


{
foreach (var file in Directory.EnumerateFiles(directory, searchPattern))
{
FileFound?.Invoke(this, new FileFoundArgs(file));
}
}
}

Alan benzeri olayları tanımlama ve oluşturma


Sınıfınıza bir olay eklemenin en kolay yolu, önceki örnekte olduğu gibi bu olayı ortak bir alan olarak
bildirkullanmaktır:

public event EventHandler<FileFoundArgs> FileFound;

Bu, nesne odaklı kötü bir uygulama gibi görünen bir ortak alan bildirmek gibi görünüyor. Özellikler veya yöntemler
aracılığıyla veri erişimini korumak istiyorsunuz. Kötü bir uygulama gibi görünebilir ancak derleyici tarafından
oluşturulan kod, olay nesnelerine yalnızca güvenli yollarla erişilebilmesi için sarmalayıcılar oluşturur. Alan benzeri
bir olayda kullanılabilen tek işlemler ekleme işleyicisidir:

EventHandler<FileFoundArgs> onFileFound = (sender, eventArgs) =>


{
Console.WriteLine(eventArgs.FoundFile);
filesFound++;
};

fileLister.FileFound += onFileFound;

ve işleyiciyi kaldır:

fileLister.FileFound -= onFileFound;

İşleyici için yerel bir değişken olduğunu unutmayın. Lambda gövdesini kullandıysanız, kaldırma doğru çalışmaz.
Bu, temsilcinin farklı bir örneği olur ve sessizce hiçbir şey yapmaz.
Sınıf dışındaki kod, olayı yükseltemez, diğer işlemleri de gerçekleştiremez.

Olay abonelerinden değer döndürme


Basit sürümünüz sorunsuz çalışıyor. Başka bir özellik ekleyelim: Iptal.
Bulunan olayı yükselttiğinizde, bu dosya son bir aranan ise, dinleyiciler daha fazla işlemeyi durdurabilir.
Olay işleyicileri bir değer döndürmüyor, bu nedenle başka bir şekilde iletişim kurması gerekir.Standart olay
deseninin, olay abonelerinin iptali iletişim kurmak için kullanabileceği alanları dahil etmek için EventArgs nesnesi
kullanılır.
Iptal sözleşmesinin semantiğine bağlı olarak kullanılabilecek iki farklı desen vardır. Her iki durumda da, bulunan
dosya olayı için EventArguments öğesine bir Boole alanı ekleyeceksiniz.
Bir model, bir abonenin işlemi iptal edebilmesini sağlar. Bu model için yeni alan false olarak başlatılır. Herhangi
bir abone, true olarak değiştirebilir. Tüm aboneler oluşturulan olayı gördüğünde, FileSearcher bileşeni Boole
değerini inceler ve işlem gerçekleştirir.
İkinci model yalnızca tüm aboneler işlemi iptal etmek istiyorlarsa işlemi iptal eder. Bu düzende, yeni alan işlemin
iptal olması gerektiğini belirtecek şekilde başlatılır ve herhangi bir abone işlemin devam etmesi gerektiğini
belirtecek şekilde değiştirebilir. Tüm aboneler oluşturulan olayı gördüğünde, FileSearcher bileşeni Boole değerini
inceler ve işlem gerçekleştirir. Bu düzende bir ek adım vardır: bileşeni, olayı gördük bir abone olup olmadığını
bilmelidir. Abone yoksa, alan yanlışlıkla iptal olduğunu gösterir.
Bu örnek için ilk sürümü uygulayalim. FileFoundArgs türüne CancelRequested adlı bir Boole alanı eklemeniz
gerekir:

public class FileFoundArgs : EventArgs


{
public string FoundFile { get; }
public bool CancelRequested { get; set;}

public FileFoundArgs(string fileName)


{
FoundFile = fileName;
}
}

Bu yeni alan, bir Boole alanı için varsayılan değer olan false için otomatik olarak başlatılır, böylece yanlışlıkla iptal
edemezsiniz. Bileşendeki tek bir değişiklik, abonelerden birinin iptal isteğinde bulunup bulunmadığını görmek için
olayı oluşturduktan sonra bayrağı denetmektir:

public void List(string directory, string searchPattern)


{
foreach (var file in Directory.EnumerateFiles(directory, searchPattern))
{
var args = new FileFoundArgs(file);
FileFound?.Invoke(this, args);
if (args.CancelRequested)
break;
}
}

Bu düzenin bir avantajı, önemli olmayan bir değişiklik değildir. Abonelerden hiçbiri daha önce bir iptal isteğinde
bulunmadı ve yine de yok. Yeni iptal protokolünü desteklemek istemmedikleri takdirde abone kodunun hiçbirinin
güncelleştirilmesi gerekmez. Çok esnek bir şekilde bağlanmış.
İlk yürütülebilir dosyayı bulduktan sonra bir iptali istemesi için aboneyi güncelleştirelim:
EventHandler<FileFoundArgs> onFileFound = (sender, eventArgs) =>
{
Console.WriteLine(eventArgs.FoundFile);
eventArgs.CancelRequested = true;
};

Başka bir olay bildirimi ekleme


Daha fazla özellik ekleyelim ve olaylar için diğer dil deyimler gösterimi. Dosya aramasında tüm alt dizinlere geçiş
yapan Search yönteminin bir aşırı yüklemesini ekleyelim.
Bu, çok sayıda alt dizine sahip bir dizinde uzun bir işlem olabilir. Her yeni dizin araması başladığında ortaya çıkan
bir olay ekleyelim. Bu sayede aboneler ilerlemeyi izleyebilir ve kullanıcıyı ilerleme durumuna göre güncelleştirebilir.
Şimdiye kadar oluşturduğunuz tüm örnekler geneldir. Bunu bir iç olay haline olalım. Diğer bir deyişle, iç
değişkenler için de kullanılan türleri de yapabilirsiniz.
Yeni dizin ve ilerlemeyi raporlamak için yeni EventArgs türetilmiş sınıfını oluşturarak başlayacaksınız.

internal class SearchDirectoryArgs : EventArgs


{
internal string CurrentSearchDirectory { get; }
internal int TotalDirs { get; }
internal int CompletedDirs { get; }

internal SearchDirectoryArgs(string dir, int totalDirs, int completedDirs)


{
CurrentSearchDirectory = dir;
TotalDirs = totalDirs;
CompletedDirs = completedDirs;
}
}

Yine, olay bağımsız değişkenleri için sabit bir başvuru türü oluşturmak üzere önerileri izleyebilirsiniz.
Sonra, olayı tanımlayın. Bu kez, farklı bir sözdizimi kullanacaksınız. Alan söz dizimini kullanmanın yanı sıra, özelliği
ekleme ve kaldırma işleyicileri ile açık bir şekilde oluşturabilirsiniz. Bu örnekte, bu işleyicilerde ek kod gerekmez,
ancak bunları nasıl oluşturacağınız gösterilmektedir.

internal event EventHandler<SearchDirectoryArgs> DirectoryChanged


{
add { directoryChanged += value; }
remove { directoryChanged -= value; }
}
private EventHandler<SearchDirectoryArgs> directoryChanged;

Birçok şekilde, yazdığınız kod, daha önce gördüğünüz alan olay tanımları için derleyicinin oluşturduğu kodu
yansıtır. Özellikleriçin kullanılan için çok benzer sözdizimini kullanarak olayı oluşturursunuz. İşleyicilerin farklı
adlara sahip olduğuna dikkat edin: add ve remove . Bunlar olaya abone olmak ya da olaydan abonelik kaldırmak
için çağırılır. Ayrıca, olay değişkenini depolamak için özel bir destek alanı bildirmeniz gerektiğini unutmayın. Null
olarak başlatılır.
Sonra, alt dizinlere geçiş yapan Search yönteminin aşırı yüklemesini ekleyelim ve her iki olayı da oluşturuyor.
Bunu yapmanın en kolay yolu, tüm dizinlerde arama yapmak istediğinizi belirtmek için varsayılan bir bağımsız
değişken kullanmaktır:
public void Search(string directory, string searchPattern, bool searchSubDirs = false)
{
if (searchSubDirs)
{
var allDirectories = Directory.GetDirectories(directory, "*.*", SearchOption.AllDirectories);
var completedDirs = 0;
var totalDirs = allDirectories.Length + 1;
foreach (var dir in allDirectories)
{
directoryChanged?.Invoke(this,
new SearchDirectoryArgs(dir, totalDirs, completedDirs++));
// Search 'dir' and its subdirectories for files that match the search pattern:
SearchDirectory(dir, searchPattern);
}
// Include the Current Directory:
directoryChanged?.Invoke(this,
new SearchDirectoryArgs(directory, totalDirs, completedDirs++));
SearchDirectory(directory, searchPattern);
}
else
{
SearchDirectory(directory, searchPattern);
}
}

private void SearchDirectory(string directory, string searchPattern)


{
foreach (var file in Directory.EnumerateFiles(directory, searchPattern))
{
var args = new FileFoundArgs(file);
FileFound?.Invoke(this, args);
if (args.CancelRequested)
break;
}
}

Bu noktada, tüm alt dizinleri aramak için aşırı yüklemeyi çağıran uygulamayı çalıştırabilirsiniz. Yeni
ChangeDirectory olayında abone yoktur, ancak ?.Invoke() deyim kullanmak bunun doğru şekilde çalıştığından
emin olmanızı sağlar.
Konsol penceresinde ilerleme durumunu gösteren bir çizgi yazmak için bir işleyici ekleyelim.

fileLister.DirectoryChanged += (sender, eventArgs) =>


{
Console.Write($"Entering '{eventArgs.CurrentSearchDirectory}'.");
Console.WriteLine($" {eventArgs.CompletedDirs} of {eventArgs.TotalDirs} completed...");
};

.NET ekosisteminin tamamında izlenen desenleri gördünüz. Bu desenleri ve kuralları öğrenerek, hızlı bir şekilde C#
ve .net ' i hızla yazabileceksiniz.
Daha sonra, en son .NET sürümünde bu desenlerde bazı değişiklikler görürsünüz.
Next
Güncelleştirilmiş .NET Core olay deseninin
30.10.2019 • 6 minutes to read • Edit Online

Öncekini
Önceki makalede en sık kullanılan olay desenleri ele alınmıştır. .NET Core daha gevşek bir düzene sahiptir. Bu
sürümde EventHandler<TEventArgs> tanımı artık TEventArgs System.EventArgs türetilmiş bir sınıf olması gereken
kısıtlamaya sahip değildir.
Bu, sizin için esnekliği artırır ve geriye dönük olarak uyumludur. Esneklik ile başlayalım. System. EventArgs sınıfı
bir yöntemi tanıtır: nesnenin basit bir kopyasını oluşturan MemberwiseClone() . Bu yöntemin, EventArgs türetilmiş
herhangi bir sınıf için işlevselliğini uygulamak üzere yansıma kullanması gerekir. Bu işlevsellik, belirli bir türetilmiş
sınıfta oluşturmak daha kolaydır. Bu, System. EventArgs 'dan Türetmenin tasarımlarınızı sınırlayan bir kısıtlamadır,
ancak başka bir avantaj sunmaz. Aslında, EventArgs türetmemesi için FileFoundArgs ve SearchDirectoryArgs
tanımlarını değiştirebilirsiniz. Program tamamen aynı şekilde çalışır.
Ayrıca, daha fazla değişiklik yaparsanız SearchDirectoryArgs bir struct olarak değiştirebilirsiniz:

internal struct SearchDirectoryArgs


{
internal string CurrentSearchDirectory { get; }
internal int TotalDirs { get; }
internal int CompletedDirs { get; }

internal SearchDirectoryArgs(string dir, int totalDirs, int completedDirs) : this()


{
CurrentSearchDirectory = dir;
TotalDirs = totalDirs;
CompletedDirs = completedDirs;
}
}

Ek değişiklik, tüm alanları Başlatan oluşturucuyu girmeden önce parametresiz oluşturucuyu çağırmaktır. Bu ek
olmadan, kuralları C# atanmadan önce özelliklere erişilmekte olduğunu raporlayabilir.
Bir sınıftan (başvuru türü) FileFoundArgs bir struct (değer türü) olarak değiştirmemelisiniz. Bunun nedeni, Cancel
işleme Protokolü olay bağımsız değişkenlerinin başvuruya göre geçirilmesini gerektirir. Aynı değişikliği
yaptıysanız, dosya arama sınıfı hiçbir türlü olay abonesinin yaptığı değişiklikleri hiçbir şekilde gözlemlemez. Her
abone için yapının yeni bir kopyası kullanılır ve bu kopya dosya arama nesnesi tarafından görülenden farklı bir
kopya olacaktır.
Daha sonra, bu değişikliğin geriye dönük olarak nasıl uyumlu olduğunu ele alalım. Kısıtlamanın kaldırılması var
olan herhangi bir kodu etkilemez. Mevcut herhangi bir olay bağımsız değişken türü System.EventArgs türetmeye
devam eder. Geriye dönük uyumluluk, System.EventArgs türetmeye devam edebilecekleri önemli bir nedendir. Var
olan tüm olay aboneleri, klasik kalıbı izleyen bir olaya abone olur.
Benzer mantığın ardından, artık oluşturulan herhangi bir olay bağımsız değişken türü herhangi bir mevcut kod
tabanı içinde abone olamaz. System.EventArgs türetmeyen yeni olay türleri, bu kod temellerini bozmaz.

Zaman uyumsuz aboneler içeren olaylar


Bilgi edinmek için bir son örüntüsünün olması gerekir: zaman uyumsuz kod çağıran olay abonelerini doğru şekilde
yazma. Bu zorluk, zaman uyumsuz ve awaitmakalesinde açıklanmaktadır. Zaman uyumsuz metotlar void dönüş
türüne sahip olabilir, ancak bu kesinlikle önerilmez. Olay abone kodunuz zaman uyumsuz bir yöntem çağırdığında,
hiçbir seçeneğiniz yoktur ancak bir async void yöntemi oluşturabilirsiniz. Olay işleyicisi imzası gereklidir.
Bu rakip kılavuzun mutabakatını yapmanız gerekir. Bir şekilde, güvenli bir async void yöntemi oluşturmanız
gerekir. Uygulamanız gereken düzenin temelleri aşağıda verilmiştir:

worker.StartWorking += async (sender, eventArgs) =>


{
try
{
await DoWorkAsync();
}
catch (Exception e)
{
//Some form of logging.
Console.WriteLine($"Async task failure: {e.ToString()}");
// Consider gracefully, and quickly exiting.
}
};

İlk olarak, işleyicinin zaman uyumsuz işleyici olarak işaretlendiğinden emin olun. Bir olay işleyicisi temsilci türüne
atanmakta olduğundan, void dönüş türüne sahip olur. Bu, işleyicide gösterilen kalıbı izlemeniz ve tüm özel
durumların zaman uyumsuz işleyicinin içeriğinden çıkmasına izin vermeniz gerektiği anlamına gelir. Bir görev
döndürmediğinden, hatayı hatalı duruma girerek bildiremeyen bir görev yoktur. Yöntemi zaman uyumsuz
olduğundan, yöntem özel durumu oluşturmamalıdır. (Çağırma yöntemi async olduğundan yürütmeye devam etti.)
Gerçek çalışma zamanı davranışı farklı ortamlar için farklı şekilde tanımlanır. İş parçacığını veya iş parçacığına
sahip olan işlemi sonlandırabilir veya işlemi belirsiz bir durumda bırakabilir. Tüm bu olası sonuçlar yüksek oranda
istenmeyen bir süreçlerdir.
Bu nedenle, kendi TRY bloğinizdeki zaman uyumsuz görev için Await ifadesini sarmalısınız. Hatalı bir göreve
neden olursa, hatayı günlüğe kaydedebilirsiniz. Uygulamanızın kurtaramayacağı bir hata ise programdan hızlı ve
sorunsuz bir şekilde çıkabilirsiniz
Bunlar, .NET olay deseninin önemli güncelleştirmeleridir. Üzerinde çalıştığınız kitaplıklarda daha önceki sürümlere
ait birçok örnek görürsünüz. Ancak, en son desenlerin de ne olduğunu anlamanız gerekir.
Bu serinin sonraki makalesi tasarımlarınızın delegates ve events kullanımını ayırt etmenize yardımcı olur. Bunlar
benzer kavramlardır ve bu makale programlarınıza en iyi kararı vermenize yardımcı olur.
Next
Temsilcileri ve Olayları Ayırt Etme
30.10.2019 • 5 minutes to read • Edit Online

Öncekini
.NET Core platformunda yeni olan geliştiriciler, events dayalı bir tasarıma delegates ve tasarımı temel alan bir
tasarım arasında karar verirken çok daha fazla zaman harcamaya uğraşır. Bu zor bir kavramdır, çünkü iki dil özelliği
çok benzerdir. Olaylar, temsilciler için dil desteği kullanılarak bile oluşturulur.
Her ikisi de bir geç bağlama senaryosu sunar: yalnızca çalışma zamanında bilinen bir yöntemi çağırarak bir
bileşenin iletişim kurduğu senaryolara olanak tanır. Her ikisi de tek ve birden çok abone yöntemini destekler. Bu
şekilde, tekcast ve çok noktaya yayın desteği olarak adlandırılan bulabilirsiniz. Bunlar her ikisi de işleyicileri
eklemek ve kaldırmak için benzer sözdizimini destekler. Son olarak, bir olayı oluşturup bir temsilciyi çağırmak, tam
olarak aynı yöntem çağrısı söz dizimini kullanır. Her ikisi de ?. işleci ile kullanmak için aynı Invoke() yöntemi
sözdizimini destekler.
Bu benzerlikler sayesinde ne zaman kullanacağınızı belirlemek oldukça kolaydır.

Olayları dinlemek Isteğe bağlıdır


Hangi dil özelliğinin kullanılacağını belirlemede en önemli nokta, eklenen bir abone olmalıdır. Kodunuzun abone
tarafından sağlanan kodu çağırması gerekiyorsa, temsilcileri temel alan bir tasarım kullanmanız gerekir. Kodunuz
herhangi bir abone çağrılmadan tüm işlerini tamamlayabiliyorsanız, olaylara dayalı bir tasarım kullanmanız gerekir.
Bu bölüm sırasında oluşturulan örnekleri göz önünde bulundurun. List.Sort() kullanarak oluşturduğunuz koda,
öğeleri doğru bir şekilde sıralamak için bir karşılaştırıcı işlevi verilmelidir. Hangi öğelerin döneceğini belirlemek için
temsilcilerle LINQ sorgularının sağlanması gerekir. Her ikisi de temsilcilerle oluşturulmuş bir tasarım kullandı.
Progress olayını göz önünde bulundurun. Bir görevde ilerlemeyi raporlar. Görev, herhangi bir dinleyici olup
olmadığına bakılmaksızın devam etmeye devam eder. FileSearcher başka bir örnektir. Hiçbir olay abonesi ekli
olmasa bile, aranan tüm dosyaları arayabilir ve bulur. UX denetimleri, olayları dinleyen bir abone olmadığında bile
hala düzgün çalışır. Bunlar her ikisi de olayları temel alan tasarımlar kullanır.

Dönüş değerleri temsilciler gerektiriyor


Temsilci yönteminiz için istediğiniz yöntem prototipi başka bir noktadır. Gördüğünüz gibi, olaylar için kullanılan
temsilcilerin void dönüş türü vardır. Ayrıca, olay bağımsız değişkeni nesnesinin özelliklerini değiştirerek olayları
olay kaynaklarına geri geçiren olay işleyicileri oluşturmak için ıoms olduğunu da gördünüz. Bu IBU deyimler
çalışırken, bir yöntemden değer döndürürken doğal olarak değildir.
Bu iki buluşsal yöntemin her ikisi de mevcut olabilir: temsilci yönteminiz bir değer döndürürse, bu durum büyük
olasılıkla algoritmayı bir şekilde etkiler.

Olay dinleyicileri genellikle daha uzun ömürleri vardır


Bu biraz daha zayıf bir gerekçe. Ancak olay tabanlı tasarımların olay kaynağı uzun bir süre boyunca olayları
oluştururken daha doğal olduğunu fark edebilirsiniz. Birçok sistemde UX denetimleri için bunun örneklerini
görebilirsiniz. Bir olaya abone olduktan sonra olay kaynağı, programın kullanım ömrü boyunca olayları
oluşturabilir. (Artık ihtiyaç kalmadığında olayları abonelikten kaldırabilirsiniz.)
Bir temsilcinin bir yönteme bağımsız değişken olarak kullanıldığı birçok temsilci tabanlı tasarım ile, bu yöntem, bu
yöntemin döndürdüğü süre dolduktan sonra kullanılmlarından farklıdır.
Dikkatle değerlendirin
Yukarıdaki konular sabit ve hızlı kurallar değildir. Bunun yerine, belirli kullanımınız için en uygun seçeneği
belirlemenize yardımcı olabilecek Kılavuzu temsil ederler. Benzer olduklarından, her ikisini de prototip yapabilir ve
bununla birlikte çalışmak için ne kadar doğal olacağını düşünün. Bunlar her ikisi de geç bağlama senaryolarını de
işler. Tasarımınızı en iyi şekilde iletişim kuran birini kullanın.
Dil ile Tümleşik Sorgu (LINQ)
23.10.2019 • 5 minutes to read • Edit Online

Dil ile tümleşik sorgu (LINQ ) tümleştirmesini sorgu özellikleri doğrudan C# dilinin temel teknoloji kümesi
adıdır. Geleneksel olarak, veri sorguları zaman veya IntelliSense desteği olmadan tür denetimini en basit
dizeler derleme olarak ifade edilir. Ayrıca, her veri kaynağı türü için bir farklı bir sorgu dili öğrenmek
zorunda: SQL veritabanlarını, XML belgeleri, çeşitli Web Hizmetleri ve benzeri. LINQ ile olduğu gibi
sınıflar, yöntemler, olaylar bir birinci sınıf dil yapısı sorgu.
Sorguları Yazar bir geliştirici için en çok görünen "dil ile tümleşik" LINQ sorgu ifadesi parçasıdır. Sorgu
ifadeleri bildirim temelli yazılır sorgu söz dizimi. Sorgu söz dizimi kullanarak, filtreleme, sıralama ve
gruplandırma işlemlerinin en az veri kaynaklarında kod gerçekleştirebilirsiniz. Aynı temel sorgu ifade
desenleri, sorgu ve veri SQL veritabanları, ADO .NET veri kümeleri, .NET koleksiyonları, XML belgeleri ve
akışları dönüştürmek için kullanın.
Aşağıdaki örnek, tam bir sorgu işlemi gösterilmektedir. Veri kaynağı oluşturma, sorgu ifadesi tanımlama
ve sorgu yürütme işlemi tamamlamak içeren bir foreach deyimi.

class LINQQueryExpressions
{
static void Main()
{

// Specify the data source.


int[] scores = new int[] { 97, 92, 81, 60 };

// Define the query expression.


IEnumerable<int> scoreQuery =
from score in scores
where score > 80
select score;

// Execute the query.


foreach (int i in scoreQuery)
{
Console.Write(i + " ");
}
}
}
// Output: 97 92 81

Sorgu ifadesi genel bakış


Sorgu ifadeleri, sorgulama ve herhangi bir LINQ özellikli veri kaynağından verileri dönüştürmek
için kullanılabilir. Örneğin, tek bir sorgu, bir SQL veritabanından veri almak ve çıktı olarak bir XML
akışı üretir.
Sorgu ifadeleri, alışık olduğunuz birçok C# dil yapılarının kullandıkları için ana kolaydır.
Çoğu durumda derleyici çıkarsayabilir türü açıkça sağlamanız gerekmez ancak bir sorgu ifadesinde
değişkenleri tüm, kesin olarak belirlenmiştir. Daha fazla bilgi için tür ilişkileri LINQ Sorgu işlemleri.
Sorgu değişkeni üzerinde yineleme kadar bir sorgu yürütülmedi Örneğin, bir foreach deyimi.
Daha fazla bilgi için LINQ sorgularına giriş.
Derleme zamanında sorgu ifadeleri C# belirtiminde ortaya konan kurallara göre standart sorgu
işleci yöntem çağrılarını dönüştürülür. Sorgu söz dizimi kullanarak ifade edilebilir herhangi bir
sorgu yöntemi söz dizimi kullanılarak da belirtilebilir. Ancak, çoğu durumda, daha okunabilir ve kısa
sorgu söz dizimi. Daha fazla bilgi için C# dil belirtimi ve standart sorgu işleçlerine genel bakış.
LINQ sorguları yazarken bir kural olarak, mümkün olduğunda sorgu sözdizimi ve yöntem
sözdizimi gerektiğinde kullanmanızı öneririz. Yok Hayır anlam veya iki farklı formlar arasında
performans farkı. Sorgu ifadeleri olan genellikle daha fazla eşdeğer ifadelerin yöntemi sözdizimi
yazılan daha okunabilir.
Bazı sorgu işlemleri gibi Count veya Max, hiçbir eşdeğer sorgu ifade yan tümcesine sahip ve bu
nedenle bir yöntem çağrısının ifade edilmelidir. Yöntem sözdizimi, çeşitli yollarla sorgu söz dizimi
ile birleştirilebilir. Daha fazla bilgi için sorgu sözdizimi ve yöntem sözdizimi LINQ.
Sorgu ifadeleri, ifade ağaçları veya Temsilciler, sorgu uygulanan türüne bağlı olarak derlenebilir.
IEnumerable<T> sorgular için temsilciler derlenir. IQueryable ve IQueryable<T> sorguları, ifade
ağaçlarına derlenir. Daha fazla bilgi için ifade ağaçları.

Sonraki adımlar
LINQ hakkında daha fazla bilgi edinmek için bazı temel kavramları hakkında bilgi sahibi olma Başlat
sorgu ifadesi Temelleri, ve ardından, olduğu ilgilenen LINQ teknolojisi için belgeleri okuyun:
XML belgeleri: LINQ to XML
ADO.NET varlık çerçevesi: LINQ to entities
.NET koleksiyonları, dosyaları, dizeleri ve bu şekilde devam eder: Nesnelere LINQ
Bir derin LINQ genel olarak anlaşılması için bkz: C# üzerinde LINQ.
C# üzerinde LINQ ile çalışmaya başlamak için öğreticiye bakın LINQ ile çalışma.
Sorgu ifadesi temelleri
23.10.2019 • 20 minutes to read • Edit Online

Bu makalede, C# sorgu ifadeleri ilgili temel kavramlar tanıtılmaktadır.

Bir sorgu nedir ve ne işe yarar?


A sorgu döndürülen verileri hangi verilerin belirli bir veri kaynağı (veya kaynaklarından) almak ve hangi şekli ve
kuruluş için olmalıdır açıklayan yönergeler kümesidir. Bir sorgu ürettiği sonuçlardan farklıdır.
Genel olarak, kaynak verileri mantıksal olarak aynı türden bir öğe dizisi düzenlenmiştir. Örneğin, bir SQL
veritabanı tablosunda bir dizi satır içerir. Bir XML dosyasında yoktur bir "dizisi" XML öğesi (bunlar hiyerarşik bir
ağaç yapısında düzenlenmiş rağmen). Bir bellek içi koleksiyon nesneleri dizisi içerir.
Bir uygulamanın bakış açısından belirli türüne ve yapısına özgün kaynak verilerin önemli olmadığından. Uygulama
her zaman kaynak verisi olarak gördüğü bir IEnumerable<T> veya IQueryable<T> koleksiyonu. Örneğin, LINQ
to XML, kaynak veriler olarak görünür hale gelir bir IEnumerable < XElement>.
Bu kaynak dizisi göz önünde bulundurulduğunda, bir sorgu işlemlerden birini yapabilirsiniz:
Tek tek öğelerine değiştirmeden yeni bir sıra oluşturmak için öğeleri kümesini alır. Sorgu sonra sıralama
veya aşağıdaki örnekte gösterildiği gibi çeşitli şekillerde döndürülen dizi Grup (varsayar scores olduğu bir
int[] ):

IEnumerable<int> highScoresQuery =
from score in scores
where score > 80
orderby score descending
select score;

Önceki örnekte olduğu gibi öğeleri dizisi alabilir, ancak bunları yeni bir nesne türüne dönüştürün. Örneğin,
bir sorgu, bir veri kaynağındaki belirli bir müşteri kayıt yalnızca son adlarını alabilirsiniz. Kaydın tamamına
almak ve başka bir bellek içi nesne türü veya hatta kullanmak Sonuç dizisi oluşturmadan XML verileri.
Aşağıdaki örnek, bir projeksiyon gelen gösterir. bir int için bir string . Yeni Not highScoresQuery .

IEnumerable<string> highScoresQuery2 =
from score in scores
where score > 80
orderby score descending
select $"The score is {score}";

Kaynak veriler hakkında bir tekil değer gibi alın:


Belirli bir koşulu karşılayan bir öğe sayısı.
En yüksek veya en düşük değere sahip öğe.
Bir koşul ya da belirtilen öğeleri kümesi içinde belirli değerlerin toplamını eşleşen ilk öğe. Örneğin,
aşağıdaki sorguyu puanları 80'den büyüktür döndürür scores tamsayı dizisi:
int highScoreCount =
(from score in scores
where score > 80
select score)
.Count();

Önceki örnekte, parantezler çağırmadan önce sorgu ifadesinde kullanımına dikkat edin Count
yöntemi. Bu, somut sonucu depolamak için yeni bir değişken kullanarak da koyabilirsiniz. Sorguyu
depolayan değişken sorgudan bir sonuç depolar ayrı tuttuğu bu daha okunabilir bir tekniktir.

IEnumerable<int> highScoresQuery3 =
from score in scores
where score > 80
select score;

int scoreCount = highScoresQuery3.Count();

Önceki örnekte, sorgu çağrısında yürütüldüğü Count , çünkü Count tarafından döndürülen öğe sayısını
belirlemek için sonuçları üzerinde yinelenmelidir highScoresQuery .

Sorgu ifadesi nedir?


A sorgu ifadesi sorgu söz diziminde ifade bir sorgu verilmiştir. Birinci sınıf dil yapısı bir sorgu ifadesidir. Bu diğer
ifade gibi ve bir C# ifadesi geçerli olduğu her bağlamda kullanılabilir. Sorgu ifadesi tümceleri SQL veya XQuery
benzer bir bildirim temelli söz yazılan bir dizi oluşur. Her yan tümcesi sırayla bir veya daha fazla C# ifadeleri
içeriyor ve bu ifadeler kendilerini bir sorgu ifadesi veya olabilir bir sorgu ifadesi içerir.
Sorgu ifadesi ile başlamalıdır bir gelen yan tümcesi ve ile sona ermelidir bir seçin veya grubu yan tümcesi. İlk
arasında from yan tümcesi ve son select veya group yan tümcesi, bir veya daha fazla isteğe bağlı bu yan
tümceleri içerebilir: burada, orderby, birleştirme , izin ve hatta ek gelen yan tümceleri. Ayrıca içine sonucunu
etkinleştirmek için anahtar sözcüğü bir join veya group ek sorgu yan tümceleri aynı sorgu ifadesinde kaynağı
olarak görev yapacak yan tümcesi.
Sorgu değişkeni
LINQ içinde bir sorgu değişkeni depolar herhangi bir değişken olduğu bir sorgu yerine sonuçları sorgu. Özellikle,
bir sorgu değişkeni her zaman bu yinelenir, bir dizi öğe üretir bir numaralandırılabilir türüdür bir foreach deyimi
veya doğrudan bir çağrı ile kendi IEnumerator.MoveNext yöntemi.
Aşağıdaki kod örneği, bir basit bir sorgu ifadesi bir veri kaynağı ile bir filtre yan tümcesi, bir sipariş yan tümce ve
kaynak öğeleri herhangi bir dönüşüm gösterir. select Sorgu yan tümcesi sonlandırır.
static void Main()
{
// Data source.
int[] scores = { 90, 71, 82, 93, 75, 82 };

// Query Expression.
IEnumerable<int> scoreQuery = //query variable
from score in scores //required
where score > 80 // optional
orderby score descending // optional
select score; //must end with select or group

// Execute the query to produce the results


foreach (int testScore in scoreQuery)
{
Console.WriteLine(testScore);
}
}
// Outputs: 93 90 82 82

Önceki örnekte, scoreQuery olduğu bir sorgu değişkeni bazen adlandırılır olarak yalnızca bir sorgu. Sorgu
değişkeni içinde oluşturulan hiçbir gerçek sonuç verileri depolayan foreach döngü. Ve ne zaman foreach deyimi
yürütür, sorgu değişkeni sorgu sonuçları döndürülmez scoreQuery . Bunun yerine, yineleme değişkeni döndürülür
testScore . scoreQuery Değişkeni bir saniye içinde yinelenir foreach döngü. Bu ne veri kaynağı değiştirilmiş
sürece aynı sonuçları oluşturur.
Bir sorgu değişkeni sorgu söz dizimi veya yöntem sözdizimi veya ikisinin birleşimini ifade edilen bir sorgu
depolayabiliriz. Aşağıdaki örneklerde, her ikisi de queryMajorCities ve queryMajorCities2 sorgu değişkenleri:

//Query syntax
IEnumerable<City> queryMajorCities =
from city in cities
where city.Population > 100000
select city;

// Method-based syntax
IEnumerable<City> queryMajorCities2 = cities.Where(c => c.Population > 100000);

Öte yandan, aşağıdaki iki örnek, her bir sorgu ile başlatılır olsa bile, sorgu değişkenleri olmayan değişkenlerini
gösterir. Sonuçları depoladıkları çünkü bunlar sorgu değişkenleri değildir:
int highestScore =
(from score in scores
select score)
.Max();

// or split the expression


IEnumerable<int> scoreQuery =
from score in scores
select score;

int highScore = scoreQuery.Max();


// the following returns the same result
int highScore = scores.Max();

List<City> largeCitiesList =
(from country in countries
from city in country.Cities
where city.Population > 10000
select city)
.ToList();

// or split the expression


IEnumerable<City> largeCitiesQuery =
from country in countries
from city in country.Cities
where city.Population > 10000
select city;

List<City> largeCitiesList2 = largeCitiesQuery.ToList();

Hızlı sorgular için farklı yollar hakkında daha fazla bilgi için bkz: sorgu sözdizimi ve yöntem sözdizimi LINQ.
Açık ve örtük değişkenler sorgu yazma
Bu belgeler, açık tür sorgu değişkeni sorgu değişkeninin türü ilişkisi göstermek için genellikle sağlar ve select yan
tümcesi. Ancak, ayrıca kullanabileceğiniz var anahtar sözcüğünü kullanarak derleyicinin derleme zamanında bir
sorgu değişkeni (veya herhangi bir yerel değişken) türünü çıkarsamak için. Örneğin, bu konuda daha önce
gösterilen sorgusu örneği de örtülü yazma'yı kullanarak ifade edilebilir:

// Use of var is optional here and in all queries.


// queryCities is an IEnumerable<City> just as
// when it is explicitly typed.
var queryCities =
from city in cities
where city.Population > 100000
select city;

Daha fazla bilgi için örtülü olarak yazılan yerel değişkenler ve tür ilişkileri LINQ Sorgu işlemleri.
Sorgu ifadesi başlatılıyor
Sorgu ifadesi ile başlamalıdır bir from yan tümcesi. Bu, bir aralık değişkeni ile birlikte bir veri kaynağını belirtir.
Aralık değişkeni kaynak sırası geçiş kaynak sırası art arda gelen her öğeyi temsil eder. Aralık değişkeni bağlı olarak
veri kaynağındaki öğelerin türü kesin. Aşağıdaki örnekte, çünkü countries dizisidir Country nesneleri olarak de
Aralık değişkeninin türü Country . Aralık değişkeninin türü kesin olarak belirtilmiş olduğundan, nokta işleci türü
kullanılabilir tüm üyelerine erişmek için kullanabilirsiniz.

IEnumerable<Country> countryAreaQuery =
from country in countries
where country.Area > 500000 //sq km
select country;
Sorgu veya noktalı virgül ile çıkıldı kadar aralık değişkeni kapsamları dahilinde olması bir devamlılık yan tümcesi.
Sorgu ifadesi birden çok içerebilir from yan tümceleri. Ek kullanım from tümceleri kaynak dizideki her öğe
kendisi bir koleksiyon olduğunda veya bir koleksiyonu içerir. Örneğin, koleksiyonu olduğunu varsayın Country
nesneleri, her biri bir koleksiyonunu içeren City adlı nesneleri Cities . Sorgulanacak City nesneleri her
Country , iki kullanın from burada gösterildiği şekilde yan tümceleri:

IEnumerable<City> cityQuery =
from country in countries
from city in country.Cities
where city.Population > 10000
select city;

Daha fazla bilgi için from yan tümcesinde.


Sorgu ifadesi bitiş
Sorgu ifadesi ile bitmelidir bir group yan tümcesi veya select yan tümcesi.
group tümcesi
Kullanım group grupları dizisini üretmek için yan, belirttiğiniz bir anahtar tarafından düzenlenir. Herhangi bir veri
türü olabilir. Örneğin, bir veya daha fazla bilgi içeren bir dizi gruplarının aşağıdaki sorguyu oluşturur Country
nesneleri ve anahtarı olan bir char değeri.

var queryCountryGroups =
from country in countries
group country by country.Name[0];

Gruplama hakkında daha fazla bilgi için bkz: group yan tümcesi.
select tümcesi
Kullanım select dizileri diğer tüm türleri üretmek için yan tümcesi. Basit bir select yan tümcesi yalnızca bir veri
kaynağında bulunan nesneleri aynı türde nesneler dizisi üretir. Bu örnekte, veri kaynağını içeren Country
nesneleri. orderby Yan tümcesi yalnızca yeni bir düzen ile öğeleri sıralar ve select yan tümcesi yeniden
düzenlenen bir dizi üretir Country nesneleri.

IEnumerable<Country> sortedQuery =
from country in countries
orderby country.Area
select country;

select Yan tümcesi, kaynak verileri yeni türleri sıralarına dönüştürmek için kullanılabilir. Bu dönüştürme de adlı
bir projeksiyon. Aşağıdaki örnekte, select yan tümcesi projeleri yalnızca özgün öğesi alanları kümesini içeren bir
anonim türleri dizisi. Yeni nesneler bir nesne Başlatıcı kullanarak başlatılır unutmayın.

// Here var is required because the query


// produces an anonymous type.
var queryNameAndPop =
from country in countries
select new { Name = country.Name, Pop = country.Population };

Tüm yollar hakkında daha fazla bilgi için bir select yan tümcesi, kaynak verileri dönüştürür, görmek için
kullanılabilir select yan tümcesi.
"İçinde" devamlılıklarla
Kullanabileceğiniz into anahtar sözcüğü bir select veya group yan tümcesi bir sorgu depolayan geçici bir
tanımlayıcı. Bunu bir gruplandırma sonra bir sorgu ek sorgu işlemleri gerçekleştirmek veya işlemi seçin. Aşağıdaki
örnekte countries 10 milyon aralığı içinde popülasyon göre gruplandırılır. Sonra bu gruplara bazı
Gruplar'kullanıma ve sıralama için oluşturulmuş, ek yan tümceleri filtre sipariş artan grupları. Bu ek işlemleri
gerçekleştirmek için devamlılık temsil ettiği countryGroup gereklidir.

// percentileQuery is an IEnumerable<IGrouping<int, Country>>


var percentileQuery =
from country in countries
let percentile = (int) country.Population / 10_000_000
group country by percentile into countryGroup
where countryGroup.Key >= 20
orderby countryGroup.Key
select countryGroup;

// grouping is an IGrouping<int, Country>


foreach (var grouping in percentileQuery)
{
Console.WriteLine(grouping.Key);
foreach (var country in grouping)
Console.WriteLine(country.Name + ":" + country.Population);
}

Daha fazla bilgi için içine.


Filtreleme, sıralama ve birleştirme
Başlangıç arasında from yan tümcesi ve bitiş select veya group yan tümcesi, diğer tüm yan tümceleri ( where ,
join , orderby , from , let ) isteğe bağlıdır. Herhangi bir isteğe bağlı yan tümceleri sıfır veya birden çok kez bir
sorgu gövdesi içinde kullanılabilir.
where tümcesi
Kullanım where veriler kaynak veri öğeleri filtrelemek için yan tümcesi bir veya daha fazla koşul ifadeleri temel.
where Yan tümcesi aşağıdaki örnekte bir koşula sahip iki koşul vardır.

IEnumerable<City> queryCityPop =
from city in cities
where city.Population < 200000 && city.Population > 100000
select city;

Daha fazla bilgi için burada yan tümcesi.


orderby tümcesi
Kullanım orderby sonuçları artan veya azalan düzende sıralamak için yan tümcesi. İkincil sıralamalar de
belirtebilirsiniz. Aşağıdaki örnekte birincil sıralama gerçekleştirir country kullanarak nesneleri Area özelliği.
Kullanarak ardından bir ikincil sıralama gerçekleştirir Population özelliği.

IEnumerable<Country> querySortedCountries =
from country in countries
orderby country.Area, country.Population descending
select country;

ascending Anahtar sözcüğü isteğe bağlı; hiçbir sırası belirtilmezse, varsayılan sıralama düzeni. Daha fazla bilgi için
orderby yan tümcesinin.
join tümcesi
Kullanım join her öğeyi belirtilen anahtarlarında bir eşitlik karşılaştırması temel ilişkilendirmek ve/veya başka bir
veri kaynağındaki öğeleri içeren bir veri kaynağındaki öğeleri birleştirme yan tümcesi. LINQ içinde öğeleri farklı
türleri olan nesneler dizisi üzerinde birleştirme işlemleri gerçekleştirilir. İki sıranın katıldıktan sonra kullanmalısınız
bir select veya group deyimi bir çıkış dizisinde depolamak için hangi öğesi belirtin. Anonim bir tür, çıkış sırası
için yeni bir türü her ilişkili öğeleri kümesi özelliklerinden birleştirin için de kullanabilirsiniz. Aşağıdaki örnek
ilişkilendirir prod ayarlanmış nesneleri Category özelliği eşleşen kategoride birini categories dize dizisi. Ürünler
olan Category herhangi bir dize eşleşmiyor categories filtrelenir. select Deyimi özellikleri hem de alınır, yeni bir
tür projeleri cat ve prod .

var categoryQuery =
from cat in categories
join prod in products on cat equals prod.Category
select new { Category = cat, Name = prod.Name };

Grup birleştirme sonuçlarının depolayarak de gerçekleştirebilirsiniz join işlemi kullanarak geçici bir değişken
içine içine anahtar sözcüğü. Daha fazla bilgi için JOIN yan tümcesi.
let tümcesi
Kullanım let yan gibi bir yöntem çağrısının bir ifadenin sonucu yeni bir aralık değişkeninde depolar. Aşağıdaki
örnekte, aralık değişkeni firstName tarafından döndürülen dizenin dizinin ilk öğesi depolar Split .

string[] names = { "Svetlana Omelchenko", "Claire O'Donnell", "Sven Mortensen", "Cesar Garcia" };
IEnumerable<string> queryFirstNames =
from name in names
let firstName = name.Split(' ')[0]
select firstName;

foreach (string s in queryFirstNames)


Console.Write(s + " ");
//Output: Svetlana Claire Sven Cesar

Daha fazla bilgi için let yan tümcesi.


Bir sorgu ifadesinde alt sorgular
Sorgu yan tümcesi kendisini bazen olarak adlandırılan bir sorgu ifadesi içerebilir bir alt sorgu. Her alt sorgu kendi
ile başlayan from mutlaka aynı veri kaynağına ilk göstermiyor yan tümcesi from yan tümcesi. Örneğin, aşağıdaki
sorguyu bir gruplandırma işlemi sonuçlarını almak için select deyiminde kullanılan bir sorgu ifadesini gösterir.

var queryGroupMax =
from student in students
group student by student.GradeLevel into studentGroup
select new
{
Level = studentGroup.Key,
HighestScore =
(from student2 in studentGroup
select student2.Scores.Average())
.Max()
};

Daha fazla bilgi için nasıl yapılır: gruplandırma işleminde alt sorgu gerçekleştirme.

Ayrıca bkz.
C# programlama kılavuzu
Dil ile Tümleşik Sorgu (LINQ )
Query keywords (LINQ )
Standart sorgu işleçlerine genel bakış
C 'de LINQ#
4.11.2019 • 2 minutes to read • Edit Online

Bu bölüm, LINQ hakkında daha ayrıntılı bilgi sağlayan konulara bağlantılar içerir.

Bu bölümde
LINQ Sorgularına Giriş
Temel LINQ sorgu işleminin tüm diller ve veri kaynakları genelinde ortak olan üç parçasını açıklar.
LINQ ve genel türler
LINQ 'te kullanıldıkları gibi Genel türlere kısa bir giriş sağlar.
LINQ ile veri dönüştürmeleri
Sorgularda alınan verileri dönüştürebilmeniz için çeşitli yollar açıklanmaktadır.
LINQ sorgu işlemlerinde tür ilişkileri
Türlerin bir LINQ sorgu işleminin üç bölümünde nasıl korunduğu ve/veya dönüştürüleceklerini açıklar
LINQ 'te sorgu sözdizimi ve Yöntem sözdizimi
Bir LINQ sorgusu ifade etmek için yöntem sözdizimini ve sorgu sözdizimini iki şekilde karşılaştırır.
C#LINQ 'i destekleyen özellikler
C# Bu, LINQ desteği olan dil yapılarını açıklar.

İlgili bölümler
LINQ sorgu ifadeleri
LINQ içindeki sorgulara genel bir bakış içerir ve ek kaynaklara bağlantılar sağlar.
Standart sorgu işleçlerine genel bakış
LINQ içinde kullanılan standart yöntemleri tanıtır.
C'de LINQ sorguları yazma#
23.10.2019 • 6 minutes to read • Edit Online

Bu makalede, C# LINQ sorgusu yazma kullandığı üç yöntem açıklanır:


1. Sorgu söz dizimi kullanın.
2. Yöntem sözdizimini kullanın.
3. Sorgu sözdizimi ve yöntem sözdizimi bir birleşimini kullanın.
Aşağıdaki örnekler, daha önce listelenen her bir yaklaşım kullanarak bazı basit LINQ sorguları gösterir.Genel
olarak, kullanım (1) mümkün olduğunda ve Kullan (2) ve (3) gerektiğinde kuralıdır.

NOTE
Bu sorgular, basit bir bellek içi koleksiyonlarda çalışır; Ancak, temel sözdizimi, LINQ to Entities ve LINQ to XML kullanılıyor
aynıdır.

Örnek - sorgu söz dizimi


Çoğu sorguları yazma için önerilen yöntem kullanmaktır sorgu söz dizimi oluşturmak için sorgu ifadelerinde.
Aşağıdaki örnek, üç sorgu ifadeleri gösterir. İlk sorgu ifadesi filtreleyin veya koşullarla uygulayarak, sonuçları
kısıtlama yapmayı gösteren bir where yan tümcesi. Değerleri 7 veya 3'ten az büyük olan kaynak dizisindeki tüm
öğeleri döndürür. İkinci deyim, döndürülen sonuçların nasıl gösterir. Üçüncü ifade, sonuçları bir anahtar göre
gruplandırmak gösterilmektedir. Bu sorgu, sözcüğün ilk harfini üzerinde alan iki gruplar döndürür.

// Query #1.
List<int> numbers = new List<int>() { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

// The query variable can also be implicitly typed by using var


IEnumerable<int> filteringQuery =
from num in numbers
where num < 3 || num > 7
select num;

// Query #2.
IEnumerable<int> orderingQuery =
from num in numbers
where num < 3 || num > 7
orderby num ascending
select num;

// Query #3.
string[] groupingQuery = { "carrots", "cabbage", "broccoli", "beans", "barley" };
IEnumerable<IGrouping<char, string>> queryFoodGroups =
from item in groupingQuery
group item by item[0];

Sorgu türü olduğuna dikkat edin IEnumerable<T>. Tüm bu sorguları kullanarak yazılabilir var aşağıdaki örnekte
gösterildiği gibi:
var query = from num in numbers...

İçindeki sorgu değişkeni üzerinde yineleme kadar her önceki örnekte sorgular gerçekten Yürütülmeyen bir
foreach deyimi veya diğer deyimi. Daha fazla bilgi için LINQ sorgularına giriş.

Örnek - yöntem sözdizimi


Bazı sorgu işlemlerinin bir yöntem çağrısının ifade edilmelidir. En yaygın tür yöntemler gibi tekil sayısal değerler
döndüren olanlardır Sum, Max, Min, Averageve benzeri. Yalnızca tek bir değeri temsil eder ve bir ek sorgu işlemi
kaynağı olarak hizmet veremez bu yöntemlerin her zaman içinde herhangi bir sorgu son çağrılmalıdır. Aşağıdaki
örnek bir sorgu ifadesinde yöntem çağrısı gösterir:

List<int> numbers1 = new List<int>() { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };


List<int> numbers2 = new List<int>() { 15, 14, 11, 13, 19, 18, 16, 17, 12, 10 };
// Query #4.
double average = numbers1.Average();

// Query #5.
IEnumerable<int> concatenationQuery = numbers1.Concat(numbers2);

Yöntem bir eylem veya Func parametrelere sahipse, bunlar biçiminde sağlanır bir lambda aşağıdaki örnekte
gösterildiği gibi ifade:

// Query #6.
IEnumerable<int> largeNumbersQuery = numbers2.Where(c => c > 15);

Önceki sorgular, yalnızca sorgu #4 hemen yürütür.Tek bir değer ve bir genel döndürür olmasıdır IEnumerable<T>
koleksiyonu. Yöntemin kendisi kullanması gereken foreach değerini hesaplamak için.
Her biri, önceki sorgular ile örtülü yazma'yı kullanarak yazılabilir var, aşağıdaki örnekte gösterildiği gibi:

// var is used for convenience in these queries


var average = numbers1.Average();
var concatenationQuery = numbers1.Concat(numbers2);
var largeNumbersQuery = numbers2.Where(c => c > 15);

Örnek - karma sorgu ve yöntem sözdizimi


Bu örnek, bir sorgu yan tümcesinin sonuçlarını temel yöntem sözdizimi kullanmayı gösterir. Yalnızca sorgu ifadesi,
parantez içine ve ardından nokta işleci uygulamak ve yöntemi çağırın. Aşağıdaki örnekte, sorgu #7, 3 ve 7 arasında
bir değeri olan sayıların sayısını döndürür. Genel olarak, ancak bu ikinci bir değişkene yöntem çağrısının sonucunu
depolamak için kullanmak en iyisidir. Bu şekilde, sorgu sorgu sonuçlarını kafanız olma olasılığı daha gereklidir.

// Query #7.

// Using a query expression with method syntax


int numCount1 =
(from num in numbers1
where num < 3 || num > 7
select num).Count();

// Better: Create a new variable to store


// the method call result
IEnumerable<int> numbersQuery =
from num in numbers1
where num < 3 || num > 7
select num;

int numCount2 = numbersQuery.Count();


Sorgu, sorgu #7 tek bir değer ve bir koleksiyonu döndürdüğünden, hemen yürütür.
Önceki sorguya ile örtülü yazma'yı kullanarak yazılabilir var gibi:

var numCount = (from num in numbers...

Bunu şu şekilde yöntemi sözdiziminde yazılabilir:

var numCount = numbers.Where(n => n < 3 || n > 7).Count();

Açık, şu şekilde yazım kullanarak yazılabilir:

int numCount = numbers.Where(n => n < 3 || n > 7).Count();

Ayrıca bkz.
İzlenecek yol: Sorguları yazmaC#
Dil ile Tümleşik Sorgu (LINQ )
where yan tümcesi
Nesneler koleksiyonunu sorgulama
23.10.2019 • 3 minutes to read • Edit Online

Bu örnek bir listesi basit bir sorgu gerçekleştirmek nasıl gösterir Student nesneleri. Her Student nesnesi Öğrenci
ve öğrencinin puanları üzerindeki dört incelemelerde temsil eden bir liste hakkında bazı temel bilgileri içerir.
Bu uygulama, aynı kullanan çok sayıda diğer örnekler için bu bölümdeki framework görür students veri kaynağı.

Örnek
Aşağıdaki sorgu bir puana 90 ya da kendi ilk sınavı büyük öğrencilere döndürür.

public class Student


{
#region data
public enum GradeLevel { FirstYear = 1, SecondYear, ThirdYear, FourthYear };

public string FirstName { get; set; }


public string LastName { get; set; }
public int Id { get; set; }
public GradeLevel Year;
public List<int> ExamScores;

protected static List<Student> students = new List<Student>


{
new Student {FirstName = "Terry", LastName = "Adams", Id = 120,
Year = GradeLevel.SecondYear,
ExamScores = new List<int> { 99, 82, 81, 79}},
new Student {FirstName = "Fadi", LastName = "Fakhouri", Id = 116,
Year = GradeLevel.ThirdYear,
ExamScores = new List<int> { 99, 86, 90, 94}},
new Student {FirstName = "Hanying", LastName = "Feng", Id = 117,
Year = GradeLevel.FirstYear,
ExamScores = new List<int> { 93, 92, 80, 87}},
new Student {FirstName = "Cesar", LastName = "Garcia", Id = 114,
Year = GradeLevel.FourthYear,
ExamScores = new List<int> { 97, 89, 85, 82}},
new Student {FirstName = "Debra", LastName = "Garcia", Id = 115,
Year = GradeLevel.ThirdYear,
ExamScores = new List<int> { 35, 72, 91, 70}},
new Student {FirstName = "Hugo", LastName = "Garcia", Id = 118,
Year = GradeLevel.SecondYear,
ExamScores = new List<int> { 92, 90, 83, 78}},
new Student {FirstName = "Sven", LastName = "Mortensen", Id = 113,
Year = GradeLevel.FirstYear,
ExamScores = new List<int> { 88, 94, 65, 91}},
new Student {FirstName = "Claire", LastName = "O'Donnell", Id = 112,
Year = GradeLevel.FourthYear,
ExamScores = new List<int> { 75, 84, 91, 39}},
new Student {FirstName = "Svetlana", LastName = "Omelchenko", Id = 111,
Year = GradeLevel.SecondYear,
ExamScores = new List<int> { 97, 92, 81, 60}},
new Student {FirstName = "Lance", LastName = "Tucker", Id = 119,
Year = GradeLevel.ThirdYear,
ExamScores = new List<int> { 68, 79, 88, 92}},
new Student {FirstName = "Michael", LastName = "Tucker", Id = 122,
Year = GradeLevel.FirstYear,
ExamScores = new List<int> { 94, 92, 91, 91}},
new Student {FirstName = "Eugene", LastName = "Zabokritski", Id = 121,
Year = GradeLevel.FourthYear,
ExamScores = new List<int> { 96, 85, 91, 60}}
ExamScores = new List<int> { 96, 85, 91, 60}}
};
#endregion

// Helper method, used in GroupByRange.


protected static int GetPercentile(Student s)
{
double avg = s.ExamScores.Average();
return avg > 0 ? (int)avg / 10 : 0;
}

public static void QueryHighScores(int exam, int score)


{
var highScores = from student in students
where student.ExamScores[exam] > score
select new {Name = student.FirstName, Score = student.ExamScores[exam]};

foreach (var item in highScores)


{
Console.WriteLine($"{item.Name,-15}{item.Score}");
}
}
}

public class Program


{
public static void Main()
{
Student.QueryHighScores(1, 90);

// Keep the console window open in debug mode.


Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
}

Bu sorgu, denemenizi etkinleştirmek kasıtlı olarak basit bir işlemdir. Örneğin, daha fazla koşullarında
deneyebilirsiniz where yan tümcesi veya kullanımı bir orderby sonuçları sıralamak için yan tümcesi.

Ayrıca bkz.
Dil ile Tümleşik Sorgu (LINQ )
Dize ilişkilendirme
Yöntemden bir sorgu döndürme (C# Programlama
Kılavuzu)
25.11.2019 • 3 minutes to read • Edit Online

Bu örnek, bir yöntemden dönüş değeri olarak ve out parametresi olarak bir sorgunun nasıl döndürülyapılacağını
gösterir.
Sorgu nesneleri birleştirilebilir, bu da bir yöntemden sorgu döndürebilmeniz anlamına gelir.Sorguları temsil eden
nesneler, sonuçta elde edilen koleksiyonu depolamaz, ancak gerektiğinde sonuçları oluşturmak için gerekli adımları
uygulayın. Yöntemlerin sorgu nesnelerini döndürmesinin avantajı, daha fazla oluşturulabilir veya değiştirilebilir. Bu
nedenle, bir sorgu döndüren bir yöntemin dönüş değeri veya out parametresi de aynı türde olmalıdır. Bir yöntem
bir sorguyu somut bir List<T> veya Array türüne alıyorsa, sorgunun kendisi yerine sorgu sonuçlarının
döndürülmesi kabul edilir. Bir yöntemden döndürülen bir sorgu değişkeni hala oluşturulabilir veya değiştirilebilir.

Örnek
Aşağıdaki örnekte, ilk yöntem bir sorgu dönüş değeri olarak döndürür ve ikinci yöntem out parametresi olarak bir
sorgu döndürür. Her iki durumda da, sorgu sonuçlarının değil, döndürülen bir sorgu olduğunu unutmayın.

class MQ
{
// QueryMethhod1 returns a query as its value.
IEnumerable<string> QueryMethod1(ref int[] ints)
{
var intsToStrings = from i in ints
where i > 4
select i.ToString();
return intsToStrings;
}

// QueryMethod2 returns a query as the value of parameter returnQ.


void QueryMethod2(ref int[] ints, out IEnumerable<string> returnQ)
{
var intsToStrings = from i in ints
where i < 4
select i.ToString();
returnQ = intsToStrings;
}

static void Main()


{
MQ app = new MQ();

int[] nums = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

// QueryMethod1 returns a query as the value of the method.


var myQuery1 = app.QueryMethod1(ref nums);

// Query myQuery1 is executed in the following foreach loop.


Console.WriteLine("Results of executing myQuery1:");
// Rest the mouse pointer over myQuery1 to see its type.
foreach (string s in myQuery1)
{
Console.WriteLine(s);
}

// You also can execute the query returned from QueryMethod1


// directly, without using myQuery1.
// directly, without using myQuery1.
Console.WriteLine("\nResults of executing myQuery1 directly:");
// Rest the mouse pointer over the call to QueryMethod1 to see its
// return type.
foreach (string s in app.QueryMethod1(ref nums))
{
Console.WriteLine(s);
}

IEnumerable<string> myQuery2;
// QueryMethod2 returns a query as the value of its out parameter.
app.QueryMethod2(ref nums, out myQuery2);

// Execute the returned query.


Console.WriteLine("\nResults of executing myQuery2:");
foreach (string s in myQuery2)
{
Console.WriteLine(s);
}

// You can modify a query by using query composition. A saved query


// is nested inside a new query definition that revises the results
// of the first query.
myQuery1 = from item in myQuery1
orderby item descending
select item;

// Execute the modified query.


Console.WriteLine("\nResults of executing modified myQuery1:");
foreach (string s in myQuery1)
{
Console.WriteLine(s);
}

// Keep console window open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}

Ayrıca bkz.
Dil ile Tümleşik Sorgu (LINQ )
Bellekte sorgunun sonuçlarını depolama
23.10.2019 • 2 minutes to read • Edit Online

Bir sorgu temel alabilir ve verileri düzenleme hakkında yönergeler kümesidir. Sorgular, gevşek, sonraki her öğe
sonucu, istenen şekilde yürütülür. Kullanırken foreach sonuçlarını yinelemek için öğeler erişilen olarak döndürülür.
Bir sorguyu değerlendirmeye ve çalıştırmadan sonuçlarını depolamak için bir foreach döngüsünde, yalnızca
aşağıdaki yöntemlerden birini sorgu değişkeni üzerinde çağırın:
ToList
ToArray
ToDictionary
ToLookup
Sorgu sonuçları depoladığınızda, döndürülen koleksiyon nesnesi için yeni bir değişken aşağıdaki örnekte
gösterildiği gibi atamanızı öneririz:

Örnek
class StoreQueryResults
{
static List<int> numbers = new List<int>() { 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };
static void Main()
{

IEnumerable<int> queryFactorsOfFour =
from num in numbers
where num % 4 == 0
select num;

// Store the results in a new variable


// without executing a foreach loop.
List<int> factorsofFourList = queryFactorsOfFour.ToList();

// Iterate the list just to prove it holds data.


Console.WriteLine(factorsofFourList[2]);
factorsofFourList[2] = 0;
Console.WriteLine(factorsofFourList[2]);

// Keep the console window open in debug mode.


Console.WriteLine("Press any key");
Console.ReadKey();
}
}

Ayrıca bkz.
Dil ile Tümleşik Sorgu (LINQ )
Sorgu sonuçlarını gruplandırma
23.10.2019 • 10 minutes to read • Edit Online

Gruplandırma LINQ en güçlü özelliklerinden biridir. Aşağıdaki örnekler, çeşitli yollarla verilerin nasıl gruplanacağını
gösterir:
Tek bir özelliğe göre.
Bir dize özelliği ilk harfi ile.
Tarafından hesaplanan bir sayısal aralık.
Boole koşulu veya diğer ifade.
Bileşik bir anahtar.
Ayrıca, son iki sorguların sonuçlarını Öğrenci ilk yalnızca içeriyor ve Soyadı yeni bir anonim tür proje. Daha fazla
bilgi için group yan tümcesi.

Örnek
Bu konunun tüm örnekleri aşağıdaki yardımcı sınıflar ve veri kaynaklarını kullanın.

public class StudentClass


{
#region data
protected enum GradeLevel { FirstYear = 1, SecondYear, ThirdYear, FourthYear };
protected class Student
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int ID { get; set; }
public GradeLevel Year;
public List<int> ExamScores;
}

protected static List<Student> students = new List<Student>


{
new Student {FirstName = "Terry", LastName = "Adams", ID = 120,
Year = GradeLevel.SecondYear,
ExamScores = new List<int>{ 99, 82, 81, 79}},
new Student {FirstName = "Fadi", LastName = "Fakhouri", ID = 116,
Year = GradeLevel.ThirdYear,
ExamScores = new List<int>{ 99, 86, 90, 94}},
new Student {FirstName = "Hanying", LastName = "Feng", ID = 117,
Year = GradeLevel.FirstYear,
ExamScores = new List<int>{ 93, 92, 80, 87}},
new Student {FirstName = "Cesar", LastName = "Garcia", ID = 114,
Year = GradeLevel.FourthYear,
ExamScores = new List<int>{ 97, 89, 85, 82}},
new Student {FirstName = "Debra", LastName = "Garcia", ID = 115,
Year = GradeLevel.ThirdYear,
ExamScores = new List<int>{ 35, 72, 91, 70}},
new Student {FirstName = "Hugo", LastName = "Garcia", ID = 118,
Year = GradeLevel.SecondYear,
ExamScores = new List<int>{ 92, 90, 83, 78}},
new Student {FirstName = "Sven", LastName = "Mortensen", ID = 113,
Year = GradeLevel.FirstYear,
ExamScores = new List<int>{ 88, 94, 65, 91}},
new Student {FirstName = "Claire", LastName = "O'Donnell", ID = 112,
Year = GradeLevel.FourthYear,
ExamScores = new List<int>{ 75, 84, 91, 39}},
new Student {FirstName = "Svetlana", LastName = "Omelchenko", ID = 111,
Year = GradeLevel.SecondYear,
ExamScores = new List<int>{ 97, 92, 81, 60}},
new Student {FirstName = "Lance", LastName = "Tucker", ID = 119,
Year = GradeLevel.ThirdYear,
ExamScores = new List<int>{ 68, 79, 88, 92}},
new Student {FirstName = "Michael", LastName = "Tucker", ID = 122,
Year = GradeLevel.FirstYear,
ExamScores = new List<int>{ 94, 92, 91, 91}},
new Student {FirstName = "Eugene", LastName = "Zabokritski", ID = 121,
Year = GradeLevel.FourthYear,
ExamScores = new List<int>{ 96, 85, 91, 60}}
};
#endregion

//Helper method, used in GroupByRange.


protected static int GetPercentile(Student s)
{
double avg = s.ExamScores.Average();
return avg > 0 ? (int)avg / 10 : 0;
}

public void QueryHighScores(int exam, int score)


{
var highScores = from student in students
where student.ExamScores[exam] > score
select new {Name = student.FirstName, Score = student.ExamScores[exam]};

foreach (var item in highScores)


{
Console.WriteLine($"{item.Name,-15}{item.Score}");
}
}
}

public class Program


{
public static void Main()
{
StudentClass sc = new StudentClass();
sc.QueryHighScores(1, 90);

// Keep the console window open in debug mode.


Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
}

Örnek
Aşağıdaki örnek, tek bir özellik öğesinin Grup anahtarı kullanarak kaynak öğeleri gruplandırmak gösterilmektedir.
Bu durumda bu anahtar, bir string , öğrencinin soyadı. Anahtar için bir alt dizesi kullanmak da mümkündür.
Gruplandırma işlemi türü için varsayılan eşitlik karşılaştırıcısını kullanır.
Aşağıdaki yönteme yapıştırın StudentClass sınıfı. Arama deyiminde değiştirme Main yönteme
sc.GroupBySingleProperty() .
public void GroupBySingleProperty()
{
Console.WriteLine("Group by a single property in an object:");

// Variable queryLastNames is an IEnumerable<IGrouping<string,


// DataClass.Student>>.
var queryLastNames =
from student in students
group student by student.LastName into newGroup
orderby newGroup.Key
select newGroup;

foreach (var nameGroup in queryLastNames)


{
Console.WriteLine($"Key: {nameGroup.Key}");
foreach (var student in nameGroup)
{
Console.WriteLine($"\t{student.LastName}, {student.FirstName}");
}
}
}
/* Output:
Group by a single property in an object:
Key: Adams
Adams, Terry
Key: Fakhouri
Fakhouri, Fadi
Key: Feng
Feng, Hanying
Key: Garcia
Garcia, Cesar
Garcia, Debra
Garcia, Hugo
Key: Mortensen
Mortensen, Sven
Key: O'Donnell
O'Donnell, Claire
Key: Omelchenko
Omelchenko, Svetlana
Key: Tucker
Tucker, Lance
Tucker, Michael
Key: Zabokritski
Zabokritski, Eugene
*/

Örnek
Aşağıdaki örnek, nesnenin bir özelliğini dışında bir şey için Grup anahtarı kullanarak kaynak öğeleri gruplandırmak
gösterilmektedir. Bu örnekte, öğrencinin son adının ilk harfi bir anahtardır.
Aşağıdaki yönteme yapıştırın StudentClass sınıfı. Arama deyiminde değiştirme Main yönteme
sc.GroupBySubstring() .
public void GroupBySubstring()
{
Console.WriteLine("\r\nGroup by something other than a property of the object:");

var queryFirstLetters =
from student in students
group student by student.LastName[0];

foreach (var studentGroup in queryFirstLetters)


{
Console.WriteLine($"Key: {studentGroup.Key}");
// Nested foreach is required to access group items.
foreach (var student in studentGroup)
{
Console.WriteLine($"\t{student.LastName}, {student.FirstName}");
}
}
}
/* Output:
Group by something other than a property of the object:
Key: A
Adams, Terry
Key: F
Fakhouri, Fadi
Feng, Hanying
Key: G
Garcia, Cesar
Garcia, Debra
Garcia, Hugo
Key: M
Mortensen, Sven
Key: O
O'Donnell, Claire
Omelchenko, Svetlana
Key: T
Tucker, Lance
Tucker, Michael
Key: Z
Zabokritski, Eugene
*/

Örnek
Aşağıdaki örnek, sayısal aralık bir Grup anahtarı kullanarak kaynak öğeleri gruplandırmak gösterilmektedir. Sorgu
sonuçları yalnızca ilk ve son adı ve Öğrenci ait olduğu yüzdebirlik aralığı içeren bir anonim tür ardından yansıtıyor.
Anonim bir tür, tam olarak kullanmak için gerekli olmadığından kullanılan Student sonuçları görüntülemek için
nesne. GetPercentile yüzde hesaplayan bir yardımcı işlevi, öğrencinin ortalama puanına göre temel alır. Yöntemi, 0
ile 10 arasında bir tamsayı döndürür.

//Helper method, used in GroupByRange.


protected static int GetPercentile(Student s)
{
double avg = s.ExamScores.Average();
return avg > 0 ? (int)avg / 10 : 0;
}

Aşağıdaki yönteme yapıştırın StudentClass sınıfı. Arama deyiminde değiştirme Main yönteme sc.GroupByRange() .
public void GroupByRange()
{
Console.WriteLine("\r\nGroup by numeric range and project into a new anonymous type:");

var queryNumericRange =
from student in students
let percentile = GetPercentile(student)
group new { student.FirstName, student.LastName } by percentile into percentGroup
orderby percentGroup.Key
select percentGroup;

// Nested foreach required to iterate over groups and group items.


foreach (var studentGroup in queryNumericRange)
{
Console.WriteLine($"Key: {studentGroup.Key * 10}");
foreach (var item in studentGroup)
{
Console.WriteLine($"\t{item.LastName}, {item.FirstName}");
}
}
}
/* Output:
Group by numeric range and project into a new anonymous type:
Key: 60
Garcia, Debra
Key: 70
O'Donnell, Claire
Key: 80
Adams, Terry
Feng, Hanying
Garcia, Cesar
Garcia, Hugo
Mortensen, Sven
Omelchenko, Svetlana
Tucker, Lance
Zabokritski, Eugene
Key: 90
Fakhouri, Fadi
Tucker, Michael
*/

Örnek
Aşağıdaki örnek, bir Boolean karşılaştırma ifadesi kullanarak kaynak öğeleri gruplandırmak gösterilmektedir. Bu
örnekte, bir öğrencinin ortalama sınavı puanı 75 büyük olup Boole ifadesi test eder. Önceki örneklerde olduğu gibi
tam kaynak öğesi gerekli değildir çünkü sonuçları anonim bir tür yansıtılan. Anonim tür özellikleri Özellikler
üzerinde hale geleceğini unutmayın Key üyesi ve sorgu yürütüldüğünde adı tarafından erişilebilir.
Aşağıdaki yönteme yapıştırın StudentClass sınıfı. Arama deyiminde değiştirme Main yönteme
sc.GroupByBoolean() .
public void GroupByBoolean()
{
Console.WriteLine("\r\nGroup by a Boolean into two groups with string keys");
Console.WriteLine("\"True\" and \"False\" and project into a new anonymous type:");
var queryGroupByAverages = from student in students
group new { student.FirstName, student.LastName }
by student.ExamScores.Average() > 75 into studentGroup
select studentGroup;

foreach (var studentGroup in queryGroupByAverages)


{
Console.WriteLine($"Key: {studentGroup.Key}");
foreach (var student in studentGroup)
Console.WriteLine($"\t{student.FirstName} {student.LastName}");
}
}
/* Output:
Group by a Boolean into two groups with string keys
"True" and "False" and project into a new anonymous type:
Key: True
Terry Adams
Fadi Fakhouri
Hanying Feng
Cesar Garcia
Hugo Garcia
Sven Mortensen
Svetlana Omelchenko
Lance Tucker
Michael Tucker
Eugene Zabokritski
Key: False
Debra Garcia
Claire O'Donnell
*/

Örnek
Aşağıdaki örnek, birden çok değer içeren bir anahtar yalıtılacak anonim bir tür kullanmayı gösterir. Bu örnekte, ilk
anahtar değeri öğrencinin Soyadı İlk harfidir. İkinci anahtar değeri Öğrenci 85 üzerinde ilk sınavı üzerinde
puanlanmış olup olmadığını belirten Boolean bir değer var. Grupları anahtarında herhangi bir özelliğe göre
sıralayabilirsiniz.
Aşağıdaki yönteme yapıştırın StudentClass sınıfı. Arama deyiminde değiştirme Main yönteme
sc.GroupByCompositeKey() .
public void GroupByCompositeKey()
{
var queryHighScoreGroups =
from student in students
group student by new { FirstLetter = student.LastName[0],
Score = student.ExamScores[0] > 85 } into studentGroup
orderby studentGroup.Key.FirstLetter
select studentGroup;

Console.WriteLine("\r\nGroup and order by a compound key:");


foreach (var scoreGroup in queryHighScoreGroups)
{
string s = scoreGroup.Key.Score == true ? "more than" : "less than";
Console.WriteLine($"Name starts with {scoreGroup.Key.FirstLetter} who scored {s} 85");
foreach (var item in scoreGroup)
{
Console.WriteLine($"\t{item.FirstName} {item.LastName}");
}
}
}

/* Output:
Group and order by a compound key:
Name starts with A who scored more than 85
Terry Adams
Name starts with F who scored more than 85
Fadi Fakhouri
Hanying Feng
Name starts with G who scored more than 85
Cesar Garcia
Hugo Garcia
Name starts with G who scored less than 85
Debra Garcia
Name starts with M who scored more than 85
Sven Mortensen
Name starts with O who scored less than 85
Claire O'Donnell
Name starts with O who scored more than 85
Svetlana Omelchenko
Name starts with T who scored less than 85
Lance Tucker
Name starts with T who scored more than 85
Michael Tucker
Name starts with Z who scored more than 85
Eugene Zabokritski
*/

Ayrıca bkz.
GroupBy
IGrouping<TKey,TElement>
Dil ile Tümleşik Sorgu (LINQ )
group yan tümcesi
Anonim Tipler
Gruplandırma işleminde alt sorgu gerçekleştirme
İç içe geçmiş grup oluşturma
Verileri Gruplandırma
İç içe geçmiş grup oluşturma
23.10.2019 • 2 minutes to read • Edit Online

Aşağıdaki örnek, bir LINQ sorgu ifadesinde iç içe geçmiş gruplar oluşturma işlemi gösterilmektedir. Öğrenci yıl
veya sınıf düzeyine göre oluşturulan her grup ardından bireylerin adlarına göre gruplara ek bölünmüştür.

Örnek
NOTE
Bu örnekte örnek koda tanımlanan nesneleri başvuruları içeren nesneler koleksiyonunu sorgulama.
public void QueryNestedGroups()
{
var queryNestedGroups =
from student in students
group student by student.Year into newGroup1
from newGroup2 in
(from student in newGroup1
group student by student.LastName)
group newGroup2 by newGroup1.Key;

// Three nested foreach loops are required to iterate


// over all elements of a grouped group. Hover the mouse
// cursor over the iteration variables to see their actual type.
foreach (var outerGroup in queryNestedGroups)
{
Console.WriteLine($"DataClass.Student Level = {outerGroup.Key}");
foreach (var innerGroup in outerGroup)
{
Console.WriteLine($"\tNames that begin with: {innerGroup.Key}");
foreach (var innerGroupElement in innerGroup)
{
Console.WriteLine($"\t\t{innerGroupElement.LastName} {innerGroupElement.FirstName}");
}
}
}
}
/*
Output:
DataClass.Student Level = SecondYear
Names that begin with: Adams
Adams Terry
Names that begin with: Garcia
Garcia Hugo
Names that begin with: Omelchenko
Omelchenko Svetlana
DataClass.Student Level = ThirdYear
Names that begin with: Fakhouri
Fakhouri Fadi
Names that begin with: Garcia
Garcia Debra
Names that begin with: Tucker
Tucker Lance
DataClass.Student Level = FirstYear
Names that begin with: Feng
Feng Hanying
Names that begin with: Mortensen
Mortensen Sven
Names that begin with: Tucker
Tucker Michael
DataClass.Student Level = FourthYear
Names that begin with: Garcia
Garcia Cesar
Names that begin with: O'Donnell
O'Donnell Claire
Names that begin with: Zabokritski
Zabokritski Eugene
*/

Üç iç içe geçmiş Not foreach iç içe geçmiş Grup iç öğeleri üzerinde yinelemek için döngüleri gereklidir.

Ayrıca bkz.
Dil ile Tümleşik Sorgu (LINQ )
Gruplandırma işleminde alt sorgu gerçekleştirme
23.10.2019 • 2 minutes to read • Edit Online

Bu makalede, kaynak verileri gruplar halinde sıralar ve sonra bir alt sorgu her bir grup üzerinde tek tek
gerçekleştiren bir sorgu oluşturmak için iki farklı yolu gösterilmektedir. Her örnekte temel tekniği kullanarak
kaynak öğeleri gruplandırmak için olan bir devamlılık adlı newGroup ve ardından yeni bir alt sorgu karşı oluşturma
newGroup . Bu alt sorgu, dış sorgu tarafından oluşturulan her yeni gruba göre çalıştırılır. Bu örnekte son çıkışı değil
bir grup ancak anonim türler düz dizisi olduğunu unutmayın.
Gruba hakkında daha fazla bilgi için bkz. group yan tümcesi.
Devamlılıklar hakkında daha fazla bilgi için bkz: içine. Aşağıdaki örnek, veri kaynağı olarak bir bellek içi veri yapısı
kullanır, ancak tüm LINQ veri kaynağı türü için aynı ilkeler geçerlidir.

Örnek
NOTE
Bu örnekte örnek koda tanımlanan nesneleri başvuruları içeren nesneler koleksiyonunu sorgulama.

public void QueryMax()


{
var queryGroupMax =
from student in students
group student by student.Year into studentGroup
select new
{
Level = studentGroup.Key,
HighestScore =
(from student2 in studentGroup
select student2.ExamScores.Average()).Max()
};

int count = queryGroupMax.Count();


Console.WriteLine($"Number of groups = {count}");

foreach (var item in queryGroupMax)


{
Console.WriteLine($" {item.Level} Highest Score={item.HighestScore}");
}
}

Yukarıdaki kod parçacığında sorgu ayrıca yöntem sözdizimini kullanarak yazılabilir. Aşağıdaki kod parçacığı,
yöntem sözdizimi kullanılarak yazılmış anlamsal olarak eşdeğer bir sorgu yok.
public void QueryMaxUsingMethodSyntax()
{
var queryGroupMax = students
.GroupBy(student => student.Year)
.Select(studentGroup => new
{
Level = studentGroup.Key,
HighestScore = studentGroup.Select(student2 => student2.ExamScores.Average()).Max()
});

int count = queryGroupMax.Count();


Console.WriteLine($"Number of groups = {count}");

foreach (var item in queryGroupMax)


{
Console.WriteLine($" {item.Level} Highest Score={item.HighestScore}");
}
}

Ayrıca bkz.
Dil ile Tümleşik Sorgu (LINQ )
Sonuçları bitişik anahtarlara göre gruplama
23.10.2019 • 8 minutes to read • Edit Online

Aşağıdaki örnek, bitişik anahtarların sıraları temsil eden öbeklere öğeleri gruplayın gösterilmektedir. Örneğin,
aşağıdaki anahtar-değer çiftleri dizisi verilen varsayın:

ANAHTAR DEĞER

BİR Biz

BİR Düşünme

BİR ,

B LINQ

C is

BİR gerçekten

B seyrek erişimli

B !

Aşağıdaki gruplar bu sırayla oluşturulur:


1. Düşünüyoruz,
2. LINQ
3. is
4. gerçekten
5. seyrek!
Çözüm, iş parçacığı açısından güvenli ve akıcı bir şekilde sonuçları döndüren bir genişletme yöntemi olarak
uygulanır. Diğer bir deyişle, kaynak sırası boyunca hareket ettikçe, grupları üretir. Farklı group veya orderby
operatörleri onu başlayabilir çağırana grupları döndüren tüm dizinin okumadan önce.
İş parçacığı güvenliği kaynak sırası yinelendiğinde gibi her bir grup veya öbek bir kopyasını kaynak kod yorumlar
bölümünde açıklandığı gibi kullanılarak gerçekleştirilir. Kaynak sırası büyük bir dizi bitişik öğesi varsa, ortak dil
çalışma zamanı oluşturabilecek bir OutOfMemoryException.

Örnek
Aşağıdaki örnek, hem genişletme yöntemi hem de onu kullanan istemci kodu gösterir:

using System;
using System.Collections.Generic;
using System.Linq;

namespace ChunkIt
namespace ChunkIt
{
// Static class to contain the extension methods.
public static class MyExtensions
{
public static IEnumerable<IGrouping<TKey, TSource>> ChunkBy<TSource, TKey>(this IEnumerable<TSource>
source, Func<TSource, TKey> keySelector)
{
return source.ChunkBy(keySelector, EqualityComparer<TKey>.Default);
}

public static IEnumerable<IGrouping<TKey, TSource>> ChunkBy<TSource, TKey>(this IEnumerable<TSource>


source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
{
// Flag to signal end of source sequence.
const bool noMoreSourceElements = true;

// Auto-generated iterator for the source array.


var enumerator = source.GetEnumerator();

// Move to the first element in the source sequence.


if (!enumerator.MoveNext()) yield break;

// Iterate through source sequence and create a copy of each Chunk.


// On each pass, the iterator advances to the first element of the next "Chunk"
// in the source sequence. This loop corresponds to the outer foreach loop that
// executes the query.
Chunk<TKey, TSource> current = null;
while (true)
{
// Get the key for the current Chunk. The source iterator will churn through
// the source sequence until it finds an element with a key that doesn't match.
var key = keySelector(enumerator.Current);

// Make a new Chunk (group) object that initially has one GroupItem, which is a copy of the
current source element.
current = new Chunk<TKey, TSource>(key, enumerator, value => comparer.Equals(key,
keySelector(value)));

// Return the Chunk. A Chunk is an IGrouping<TKey,TSource>, which is the return value of the
ChunkBy method.
// At this point the Chunk only has the first element in its source sequence. The remaining
elements will be
// returned only when the client code foreach's over this chunk. See Chunk.GetEnumerator for
more info.
yield return current;

// Check to see whether (a) the chunk has made a copy of all its source elements or
// (b) the iterator has reached the end of the source sequence. If the caller uses an inner
// foreach loop to iterate the chunk items, and that loop ran to completion,
// then the Chunk.GetEnumerator method will already have made
// copies of all chunk items before we get here. If the Chunk.GetEnumerator loop did not
// enumerate all elements in the chunk, we need to do it here to avoid corrupting the iterator
// for clients that may be calling us on a separate thread.
if (current.CopyAllChunkElements() == noMoreSourceElements)
{
yield break;
}
}
}

// A Chunk is a contiguous group of one or more source elements that have the same key. A Chunk
// has a key and a list of ChunkItem objects, which are copies of the elements in the source sequence.
class Chunk<TKey, TSource> : IGrouping<TKey, TSource>
{
// INVARIANT: DoneCopyingChunk == true ||
// (predicate != null && predicate(enumerator.Current) && current.Value == enumerator.Current)

// A Chunk has a linked list of ChunkItems, which represent the elements in the current chunk. Each
ChunkItem
ChunkItem
// has a reference to the next ChunkItem in the list.
class ChunkItem
{
public ChunkItem(TSource value)
{
Value = value;
}
public readonly TSource Value;
public ChunkItem Next = null;
}

// The value that is used to determine matching elements


private readonly TKey key;

// Stores a reference to the enumerator for the source sequence


private IEnumerator<TSource> enumerator;

// A reference to the predicate that is used to compare keys.


private Func<TSource, bool> predicate;

// Stores the contents of the first source element that


// belongs with this chunk.
private readonly ChunkItem head;

// End of the list. It is repositioned each time a new


// ChunkItem is added.
private ChunkItem tail;

// Flag to indicate the source iterator has reached the end of the source sequence.
internal bool isLastSourceElement = false;

// Private object for thread syncronization


private object m_Lock;

// REQUIRES: enumerator != null && predicate != null


public Chunk(TKey key, IEnumerator<TSource> enumerator, Func<TSource, bool> predicate)
{
this.key = key;
this.enumerator = enumerator;
this.predicate = predicate;

// A Chunk always contains at least one element.


head = new ChunkItem(enumerator.Current);

// The end and beginning are the same until the list contains > 1 elements.
tail = head;

m_Lock = new object();


}

// Indicates that all chunk elements have been copied to the list of ChunkItems,
// and the source enumerator is either at the end, or else on an element with a new key.
// the tail of the linked list is set to null in the CopyNextChunkElement method if the
// key of the next element does not match the current chunk's key, or there are no more elements in
the source.
private bool DoneCopyingChunk => tail == null;

// Adds one ChunkItem to the current group


// REQUIRES: !DoneCopyingChunk && lock(this)
private void CopyNextChunkElement()
{
// Try to advance the iterator on the source sequence.
// If MoveNext returns false we are at the end, and isLastSourceElement is set to true
isLastSourceElement = !enumerator.MoveNext();

// If we are (a) at the end of the source, or (b) at the end of the current chunk
// then null out the enumerator and predicate for reuse with the next chunk.
if (isLastSourceElement || !predicate(enumerator.Current))
{
enumerator = null;
predicate = null;
}
else
{
tail.Next = new ChunkItem(enumerator.Current);
}

// tail will be null if we are at the end of the chunk elements


// This check is made in DoneCopyingChunk.
tail = tail.Next;
}

// Called after the end of the last chunk was reached. It first checks whether
// there are more elements in the source sequence. If there are, it
// Returns true if enumerator for this chunk was exhausted.
internal bool CopyAllChunkElements()
{
while (true)
{
lock (m_Lock)
{
if (DoneCopyingChunk)
{
// If isLastSourceElement is false,
// it signals to the outer iterator
// to continue iterating.
return isLastSourceElement;
}
else
{
CopyNextChunkElement();
}
}
}
}

public TKey Key => key;

// Invoked by the inner foreach loop. This method stays just one step ahead
// of the client requests. It adds the next element of the chunk only after
// the clients requests the last element in the list so far.
public IEnumerator<TSource> GetEnumerator()
{
//Specify the initial element to enumerate.
ChunkItem current = head;

// There should always be at least one ChunkItem in a Chunk.


while (current != null)
{
// Yield the current item in the list.
yield return current.Value;

// Copy the next item from the source sequence,


// if we are at the end of our local list.
lock (m_Lock)
{
if (current == tail)
{
CopyNextChunkElement();
}
}

// Move to the next ChunkItem in the list.


current = current.Next;
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
}
}

// A simple named type is used for easier viewing in the debugger. Anonymous types
// work just as well with the ChunkBy operator.
public class KeyValPair
{
public string Key { get; set; }
public string Value { get; set; }
}

class Program
{
// The source sequence.
public static IEnumerable<KeyValPair> list;

// Query variable declared as class member to be available


// on different threads.
static IEnumerable<IGrouping<string, KeyValPair>> query;

static void Main(string[] args)


{
// Initialize the source sequence with an array initializer.
list = new[]
{
new KeyValPair{ Key = "A", Value = "We" },
new KeyValPair{ Key = "A", Value = "think" },
new KeyValPair{ Key = "A", Value = "that" },
new KeyValPair{ Key = "B", Value = "Linq" },
new KeyValPair{ Key = "C", Value = "is" },
new KeyValPair{ Key = "A", Value = "really" },
new KeyValPair{ Key = "B", Value = "cool" },
new KeyValPair{ Key = "B", Value = "!" }
};

// Create the query by using our user-defined query operator.


query = list.ChunkBy(p => p.Key);

// ChunkBy returns IGrouping objects, therefore a nested


// foreach loop is required to access the elements in each "chunk".
foreach (var item in query)
{
Console.WriteLine($"Group key = {item.Key}");
foreach (var inner in item)
{
Console.WriteLine($"\t{inner.Value}");
}
}

Console.WriteLine("Press any key to exit");


Console.ReadKey();
}
}
}

Projenizde genişletme yöntemini kullanmak için kopyalayın MyExtensions statik sınıf için yeni veya mevcut bir
kaynak kod dosyası ve, gerekirse ekleme bir using bulunduğu olduğu ad alanı için yönerge.

Ayrıca bkz.
Dil ile Tümleşik Sorgu (LINQ )
Çalışma zamanında koşul filtrelerini dinamik olarak
belirtme
23.10.2019 • 4 minutes to read • Edit Online

Bazı durumlarda, doğrulamaları kaç kaynak öğeleri uygulamak sahip olduğunuz çalışma zamanına kadar
bilmiyorum where yan tümcesi. Birden çok koşul filtrelerini dinamik olarak belirtmek için tek bir yolu Contains
yöntemi, aşağıdaki örnekte gösterildiği gibi. Örneğin, iki şekilde oluşturulur. İlk olarak, projeyi programda sağlanan
değerleri filtreleyerek çalıştırılır. Ardından projeyi yeniden çalışma zamanında sağlanan giriş kullanılarak çalıştırılır.

Contains yöntemi kullanarak filtre uygulamak için


1. Yeni bir konsol uygulaması'nı açın ve adlandırın PredicateFilters .
2. Kopyalama StudentClass gelen sınıfı nesneler koleksiyonunu sorgulama ve ad alanına yapıştırın
PredicateFilters sınıfı altında Program . StudentClass bir listesini sağlar Student nesneleri.
3. Açıklama Main yönteminde StudentClass .
4. Sınıf değiştirin Program aşağıdaki kod ile:

class DynamicPredicates : StudentClass


{
static void Main(string[] args)
{
string[] ids = { "111", "114", "112" };

Console.WriteLine("Press any key to exit.");


Console.ReadKey();
}

static void QueryByID(string[] ids)


{
var queryNames =
from student in students
let i = student.ID.ToString()
where ids.Contains(i)
select new { student.LastName, student.ID };

foreach (var name in queryNames)


{
Console.WriteLine($"{name.LastName}: {name.ID}");
}
}
}

5. Aşağıdaki satırı ekleyin Main sınıfındaki yöntemi DynamicPredicates , bildirimi altında ids .

QueryById(ids);

6. Projeyi çalıştırın.
7. Aşağıdaki çıktıyı konsol penceresinde görüntülenir:
Garcia: 114
O'Donnell: 112
Omelchenko: 111
8. Sonraki adımda projeyi yeniden çalıştırmak için çalışma zamanında dizi yerine Giriş kullanarak bu saati
girildi. ids . Değişiklik QueryByID(ids) için QueryByID(args) içinde Main yöntemi.
9. Komut satırı bağımsız değişkenleri ile projeyi Çalıştır 122 117 120 115 . Projeyi çalıştırdığınızda, bu değerleri
öğelerini haline args , parametresi Main yöntemi.
10. Aşağıdaki çıktıyı konsol penceresinde görüntülenir:
Adams: 120
Feng: 117
Garcia: 115
Tucker: 122

Switch deyimi kullanarak filtre uygulamak için


1. Kullanabileceğiniz bir switch arasından seçim yapmak deyimi önceden alternatif sorgular. Aşağıdaki
örnekte, studentQuery farklı bir kullanan where bağlı olarak hangi sınıf düzeyinde veya yıl, belirtilen
çalışma zamanında yan tümcesi.
2. Aşağıdaki yöntemi kopyalayın ve sınıfına yapıştırın DynamicPredicates .
// To run this sample, first specify an integer value of 1 to 4 for the command
// line. This number will be converted to a GradeLevel value that specifies which
// set of students to query.
// Call the method: QueryByYear(args[0]);

static void QueryByYear(string level)


{
GradeLevel year = (GradeLevel)Convert.ToInt32(level);
IEnumerable<Student> studentQuery = null;
switch (year)
{
case GradeLevel.FirstYear:
studentQuery = from student in students
where student.Year == GradeLevel.FirstYear
select student;
break;
case GradeLevel.SecondYear:
studentQuery = from student in students
where student.Year == GradeLevel.SecondYear
select student;
break;
case GradeLevel.ThirdYear:
studentQuery = from student in students
where student.Year == GradeLevel.ThirdYear
select student;
break;
case GradeLevel.FourthYear:
studentQuery = from student in students
where student.Year == GradeLevel.FourthYear
select student;
break;

default:
break;
}
Console.WriteLine($"The following students are at level {year}");
foreach (Student name in studentQuery)
{
Console.WriteLine($"{name.LastName}: {name.ID}");
}
}

3. İçinde Main yöntemi çağrısını QueryByID aşağıdaki çağrısıyla, gönderdiği ilk öğenin args kendi bağımsız
değişkeni olarak bir dizi: QueryByYear(args[0]) .
4. Projeyi, 1 ile 4 arasında bir tamsayı değeri bir komut satırı bağımsız değişkeni ile çalıştırın.

Ayrıca bkz.
Dil ile Tümleşik Sorgu (LINQ )
where yan tümcesi
İç birleşimler gerçekleştirme
23.10.2019 • 13 minutes to read • Edit Online

İlişkisel veritabanı koşullarında bir INNER JOIN bir sonuç kümesi her hangi bir öğedeki ilk koleksiyonun ikinci
koleksiyon eşleşen her öğe için bir kez görünür üretir. İlk koleksiyondaki bir öğe eşleşen bir öğe varsa, sonuç
kümesinde görünmüyor. Join Tarafından çağrılan yöntem join yan tümcesinde C# ' ta, bir iç birleştirme uygular.
Bu makalede, dört çözümlenmeyebileceği iç birleşim gerçekleştirme gösterir:
Basit bir anahtarına göre iki veri kaynağı öğelerinden karşılık gelen basit bir iç birleştirme.
İki veri kaynaklarından alınan öğeleri karşılık gelen bir iç birleştirme temel alan bir bileşik anahtarı. Birden
fazla değerini içeren bir anahtarı olan bir bileşik anahtarı birden fazla özelliğe dayalı öğeleri bağıntısını
kurmanızı sağlar.
A birden fazla birleşim hangi art arda gelen birleştirme işlemleri birbirine eklenir.
Bir iç birleştirme group JOIN kullanılarak gerçekleştirilir.

Örnek - basit anahtar birleştirme


Aşağıdaki örnek, iki tür, kullanıcı tanımlı nesneler içeren iki koleksiyonları oluşturur Person ve Pet . Sorgu
kullanan join yan tümcesinde eşleştirmek için C# Person nesnelerini Pet ayarlanmış nesneleri Owner olan
Person . select Yan tümcesinde C#, elde edilen nesnelerin nasıl görüneceğini tanımlar. Bu örnekte, sonuçta elde
edilen sahibinin adı ve Evcil hayvanınızın adı oluşur anonim türler nesneleridir.
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}

class Pet
{
public string Name { get; set; }
public Person Owner { get; set; }
}

/// <summary>
/// Simple inner join.
/// </summary>
public static void InnerJoinExample()
{
Person magnus = new Person { FirstName = "Magnus", LastName = "Hedlund" };
Person terry = new Person { FirstName = "Terry", LastName = "Adams" };
Person charlotte = new Person { FirstName = "Charlotte", LastName = "Weiss" };
Person arlene = new Person { FirstName = "Arlene", LastName = "Huff" };
Person rui = new Person { FirstName = "Rui", LastName = "Raposo" };

Pet barley = new Pet { Name = "Barley", Owner = terry };


Pet boots = new Pet { Name = "Boots", Owner = terry };
Pet whiskers = new Pet { Name = "Whiskers", Owner = charlotte };
Pet bluemoon = new Pet { Name = "Blue Moon", Owner = rui };
Pet daisy = new Pet { Name = "Daisy", Owner = magnus };

// Create two lists.


List<Person> people = new List<Person> { magnus, terry, charlotte, arlene, rui };
List<Pet> pets = new List<Pet> { barley, boots, whiskers, bluemoon, daisy };

// Create a collection of person-pet pairs. Each element in the collection


// is an anonymous type containing both the person's name and their pet's name.
var query = from person in people
join pet in pets on person equals pet.Owner
select new { OwnerName = person.FirstName, PetName = pet.Name };

foreach (var ownerAndPet in query)


{
Console.WriteLine($"\"{ownerAndPet.PetName}\" is owned by {ownerAndPet.OwnerName}");
}
}

// This code produces the following output:


//
// "Daisy" is owned by Magnus
// "Barley" is owned by Terry
// "Boots" is owned by Terry
// "Whiskers" is owned by Charlotte
// "Blue Moon" is owned by Rui

Unutmayın Person nesnesi LastName "Huff" sonuç olduğundan kümesine görünmez olduğundan hiçbir Pet
nesnesi Pet.Owner eşit Person .

Örnek - bileşik anahtar birleştirme


Öğeleri yalnızca bir özelliğe dayalı bağıntı yerine birden fazla özelliğe göre öğeleri karşılaştırılacak bir bileşik
anahtarı kullanabilirsiniz. Bunu yapmak için karşılaştırmak istediğiniz özellikleri içeren bir anonim tür dönmek her
bir koleksiyon için anahtar Seçici işlevi belirtin. Özellikleri etiketi, aynı etiketi her anahtarın anonim türünde
olmalıdır. Özellikleri de aynı sırada yer almalıdır.
Aşağıdaki örnek, bir listesini kullanır Employee nesneleri ve listesini Student hangi çalışanların da Öğrenciler
olduğunu belirlemek için nesneleri. Bu tür hem de bir FirstName ve LastName türünün özelliği String. Join
anahtarlar her listenin öğeleri oluşturan işlevler içeren bir anonim bir tür döndürür FirstName ve LastName her
öğenin özellikleri. Birleştirme işlemi, bu bileşik anahtarlar eşitliği karşılaştırır ve hem ad ve Soyadı eşleştiği her
listeden çiftleri nesne döndürür.

class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int EmployeeID { get; set; }
}

class Student
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int StudentID { get; set; }
}

/// <summary>
/// Performs a join operation using a composite key.
/// </summary>
public static void CompositeKeyJoinExample()
{
// Create a list of employees.
List<Employee> employees = new List<Employee> {
new Employee { FirstName = "Terry", LastName = "Adams", EmployeeID = 522459 },
new Employee { FirstName = "Charlotte", LastName = "Weiss", EmployeeID = 204467 },
new Employee { FirstName = "Magnus", LastName = "Hedland", EmployeeID = 866200 },
new Employee { FirstName = "Vernette", LastName = "Price", EmployeeID = 437139 } };

// Create a list of students.


List<Student> students = new List<Student> {
new Student { FirstName = "Vernette", LastName = "Price", StudentID = 9562 },
new Student { FirstName = "Terry", LastName = "Earls", StudentID = 9870 },
new Student { FirstName = "Terry", LastName = "Adams", StudentID = 9913 } };

// Join the two data sources based on a composite key consisting of first and last name,
// to determine which employees are also students.
IEnumerable<string> query = from employee in employees
join student in students
on new { employee.FirstName, employee.LastName }
equals new { student.FirstName, student.LastName }
select employee.FirstName + " " + employee.LastName;

Console.WriteLine("The following people are both employees and students:");


foreach (string name in query)
Console.WriteLine(name);
}

// This code produces the following output:


//
// The following people are both employees and students:
// Terry Adams
// Vernette Price

Örnek - birden çok birleştirme


Herhangi bir sayıda birleştirme işlemleri birden fazla birleşim gerçekleştirmek için birbirlerine eklenmiş. Her join
yan tümcesinde C# belirtilen veri kaynağı önceki birleştirme sonuçlarının ile ilişkilendirir.
Aşağıdaki örnek, üç koleksiyonu oluşturur: bir listesini Person nesneleri, listesini Cat nesneleri ve listesini Dog
nesneleri.
İlk join yan tümcesinde C#, kişiler ve temel kediler eşleşen bir Person nesne eşleşen Cat.Owner . Bir dizi içeren
bir anonim türleri döndürür Person nesne ve Cat.Name .
İkinci join yan tümcesinde C# ile ilk birleşimi tarafından döndürülen anonim türler karşılık gelen Dog köpekler,
sağlanan listesi nesneleri içeren bir bileşik anahtarı tabanlı Owner türünün özelliği Person ilk Harf donatarak'ın
adı. Bir dizi içeren bir anonim türleri döndürür Cat.Name ve Dog.Name eşleşen her çift özellikleri. Bu bir iç
birleştirme olduğundan, yalnızca bir eşleşme ikinci veri kaynağına sahip ilk veri kaynağı nesnelerden döndürülür.

class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}

class Pet
{
public string Name { get; set; }
public Person Owner { get; set; }
}

class Cat : Pet


{ }

class Dog : Pet


{ }

public static void MultipleJoinExample()


{
Person magnus = new Person { FirstName = "Magnus", LastName = "Hedlund" };
Person terry = new Person { FirstName = "Terry", LastName = "Adams" };
Person charlotte = new Person { FirstName = "Charlotte", LastName = "Weiss" };
Person arlene = new Person { FirstName = "Arlene", LastName = "Huff" };
Person rui = new Person { FirstName = "Rui", LastName = "Raposo" };
Person phyllis = new Person { FirstName = "Phyllis", LastName = "Harris" };

Cat barley = new Cat { Name = "Barley", Owner = terry };


Cat boots = new Cat { Name = "Boots", Owner = terry };
Cat whiskers = new Cat { Name = "Whiskers", Owner = charlotte };
Cat bluemoon = new Cat { Name = "Blue Moon", Owner = rui };
Cat daisy = new Cat { Name = "Daisy", Owner = magnus };

Dog fourwheeldrive = new Dog { Name = "Four Wheel Drive", Owner = phyllis };
Dog duke = new Dog { Name = "Duke", Owner = magnus };
Dog denim = new Dog { Name = "Denim", Owner = terry };
Dog wiley = new Dog { Name = "Wiley", Owner = charlotte };
Dog snoopy = new Dog { Name = "Snoopy", Owner = rui };
Dog snickers = new Dog { Name = "Snickers", Owner = arlene };

// Create three lists.


List<Person> people =
new List<Person> { magnus, terry, charlotte, arlene, rui, phyllis };
List<Cat> cats =
new List<Cat> { barley, boots, whiskers, bluemoon, daisy };
List<Dog> dogs =
new List<Dog> { fourwheeldrive, duke, denim, wiley, snoopy, snickers };

// The first join matches Person and Cat.Owner from the list of people and
// cats, based on a common Person. The second join matches dogs whose names start
// with the same letter as the cats that have the same owner.
var query = from person in people
join cat in cats on person equals cat.Owner
join dog in dogs on
new { Owner = person, Letter = cat.Name.Substring(0, 1) }
equals new { dog.Owner, Letter = dog.Name.Substring(0, 1) }
select new { CatName = cat.Name, DogName = dog.Name };

foreach (var obj in query)


foreach (var obj in query)
{
Console.WriteLine(
$"The cat \"{obj.CatName}\" shares a house, and the first letter of their name,
with \"{obj.DogName}\".");
}
}

// This code produces the following output:


//
// The cat "Daisy" shares a house, and the first letter of their name, with "Duke".
// The cat "Whiskers" shares a house, and the first letter of their name, with "Wiley".

Örnek - kullanarak iç birleştirmesi birleştirme gruplandırılır.


Aşağıdaki örnek bir iç birleştirme group JOIN uygulamak gösterilmektedir.
İçinde query1, listesini Person nesneleri, Grup katılmış listesine Pet nesneleri temel alarak Person eşleşen
Pet.Owner özelliği. Grup birleştirme olduğu her grubu oluşur Ara grubun bir koleksiyonunu oluşturur bir Person
nesne ve sıralamadaki eşleşen Pet nesneleri.
İkinci ekleyerek from dizileri bu dizi sorgu yan tümcesinin birleştirilmiş (veya düzleştirilmiş) bir uzun dizi. Son
sırasının öğelerin türü tarafından belirtilen select yan tümcesi. Bu örnekte, türü içeren bir anonim tür olduğunu
Person.FirstName ve Pet.Name eşleşen her çift özellikleri.

Sonucu query1 kullanılarak elde sonuç kümesi eşdeğerdir join yan tümcesi olmadan into iç birleşim
gerçekleştirmek için yan tümcesi. query2 Eşdeğer bu sorgu değişkeni gösterir.

class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}

class Pet
{
public string Name { get; set; }
public Person Owner { get; set; }
}

/// <summary>
/// Performs an inner join by using GroupJoin().
/// </summary>
public static void InnerGroupJoinExample()
{
Person magnus = new Person { FirstName = "Magnus", LastName = "Hedlund" };
Person terry = new Person { FirstName = "Terry", LastName = "Adams" };
Person charlotte = new Person { FirstName = "Charlotte", LastName = "Weiss" };
Person arlene = new Person { FirstName = "Arlene", LastName = "Huff" };

Pet barley = new Pet { Name = "Barley", Owner = terry };


Pet boots = new Pet { Name = "Boots", Owner = terry };
Pet whiskers = new Pet { Name = "Whiskers", Owner = charlotte };
Pet bluemoon = new Pet { Name = "Blue Moon", Owner = terry };
Pet daisy = new Pet { Name = "Daisy", Owner = magnus };

// Create two lists.


List<Person> people = new List<Person> { magnus, terry, charlotte, arlene };
List<Pet> pets = new List<Pet> { barley, boots, whiskers, bluemoon, daisy };

var query1 = from person in people


join pet in pets on person equals pet.Owner into gj
from subpet in gj
select new { OwnerName = person.FirstName, PetName = subpet.Name };
Console.WriteLine("Inner join using GroupJoin():");
foreach (var v in query1)
{
Console.WriteLine($"{v.OwnerName} - {v.PetName}"));
}

var query2 = from person in people


join pet in pets on person equals pet.Owner
select new { OwnerName = person.FirstName, PetName = pet.Name };

Console.WriteLine("\nThe equivalent operation using Join():");


foreach (var v in query2)
Console.WriteLine($"{v.OwnerName} - {v.PetName}"));
}

// This code produces the following output:


//
// Inner join using GroupJoin():
// Magnus - Daisy
// Terry - Barley
// Terry - Boots
// Terry - Blue Moon
// Charlotte - Whiskers
//
// The equivalent operation using Join():
// Magnus - Daisy
// Terry - Barley
// Terry - Boots
// Terry - Blue Moon
// Charlotte - Whiskers

Ayrıca bkz.
Join
GroupJoin
Gruplanmış birleşimler gerçekleştirme
Sol dış birleştirmeler gerçekleştirme
Anonim türler
Gruplanmış birleşimler gerçekleştirme
23.10.2019 • 6 minutes to read • Edit Online

Grup birleştirme hiyerarşik veri yapıları üretmek için kullanışlıdır. Bu, her öğeden ilk koleksiyonun ikinci
koleksiyondan ilişkili öğeleri kümesi ile eşleşmesini.
Örneğin, bir sınıf veya adlı bir ilişkisel veritabanı tablo Student iki alanları içerebilir: Id ve Name . Adlı ikinci bir
sınıf veya ilişkisel veritabanı tablo Course iki alanları içerebilir: StudentId ve CourseTitle . Bu iki veri kaynağı
grubu birleşimi tabanlı eşleşen Student.Id ve Course.StudentId , her grup Student koleksiyonuyla Course (boş
olabilir) nesneleri.

NOTE
Sonuç kümesinde ilişkili öğeleri ikinci koleksiyonda bulunup bakılmaksızın, bir grup birleşimin ilk koleksiyonun her öğesine
görünür. Bağlantılı öğe bulunduğu durumlarda, o öğe için bağlantılı öğe dizisi boştur. Sonuç Seçici, bu nedenle ilk
koleksiyonun her öğesine erişimi vardır. Bu ikinci koleksiyonda eşleşme olan ilk koleksiyondan öğeler erişilemiyor bir grup
olmayan birleştirme sonucu seçicide farklıdır.

Bu makalede ilk örnekte grubuna katılma işlemi gösterilmektedir. İkinci örnek XML öğeleri oluşturmak için bir
grup birleştirme kullanmayı gösterir.

Örnek - Group JOIN


Aşağıdaki örnek, bir grup birleşim türünde nesne gerçekleştirir Person ve Pet göre Person eşleşen Pet.Owner
özelliği. Her bir eşleştirmeyi çiftlerini oluşturur, bir grup olmayan birleşimin aksine group JOIN olan bu örnekte ilk
koleksiyonun her öğe için yalnızca bir sonuç nesnesi oluşturur. bir Person nesne. Olan bu örnekte ikinci
koleksiyon karşılık gelen öğeleri Pet nesneleri, bir koleksiyona gruplandırılır. Son olarak, sonuç Seçici işlevi içeren
her bir eşleşme için anonim bir tür oluşturur Person.FirstName ve koleksiyonu Pet nesneleri.
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}

class Pet
{
public string Name { get; set; }
public Person Owner { get; set; }
}

/// <summary>
/// This example performs a grouped join.
/// </summary>
public static void GroupJoinExample()
{
Person magnus = new Person { FirstName = "Magnus", LastName = "Hedlund" };
Person terry = new Person { FirstName = "Terry", LastName = "Adams" };
Person charlotte = new Person { FirstName = "Charlotte", LastName = "Weiss" };
Person arlene = new Person { FirstName = "Arlene", LastName = "Huff" };

Pet barley = new Pet { Name = "Barley", Owner = terry };


Pet boots = new Pet { Name = "Boots", Owner = terry };
Pet whiskers = new Pet { Name = "Whiskers", Owner = charlotte };
Pet bluemoon = new Pet { Name = "Blue Moon", Owner = terry };
Pet daisy = new Pet { Name = "Daisy", Owner = magnus };

// Create two lists.


List<Person> people = new List<Person> { magnus, terry, charlotte, arlene };
List<Pet> pets = new List<Pet> { barley, boots, whiskers, bluemoon, daisy };

// Create a list where each element is an anonymous type


// that contains the person's first name and a collection of
// pets that are owned by them.
var query = from person in people
join pet in pets on person equals pet.Owner into gj
select new { OwnerName = person.FirstName, Pets = gj };

foreach (var v in query)


{
// Output the owner's name.
Console.WriteLine($"{v.OwnerName}:");
// Output each of the owner's pet's names.
foreach (Pet pet in v.Pets)
Console.WriteLine($" {pet.Name}");
}
}

// This code produces the following output:


//
// Magnus:
// Daisy
// Terry:
// Barley
// Boots
// Blue Moon
// Charlotte:
// Whiskers
// Arlene:

Örnek - Group JOIN XML dosyası oluşturmak için


Grup birleştirmeleri, LINQ to XML kullanarak XML oluşturmak için idealdir. Aşağıdaki örnek, anonim türler
oluşturmak yerine, sonuç Seçici işlevi katılan nesnelerini temsil eden bir XML öğeleri oluşturur dışında önceki
örneğe benzerdir.

class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}

class Pet
{
public string Name { get; set; }
public Person Owner { get; set; }
}

/// <summary>
/// This example creates XML output from a grouped join.
/// </summary>
public static void GroupJoinXMLExample()
{
Person magnus = new Person { FirstName = "Magnus", LastName = "Hedlund" };
Person terry = new Person { FirstName = "Terry", LastName = "Adams" };
Person charlotte = new Person { FirstName = "Charlotte", LastName = "Weiss" };
Person arlene = new Person { FirstName = "Arlene", LastName = "Huff" };

Pet barley = new Pet { Name = "Barley", Owner = terry };


Pet boots = new Pet { Name = "Boots", Owner = terry };
Pet whiskers = new Pet { Name = "Whiskers", Owner = charlotte };
Pet bluemoon = new Pet { Name = "Blue Moon", Owner = terry };
Pet daisy = new Pet { Name = "Daisy", Owner = magnus };

// Create two lists.


List<Person> people = new List<Person> { magnus, terry, charlotte, arlene };
List<Pet> pets = new List<Pet> { barley, boots, whiskers, bluemoon, daisy };

// Create XML to display the hierarchical organization of people and their pets.
XElement ownersAndPets = new XElement("PetOwners",
from person in people
join pet in pets on person equals pet.Owner into gj
select new XElement("Person",
new XAttribute("FirstName", person.FirstName),
new XAttribute("LastName", person.LastName),
from subpet in gj
select new XElement("Pet", subpet.Name)));

Console.WriteLine(ownersAndPets);
}

// This code produces the following output:


//
// <PetOwners>
// <Person FirstName="Magnus" LastName="Hedlund">
// <Pet>Daisy</Pet>
// </Person>
// <Person FirstName="Terry" LastName="Adams">
// <Pet>Barley</Pet>
// <Pet>Boots</Pet>
// <Pet>Blue Moon</Pet>
// </Person>
// <Person FirstName="Charlotte" LastName="Weiss">
// <Pet>Whiskers</Pet>
// </Person>
// <Person FirstName="Arlene" LastName="Huff" />
// </PetOwners>
Ayrıca bkz.
Join
GroupJoin
İç birleşimler gerçekleştirme
Sol dış birleştirmeler gerçekleştirme
Anonim türler
Sol dış birleşimler gerçekleştirme
23.10.2019 • 3 minutes to read • Edit Online

Sol dış birleşim bir birleşim olduğunu, hangi ilk koleksiyonun her öğesine, bunu herhangi bir bağlantılı öğe ikinci
koleksiyonda olup bağımsız olarak döndürülür. LINQ çağırarak bir sol dış birleşim gerçekleştirmek için
kullanabileceğiniz DefaultIfEmpty Grup birleştirme sonuçlarının yöntemi.

Örnek
Aşağıdaki örnek nasıl kullanılacağını gösterir DefaultIfEmpty bir grup birleşimin sol dış birleşim sonuçlara göre
yöntemi.
Bir sol dış birleşim iki koleksiyon oluşturmayı ilk adımı, bir grup birleşim kullanarak bir iç birleştirme
gerçekleştirmektir. (Bkz iç birleştirmeler gerçekleştirme bu işlemin açıklaması.) Bu örnekte, listesini Person
nesneleri, iç katılmış listesine Pet nesneleri temel alan bir Person eşleşen nesne Pet.Owner .
İkinci adım sonuç o öğenin sağ koleksiyondaki herhangi bir eşleşme olsa bile kümesinde (soldaki) ilk
koleksiyonun her öğesine eklemektir. Bu çağrılarak gerçekleştirilir DefaultIfEmpty group JOIN öğelerden eşleşen
her dizisi üzerinde. Bu örnekte, DefaultIfEmpty eşleşen her sırası adlı Pet nesneleri. Yöntemi, tek bir varsayılan
değer içeren bir koleksiyon döndürür eşleşen dizisi Pet nesneleri için boş Person nesne, böylece, her sağlama
Person nesne sonucu koleksiyonda temsil edilir.

NOTE
Bir başvuru türü için varsayılan değerdir null ; bu nedenle, her birinin her öğe erişmeden önce bir null başvuru için örnek
denetler Pet koleksiyonu.
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}

class Pet
{
public string Name { get; set; }
public Person Owner { get; set; }
}

public static void LeftOuterJoinExample()


{
Person magnus = new Person { FirstName = "Magnus", LastName = "Hedlund" };
Person terry = new Person { FirstName = "Terry", LastName = "Adams" };
Person charlotte = new Person { FirstName = "Charlotte", LastName = "Weiss" };
Person arlene = new Person { FirstName = "Arlene", LastName = "Huff" };

Pet barley = new Pet { Name = "Barley", Owner = terry };


Pet boots = new Pet { Name = "Boots", Owner = terry };
Pet whiskers = new Pet { Name = "Whiskers", Owner = charlotte };
Pet bluemoon = new Pet { Name = "Blue Moon", Owner = terry };
Pet daisy = new Pet { Name = "Daisy", Owner = magnus };

// Create two lists.


List<Person> people = new List<Person> { magnus, terry, charlotte, arlene };
List<Pet> pets = new List<Pet> { barley, boots, whiskers, bluemoon, daisy };

var query = from person in people


join pet in pets on person equals pet.Owner into gj
from subpet in gj.DefaultIfEmpty()
select new { person.FirstName, PetName = subpet?.Name ?? String.Empty };

foreach (var v in query)


{
Console.WriteLine($"{v.FirstName+":",-15}{v.PetName}");
}
}

// This code produces the following output:


//
// Magnus: Daisy
// Terry: Barley
// Terry: Boots
// Terry: Blue Moon
// Charlotte: Whiskers
// Arlene:

Ayrıca bkz.
Join
GroupJoin
İç birleşimler gerçekleştirme
Gruplanmış birleşimler gerçekleştirme
Anonim türler
Join yan tümcesinin sonuçlarını sıralama
23.10.2019 • 2 minutes to read • Edit Online

Bu örnek, bir birleştirme işleminin sonuçlarını sıralama gösterilmektedir. Sıralama alanına katılım işleminden
gerçekleştirildiğini unutmayın. Hizmetini kullanıyor olsanız da bir orderby yan tümcesi bir veya daha fazla kaynak
ile birleştirme öncesinde dizilerinin, genellikle bunu önermiyoruz. Bazı LINQ sağlayıcıları sıralama alanına katılım
işleminden koruyabilir değil.

Örnek
Bu sorgu, bir grup birleştirme oluşturur ve sonra hala kapsamındaki kategori öğesi temelinde grupları sıralar.
Anonim tür başlatıcı içinde alt sorguda ürünleri serisinden eşleşen tüm öğeleri sıralar.

class HowToOrderJoins
{
#region Data
class Product
{
public string Name { get; set; }
public int CategoryID { get; set; }
}

class Category
{
public string Name { get; set; }
public int ID { get; set; }
}

// Specify the first data source.


List<Category> categories = new List<Category>()
{
new Category(){Name="Beverages", ID=001},
new Category(){ Name="Condiments", ID=002},
new Category(){ Name="Vegetables", ID=003},
new Category() { Name="Grains", ID=004},
new Category() { Name="Fruit", ID=005}
};

// Specify the second data source.


List<Product> products = new List<Product>()
{
new Product{Name="Cola", CategoryID=001},
new Product{Name="Tea", CategoryID=001},
new Product{Name="Mustard", CategoryID=002},
new Product{Name="Pickles", CategoryID=002},
new Product{Name="Carrots", CategoryID=003},
new Product{Name="Bok Choy", CategoryID=003},
new Product{Name="Peaches", CategoryID=005},
new Product{Name="Melons", CategoryID=005},
};
#endregion
static void Main()
{
HowToOrderJoins app = new HowToOrderJoins();
app.OrderJoin1();

// Keep console window open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}

void OrderJoin1()
{
var groupJoinQuery2 =
from category in categories
join prod in products on category.ID equals prod.CategoryID into prodGroup
orderby category.Name
select new
{
Category = category.Name,
Products = from prod2 in prodGroup
orderby prod2.Name
select prod2
};

foreach (var productGroup in groupJoinQuery2)


{
Console.WriteLine(productGroup.Category);
foreach (var prodItem in productGroup.Products)
{
Console.WriteLine($" {prodItem.Name,-10} {prodItem.CategoryID}");
}
}
}
/* Output:
Beverages
Cola 1
Tea 1
Condiments
Mustard 2
Pickles 2
Fruit
Melons 5
Peaches 5
Grains
Vegetables
Bok Choy 3
Carrots 3
*/
}

Ayrıca bkz.
Dil ile Tümleşik Sorgu (LINQ )
orderby yan tümcesi
join yan tümcesi
Bileşik anahtarlar kullanarak birleştirme
23.10.2019 • 2 minutes to read • Edit Online

Bu örnek, birden fazla anahtar bir eşleşme tanımlamak için kullanmak istediğiniz birleştirme işlemleri
gerçekleştirme gösterilmektedir. Bu, bir bileşik anahtarı kullanılarak gerçekleştirilir. Bir bileşik anahtarı anonim bir
tür olarak veya adlandırılmış karşılaştırmak istediğiniz değerlerle yazılı oluşturursunuz. Sorgu değişkeni yöntemi
sınırlarında geçirilir, geçersiz kılmalar adlandırılmış bir tür kullanın. Equals ve GetHashCode anahtarı. Özellikler ve,
bunlar, sırayla adları içindeki her anahtarın aynı olmalıdır.

Örnek
Aşağıdaki örnek, üç tablolardaki verileri birleştirmek için bir bileşik anahtarı kullanacak şekilde gösterilmiştir:

var query = from o in db.Orders


from p in db.Products
join d in db.OrderDetails
on new {o.OrderID, p.ProductID} equals new {d.OrderID, d.ProductID} into details
from d in details
select new {o.OrderID, p.ProductID, d.UnitPrice};

Anahtarlar ve, bunlar sırayla özelliklerinde adlarını bileşik anahtarlar tür çıkarımı bağlıdır. Kaynak dizileri
özelliklerinde aynı ada sahip değilseniz, yeni anahtarları adlarında atamanız gerekir. Örneğin, varsa Orders tablo
ve OrderDetails her tabloda kullanılan kendilerine ait sütunların için farklı adlar, anonim türde aynı ada atayarak
bileşik anahtarlar oluşturabilirsiniz:

join...on new {Name = o.CustomerName, ID = o.CustID} equals


new {Name = d.CustName, ID = d.CustID }

Bileşik anahtarlar da kullanılabilir bir group yan tümcesi.

Ayrıca bkz.
Dil ile Tümleşik Sorgu (LINQ )
join yan tümcesi
group yan tümcesi
Özel birleştirme işlemleri gerçekleştirme
23.10.2019 • 6 minutes to read • Edit Online

Bu örnek ile mümkün olmayan birleştirme işlemleri gerçekleştirme işlemini gösterir join yan tümcesi. Bir sorgu
ifadesinde join yan tümcesi ile sınırlıdır ve en iyi duruma getirilmiş, birleştirme işlemi arayla en yaygın olan
equijoins yazın. Equijoin gerçekleştirirken, büyük olasılıkla her zaman en iyi performansı kullanarak erişmenizi
sağlayacak join yan tümcesi.
Ancak, join yan tümcesi aşağıdaki durumlarda kullanılamaz:
Ne zaman eşitsizlik (bir olmayan-equijoin) bir ifade üzerinde birleştirme predicated.
Ne zaman birleştirme eşitlik ve eşitsizlik birden fazla deyimde de predicated.
Ne zaman, birleştirme işleminden önce sağ tarafındaki (iç) dizisi için bir geçici aralık değişkeni Ekle gerekir.
Equijoins olmayan birleştirmeler gerçekleştirme için birden çok kullanabilirsiniz from bağımsız olarak her bir veri
kaynağı tanıtmak amacıyla yan tümceler. Ardından bir koşul ifadesinde geçerli bir where yan tümcesinin aralık
değişkeni için her kaynak. İfade bir yöntem çağrısının form da yararlanabilirsiniz.

NOTE
Bu tür özel birleştirme işlemi birden çok kullanımıyla karıştırmayın from iç koleksiyonlara erişmek için yan tümcesi. Daha
fazla bilgi için JOIN yan tümcesi.

Örnek
İlk yöntem aşağıdaki örnekte basit bir çapraz birleştirme gösterir. Çok büyük sonuç kümelerinin oluşturmadığından
arası birleştirmeler dikkatli kullanılmalıdır. Ancak, bunlar karşı ek sorgular çalıştırdığınız kaynak dizileri oluşturmak
için bazı senaryolarda yararlı olabilir.
İkinci yöntem, bir dizi Kategori Kimliği Kategori listesinden sol tarafta listelenen tüm ürünlerin üretir. Kullanımına
dikkat edin let yan tümcesi ve Contains geçici bir dizi oluşturmak için yöntemi. Sorgu önce bir dizi oluşturun ve
ilk ortadan kaldırmak da mümkündür from yan tümcesi.

class CustomJoins
{

#region Data

class Product
{
public string Name { get; set; }
public int CategoryID { get; set; }
}

class Category
{
public string Name { get; set; }
public int ID { get; set; }
}

// Specify the first data source.


List<Category> categories = new List<Category>()
{
new Category(){Name="Beverages", ID=001},
new Category(){Name="Beverages", ID=001},
new Category(){ Name="Condiments", ID=002},
new Category(){ Name="Vegetables", ID=003},
};

// Specify the second data source.


List<Product> products = new List<Product>()
{
new Product{Name="Tea", CategoryID=001},
new Product{Name="Mustard", CategoryID=002},
new Product{Name="Pickles", CategoryID=002},
new Product{Name="Carrots", CategoryID=003},
new Product{Name="Bok Choy", CategoryID=003},
new Product{Name="Peaches", CategoryID=005},
new Product{Name="Melons", CategoryID=005},
new Product{Name="Ice Cream", CategoryID=007},
new Product{Name="Mackerel", CategoryID=012},
};
#endregion

static void Main()


{
CustomJoins app = new CustomJoins();
app.CrossJoin();
app.NonEquijoin();

Console.WriteLine("Press any key to exit.");


Console.ReadKey();
}

void CrossJoin()
{
var crossJoinQuery =
from c in categories
from p in products
select new { c.ID, p.Name };

Console.WriteLine("Cross Join Query:");


foreach (var v in crossJoinQuery)
{
Console.WriteLine($"{v.ID,-5}{v.Name}");
}
}

void NonEquijoin()
{
var nonEquijoinQuery =
from p in products
let catIds = from c in categories
select c.ID
where catIds.Contains(p.CategoryID) == true
select new { Product = p.Name, CategoryID = p.CategoryID };

Console.WriteLine("Non-equijoin query:");
foreach (var v in nonEquijoinQuery)
{
Console.WriteLine($"{v.CategoryID,-5}{v.Product}");
}
}
}
/* Output:
Cross Join Query:
1 Tea
1 Mustard
1 Pickles
1 Carrots
1 Bok Choy
1 Peaches
1 Melons
1 Ice Cream
1 Ice Cream
1 Mackerel
2 Tea
2 Mustard
2 Pickles
2 Carrots
2 Bok Choy
2 Peaches
2 Melons
2 Ice Cream
2 Mackerel
3 Tea
3 Mustard
3 Pickles
3 Carrots
3 Bok Choy
3 Peaches
3 Melons
3 Ice Cream
3 Mackerel
Non-equijoin query:
1 Tea
2 Mustard
2 Pickles
3 Carrots
3 Bok Choy
Press any key to exit.
*/

Örnek
Aşağıdaki örnekte sorgu iç (sağ taraf) dizisi söz konusu olduğunda join tümcesi kendisini önce alınamıyor,
anahtarların eşleşmesi temeline göre iki diziyi eklemeniz gerekir. Bu birleştirme ile gerçekleştirilmişse bir join yan
tümcesi, ardından Split her öğe için çağrılacak yöntem sahip. Birden çok kullanımı from yinelenen yöntem
çağrısının ek yükten kaçınmak sorgu yan tümceleri sağlar. Ancak, bu yana join hala olabilir kullanarak birden çok
daha hızlı bu özel durumda iyileştirilmiş from yan tümceleri. Sonuçlar, öncelikli olarak nasıl pahalı yöntem
çağrısında olduğuna bağlı olarak değişir.

class MergeTwoCSVFiles
{
static void Main()
{
// See section Compiling the Code for information about the data files.
string[] names = System.IO.File.ReadAllLines(@"../../../names.csv");
string[] scores = System.IO.File.ReadAllLines(@"../../../scores.csv");

// Merge the data sources using a named type.


// You could use var instead of an explicit type for the query.
IEnumerable<Student> queryNamesScores =
// Split each line in the data files into an array of strings.
from name in names
let x = name.Split(',')
from score in scores
let s = score.Split(',')
// Look for matching IDs from the two data files.
where x[2] == s[0]
// If the IDs match, build a Student object.
select new Student()
{
FirstName = x[0],
LastName = x[1],
ID = Convert.ToInt32(x[2]),
ExamScores = (from scoreAsText in s.Skip(1)
select Convert.ToInt32(scoreAsText)).
ToList()
ToList()
};

// Optional. Store the newly created student objects in memory


// for faster access in future queries
List<Student> students = queryNamesScores.ToList();

foreach (var student in students)


{
Console.WriteLine($"The average score of {student.FirstName} {student.LastName} is
{student.ExamScores.Average()}.");
}

//Keep console window open in debug mode


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}

class Student
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int ID { get; set; }
public List<int> ExamScores { get; set; }
}

/* Output:
The average score of Omelchenko Svetlana is 82.5.
The average score of O'Donnell Claire is 72.25.
The average score of Mortensen Sven is 84.5.
The average score of Garcia Cesar is 88.25.
The average score of Garcia Debra is 67.
The average score of Fakhouri Fadi is 92.25.
The average score of Feng Hanying is 88.
The average score of Garcia Hugo is 85.75.
The average score of Tucker Lance is 81.75.
The average score of Adams Terry is 85.25.
The average score of Zabokritski Eugene is 83.
The average score of Tucker Michael is 92.
*/

Ayrıca bkz.
Dil ile Tümleşik Sorgu (LINQ )
join yan tümcesi
Join yan tümcesinin sonuçlarını sıralama
Sorgu ifadelerinde boş değerler işleme
8.11.2019 • 2 minutes to read • Edit Online

Bu örnek, kaynak koleksiyonlarında olası null değerlerin nasıl işleneceğini gösterir. IEnumerable<T> gibi bir nesne
koleksiyonu, değeri nullolan öğeleri içerebilir. Bir kaynak koleksiyon null ise veya değeri null olan bir öğe içeriyorsa
ve sorgunuz null değerleri işlemezse, sorguyu yürüttüğünüzde bir NullReferenceException atılır.

Örnek
Aşağıdaki örnekte gösterildiği gibi, bir null başvurusu özel durumunun önüne geçmek için savunmaya büyük bir
kod oluşturabilirsiniz:

var query1 =
from c in categories
where c != null
join p in products on c.ID equals
p?.CategoryID
select new { Category = c.Name, Name = p.Name };

Önceki örnekte, where yan tümcesi Kategoriler dizisindeki tüm null öğeleri filtreler. Bu teknik, JOIN yan
tümcesindeki null denetiminden bağımsızdır. Bu örnekte null değeri olan koşullu ifade, Products.CategoryID
Nullable<int> için toplu olan int? türünde olduğundan işe yarar.

Örnek
JOIN yan tümcesinde, karşılaştırma anahtarlarından yalnızca biri null yapılabilir bir değer türü ise, diğerini sorgu
ifadesinde null yapılabilen bir türe çevirebilirsiniz. Aşağıdaki örnekte, EmployeeID int? türünde değerler içeren bir
sütun olduğunu varsayalım:

void TestMethod(Northwind db)


{
var query =
from o in db.Orders
join e in db.Employees
on o.EmployeeID equals (int?)e.EmployeeID
select new { o.OrderID, e.FirstName };
}

Ayrıca bkz.
Nullable<T>
Dil ile Tümleşik Sorgu (LINQ )
Null yapılabilir değer türleri
Sorgu ifadelerinde özel durumları işleme
23.10.2019 • 3 minutes to read • Edit Online

Sorgu ifadesi bağlamında herhangi bir yöntemi çağırmak mümkündür. Ancak, veri kaynağı içeriğini değiştirme ya
da bir özel durum gibi bir yan etkisi oluşturabilmeniz için bir sorgu ifadesinde herhangi bir yöntemini çağırmadan
kaçınmanızı öneririz. Bu örnek, genel özel durum işleme .NET yönergeleri ihlal etmeden sorgu ifadesinde yöntem
çağırdığınızda, özel durumlarını oluşturma önlemek gösterilmektedir. Kabul edilebilir neden belirli bir bağlamda
durum anladığınızda, belirli bir özel durum yakalamak için bu yönergeleri durumu. Daha fazla bilgi için özel
durumlar için en iyi yöntemler.
Son örnek bir sorgu yürütülürken bir özel durum gerekir, bu durumların nasıl işleneceğini gösterir.

Örnek
Aşağıdaki örnek, özel durum işleme bir sorgu ifadesinin dışındaki kod taşımak gösterilmektedir. Yalnızca yöntemi
sorguya yerel değişkenlerin bağlı olmayan mümkün olur.

class ExceptionsOutsideQuery
{
static void Main()
{
// DO THIS with a datasource that might
// throw an exception. It is easier to deal with
// outside of the query expression.
IEnumerable<int> dataSource;
try
{
dataSource = GetData();
}
catch (InvalidOperationException)
{
// Handle (or don't handle) the exception
// in the way that is appropriate for your application.
Console.WriteLine("Invalid operation");
goto Exit;
}

// If we get here, it is safe to proceed.


var query = from i in dataSource
select i * i;

foreach (var i in query)


Console.WriteLine(i.ToString());

//Keep the console window open in debug mode


Exit:
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}

// A data source that is very likely to throw an exception!


static IEnumerable<int> GetData()
{
throw new InvalidOperationException();
}
}
Örnek
Bazı durumlarda, sorgu yürütme hemen durdurmak için bir sorgu içinde oluşturulan bir özel durum için en iyi
yanıtı olabilir. Aşağıdaki örnek, gelen sorgu gövdesi içinde oluşturulabilecek özel durumların nasıl işleneceğini
gösterir. Varsayımında SomeMethodThatMightThrow durdurmak için sorgu yürütme gerektiren bir özel durum neden
olabilir.
Unutmayın try blok kapsayan foreach döngüsü ve sorgunun kendisi. Bunun nedeni, foreach döngü, hangi
sorgu gerçekte yürütülür noktasıdır. Daha fazla bilgi için LINQ sorgularına giriş.

class QueryThatThrows
{
static void Main()
{
// Data source.
string[] files = { "fileA.txt", "fileB.txt", "fileC.txt" };

// Demonstration query that throws.


var exceptionDemoQuery =
from file in files
let n = SomeMethodThatMightThrow(file)
select n;

// Runtime exceptions are thrown when query is executed.


// Therefore they must be handled in the foreach loop.
try
{
foreach (var item in exceptionDemoQuery)
{
Console.WriteLine($"Processing {item}");
}
}

// Catch whatever exception you expect to raise


// and/or do any necessary cleanup in a finally block
catch (InvalidOperationException e)
{
Console.WriteLine(e.Message);
}

//Keep the console window open in debug mode


Console.WriteLine("Press any key to exit");
Console.ReadKey();
}

// Not very useful as a general purpose method.


static string SomeMethodThatMightThrow(string s)
{
if (s[4] == 'C')
throw new InvalidOperationException();
return @"C:\newFolder\" + s;
}
}
/* Output:
Processing C:\newFolder\fileA.txt
Processing C:\newFolder\fileB.txt
Operation is not valid due to the current state of the object.
*/

Ayrıca bkz.
Dil ile Tümleşik Sorgu (LINQ )
Zaman uyumsuz programlama
30.10.2019 • 17 minutes to read • Edit Online

G/ç bağlantılı bir gereksinimleriniz varsa (bir ağdan veri istemek veya bir veritabanına erişmek gibi), zaman
uyumsuz programlamayı kullanmak isteyeceksiniz. Ayrıca, zaman uyumsuz kod yazmak için iyi bir senaryo olan
pahalı bir hesaplama yapma gibi CPU 'ya göre büyük bir kod de vardır.
C#, geri çağırmaları desteklemek veya bir kitaplığa uymak zorunda kalmadan, zaman uyumsuz kodların kolayca
yazılmasına izin veren dil düzeyinde bir zaman uyumsuz programlama modeline sahiptir. Görev tabanlı zaman
uyumsuz model (TAP )olarak bilinen öğeleri izler.

Zaman uyumsuz modele temel genel bakış


Zaman uyumsuz programlama çekirdeği, zaman uyumsuz işlemleri modellerdeki Task ve Task<T> nesneleridir.
async ve await anahtar sözcükleri desteklenir. Çoğu durumda model oldukça basittir:

G/ç ile bağlantılı kod için, bir async yönteminin içinde Task veya Task<T> döndüren bir işlem await .
CPU 'ya bağlı kod için, Task.Run yöntemine sahip bir arka plan iş parçacığında başlatılan bir işlem await .
await anahtar sözcüğü, Magic 'in gerçekleştiği yerdir. await gerçekleştirdiği yöntemin çağıranına denetim verir
ve sonunda bir kullanıcı arabiriminin yanıt vermesini veya bir hizmetin esnek olmasını sağlar.
Zaman uyumsuz koda async yaklaşımı ve yukarıda bağlantı verilen dokunma makalesinde özetlenen await için
başka yollar vardır, ancak bu belge bu noktadan sonra gelen dil düzeyi yapılarına odaklanacaktır.
G/ç bağlantılı örnek: bir Web hizmetinden veri Indirme
Düğmeye basıldığında bir Web hizmetinden bazı verileri indirmeniz gerekebilir, ancak UI iş parçacığını
engellemek istemezsiniz. Bu, şöyle gerçekleştirilebilir:

private readonly HttpClient _httpClient = new HttpClient();

downloadButton.Clicked += async (o, e) =>


{
// This line will yield control to the UI as the request
// from the web service is happening.
//
// The UI thread is now free to perform other work.
var stringData = await _httpClient.GetStringAsync(URL);
DoSomethingWithData(stringData);
};

İşte bu kadar! Kod, görev nesneleriyle etkileşimde bulunmak için sürüklenmeden azaltma olmadan amacı ifade
eder (bazı verileri zaman uyumsuz olarak indirme).
CPU -bağlantılı örnek: bir oyun için hesaplama gerçekleştirme
Bir düğmeye basmakta olduğunuz bir mobil oyun yazıyorsanız, ekranda çok sayıda enemaya zarar verebilir. Hasar
hesaplamasının gerçekleştirilmesi pahalı olabilir ve Kullanıcı arabirimi iş parçacığında yapıldığında, hesaplama
gerçekleştirilirken oyun duraklatılmasını sağlar!
Bunu işlemenin en iyi yolu, Task.Run kullanarak çalışmayı başlatan bir arka plan iş parçacığını başlatmak ve onun
sonucunu await . Bu, iş yapıldığı için Kullanıcı arabiriminin sorunsuz bir şekilde çalışmasına olanak sağlar.
private DamageResult CalculateDamageDone()
{
// Code omitted:
//
// Does an expensive calculation and returns
// the result of that calculation.
}

calculateButton.Clicked += async (o, e) =>


{
// This line will yield control to the UI while CalculateDamageDone()
// performs its work. The UI thread is free to perform other work.
var damageResult = await Task.Run(() => CalculateDamageDone());
DisplayDamage(damageResult);
};

İşte bu kadar! Bu kod, düğmenin tıklama olayının amacını düzgün bir şekilde ifade eder, arka plan iş parçacığını el
ile yönetmeyi gerektirmez ve bunu engellenmeyen bir şekilde yapar.
Kapakların altında ne olur?
Zaman uyumsuz işlemlere önem taşıyan çok sayıda hareketli parça vardır. Task ve Task<T> kapakların altında
neler olduğunu merak ediyorsanız, daha fazla bilgi için zaman uyumsuz ayrıntılı makaleyi kullanıma alın.
Nesnelerin C# yanında, derleyici kodunuzu bir durum makinesine dönüştürür ve bu da bir await erişildiğinde ve
bir arka plan işi bittiğinde yürütmeye devam eder.
Teorik olarak, bu, zaman uyumsuzluğu 'nin Promise modelininbir uygulamasıdır.

Anlaşılması için önemli parçalar


Zaman uyumsuz kod hem g/ç bağlantılı hem de CPU ile bağlantılı kod için kullanılabilir, ancak her senaryo
için farklı olabilir.
Zaman uyumsuz kod, arka planda gerçekleştirilen işleri modellemek için kullanılan yapılar olan Task<T> ve
Task kullanır.
async anahtar sözcüğü bir yöntemi bir zaman uyumsuz metoda dönüştürür. Bu, gövdesinde await anahtar
sözcüğünü kullanmanıza olanak sağlar.
await anahtar sözcüğü uygulandığında, çağıran yöntemi askıya alır ve bekleme görevi tamamlanana kadar
denetimi çağrı yapana geri verir.
await yalnızca zaman uyumsuz bir yöntem içinde kullanılabilir.

CPU ile bağlantılı ve g/ç bağlantılı çalışmayı tanıma


Bu kılavuzun ilk iki örneği g/ç ile bağlantılı ve CPU ile bağlantılı çalışma için async ve await nasıl
kullanabileceğinizi gösterdi. Bu, kodunuzun performansını önemli ölçüde etkileyebildiğinden ve belirli yapıların
yanlış kullanılmasına neden olabileceği için ne zaman bir iş yapmanız gerektiğini (g/ç) veya CPU ile bağlantılı
olarak belirleyebilmeniz için bir anahtardır.
Kodu yazmadan önce sormanız gereken iki soru aşağıda verilmiştir:
1. Kodunuz, bir veritabanının verileri gibi bir şey için "bekliyor" olarak değiştirilsin mi?
Yanıtınız "Evet" ise, çalışmanız g/ç 'ye bağlanır.
2. Kodunuz çok pahalı bir hesaplama gerçekleştiriyor mu?
"Evet" yanıtını verdiyseniz, çalışmanız CPU 'ya bağlanır.
Sahip olduğunuz iş g/ç 'ye bağlıysa, Task.Run olmadan async ve await kullanın. Görev paralel kitaplığı
kullanmamalısınız. Bunun nedeni, zaman uyumsuz olarak zaman uyumsuz makalesindeaçıklanmıştır.
Sahip olduğunuz iş, CPU 'ya bağlıysa ve yanıt hızını düşünüyorsanız, async ve await kullanın, ancak çalışmayı
Task.Run ile başka bir iş parçacığında üretme işlemini yapın. İş eşzamanlılık ve paralellik için uygunsa, görev
paralel kitaplığıkullanmayı da göz önünde bulundurmanız gerekir.
Ayrıca, kodunuzun yürütülmesini her zaman ölçmelisiniz. Örneğin, iş parçacığı oluşturma sırasında bağlam
anahtarlarının ek yüküne kıyasla, CPU bağlantılı çalışmanızın yeterince yüksek maliyetli olmadığı bir durumda
kendinizi bulabilirsiniz. Her seçim kendi zorunluluğunu getirir sahiptir ve durumunuz için doğru zorunluluğunu
getirir öğesini seçmeniz gerekir.

Daha fazla örnek


Aşağıdaki örneklerde, içinde C#zaman uyumsuz kod yazmak için kullanabileceğiniz çeşitli yollar gösterilmektedir.
Bunlar arasında karşılaşabileceğiniz birkaç farklı senaryo ele alınmaktadır.
Bir ağdan veri ayıklama
Bu kod parçacığı, www.dotnetfoundation.org adresindeki GIRIŞ sayfasından HTML 'i indirir ve ".net" dizesinin
HTML 'de oluşma sayısını sayar. Bu görevi gerçekleştiren bir Web denetleyicisi yöntemi tanımlamak için ASP.NET
MVC kullanır, sayı döndürür.

NOTE
Üretim kodunda HTML ayrıştırma işlemi yapmanız planlandıysanız, normal ifadeleri kullanmayın. Bunun yerine bir ayrıştırma
kitaplığı kullanın.

private readonly HttpClient _httpClient = new HttpClient();

[HttpGet]
[Route("DotNetCount")]
public async Task<int> GetDotNetCountAsync()
{
// Suspends GetDotNetCountAsync() to allow the caller (the web server)
// to accept another request, rather than blocking on this one.
var html = await _httpClient.GetStringAsync("https://dotnetfoundation.org");

return Regex.Matches(html, @"\.NET").Count;


}

Bir düğmeye basıldığında aynı görevi gerçekleştiren bir Evrensel Windows uygulaması için yazılan senaryo
aşağıda verilmiştir:
private readonly HttpClient _httpClient = new HttpClient();

private async void SeeTheDotNets_Click(object sender, RoutedEventArgs e)


{
// Capture the task handle here so we can await the background task later.
var getDotNetFoundationHtmlTask = _httpClient.GetStringAsync("https://www.dotnetfoundation.org");

// Any other work on the UI thread can be done here, such as enabling a Progress Bar.
// This is important to do here, before the "await" call, so that the user
// sees the progress bar before execution of this method is yielded.
NetworkProgressBar.IsEnabled = true;
NetworkProgressBar.Visibility = Visibility.Visible;

// The await operator suspends SeeTheDotNets_Click, returning control to its caller.


// This is what allows the app to be responsive and not block the UI thread.
var html = await getDotNetFoundationHtmlTask;
int count = Regex.Matches(html, @"\.NET").Count;

DotNetCountLabel.Text = $"Number of .NETs on dotnetfoundation.org: {count}";

NetworkProgressBar.IsEnabled = false;
NetworkProgressBar.Visibility = Visibility.Collapsed;
}

Birden çok görevin tamamlanması bekleniyor


Kendinizi aynı anda birden çok veri parçası almanız gereken bir durumda bulabilirsiniz. Task API 'SI, birden fazla
arka plan iş üzerinde engellenmeyen bir bekleme kodu gerçekleştiren zaman uyumsuz kod yazmanızı sağlayan
Task.WhenAll ve Task.WhenAny iki yöntem içerir.

Bu örnek, bir userId s kümesi için User verilerini nasıl kullanabileceğinizi gösterir.

public async Task<User> GetUserAsync(int userId)


{
// Code omitted:
//
// Given a user Id {userId}, retrieves a User object corresponding
// to the entry in the database with {userId} as its Id.
}

public static async Task<IEnumerable<User>> GetUsersAsync(IEnumerable<int> userIds)


{
var getUserTasks = new List<Task<User>>();

foreach (int userId in userIds)


{
getUserTasks.Add(GetUserAsync(userId));
}

return await Task.WhenAll(getUserTasks);


}

Bu, LINQ kullanarak bu bit daha fazla succinctly yazmak için başka bir yoldur:
public async Task<User> GetUserAsync(int userId)
{
// Code omitted:
//
// Given a user Id {userId}, retrieves a User object corresponding
// to the entry in the database with {userId} as its Id.
}

public static async Task<User[]> GetUsersAsync(IEnumerable<int> userIds)


{
var getUserTasks = userIds.Select(id => GetUserAsync(id));
return await Task.WhenAll(getUserTasks);
}

Daha az kod olsa da, LINQ 'i zaman uyumsuz kodla karıştırdığınızda dikkatli olmanız gerekir. LINQ, ertelenmiş
(geç) yürütmeyi kullandığından, üretilen sırayı .ToList() veya .ToArray() çağrısıyla tekrarlamaya zorlamayın,
zaman uyumsuz çağrılar foreach() döngüsünde göründükleri şekilde hemen gerçekleşmeyecek.

Önemli bilgi ve öneriler


Zaman uyumsuz programlama görece basittir, ancak beklenmeyen davranışları engelleyebilen aklınızda
bulundurmanız gereken bazı ayrıntılar vardır.
async yöntemlerinin gövdesinde bir await anahtar sözcüğü olması gerekir , Aksi durumda hiçbir
şekilde sonuç vermez!
Göz önünde bulundurmanız önemlidir. await bir async yönteminin gövdesinde kullanılmıyorsa, C# derleyici bir
uyarı oluşturur, ancak kod normal bir yöntem gibi derleyip çalıştırılır. Bu, zaman uyumsuz yöntem için C# derleyici
tarafından oluşturulan durum makinesi herhangi bir şeyi gerçekleştiremeyecek olduğundan, bunun da inanılmaz
verimsiz olacağını unutmayın.
Yazdığınız her zaman uyumsuz yöntem adının soneki olarak "Async" eklemeniz gerekir.
Bu, zaman uyumlu ve zaman uyumsuz yöntemleri daha kolay ayırt etmek için .NET ' te kullanılan kuraldır.
Kodunuz (örneğin, olay işleyicileri veya Web denetleyicisi yöntemleri) tarafından açıkça çağrılmayan bazı
yöntemlerin uygulanması gerekmediğini unutmayın. Bunlar kodunuz tarafından açıkça çağrılmadığı için,
adlandırmalarına yönelik açık olması önemli değildir.
async void yalnızca olay işleyicileri için kullanılmalıdır.

async void , zaman uyumsuz olay işleyicilerinin çalışmasına izin veren tek yoldur çünkü olaylar dönüş türlerine
sahip değildir (Bu nedenle Task ve Task<T> kullanamaz). async void diğer tüm kullanımı, dokunma modelini
takip etmez ve şu gibi kullanımı zor olabilir:
async void yöntemde oluşturulan özel durumlar, bu yöntemin dışında yakalanamıyor.
async void yöntemlerinin test edilmesi çok zordur.
async void Yöntemler, çağıranın zaman uyumsuz olmasını beklemiyorsanız hatalı yan etkilere neden
olabilir.
LINQ ifadelerinde zaman uyumsuz Lambdalar kullanırken Tread dikkatlice
LINQ kullanım içindeki lambda ifadeleri ertelenmiş yürütme, bu kodun bir kez çalıştırılmasını beklemiyorduk. Bu
görevin engellenmesi, doğru yazılmayan bir kilitlenmeye neden olabilir. Ayrıca, bu gibi zaman uyumsuz kodun iç
içe geçirilmesi, kodun yürütülmesi ile ilgili nedenlerle da daha zor hale gelir. Async ve LINQ güçlü, ancak
mümkün olduğunca dikkatli ve açık olarak kullanılmalıdır.
Görevleri engellenmeyen bir şekilde beklede bir kod yazın
Görevin tamamlanmasını beklemek için geçerli iş parçacığını engellemek, kilitlenmeleri ve engellenen bağlam iş
parçacıklarının oluşmasına neden olabilir ve önemli ölçüde daha karmaşık hata işleme gerektirebilir. Aşağıdaki
tabloda, engellenmeyen bir şekilde görevlerin beklenmesiyle ilgili yönergeler sağlanmaktadır:

BUNU KULLAN... BUNUN YERINE... BUNU YAPMAK IÇIN

await Task.Wait veya Task.Result Arka plan görevinin sonucunu alma

await Task.WhenAny Task.WaitAny Herhangi bir görevin tamamlanması


bekleniyor

await Task.WhenAll Task.WaitAll Tüm görevlerin tamamlanması


bekleniyor

await Task.Delay Thread.Sleep Bir süre bekleniyor

Daha az durum bilgisi olan kod yazma


Genel nesnelerin durumuna veya belirli yöntemlerin yürütülmesine bağlı değildir. Bunun yerine, yalnızca
yöntemlerin dönüş değerlerine göre değişir. Neden?
Kodun nedeni daha kolay olacaktır.
Kodun test etmek daha kolay olacaktır.
Zaman uyumsuz ve zaman uyumlu kodu karıştırma çok basittir.
Yarış koşullarından genellikle tamamen kaçınılabilir.
Dönüş değerlerine bağlı olarak, zaman uyumsuz kod koordine etme basit hale gelir.
(Ödül) bağımlılık ekleme ile oldukça iyi bir şekilde çalışmaktadır.

Önerilen bir amaç, kodunuzda tam veya neredeyse tam bir bilgi saydamlığı elde etmek için kullanılır. Bunun
yapılması, son derece öngörülebilir, test edilebilir ve sürdürülebilir kod temeli oluşmasına neden olur.

Diğer Kaynaklar
Zaman uyumsuz kapsamlı, görevlerin nasıl çalıştığı hakkında daha fazla bilgi sağlar.
Async ve await (C#) ile zaman uyumsuz programlama
Zaman uyumsuz programlama için Lucian Wıchık 'nin altı temel ipucu , Async programlama için harika bir
kaynaktır
Desen Eşleştirme
30.10.2019 • 20 minutes to read • Edit Online

Desenler bir değerin belirli bir şeklesahip olduğunu ve eşleşen şekline sahip olduğu zaman değerden bilgi
ayıklayabilirler . Model eşleştirme, günümüzde zaten kullandığınız algoritmalar için daha kısa sözdizimi sağlar.
Mevcut söz dizimini kullanarak model eşleştirme algoritmaları zaten oluşturmuş olursunuz. Değerleri test eden
if veya switch deyimlerini yazarsınız. Daha sonra, bu deyimler eşleşiyorsa, bu değerden bilgi ayıklar ve bunları
kullanabilirsiniz. Yeni sözdizimi öğeleri, zaten bildiğiniz deyimlere yönelik uzantılardır: is ve switch . Bu yeni
uzantılar bir değeri test eden ve bu bilgileri ayıklayarak birleştirir.
Bu makalede, nasıl okunabilir, kısa kod etkinleştirmesinin nasıl yapıldığını gösteren yeni sözdizimine bakacağız.
Desen eşleştirme, verilerin ve kodun ayrıldığı ve verilerin ve bunları işleyen yöntemlerin sıkı bir şekilde birbirine
bağlı olduğu nesne odaklı tasarımlardan farklı olarak, verilerin ve kodun ayrıldığı deyimler sunar.
Bu yeni deyimleri göstermek için, model eşleştirme deyimlerini kullanarak geometrik şekilleri temsil eden
yapılarla çalışmaalım. Nesnenin çalışma zamanı türüne göre nesne davranışını özelleştirmek için sınıf hiyerarşileri
oluşturma ve sanal yöntemleri oluşturma ve geçersiz kılınan Yöntemler hakkında bilgi sahibisiniz.
Bu teknikler, bir sınıf hiyerarşisinde yapılandırılmamış veriler için mümkün değildir.Veriler ve Yöntemler ayrı
olduğunda, diğer araçlara ihtiyacınız vardır. Yeni model eşleştirme yapıları, verileri incelemek ve bu verilerin
herhangi bir koşuluna göre denetim akışını işlemek için temizleyici sözdizimini etkinleştirir. Bir değişkenin
değerini test eden if deyimlerini ve switch zaten yazın. Bir değişkenin türünü test eden is deyimlerini
yazarsınız. Model eşleştirme , bu deyimlere yeni yetenekler ekler.
Bu makalede, farklı geometrik şekillerin alanını hesaplayan bir yöntem oluşturacaksınız. Ancak, nesne yönelimli
teknikler için bir daha olmadan ve farklı şekiller için bir sınıf hiyerarşisi oluşturmadan bunu yapabilirsiniz. Bunun
yerine model eşleştirmeyi kullanacaksınız. Bu örneğe giderek, bu kodun bir nesne hiyerarşisi olarak nasıl
yapılandırıldığı ile karşıtlığı vardır. Sorgu ve işleme gereken veriler bir sınıf hiyerarşisi olmadığında, desen
eşleştirme zarif tasarımları mümkün değildir.
Bir soyut şekil tanımıyla başlamak ve farklı özel şekil sınıfları eklemek yerine, yalnızca geometrik şekillerin her biri
için yalnızca basit veri tanımlarıyla başlayalım.
public class Square
{
public double Side { get; }

public Square(double side)


{
Side = side;
}
}
public class Circle
{
public double Radius { get; }

public Circle(double radius)


{
Radius = radius;
}
}
public struct Rectangle
{
public double Length { get; }
public double Height { get; }

public Rectangle(double length, double height)


{
Length = length;
Height = height;
}
}
public class Triangle
{
public double Base { get; }
public double Height { get; }

public Triangle(double @base, double height)


{
Base = @base;
Height = height;
}
}

Bu yapılardan, bazı şekillerin alanını hesaplayan bir yöntem yazalım.

is tür deseninin ifadesi


7,0 C# öncesinde, her türü bir dizi if ve is deyimlerde test etmeniz gerekir:
public static double ComputeArea(object shape)
{
if (shape is Square)
{
var s = (Square)shape;
return s.Side * s.Side;
}
else if (shape is Circle)
{
var c = (Circle)shape;
return c.Radius * c.Radius * Math.PI;
}
// elided
throw new ArgumentException(
message: "shape is not a recognized shape",
paramName: nameof(shape));
}

Yukarıdaki kod, tür desenininklasik bir ifadesidir: türünü tespit etmek ve bu türe göre farklı bir eylem almak için
bir değişkeni test etiyorsunuz.
Bu kod, test başarılı olursa bir değişken atamak için is ifadesi uzantıları kullanılarak daha kolay hale gelir:

public static double ComputeAreaModernIs(object shape)


{
if (shape is Square s)
return s.Side * s.Side;
else if (shape is Circle c)
return c.Radius * c.Radius * Math.PI;
else if (shape is Rectangle r)
return r.Height * r.Length;
// elided
throw new ArgumentException(
message: "shape is not a recognized shape",
paramName: nameof(shape));
}

Bu güncelleştirilmiş sürümde, is ifadesi her ikisi de değişkeni sınar ve uygun türdeki yeni bir değişkene atar.
Ayrıca, bu sürümün bir struct``Rectangle türünü de içerdiğine dikkat edin. Yeni is ifadesi, değer türleri ve
başvuru türleri ile birlikte kullanılabilir.
Bir eşleştirme ifadesinin sonuçlarının yanlış kullanılmasını önlemenize yardımcı olacak şekilde, model eşleştirme
ifadelerine yönelik dil kuralları. Yukarıdaki örnekte, s , c ve r değişkenleri yalnızca kapsamdadır ve ilgili model
eşleştirme ifadelerinde true sonuçları olduğunda kesinlikle atanır. Başka bir konumda herhangi bir değişken
kullanmayı denerseniz, kodunuz derleyici hataları oluşturur.
Bu kuralların her ikisini de kapsam ile başlayarak ayrıntılı bir şekilde incelim. c değişkeni yalnızca ilk if deyimin
else dalında kapsamdadır. s değişkeni, metot ComputeAreaModernIs kapsamdadır. Bunun nedeni, if deyimin
her bir dalı değişkenler için ayrı bir kapsam oluşturur. Ancak, if deyimin kendisi değildir. Diğer bir deyişle, if
bildiriminde belirtilen değişkenlerin if bildirimiyle aynı kapsamda (Bu durumda, yöntemi). Bu davranış, model
eşleştirmeye özgü değildir, ancak değişken kapsamları ve if ve else deyimleri için tanımlanan davranıştır.
c ve s değişkenleri, kesin olarak atanan doğru mekanizmasından dolayı ilgili if deyimleri doğru olduğunda
atanır.
TIP
Bu konudaki örneklerde, if deyiminin true dalında eşleşme değişkenini kesin bir şekilde atayan bir model eşleştirme
is ifadesi, önerilen yapıyı kullanır. if (!(shape is Square s)) diyerek mantığı ters çevirebilirsiniz ve s değişkeni
yalnızca false dalında kesinlikle atanmasını sağlayabilirsiniz. Bu geçerli C#olsa da, mantığın izlenmesi daha kafa karıştırıcı
olduğundan önerilmez.

Bu kurallar, bu düzenin karşılanmadığı zaman bir model eşleştirme ifadesinin sonucuna yanlışlıkla erişmeniz çok
düşüktür.

Model eşleştirme switch deyimlerini kullanma


Aynı zamanda, diğer şekil türlerini desteklemeniz gerekebilir. Test ettiğiniz koşulların sayısı arttıkça, is deseninin
eşleşen ifadelerin kullanımı fazla olabilir. Denetlemek istediğiniz her türde if deyimlerinin gerektirmesinin yanı
sıra, girişin tek bir türle eşleşmesi durumunda is ifadeleri test etmek için sınırlandırılır. Bu durumda, switch
deseninin eşleşen ifadelerin daha iyi bir seçenek haline geldiğini göreceksiniz.
Geleneksel switch deyimi bir desenli ifadedir: sabit örüntü destekleniyor. Bir değişkeni case ifadesinde
kullanılan herhangi bir sabitle karşılaştırabilirsiniz:

public static string GenerateMessage(params string[] parts)


{
switch (parts.Length)
{
case 0:
return "No elements to the input";
case 1:
return $"One element: {parts[0]}";
case 2:
return $"Two elements: {parts[0]}, {parts[1]}";
default:
return $"Many elements. Too many to write";
}
}

switch deyimin desteklediği tek desenler sabit bir modeldir. Sayısal türlerle ve string türüyle daha fazla
sınırlandırıldı. Bu kısıtlamalar kaldırılmıştır ve artık tür modelini kullanarak bir switch ifadesini yazabilirsiniz:

public static double ComputeAreaModernSwitch(object shape)


{
switch (shape)
{
case Square s:
return s.Side * s.Side;
case Circle c:
return c.Radius * c.Radius * Math.PI;
case Rectangle r:
return r.Height * r.Length;
default:
throw new ArgumentException(
message: "shape is not a recognized shape",
paramName: nameof(shape));
}
}

switch ifadesiyle eşleşen desenler, geleneksel C stili switch ifadesini kullanan geliştiriciler için tanıdık
sözdizimini kullanır. Her case değerlendirilir ve giriş değişkeniyle eşleşen koşulun altındaki kod yürütülür. Kod
yürütme, bir Case ifadesinden sonrakine "düşmüyor". case deyimin sözdizimi her bir case break , return veya
goto ile bitmesidir.

NOTE
Başka bir etikete atlanacak goto deyimleri yalnızca sabit model için geçerlidir (klasik switch deyimi).

switch ifadesini düzenleyen önemli yeni kurallar vardır. switch ifadesindeki değişkenin türüyle ilgili kısıtlamalar
kaldırılmıştır. Bu örnekteki object gibi herhangi bir tür kullanılabilir. Case ifadeleri artık sabit değerlerle sınırlı
değildir. Bu sınırlamanın kaldırılması, yeniden sıralama switch bölümlerinin bir programın davranışını
değiştirebileceği anlamına gelir.
Sabit değerlerle sınırlı olduğunda, birden fazla case etiketi switch ifadesinin değeriyle eşleşemez. Her switch
bölümünün bir sonraki bölüme düşmemelidir ve switch bölümlerinin davranışı etkilemeden herhangi bir sırada
yeniden düzenlenebilir olması için bunu birleştirin. Artık, daha Genelleştirilmiş switch ifadelerle, her bölümün
sırası önemlidir. switch ifadeleri metin sırasına göre değerlendirilir. Yürütme aktarımları, switch ifadesiyle
eşleşen ilk switch etiketine aktarılır.
default durum yalnızca başka bir durum etiketi eşleşmezse yürütülür. default durum, metin sırası ne olursa
olsun son olarak değerlendirilir. default bir durum yoksa ve diğer case deyimlerinin hiçbiri eşleşmezse,
yürütme, switch deyiminden sonraki deyimde devam eder. case etiket kodunun hiçbiri yürütülmez.

case ifadelerinde when yan tümceleri


case etiketinde bir when yan tümcesini kullanarak 0 alanı olan şekiller için özel durumlar yapabilirsiniz. Yüz
uzunluğu 0 olan bir kare veya yarıçapı 0 olan bir daire 0 alanına sahiptir. case etiketinde when yan tümcesini
kullanarak bu koşulu belirtirsiniz:

public static double ComputeArea_Version3(object shape)


{
switch (shape)
{
case Square s when s.Side == 0:
case Circle c when c.Radius == 0:
return 0;

case Square s:
return s.Side * s.Side;
case Circle c:
return c.Radius * c.Radius * Math.PI;
default:
throw new ArgumentException(
message: "shape is not a recognized shape",
paramName: nameof(shape));
}
}

Bu değişiklik, yeni sözdizimi hakkında bazı önemli noktaları gösterir. İlk olarak, birden çok case etiketi bir
switch bölümüne uygulanabilir. Bu etiketlerin herhangi biri true olduğunda, ekstre bloğu yürütülür. Bu örnekte,
switch ifadesi bir daire ya da 0 alanı olan bir kare ise, yöntem 0 sabitini döndürür.

Bu örnek, ilk switch bloğunun iki case etiketlerinde iki farklı değişken tanıtır. Bu switch bloğundaki deyimlerin
c (daire için) veya s (kare için) değişkenlerini kullandığına dikkat edin. Bu değişkenlerden hiçbiri kesinlikle bu
switch bloğunda atanmaz. Bu durumlardan biri eşleşiyorsa, değişkenlerden açıkça biri atanır. Ancak, çalışma
zamanında eşleşeceğinden, derleme zamanında hangisinin atandığını söylemek olanaksızdır. Bu nedenle, aynı
blok için birden çok case etiketi kullandığınızda, case bildiriminde yeni bir değişken açıklamaz veya yalnızca
when yan tümcesindeki değişkenini kullanacaksınız.
Bu şekilleri 0 alanla eklediyseniz, daha fazla şekil türü ekleyelim: dikdörtgen ve üçgen:

public static double ComputeArea_Version4(object shape)


{
switch (shape)
{
case Square s when s.Side == 0:
case Circle c when c.Radius == 0:
case Triangle t when t.Base == 0 || t.Height == 0:
case Rectangle r when r.Length == 0 || r.Height == 0:
return 0;

case Square s:
return s.Side * s.Side;
case Circle c:
return c.Radius * c.Radius * Math.PI;
case Triangle t:
return t.Base * t.Height / 2;
case Rectangle r:
return r.Length * r.Height;
default:
throw new ArgumentException(
message: "shape is not a recognized shape",
paramName: nameof(shape));
}
}

Bu değişiklik kümesi, Yeni şekillerin her biri için bozuk Case ve Labels ve blokların case Etiketler ekler.
Son olarak, bağımsız değişkenin null olmamasını sağlamak için null bir durum ekleyebilirsiniz:

public static double ComputeArea_Version5(object shape)


{
switch (shape)
{
case Square s when s.Side == 0:
case Circle c when c.Radius == 0:
case Triangle t when t.Base == 0 || t.Height == 0:
case Rectangle r when r.Length == 0 || r.Height == 0:
return 0;

case Square s:
return s.Side * s.Side;
case Circle c:
return c.Radius * c.Radius * Math.PI;
case Triangle t:
return t.Base * t.Height / 2;
case Rectangle r:
return r.Length * r.Height;
case null:
throw new ArgumentNullException(paramName: nameof(shape), message: "Shape must not be null");
default:
throw new ArgumentException(
message: "shape is not a recognized shape",
paramName: nameof(shape));
}
}

null deseninin özel davranışı ilginç olduğundan, düzendeki sabit null bir tür olmadığından, ancak herhangi bir
başvuru türüne veya null yapılabilir türe dönüştürülebildiğinden. null , herhangi bir türe dönüştürmek yerine,
değişkenin derleme zamanı türünden bağımsız olarak, bir null değerinin herhangi bir tür düzeniyle
eşleşmeyeceğini tanımlar. Bu davranış yeni switch tabanlı tür deseninin is ifadesiyle tutarlı olmasını sağlar: is
deyimleri, denetlenen değer null olduğunda her zaman false döndürür. Ayrıca daha basittir: türü denetledikten
sonra, ek null bir denetim gerekmez. Yukarıdaki örneklerin herhangi bir durum bloklarında hiçbir null denetim
olmadığını ve tür örüntüsünün eşleşmesi null olmayan bir değer garantisi olduğundan, bu durum gerekli değildir.

case ifadelerinde var bildirimleri


Eşleşme ifadelerinden biri olarak var giriş, model eşleştirmesinde yeni kurallar tanıtır.
İlk kural var bildirimi normal tür çıkarımı kurallarını izliyorsa: tür, anahtar ifadesinin statik türü olarak algılanır.
Bu kuraldan, türü her zaman eşleşir.
İkinci kural, var bildiriminde diğer tür deseninin içerdiği null denetimi yoktur. Bu, değişkenin null olabileceği ve
bu durumda null bir denetim olması gerektiği anlamına gelir.
Bu iki kural birçok örnekte, bir case ifadesinde var bildirimi default ifadesiyle aynı koşullara uyan anlamına
gelir. default durum için varsayılan olmayan herhangi bir durum tercih edildiği için, default durumu hiçbir
şekilde yürütülmeyecektir.

NOTE
Derleyici, default bir durumun yazıldığı ancak hiçbir zaman yürütülebileceği durumlarda uyarı göstermez. Bu, olası tüm
durumlar listelendiğinde geçerli switch deyimin davranışıyla tutarlıdır.

Üçüncü kural, var bir durumun yararlı olabileceği yerleri kullanır. Girişin bir dize olduğu ve bilinen komut
değerlerini aradığınız bir model eşleşmesi yaptığınızı düşünün. Şöyle bir işlem yazabilirsiniz:

static object CreateShape(string shapeDescription)


{
switch (shapeDescription)
{
case "circle":
return new Circle(2);

case "square":
return new Square(4);

case "large-circle":
return new Circle(12);

case var o when (o?.Trim().Length ?? 0) == 0:


// white space
return null;
default:
return "invalid shape description";
}
}

var durum null , boş dize veya yalnızca boşluk içeren herhangi bir dizeyle eşleşir. Önceki kodun, yanlışlıkla bir
NullReferenceExceptionoluşturmadığından emin olmak için ?. işlecini kullandığına dikkat edin. default durum,
bu komut ayrıştırıcısı tarafından anlaşılmayan diğer dize değerlerini işler.
Bu, bir default ifadesinden farklı bir var Case ifadesini düşünmek isteyebileceğiniz bir örnektir.

Sonuçlar
Model eşleştirme yapıları , bir devralma hiyerarşisi tarafından ilgili olmayan farklı değişkenler ve türler arasında
denetim akışını kolayca yönetmenizi sağlar. Ayrıca, değişkende test ettiğiniz herhangi bir koşulu kullanmak için
mantığı da denetleyebilirsiniz. Daha fazla dağıtılmış uygulama oluştururken daha sık ihtiyacınız olacak desenler ve
deyimler sayesinde, verilerin ve bu verileri işleyen yöntemlerin ayrı olduğu durumlar vardır. Bu örnekte kullanılan
şekil yapıların hiçbir yöntem içermediğini, yalnızca salt okunurdur özellikleri olduğunu fark edeceksiniz. Model
eşleştirme, herhangi bir veri türü ile birlikte çalışabilir. Nesneyi inceleyecek ve bu koşullara göre denetim akışı
kararları veren ifadeler yazarsınız.
Bu örnekteki kodu, bir soyut Shape için bir sınıf hiyerarşisi oluşturmaktan ve her biri, alanı hesaplamak için bir
sanal yöntemin kendi uygulamalarına sahip olan belirli türetilmiş şekillerin, bu örnekten karşılaştırın. Genellikle,
verilerle çalışırken ve veri depolama sorunlarını davranış kaygılarından ayırmak istediğinizde, model eşleştirme
ifadelerinin çok faydalı bir araç olduğunu fark edeceksiniz.
Güvenli ve verimli C# kod yazma
30.10.2019 • 26 minutes to read • Edit Online

' Deki C# yeni özellikler daha iyi performansa sahip doğrulanabilir güvenli kod yazmanızı sağlar. Bu teknikleri
dikkatle uygularsanız, daha az senaryo güvenli olmayan kod gerektirir. Bu özellikler, yöntem bağımsız değişkenleri
olarak değer türlerine yapılan başvuruların kullanımını kolaylaştırır ve yöntemi döndürür. Güvenli bir şekilde
bitince, bu teknikler kopyalama değer türlerini en aza indirir. Değer türlerini kullanarak, ayırma sayısını ve çöp
toplama geçişlerini en aza indirmiş olursunuz.
Bu makaledeki örnek kodun çoğu 7,2 ' de C# eklenen özellikleri kullanır. Bu özellikleri kullanmak için, projenizi 7,2
veya sonraki bir sürümü kullanacak C# şekilde yapılandırmanız gerekir. Dil sürümünü ayarlama hakkında daha
fazla bilgi için bkz. dil sürümünü yapılandırma.
Bu makalede, verimli kaynak yönetimine yönelik teknikler ele alınmaktadır. Değer türlerini kullanmanın bir avantajı
genellikle yığın ayırmaların önlerinden kaçınmaktır. Dezavantajı, değere göre kopyalanmasıdır. Bu zorunluluğunu
getirir, büyük miktarlarda veri üzerinde çalışan algoritmaların iyileştirmesini zorlaştırır. C# 7,2 sürümündeki yeni dil
özellikleri, değer türlerine başvurular kullanarak güvenli verimli kod etkinleştiren mekanizmalar sağlar. Her iki
ayırma ve kopyalama işlemini en aza indirmek için bu özellikleri daha seyrek kullanın. Bu makalede bu yeni
özellikler incelenmektedir.
Bu makalede aşağıdaki kaynak yönetimi teknikleri ele alınmaktadır:
Bir türün sabit olduğunu ifade etmek için bir readonly struct bildirin ve in parametreleri kullanılırken
derleyicinin kopyaları kaydetmesine olanak sağlar.
Bir tür sabit olamaz, üyenin durumu değiştirmediğini göstermek için struct üyeleri readonly bildirin.
Dönüş değeri IntPtr.Size daha büyük bir struct olduğunda ve depolama ömrü değeri döndüren yöntemden
daha büyük olduğunda bir ref readonly dönüşü kullanın.
readonly struct boyutu IntPtr.Sizedaha büyük olduğunda, performans nedenleriyle bunu bir in parametresi
olarak geçirmeniz gerekir.
readonly değiştiricisi ile bildirilemediği veya yöntem yalnızca yapının readonly üyelerini çağırdığı sürece bir
struct in parametresi olarak geçirmeyin. Bu kılavuzun ihlal olması, performansı olumsuz etkileyebilir ve bu
da belirsiz bir davranışa yol açabilir.
Bellekle bir bayt dizisi olarak çalışmak için ref struct veya Span<T> ya da ReadOnlySpan<T> gibi bir
readonly ref struct kullanın.

Bu teknikler, başvuru ve değeraçısından birbiriyle rekabet eden iki hedefi dengelemenize zorlar. Başvuru türleri
olan değişkenler bellekteki konuma bir başvuru tutar. Değer türleri olan değişkenler doğrudan değerlerini içerir. Bu
farklılıklar, bellek kaynaklarını yönetmek için önemli olan önemli farklılıkları vurgulamaktadır. Değer türleri
genellikle bir yönteme geçirildiğinde veya bir yöntemden döndürüldüğünde kopyalanır. Bu davranış, bir değer
türünün üyelerini çağırırken this değerini kopyalamayı içerir. Kopyanın maliyeti, türün boyutuyla ilgilidir.
Başvuru türleri yönetilen yığında ayrılır. Her yeni bir nesne için yeni bir ayırma gerekir ve ardından geri kazanılır.
Bu işlemlerin her ikisi de zaman alır. Başvuru, bir yönteme bir bağımsız değişken olarak geçirildiğinde veya bir
yöntemden döndürüldüğünde kopyalanır.
Bu makalede, bu önerileri açıklamak için 3B nokta yapısının aşağıdaki örnek kavramı kullanılmaktadır:
public struct Point3D
{
public double X;
public double Y;
public double Z;
}

Farklı örnekler bu kavramın farklı uygulamalarını kullanır.

Değişmez değer türleri için salt okunur yapılar bildirme


readonly değiştiricisini kullanarak bir struct bildirmek, derleyiciye sabit bir tür oluşturmak için olduğunu bildirir.
Derleyici, aşağıdaki kurallarla bu tasarım kararı uygular:
Tüm alan üyeleri readonly olmalıdır
Otomatik uygulanan özellikler dahil olmak üzere tüm özellikler salt okunabilir olmalıdır.
Bu iki kural, bir readonly struct üyesinin bu yapının durumunu değiştirmemesini sağlamak için yeterlidir. struct
sabittir. Point3D yapısı, aşağıdaki örnekte gösterildiği gibi sabit bir yapı olarak tanımlanabilir:

readonly public struct ReadonlyPoint3D


{
public ReadonlyPoint3D(double x, double y, double z)
{
this.X = x;
this.Y = y;
this.Z = z;
}

public double X { get; }


public double Y { get; }
public double Z { get; }
}

Tasarım amacınızda sabit değer türü oluşturmak her seferinde bu öneriyi izleyin. Tüm performans geliştirmeleri,
ek bir avantajdır. readonly struct tasarım amacınızı açıkça ifade eder.

Bir yapı sabit olamaz, salt okunur Üyeler bildirin


C# 8,0 ve sonraki sürümlerde, bir struct türü değişebilir olduğunda, readonly bir şekilde olmasına neden olmayan
Üyeler bildirmeniz gerekir. Örneğin, aşağıda 3B nokta yapısının değişebilir bir çeşitlemesi verilmiştir:
public struct Point3D
{
public Point3D(double x, double y, double z)
{
this.X = x;
this.Y = y;
this.Z = z;
}

private double _x;


public double X
{
readonly get { return _x;};
set { _x = value; }
}

private double _y;


public double Y
{
readonly get { return _y;};
set { _y = value; }
}

private double _z;


public double Z
{
readonly get { return _z;};
set { _z = value; }
}

public readonly double Distance => Math.Sqrt(X * X + Y * Y + Z * Z);

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


}

Yukarıdaki örnek, readonly değiştiricisini uygulayabileceğiniz konumların çoğunu gösterir: Yöntemler, Özellikler
ve özellik erişimcileri. Otomatik uygulanan özellikler kullanırsanız, derleyici, okuma-yazma özellikleri için get
erişimcisine readonly değiştiricisini ekler. Derleyici, readonly değiştiricisini yalnızca bir get erişimcisi olan
özellikler için otomatik uygulanan özellik bildirimlerine ekler.
readonly değiştiricisini bulunmamalıdır olmayan üyelere eklemek, iki ilgili avantaj sağlar. İlk olarak, derleyici
amacınızı zorluyor. Bu üye yapının durumunu veya readonly de işaretlenmemiş bir üyeye erişim sağlayabilir.
İkincisi, derleyici bir readonly üyesine erişirken in parametrelerinin savunma kopyalarını oluşturmaz. Derleyici,
struct bir readonly üyesi tarafından değiştirilmediğini garanti ettiğinden, bu iyileştirmesi güvenli hale getirir.

Mümkün olduğunda büyük yapılar için ref readonly return deyimlerini


kullanın
Döndürülmekte olan değer döndürülen yönteme yerel olmadığında, değerleri başvuruya göre döndürebilirsiniz.
Başvuruya göre döndürme, yapıyı değil yalnızca başvurunun kopyalandığı anlamına gelir. Aşağıdaki örnekte,
döndürülen değer yerel bir değişken olduğundan, Origin özelliği bir ref dönüşü kullanamaz:

public Point3D Origin => new Point3D(0,0,0);

Ancak, döndürülen değer statik bir üye olduğu için aşağıdaki özellik tanımı başvuru ile döndürülebilir:
public struct Point3D
{
private static Point3D origin = new Point3D(0,0,0);

// Dangerous! returning a mutable reference to internal storage


public ref Point3D Origin => ref origin;

// other members removed for space


}

Çağıranların kaynağı değiştirmesini istemezsiniz, bu yüzden değeri readonly ref döndürmelidir:

public struct Point3D


{
private static Point3D origin = new Point3D(0,0,0);

public static ref readonly Point3D Origin => ref origin;

// other members removed for space


}

ref readonly döndürmek, daha büyük yapıları kopyalamayı ve iç veri üyelerinizin dengeszlik durumunu
korumanızı sağlar.
Çağıran sitede, arayanlar Origin özelliğini readonly ref veya bir değer olarak kullanma seçeneğini yapar:

var originValue = Point3D.Origin;


ref readonly var originReference = ref Point3D.Origin;

Yukarıdaki koddaki ilk atama Origin sabitinin bir kopyasını oluşturur ve bu kopyayı atar. İkincisi bir başvuru atar.
readonly değiştiricinin, değişkenin bildiriminin bir parçası olması gerektiğini unutmayın. Başvurduğu başvuru
değiştirilemez. Bunun için denemeler, derleme zamanı hatasına neden olacak.
readonly değiştiricisi originReference bildiriminde gereklidir.
Derleyici, çağıranın başvuruyu değiştiremiyorum. Değer atama denemeleri doğrudan derleme zamanı hatası
oluşturur. Ancak derleyici, herhangi bir üye yönteminin yapının durumunu değiştirmediğini bilmez. Nesnenin
değiştirilmediğinden emin olmak için, derleyici bir kopya oluşturur ve bu kopyayı kullanarak üye başvuruları
çağırır. Tüm değişiklikler, savunma kopyasına göre yapılır.

in değiştiricisini System.IntPtr.Size daha büyük readonly struct


parametrelere uygulayın
in anahtar sözcüğü, değişkenleri başvuruya göre geçirmek için mevcut ref ve out anahtar sözcüklerini
tamamlar. in anahtar sözcüğü, bağımsız değişkeni başvuruya göre geçirmeyi belirtir, ancak çağrılan yöntem
değeri değiştirmez.
Bu ek, tasarım amacınızı ifade etmek için tam bir sözlük sağlar. Değer türleri, yöntem imzasında Aşağıdaki
değiştiricilerin hiçbirini belirtmezseniz, çağrılan bir yönteme geçirildiğinde kopyalanır. Bu değiştiricilerin her biri,
bir değişkenin başvuruya göre geçtiğini belirtir ve kopyalama önlenir. Her değiştirici farklı bir amacı ifade eder:
out : Bu yöntem, bu parametre olarak kullanılan bağımsız değişkenin değerini ayarlar.
ref : Bu yöntem, bu parametre olarak kullanılan bağımsız değişkenin değerini ayarlayabilir.
in : Bu yöntem, bu parametre olarak kullanılan bağımsız değişkenin değerini değiştirmez.

Bir bağımsız değişkeni başvuruya göre geçirmek için in değiştiricisini ekleyin ve gereksiz kopyalama olmaması
için bağımsız değişkenleri başvuruya göre iletmek üzere tasarım amacınızı bildirin. Bu bağımsız değişken olarak
kullanılan nesneyi değiştirmeyi düşünmüyorsanız.
Bu uygulama genellikle IntPtr.Sizedaha büyük salt okunur değer türleri için performansı geliştirir. Basit türler (
sbyte , byte , short , ushort , int , uint , long , ulong , char , float , double , decimal ve bool ve enum
türleri) için , olası performans kazançları en düşük düzeydedir. Aslında, IntPtr.Size' den küçük türler için doğrudan
başvuru aracılığıyla performans düşebilir.
Aşağıdaki kod, 3B alanda iki işaret arasındaki mesafeyi hesaplayan bir yöntem örneği gösterir.

private static double CalculateDistance(in Point3D point1, in Point3D point2)


{
double xDifference = point1.X - point2.X;
double yDifference = point1.Y - point2.Y;
double zDifference = point1.Z - point2.Z;

return Math.Sqrt(xDifference * xDifference + yDifference * yDifference + zDifference * zDifference);


}

Bağımsız değişkenler, her biri üç Double içeren iki yapıya sahiptir.Çift 8 bayttır, bu nedenle her bağımsız değişken
24 bayttır. in değiştiricisini belirterek, makinenin mimarisine bağlı olarak bu bağımsız değişkenlere 4 baytlık veya
8 baytlık bir başvuru geçirirsiniz. Boyut farkı küçüktür, ancak uygulamanız bu yöntemi birçok farklı değer
kullanarak sıkı bir döngüde çağırdığında ekler.
in değiştirici out ve ref başka yollarla da tamamlar. Yalnızca in , out veya ref varlığı farklı olan bir yöntemin
aşırı yüklerini oluşturamazsınız. Bu yeni kurallar, out ve ref parametreleri için her zaman tanımlanan davranışı
genişletir. out ve ref değiştiricilerine benzer şekilde, in değiştiricisi uygulandığından değer türleri
paketlenmez.
in değiştiricisi Parametreler alan herhangi bir üyeye uygulanabilir: Yöntemler, temsilciler, Lambdalar, yerel
işlevler, Dizin oluşturucular, işleçler.
in parametrelerinin başka bir özelliği, bir in parametresine bağımsız değişken için değişmez değer veya sabitler
kullanbiliriz. Ayrıca, bir ref veya out parametresinden farklı olarak, çağrı sitesinde in değiştiricisini
uygulamanız gerekmez. Aşağıdaki kod, CalculateDistance yöntemini çağırmanın iki örneğini göstermektedir. İlki,
başvuruya göre geçirilen iki yerel değişkeni kullanır. İkincisi, yöntem çağrısının bir parçası olarak oluşturulan geçici
bir değişken içerir.

var distance = CalculateDistance(pt1, pt2);


var fromOrigin = CalculateDistance(pt1, new Point3D());

Derleyicinin in bağımsız değişkeninin salt okunurdur yapısını zorladığı çeşitli yollar vardır. İlki, çağrılan yöntem
bir in parametresine doğrudan atanamaz. Bu değer struct bir tür olduğunda, in parametresinin hiçbir alanına
doğrudan atanamaz. Ayrıca, ref veya out değiştiricisini kullanarak herhangi bir yönteme in parametresi
geçirilemez. Bu kurallar, in parametresinin herhangi bir alanı için geçerlidir, alan bir struct türü ve parametresi
de bir struct türüdür. Aslında, bu kurallar birçok üye erişimi katmanı için geçerlidir, tüm üye erişimi
düzeylerindeki türler structs . Derleyici, in bağımsız değişken olarak geçirilen struct türlerini ve struct
üyelerini diğer yöntemlere bağımsız değişkenler olarak kullanıldığında salt okunurdur.
in parametrelerinin kullanımı, kopya yapmanın olası performans maliyetlerinden kaçınabilir. Herhangi bir
yöntem çağrısının semantiğini değiştirmez. Bu nedenle, çağrı sitesinde in değiştiricisini belirtmeniz gerekmez.
Çağrı sitesindeki in değiştiricinin atlanması derleyicinin aşağıdaki nedenlerden dolayı bağımsız değişkenin bir
kopyasını yapmasına izin verildiğini bildirir:
Bağımsız değişken türünden parametre türüne bir kimlik dönüştürmesi değil, örtük bir dönüştürme var.
Bağımsız değişken bir ifadedir ancak bilinen bir depolama değişkenine sahip değildir.
in varlığı veya yokluğuna göre farklı bir aşırı yükleme var. Bu durumda, değer olarak aşırı yüklemesi daha iyi
bir eşleşmedir.
Bu kurallar, var olan kodu salt okuma başvuru bağımsız değişkenlerini kullanacak şekilde güncelleştirdiğinizde
yararlıdır. Çağrılan yöntemin içinde, değer parametrelerine göre kullanan herhangi bir örnek yöntemini
çağırabilirsiniz. Bu örneklerde in parametresinin bir kopyası oluşturulur. Derleyici herhangi bir in parametresi
için geçici bir değişken oluşturabileceğinden, herhangi bir in parametresi için varsayılan değerleri de
belirtebilirsiniz. Aşağıdaki kod, kaynak (nokta 0, 0) ikinci nokta için varsayılan değer olarak belirtir:

private static double CalculateDistance2(in Point3D point1, in Point3D point2 = default)


{
double xDifference = point1.X - point2.X;
double yDifference = point1.Y - point2.Y;
double zDifference = point1.Z - point2.Z;

return Math.Sqrt(xDifference * xDifference + yDifference * yDifference + zDifference * zDifference);


}

Derleyiciye başvuruya göre salt okuma bağımsız değişkenlerini geçirmeye zorlamak için, aşağıdaki kodda
gösterildiği gibi, çağrı sitesindeki bağımsız değişkenlerde in değiştiricisini belirtin:

distance = CalculateDistance(in pt1, in pt2);


distance = CalculateDistance(in pt1, new Point3D());
distance = CalculateDistance(pt1, in Point3D.Origin);

Bu davranış, performans kazançlarının mümkün olduğu büyük kod tabanlarında zaman içinde in
parametrelerinin benimsenmesini kolaylaştırır. in değiştiricisini öncelikle Yöntem imzalarına eklersiniz. Ardından,
çağrı sitelerine in değiştiricisini ekleyebilir ve derleyicinin daha fazla konumda in parametrelerinin savunma
kopyalarını oluşturmaktan kaçınmasını sağlamak için readonly struct türleri oluşturabilirsiniz.
in parametresi ataması, başvuru türleri veya sayısal değerlerle de kullanılabilir. Ancak, her iki durumda da
avantajlar, varsa en az düzeydedir.

in bağımsız değişkeni olarak hiçbir şekilde kesilebilir yapılar


kullanmayın
Yukarıda açıklanan teknikler, başvuruları döndürerek ve değerlere başvuruya göre geçirerek kopyaların nasıl
önleneceğini açıklamaktadır. Bu teknikler, bağımsız değişken türleri readonly struct türleri olarak bildirildiğinde
en iyi şekilde çalışır. Aksi takdirde, derleyicinin herhangi bir bağımsız değişken için salt okunur hale getirilmesi
zorunlu kılmak için birçok durumda savunma kopyaları oluşturması gerekir. Bir 3B noktanın kaynaktan
uzaklığını hesaplayan aşağıdaki örneği göz önünde bulundurun:

private static double CalculateDistance(in Point3D point1, in Point3D point2)


{
double xDifference = point1.X - point2.X;
double yDifference = point1.Y - point2.Y;
double zDifference = point1.Z - point2.Z;

return Math.Sqrt(xDifference * xDifference + yDifference * yDifference + zDifference * zDifference);


}

Point3D yapısı ReadOnly bir struct değil . Bu yöntemin gövdesinde altı farklı özellik erişim çağrısı vardır. İlk
inceleme durumunda bu erişimlerin güvenli olduğunu düşündük. Tüm get erişimci nesnenin durumunu
değiştirmez. Ancak bunu zorlayan bir dil kuralı yoktur. Yalnızca ortak bir kuraldır. Herhangi bir tür, iç durumu
değiştiren bir get erişimcisi uygulayabilir. Bazı dil garantisi olmadan, derleyicinin herhangi bir üyeyi çağırmadan
önce bağımsız değişkenin geçici bir kopyasını oluşturması gerekir. Geçici depolama, yığında oluşturulur, bağımsız
değişkenin değerleri geçici depolamaya kopyalanır ve değer this bağımsız değişkeni olarak her üye erişiminde
yığına kopyalanır. Birçok durumda, bu kopyalar, bağımsız değişken türü readonly struct olmadığında, bu kopya,
değere göre geçiş, salt okunur başvuruya göre daha hızlıdır.
Bunun yerine, uzaklık hesaplaması değişmez yapıyı kullanıyorsa ReadonlyPoint3D geçici nesneler gerekmez:

private static double CalculateDistance3(in ReadonlyPoint3D point1, in ReadonlyPoint3D point2 = default)


{
double xDifference = point1.X - point2.X;
double yDifference = point1.Y - point2.Y;
double zDifference = point1.Z - point2.Z;

return Math.Sqrt(xDifference * xDifference + yDifference * yDifference + zDifference * zDifference);


}

readonly struct üyelerini çağırdığınızda derleyici daha verimli kod üretir: alıcının bir kopyası yerine this
başvurusu, her zaman üye yöntemine başvuru ile geçirilen bir in parametresidir. Bu iyileştirme, bir
readonly struct in bağımsız değişkeni olarak kullandığınızda kopyalamayı kaydeder.

Null yapılabilir bir değer türünü in bağımsız değişken olarak geçirmemelisiniz. Nullable<T> türü salt okunurdur
struct olarak bildirilmemiş. Bu, derleyicinin parametre bildiriminde in değiştiricisini kullanarak bir yönteme
geçirilen herhangi bir Nullable değer türü bağımsız değişkeni için savunma kopyaları oluşturması gerektiği
anlamına gelir.
GitHub 'daki örnek depolarımızda , benchmarkdotnet kullanarak performans farklarını gösteren bir örnek
program görebilirsiniz. Değere ve başvuruya göre değişmez bir struct geçirilerek başvuruya göre kesilebilir bir
yapının geçirilmesini karşılaştırır. Değişmez yapının kullanımı ve başvuruya göre Pass en hızlı.

Tek bir yığın çerçevesinde bloklarla veya bellekle çalışmak için


ref struct türlerini kullanın
İlgili dil özelliği, tek bir yığın çerçevesiyle sınırlandırılmak zorunda olması gereken bir değer türü bildirebilmesidir.
Bu kısıtlama derleyicinin birkaç iyileştirme yapmasına olanak sağlar. Bu özellik için birincil mosyon Span<T> ve
ilgili yapılarıdır. Span<T> türünü kullanan yeni ve güncelleştirilmiş .NET API 'Leri kullanarak bu geliştirmelerden
performans iyileştirmeleri elde edersiniz.
stackalloc kullanılarak oluşturulan ve birlikte çalışma API 'lerinden bellek kullanırken benzer gereksinimlerle
çalışıyor olabilirsiniz. Bu gereksinimler için kendi ref struct türlerinizi tanımlayabilirsiniz.

readonly ref struct türü


Bir yapının readonly ref olarak bildirilmesi, ref struct ve readonly struct bildirimlerinin avantajlarını ve
kısıtlamalarını birleştirir. Salt okunur yayılma alanı tarafından kullanılan bellek tek bir yığın çerçevesiyle kısıtlıdır ve
salt okunur olarak kullanılan bellek değiştirilemez.

Sonuçlar
Değer türlerini kullanmak, ayırma işlemlerinin sayısını en aza indirir:
Değer türleri için depolama, yerel değişkenler ve Yöntem bağımsız değişkenleri için ayrılmış yığındır.
Diğer nesnelerin üyesi olan değer türleri için depolama alanı, ayrı bir ayırma olarak değil, bu nesnenin bir
parçası olarak ayrılır.
Değer türü dönüş değerleri için depolama, yığın olarak ayrıldı.
Aynı durumlarda başvuru türleri ile karşıtlık:
Başvuru türleri için depolama, yerel değişkenler ve Yöntem bağımsız değişkenleri için ayrılır. Başvuru yığın
üzerinde depolanır.
Diğer nesnelerin üyesi olan başvuru türleri için depolama, yığın üzerinde ayrı olarak ayrılır. İçerilen nesne
başvuruyu depolar.
Başvuru türü dönüş değerleri için depolama, yığın olarak ayrıldı. Bu depolamanın başvurusu yığında depolanır.
En aza indirme ayırmaları, dengelerle gelir. struct boyutu bir başvurunun boyutundan daha büyükse daha fazla
bellek kopyalayabilirsiniz. Başvuru genellikle 64 bit veya 32 bittir ve hedef makine CPU 'suna bağlıdır.
Bu dengeler genellikle en düşük performans etkisine sahiptir. Ancak, büyük yapılar veya daha büyük koleksiyonlar
için performans etkisi artar. Etki, sıkı Döngülerde ve programlar için etkin yollarda büyük olabilir.
Bu C# dilde geliştirmeler, bellek ayırmalarının en aza indirmek için gerekli performansı elde etmek için önemli bir
faktör olan performans açısından kritik algoritmalarda tasarlanmıştır. Bu özellikleri genellikle yazdığınız kodda
kullanmacağınızı fark edebilirsiniz. Ancak, bu geliştirmeler .NET genelinde benimsenmiştir. Daha fazla API bu
özellikleri kullanırken, uygulamalarınızın performansının iyileştireyi görürsünüz.

Ayrıca bkz.
ref anahtar sözcüğü
Ref dönüşler ve ref yerel ayarlar
İfade Ağaçları
30.10.2019 • 3 minutes to read • Edit Online

LINQ kullandıysanız, Func türlerinin API kümesinin bir parçası olduğu zengin bir kitaplık ile karşılaşırsınız. (LINQ
hakkında bilginiz yoksa, büyük olasılıkla LINQ öğreticisini ve bu uygulamadan önce lambda ifadeleri hakkındaki
makaleyi okumak istersiniz.) Ifade ağaçları , işlevleri olan bağımsız değişkenlerle daha zengin etkileşim sağlar.
LINQ sorguları oluştururken, genellikle lambda Ifadeleri kullanarak işlev bağımsız değişkenleri yazarsınız. Tipik
bir LINQ sorgusunda, bu işlev bağımsız değişkenleri derleyicinin oluşturduğu bir temsilciye dönüştürülür.
Daha zengin bir etkileşim sağlamak istediğinizde, Ifade ağaçlarıkullanmanız gerekir. İfade ağaçları kodu,
inceleyebileceğiniz, değiştirebileceğiniz veya yürütebilmeniz için bir yapı olarak temsil eder. Bu araçlar, çalışma
zamanında kodu işleme gücü sağlar. Çalışan algoritmaların incelediği veya yeni özellikleri barındıran bir kod
yazabilirsiniz. Daha Gelişmiş senaryolarda, çalışan algoritmaları değiştirebilir ve hatta farklı bir ortamda yürütmek
üzere C# ifadeleri başka bir biçimde çevirebilirsiniz.
Büyük olasılıkla Ifade ağaçları kullanan kodu zaten yazmış olabilirsiniz. Entity Framework LINQ API 'Leri, LINQ
sorgu Ifade deseninin bağımsız değişkenleri olarak Ifade ağaçlarını kabul eder. Bu, Entity Framework , yazdığınız
sorguyu veritabanı ALTYAPıSıNDA yürütülen SQL C# 'e çevirmesini sağlar. .NET için popüler bir sahte işlem
çerçevesi olan moqbaşka bir örnektir.
Bu öğreticinin geri kalan bölümleri, Ifade ağaçlarının ne olduğunu keşfedebilir, ifade ağaçlarını destekleyen
çerçeve sınıflarını inceler ve ifade ağaçlarıyla nasıl çalışabileceğinize yardımcı olur. İfade ağaçlarını nasıl
okuyacağınızı, ifade ağaçları oluşturmayı, değiştirilmiş ifade ağaçları oluşturmayı ve ifade ağaçları tarafından
temsil edilen kodun nasıl yürütüleceğini öğreneceksiniz. Okunduktan sonra, zengin Uyarlamalı algoritmalar
oluşturmak için bu yapıları kullanmaya hazırlanın.
1. İfade Ağaçları Açıklaması
Ifade ağaçlarıarkasındaki yapıyı ve kavramları anlayın.
2. İfade Ağaçlarını Destekleyen Çerçeve Türleri
İfade ağaçlarını tanımlayan ve işleyen yapılar ve sınıflar hakkında bilgi edinin.
3. İfade Yürütme
Lambda Ifadesi olarak temsil edilen bir ifade ağacını temsilciye dönüştürmeyi ve elde edilen temsilciyi
yürütmeyi öğrenin.
4. İfade Yorumlama
İfade ağacının hangi kodun temsil ettiğini anlamak için, ifade ağaçlarına çapraz geçiş yapma ve İnceleme
hakkında bilgi edinin.
5. İfade Derleme
Bir ifade ağacı ve derleme ifade ağaçları için düğümleri oluşturmayı öğrenin.
6. İfade Çevirme
Bir ifade ağacının değiştirilmiş bir kopyasını oluşturmayı veya bir ifade ağacını farklı bir biçime
çevireceğinizi öğrenin.
7. Toplam
İfade ağaçları hakkındaki bilgileri gözden geçirin.
İfade Ağaçları Açıklaması
30.10.2019 • 8 minutes to read • Edit Online

Önceki--genel bakış
Ifade ağacı kodu tanımlayan bir veri yapısıdır. Bunlar, bir derleyicinin kodu çözümlemek ve derlenen çıktıyı
oluşturmak için kullandığı yapıları temel alırlar. Bu öğreticiyi okurken, çözümleyiciler ve kod
düzeltmelerioluşturmak Için ifade ağaçları ve Roslyn API 'lerinde kullanılan türler arasında çok sayıda benzerlik
olduğunu fark edeceksiniz. (Çözümleyiciler ve kod düzeltmeleri, kodda statik analiz gerçekleştiren ve bir geliştirici
için olası düzeltmeler öneren NuGet paketlerdir.) Kavramlar benzerdir ve nihai sonuç, kaynak kodun anlamlı bir
şekilde incelemesini sağlayan bir veri yapısıdır. Ancak, Ifade ağaçları, Roslyn API 'Lerine göre tamamen farklı bir
sınıf ve API kümesine dayanır.
Basit bir örneğe bakalım. Aşağıda bir kod satırı verilmiştir:

var sum = 1 + 2;

Bunu bir ifade ağacı olarak çözümlüyorsanız, ağaç birkaç düğüm içerir. En dıştaki düğüm, birden çok alt düğüm
içeren bir atama ( var sum = 1 + 2; ) olan bir değişken bildirimi deyimidir: değişken bildirimi, atama işleci ve eşittir
işaretinin sağ tarafını temsil eden bir ifade. Bu ifade, toplama işlemini ve ek olarak sol ve sağ işlenenleri temsil eden
ifadelere daha fazla bölünmüştür.
Eşittir işaretinin sağ tarafını oluşturan ifadelerle biraz daha fazla ayrıntıya bakalım. İfade 1 + 2 . Bu bir ikili ifadedir.
Daha özel olarak, bu bir ikili ekleme ifadesidir. İkili ekleme ifadesinde, ek ifadenin sol ve sağ düğümleri temsil eden
iki alt öğe vardır. Her iki düğüm de sabit ifadelerdir: Sol işlenen 1 değerdir ve sağ işlenen değer 2 .
Görsel olarak, tüm deyimin bir ağaç olması gerekir: kök düğümden başlayabilir ve bu ifadeyi oluşturan kodu
görmek için ağaçtaki her bir düğüme yolculuk yapabilirsiniz:
Atama ile değişken bildirimi ekstresi ( var sum = 1 + 2; )
Örtük değişken türü bildirimi ( var sum )
Örtük var anahtar sözcüğü ( var )
Değişken adı bildirimi ( sum )
Atama işleci ( = )
İkili ekleme ifadesi ( 1 + 2 )
Sol işlenen ( 1 )
Toplama işleci ( + )
Sağ işlenen ( 2 )
Bu karmaşık görünebilir, ancak çok güçlüdür.Aynı süreci izleyerek, daha karmaşık ifadeler de oluşturabilirsiniz. Şu
ifadeyi göz önünde bulundurun:

var finalAnswer = this.SecretSauceFunction(


currentState.createInterimResult(), currentState.createSecondValue(1, 2),
decisionServer.considerFinalOptions("hello")) +
MoreSecretSauce('A', DateTime.Now, true);

Yukarıdaki ifade ayrıca atama içeren bir değişken bildirimidir. Bu örnekte, atamanın sağ tarafı çok daha karmaşık
bir ağacdır. Bu ifadeyi parçalara ayırmayı istemiyorum, ancak farklı düğümlerin ne olabileceğini düşünün. Geçerli
nesneyi alıcı olarak kullanan ve açık bir this alıcısı olan, diğeri olmayan yöntem çağrıları vardır. Diğer alıcı
nesnelerini kullanan Yöntem çağrıları vardır, farklı türlerde sabit bağımsız değişkenler vardır. Son olarak, bir ikili
toplama işleci vardır. SecretSauceFunction() veya MoreSecretSauce() dönüş türüne bağlı olarak, bu ikili ek işleç, bir
sınıf için tanımlanan ikili toplama işlecine bir statik yöntem çağrısına çözüm olarak, geçersiz kılınan bir toplama
işlecine bir yöntem çağrısı olabilir.
Bu algılanan karmaşıklığa rağmen yukarıdaki ifade, ilk örnek olarak kolayca gezinilede bir ağaç yapısı oluşturur.
İfadede yaprak düğümleri bulmak için alt düğümlerin geçiş tutulmasını sağlayabilirsiniz. Üst düğümlerin alt
öğelerine başvuruları olacaktır ve her düğüm, ne tür bir düğüm olduğunu açıklayan bir özelliğe sahiptir.
Bir ifade ağacının yapısı çok tutarlıdır. Temel bilgileri öğrendikten sonra, bir ifade ağacı olarak temsil edildiğinde en
karmaşık kodu bile anlayabilirsiniz. Veri yapısındaki inceliğini, C# derleyicinin en karmaşık C# programları nasıl
çözümleyebileceğini ve bu karmaşık kaynak kodundan doğru çıktı oluşturmasına nasıl yönelik olduğunu açıklar.
İfade ağaçları yapısına alışdıktan sonra, elde ettiğiniz bilgileri daha fazla ve daha fazla gelişmiş senaryolarla
çalışmanıza olanak tanıcaksınız. İfade ağaçları için inanılmaz güç vardır.
Algoritmaları başka ortamlarda yürütmek üzere çevirmenin yanı sıra, kod yürütmeden önce kodu İnceleme
algoritmalarının yazmayı kolaylaştırmak için ifade ağaçları kullanılabilir. Bağımsız değişkenleri ifade olan bir
yöntem yazabilir ve ardından kodu yürütmeden önce bu ifadeleri inceleyebilirsiniz. Ifade ağacı kodun tam bir
gösterimidir: herhangi bir alt ifadenin değerlerini görebilirsiniz. Yöntem ve özellik adlarını görebilirsiniz. Herhangi
bir sabit ifadenin değerini görebilirsiniz. Ayrıca, bir ifade ağacını yürütülebilir bir temsilciye dönüştürebilir ve kodu
yürütebilirsiniz.
Ifade ağaçları için API 'Ler, neredeyse tüm geçerli kod yapısını temsil eden ağaçlar oluşturmanızı sağlar. Ancak,
şeyleri mümkün olduğunca basit tutmak için bir ifade ağacında C# bazı ıoms oluşturulamaz. Bir örnek, zaman
uyumsuz ifadelerdir ( async ve await anahtar kelimeleri kullanılarak). Gereksinimleriniz zaman uyumsuz
algoritmalar gerektiriyorsa, derleyici desteğine göre değil, Task nesnelerini doğrudan değiştirmeniz gerekir. Başka
bir döngü de oluşturmaktır. Genellikle, for , foreach , while veya do döngülerini kullanarak bunları
oluşturursunuz. Bu serinin ilerleyen kısımlarındagöreceğiniz gibi, ifade ağaçları Için API 'ler, break ve döngüyü
yinelemeyi denetleyen continue ifadelerle tek bir döngü ifadesi destekler.
Yapamayacağınız her şey bir ifade ağacını değiştirmektir. İfade ağaçları değişmez veri yapılarıdır. Bir ifade ağacını
bulunmamalıdır (değiştirmek) istiyorsanız, orijinalin bir kopyası olan, ancak istediğiniz değişikliklerle yeni bir ağaç
oluşturmanız gerekir.
Ifade ağaçlarını destekleyen bir sonraki--çerçeve türleri
İfade Ağaçlarını Destekleyen Çerçeve Türleri
30.10.2019 • 5 minutes to read • Edit Online

Önceki--Ifade ağaçları açıklanıyor


.NET Core Framework 'te Ifade ağaçları ile çalışan sınıfların büyük bir listesi vardır. System.Linq.Expressionslistenin
tam listesini görebilirsiniz. Tam liste üzerinden çalıştırmak yerine, Framework sınıflarının nasıl tasarlandığını
anlayalim.
Dil tasarımında, bir ifade bir değeri değerlendiren ve döndüren bir kod gövdesidir. İfadeler çok basit olabilir: 1
sabit ifade, 1 sabit değerini döndürür. Daha karmaşık olabilir: ifade (-B + Math.Sqrt(B*B - 4 * A * C)) / (2 * A)
ikinci dereceden bir Denklem için bir kök döndürür (denklemin bir çözüme sahip olduğu durumda).

Hepsi System. LINQ. Expression ile başlar


İfade ağaçları ile çalışmanın karmaşıklıklarından biri, programlarda birçok yerde birçok farklı türde ifade geçerli
olur. Atama ifadesi düşünün. Atamanın sağ tarafı sabit bir değer, bir değişken, bir yöntem çağrısı ifadesi veya başka
bir değer olabilir. Bu dil esnekliği, bir ifade ağacında çapraz geçiş yaparken bir ağacın düğümleri içinde herhangi
bir yerde birçok farklı ifade türüyle karşılaşacağınız anlamına gelir. Bu nedenle, temel ifade türüyle çalışabilmeniz
için en kolay yöntem vardır. Ancak bazen daha fazla bilmeniz gerekir. Taban Ifade sınıfı, bu amaçla bir NodeType
özelliği içerir. Olası ifade türlerinin numaralandırması olan bir ExpressionType döndürür. Düğümün türünü
öğrendikten sonra, bu türe çevirebilirsiniz ve ifade düğümünün türünü bilmenin belirli eylemlerini
gerçekleştirebilirsiniz. Belirli düğüm türlerini arayabilir ve ardından bu tür bir ifadenin belirli özellikleriyle
çalışabilirsiniz.
Örneğin, bu kod bir değişken erişim ifadesi için bir değişkenin adını yazdırır. Düğüm türünü denetleme, sonra bir
değişken erişim ifadesine atama ve ardından belirli bir ifade türünün özelliklerini denetleme alıştırması yaşıyorum:

Expression<Func<int, int>> addFive = (num) => num + 5;

if (addFive.NodeType == ExpressionType.Lambda)
{
var lambdaExp = (LambdaExpression)addFive;

var parameter = lambdaExp.Parameters.First();

Console.WriteLine(parameter.Name);
Console.WriteLine(parameter.Type);
}

Ifade ağaçları oluşturma


System.Linq.Expression sınıfı, ifadeler oluşturmak için birçok statik yöntem de içerir. Bu yöntemler, alt öğeleri için
sağlanan bağımsız değişkenleri kullanarak bir ifade düğümü oluşturur. Bu şekilde, yaprak düğümlerinden bir ifade
oluşturursunuz. Örneğin, bu kod bir ekleme ifadesi oluşturur:

// Addition is an add expression for "1 + 2"


var one = Expression.Constant(1, typeof(int));
var two = Expression.Constant(2, typeof(int));
var addition = Expression.Add(one, two);

Bu basit örnekte, ifade ağaçları oluşturmak ve bunlarla çalışmak için birçok tür bulunduğunu görebilirsiniz. Bu
karmaşıklık, C# dilin sağladığı zengin sözlük yeteneklerini sağlamak için gereklidir.

API 'Lerde gezinme


C# Dilin sözdizimi öğelerinin neredeyse tamamına eşlenen ifade düğüm türleri vardır. Her türün bu tür dil öğesi
için özel yöntemleri vardır. Tek seferde baş bir süre içinde tutulması çok önemlidir. Her şeyi yeniden denemeye
çalışmak yerine, Ifade ağaçları ile çalışmak için kullandığım teknikler şunlardır:
1. İnceleme yapmanız gereken olası düğümleri öğrenmek için ExpressionType numaralandırmasının üyelerine
bakın. Bu aslında bir ifade ağacını geçmek ve anlamak istediğinizde yardımcı olur.
2. Bir ifade oluşturmak için Expression sınıfının statik üyelerine bakın. Bu yöntemler bir alt düğümleri
kümesinden herhangi bir ifade türü oluşturabilir.
3. Değiştirilen bir ifade ağacı oluşturmak için ExpressionVisitor sınıfına bakın.
Bu üç alanın her birine baktığımızda daha fazla bilgi bulabilirsiniz. Bağımsız olarak, bu üç adımdan biriyle
başladığınızda ne yapmanız gerektiğini öğreneceksiniz.
Sonraki--Ifade ağaçları yürütülüyor
Ifade ağaçları yürütülüyor
30.10.2019 • 10 minutes to read • Edit Online

Ifade ağaçlarını destekleyen önceki Framework türleri


İfade ağacı , bazı kodları temsil eden bir veri yapısıdır. Derlenmez ve çalıştırılabilir kod değildir. Bir ifade ağacı
tarafından temsil edilen .NET kodunu yürütmek istiyorsanız, onu yürütülebilir Il yönergelerine dönüştürmeniz
gerekir.

IŞLEVLERE lambda Ifadeleri


Herhangi bir Lambdavexpression veya Lambdavexpression 'dan türetilmiş herhangi bir tür çalıştırılabilir Il 'ye
dönüştürebilirsiniz. Diğer ifade türleri doğrudan koda dönüştürülemez. Bu kısıtlama pratikte çok daha etkilidir.
Lambda ifadeleri, yürütülebilir ara dile (IL ) dönüştürerek yürütmek istediğiniz tek ifade türleridir. (Bir
ConstantExpression doğrudan yürütmek için ne anlama geldiğini düşünün. Herhangi bir şey yararlı mı?)
LambdaExpression olan herhangi bir ifade ağacı veya LambdaExpression türetilmiş bir tür Il 'ye dönüştürülebilir.
Expression<TDelegate> ifade türü, .NET Core kitaplıklarında tek somut örnektir. Herhangi bir temsilci türüyle
eşleşen bir ifadeyi temsil etmek için kullanılır. Bu tür bir temsilci türüne eşlendiğinden, .NET ifadeyi inceleyebilir ve
lambda ifadesinin imzasıyla eşleşen uygun bir temsilci için Il oluşturabilir.
Çoğu durumda bu, bir ifade ve onun karşılık gelen temsilcisi arasında basit bir eşleme oluşturur. Örneğin,
Expression<Func<int>> tarafından temsil edilen bir ifade ağacı Func<int> türünün bir temsilcisine dönüştürülür.
Herhangi bir dönüş türü ve bağımsız değişken listesi olan bir lambda ifadesinde, bu lambda ifadesi tarafından
temsil edilen çalıştırılabilir kodun hedef türü olan bir temsilci türü vardır.
LambdaExpression türü, bir ifade ağacını çalıştırılabilir koda dönüştürmek için kullanacağınız Compile ve
CompileToMethod üyelerini içerir. Compile yöntemi bir temsilci oluşturur. CompileToMethod yöntemi, ifade ağacının
derlenmiş çıkışını temsil eden Il ile bir MethodBuilder nesnesini günceller. CompileToMethod , .NET Core 'da değil,
yalnızca tam masaüstü çerçevesinde kullanılabilir olduğunu unutmayın.
İsteğe bağlı olarak, oluşturulan temsilci nesnesi için simge hata ayıklama bilgilerini alacak bir DebugInfoGenerator
de sağlayabilirsiniz. Bu, ifade ağacını bir temsilci nesnesine dönüştürmenize ve oluşturulan temsilciyle ilgili tam
hata ayıklama bilgilerine sahip etmenize olanak sağlar.
Aşağıdaki kodu kullanarak bir ifadeyi temsilciye dönüştürürsünüz:

Expression<Func<int>> add = () => 1 + 2;


var func = add.Compile(); // Create Delegate
var answer = func(); // Invoke Delegate
Console.WriteLine(answer);

Temsilci türünün ifade türüne göre olduğuna dikkat edin. Temsilci nesnesini kesin olarak belirlenmiş bir şekilde
kullanmak istiyorsanız, dönüş türünü ve bağımsız değişken listesini bilmeniz gerekir. LambdaExpression.Compile()
yöntemi Delegate türünü döndürür. Herhangi bir derleme zamanı aracının bağımsız değişken listesini veya dönüş
türünü denetlemesini sağlamak için onu doğru temsilci türüne atamalısınız.

Yürütme ve yaşam süreleri


Kodu, LambdaExpression.Compile() çağrıldığında oluşturulan temsilciyi çağırarak yürütün. Bunu, add.Compile() bir
temsilci döndürdüğü yerde görebilirsiniz. Bu temsilciyi çağırmak func() çağırarak kodu yürütür.
Bu temsilci, ifade ağacındaki kodu temsil eder. Bu temsilciye yönelik tanıtıcıyı koruyabilir ve daha sonra
çağırabilirsiniz. Temsil ettiği kodu yürütmek istediğiniz her seferinde ifade ağacını derlemeniz gerekmez. (İfade
ağaçlarının sabit olduğunu unutmayın ve aynı ifade ağacını daha sonra derlemek aynı kodu çalıştıran bir temsilci
oluşturur.)
Gereksiz derleme çağrılarını önleyerek performansı artırmak için daha gelişmiş bir önbelleğe alma mekanizması
oluşturmaya çalışırken dikkatli olunacaktır. İki rastgele ifade ağacının karşılaştırılması, aynı algoritmanın aynı
algoritmayı temsil ettiğini tespit etmek için zaman alıcı olarak da kullanılır. Büyük olasılıkla,
LambdaExpression.Compile() ek çağrılarından kaçınmaktan kaynaklanan işlem zamanının, aynı çalıştırılabilir kodun
sonucu olan iki farklı ifade ağacının sonucunu belirleyen kod yürütme sırasında tüketildiğinden daha fazla
olacağını fark edeceksiniz.

Uyarılar
Bir lambda ifadesini bir temsilciye derlemek ve bu temsilciyi çağırmak, bir ifade ağacı ile gerçekleştirebileceğiniz
en basit işlemlerden biridir. Ancak, bu basit işlemle birlikte, bilmeniz gereken uyarılar da vardır.
Lambda Ifadeleri, ifadede başvurulan herhangi bir yerel değişken üzerinde kapanışları oluşturur. Temsilcinin
parçası olacak tüm değişkenlerin Compile çağırdığınız konumda kullanılabilir olduğunu ve elde edilen temsilciyi
yürüttüğünüzde emin olmanız gerekir.
Genel olarak, derleyici bunun doğru olduğundan emin olur. Ancak, ifadeniz IDisposable uygulayan bir değişkene
eriştiğinde, kodunuzun nesneyi hala ifade ağacı tarafından tutulurken atma olasılığı vardır.
Örneğin, int IDisposable uygulamadığından, bu kod düzgün çalışıyor:

private static Func<int, int> CreateBoundFunc()


{
var constant = 5; // constant is captured by the expression tree
Expression<Func<int, int>> expression = (b) => constant + b;
var rVal = expression.Compile();
return rVal;
}

Temsilci constant yerel değişkenine bir başvuru yakalamıştır. Bu değişkene, daha sonra CreateBoundFunc
tarafından döndürülen işlev çalıştırıldığında her zaman erişilir.
Ancak, IDisposable uygulayan (Bunun yerine contrived) sınıfını göz önünde bulundurun:

public class Resource : IDisposable


{
private bool isDisposed = false;
public int Argument
{
get
{
if (!isDisposed)
return 5;
else throw new ObjectDisposedException("Resource");
}
}

public void Dispose()


{
isDisposed = true;
}
}

Bunu aşağıda gösterildiği gibi bir ifadede kullanırsanız, Resource.Argument özelliği tarafından başvurulan kodu
yürüttüğünüzde ObjectDisposedException alırsınız:

private static Func<int, int> CreateBoundResource()


{
using (var constant = new Resource()) // constant is captured by the expression tree
{
Expression<Func<int, int>> expression = (b) => constant.Argument + b;
var rVal = expression.Compile();
return rVal;
}
}

Bu yöntemden döndürülen temsilci, atılmış olan constant nesnesi üzerinde kapandı. (Bir using bildiriminde
bildirildiği için atılmış.)
Artık bu yöntemden döndürülen temsilciyi yürüttüğünüzde, yürütme noktasında bir ObjectDisposedException
oluşturulur.
Derleme zamanı yapısını temsil eden bir çalışma zamanı hatası olması garip görünür, ancak bu, ifade ağaçları ile
çalışırken girdiğimiz dünya.
Bu sorunun birçok permütasyon vardır. bu nedenle, bunu önlemek için genel rehberlik sunmak zordur.İfadeleri
tanımlarken yerel değişkenlere erişmede dikkatli olun ve genel bir API tarafından döndürülebilecek bir ifade ağacı
oluştururken geçerli nesnedeki duruma ( this göre gösterilen) erişme konusunda dikkatli olun.
Deyiminizdeki kod, diğer derlemelerdeki yöntemlere veya özelliklere başvurabilir. İfade tanımlandığında ve
derlendikten sonra ve elde edilen temsilci çağrıldığında bu derlemeye erişilebilir olması gerekir. Mevcut olmadığı
durumlarda ReferencedAssemblyNotFoundException karşılanır.

Özet
Lambda ifadelerini temsil eden ifade ağaçları, yürütebilmeniz için bir temsilci oluşturmak üzere derlenebilir. Bu, bir
ifade ağacı tarafından temsil edilen kodu yürütmek için bir mekanizma sağlar.
Ifade ağacı, oluşturduğunuz herhangi bir yapı için yürütülecek kodu temsil eder. Kodu derlemek ve yürütmek
istediğiniz ortam, ifadeyi oluşturduğunuz ortamla eşleşiyorsa, her şey beklendiği gibi çalışmaktadır. Bu durum
gerçekleşmezse, hatalar çok öngörülebilir olur ve ifade ağaçları kullanılarak herhangi bir kodun ilk testlerinizde
yakalanacaktır.
Sonraki--Ifadeleri yorumlama
İfade Yorumlama
30.10.2019 • 19 minutes to read • Edit Online

Önceki--Ifadeler yürütülüyor
Şimdi bir ifade ağacınınyapısını incelemek için bazı kodlar yazalım. Bir ifade ağacındaki her düğüm, Expression
türetilen bir sınıfın nesnesi olur.
Bu tasarım, bir ifade ağacındaki tüm düğümleri görece düz ileri özyinelemeli bir işlem olarak ziyaret etmenizi
sağlar. Genel strateji, kök düğümde başlamak ve ne tür bir düğüm olduğunu belirlemektir.
Düğüm türünün alt öğeleri varsa, yinelemeli olarak alt öğeleri ziyaret edin. Her alt düğümde, kök düğümde
kullanılan işlemi yineleyin: türü belirleme ve türün alt öğeleri varsa, alt öğelerin her birini ziyaret edin.

Alt öğe Içermeyen bir Ifadeyi İnceleme


Her düğümü çok basit bir ifade ağacında ziyaret ederek başlayalım. Sabit bir ifade oluşturan ve sonra özelliklerini
incelediği kod aşağıda verilmiştir:

var constant = Expression.Constant(24, typeof(int));

Console.WriteLine($"This is a/an {constant.NodeType} expression type");


Console.WriteLine($"The type of the constant value is {constant.Type}");
Console.WriteLine($"The value of the constant value is {constant.Value}");

Bu işlem şunları yazdırır:

This is an Constant expression type


The type of the constant value is System.Int32
The value of the constant value is 24

Şimdi, bu ifadeyi inceleyecek ve ilgili bazı önemli özellikleri yazacak olan kodu yazalım. Bu kod şu şekildedir:

Basit bir toplama Ifadesi İnceleme


Bu bölüme giriş bölümünde ek örnekle başlayalım.

Expression<Func<int>> sum = () => 1 + 2;

Atamanın sağ tarafı örtük olarak yazıldığından, bu ifade ağacını bildirmek için var kullanmıyorum. Daha
derin anlamak için buradanokuyun.

Kök düğüm bir LambdaExpression . => işlecinin sağ tarafında ilginç kod almak için LambdaExpression alt
öğelerinden birini bulmanız gerekir. Bu bölümdeki tüm ifadelerle bunu yapacağız. Üst düğüm LambdaExpression
dönüş türünü bulmamıza yardımcı olur.
Bu ifadedeki her bir düğümü incelemek için, bir dizi düğümü yinelemeli olarak ziyaret etmemiz gerekir. Basit bir ilk
uygulama aşağıda verilmiştir:
Expression<Func<int, int, int>> addition = (a, b) => a + b;

Console.WriteLine($"This expression is a {addition.NodeType} expression type");


Console.WriteLine($"The name of the lambda is {((addition.Name == null) ? "<null>" : addition.Name)}");
Console.WriteLine($"The return type is {addition.ReturnType.ToString()}");
Console.WriteLine($"The expression has {addition.Parameters.Count} arguments. They are:");
foreach(var argumentExpression in addition.Parameters)
{
Console.WriteLine($"\tParameter Type: {argumentExpression.Type.ToString()}, Name:
{argumentExpression.Name}");
}

var additionBody = (BinaryExpression)addition.Body;


Console.WriteLine($"The body is a {additionBody.NodeType} expression");
Console.WriteLine($"The left side is a {additionBody.Left.NodeType} expression");
var left = (ParameterExpression)additionBody.Left;
Console.WriteLine($"\tParameter Type: {left.Type.ToString()}, Name: {left.Name}");
Console.WriteLine($"The right side is a {additionBody.Right.NodeType} expression");
var right= (ParameterExpression)additionBody.Right;
Console.WriteLine($"\tParameter Type: {right.Type.ToString()}, Name: {right.Name}");

Bu örnek aşağıdaki çıktıyı yazdırır:

This expression is a/an Lambda expression type


The name of the lambda is <null>
The return type is System.Int32
The expression has 2 arguments. They are:
Parameter Type: System.Int32, Name: a
Parameter Type: System.Int32, Name: b
The body is a/an Add expression
The left side is a Parameter expression
Parameter Type: System.Int32, Name: a
The right side is a Parameter expression
Parameter Type: System.Int32, Name: b

Yukarıdaki kod örneğinde çok fazla yineleme olduğunu fark edeceksiniz. Bunu temizleyelim ve daha genel amaçlı
bir ifade düğümü ziyaretçisi oluşturalım. Bu, özyinelemeli bir algoritma yazmamızı gerektireceğiz. Herhangi bir
düğüm, alt öğelerine sahip olabilecek bir türde olabilir. Alt öğeleri olan herhangi bir düğüm, bu alt öğeleri ziyaret
etmemizi ve bu düğümün ne olduğunu belirlemenizi ister. Ek işlemleri ziyaret eden özyineleme kullanan
temizlenmiş bir sürüm aşağıda verilmiştir:

// Base Visitor class:


public abstract class Visitor
{
private readonly Expression node;

protected Visitor(Expression node)


{
this.node = node;
}

public abstract void Visit(string prefix);

public ExpressionType NodeType => this.node.NodeType;


public static Visitor CreateFromExpression(Expression node)
{
switch(node.NodeType)
{
case ExpressionType.Constant:
return new ConstantVisitor((ConstantExpression)node);
case ExpressionType.Lambda:
return new LambdaVisitor((LambdaExpression)node);
case ExpressionType.Parameter:
return new ParameterVisitor((ParameterExpression)node);
case ExpressionType.Add:
return new BinaryVisitor((BinaryExpression)node);
default:
Console.Error.WriteLine($"Node not processed yet: {node.NodeType}");
return default(Visitor);
}
}
}

// Lambda Visitor
public class LambdaVisitor : Visitor
{
private readonly LambdaExpression node;
public LambdaVisitor(LambdaExpression node) : base(node)
{
this.node = node;
}

public override void Visit(string prefix)


{
Console.WriteLine($"{prefix}This expression is a {NodeType} expression type");
Console.WriteLine($"{prefix}The name of the lambda is {((node.Name == null) ? "<null>" :
node.Name)}");
Console.WriteLine($"{prefix}The return type is {node.ReturnType.ToString()}");
Console.WriteLine($"{prefix}The expression has {node.Parameters.Count} argument(s). They are:");
// Visit each parameter:
foreach (var argumentExpression in node.Parameters)
{
var argumentVisitor = Visitor.CreateFromExpression(argumentExpression);
argumentVisitor.Visit(prefix + "\t");
}
Console.WriteLine($"{prefix}The expression body is:");
// Visit the body:
var bodyVisitor = Visitor.CreateFromExpression(node.Body);
bodyVisitor.Visit(prefix + "\t");
}
}

// Binary Expression Visitor:


public class BinaryVisitor : Visitor
{
private readonly BinaryExpression node;
public BinaryVisitor(BinaryExpression node) : base(node)
{
this.node = node;
}

public override void Visit(string prefix)


{
Console.WriteLine($"{prefix}This binary expression is a {NodeType} expression");
var left = Visitor.CreateFromExpression(node.Left);
Console.WriteLine($"{prefix}The Left argument is:");
left.Visit(prefix + "\t");
var right = Visitor.CreateFromExpression(node.Right);
Console.WriteLine($"{prefix}The Right argument is:");
right.Visit(prefix + "\t");
}
}

// Parameter visitor:
public class ParameterVisitor : Visitor
{
private readonly ParameterExpression node;
public ParameterVisitor(ParameterExpression node) : base(node)
{
this.node = node;
}
public override void Visit(string prefix)
{
Console.WriteLine($"{prefix}This is an {NodeType} expression type");
Console.WriteLine($"{prefix}Type: {node.Type.ToString()}, Name: {node.Name}, ByRef: {node.IsByRef}");
}
}

// Constant visitor:
public class ConstantVisitor : Visitor
{
private readonly ConstantExpression node;
public ConstantVisitor(ConstantExpression node) : base(node)
{
this.node = node;
}

public override void Visit(string prefix)


{
Console.WriteLine($"{prefix}This is an {NodeType} expression type");
Console.WriteLine($"{prefix}The type of the constant value is {node.Type}");
Console.WriteLine($"{prefix}The value of the constant value is {node.Value}");
}
}

Bu algoritma, herhangi bir rastgele LambdaExpression ziyaret edebildikleri bir algoritmanın temelini oluşturur.
Oluşturduğum kodun yalnızca, karşılaşabileceği ifade ağacı düğümlerinin çok küçük bir örneğine bakabilmesini
sağlayan çok sayıda delik vardır. Bununla birlikte, ne kadar çok şey ürettiğini de öğrenirsiniz. (
Visitor.CreateFromExpression yönteminde varsayılan durum, yeni bir düğüm türüyle karşılaşıldığında hata
konsoluna bir ileti yazdırır. Bu şekilde, yeni bir ifade türü eklemeyi bilirsiniz.)
Yukarıda gösterilen ekleme ifadesinde bu ziyaretçisini çalıştırdığınızda aşağıdaki çıktıyı alırsınız:

This expression is a/an Lambda expression type


The name of the lambda is <null>
The return type is System.Int32
The expression has 2 argument(s). They are:
This is an Parameter expression type
Type: System.Int32, Name: a, ByRef: False
This is an Parameter expression type
Type: System.Int32, Name: b, ByRef: False
The expression body is:
This binary expression is a Add expression
The Left argument is:
This is an Parameter expression type
Type: System.Int32, Name: a, ByRef: False
The Right argument is:
This is an Parameter expression type
Type: System.Int32, Name: b, ByRef: False

Artık daha genel bir ziyaretçi uygulamasına sahip olduğunuza göre, daha birçok farklı tür ifadeyi ziyaret edebilir ve
işleyebilirsiniz.

Birçok düzey içeren bir toplama Ifadesi inceleniyor


Daha karmaşık bir örnek deneyelim, ancak yine de düğüm türlerini yalnızca ekleme ile sınırlandıralım:

Expression<Func<int>> sum = () => 1 + 2 + 3 + 4;

Bunu ziyaretçi algoritmasında çalıştırmadan önce, çıktının ne kadar olabileceğini öğrenmek için düşündüyü
deneyin. + işlecinin bir ikili işleçolduğunu unutmayın: sol ve sağ işlenenleri temsil eden iki alt öğesi olmalıdır.
Doğru olabilecek bir ağaç oluşturmak için birkaç olası yol vardır:

Expression<Func<int>> sum1 = () => 1 + (2 + (3 + 4));


Expression<Func<int>> sum2 = () => ((1 + 2) + 3) + 4;

Expression<Func<int>> sum3 = () => (1 + 2) + (3 + 4);


Expression<Func<int>> sum4 = () => 1 + ((2 + 3) + 4);
Expression<Func<int>> sum5 = () => (1 + (2 + 3)) + 4;

En fazla taahhüdün vurgulanmasını sağlamak için ayrımı iki olası yanıt halinde görebilirsiniz. İlki, doğru
ilişkilendirilebilir ifadeleri temsil eder. İkincisi sol ilişkilendirilebilir ifadeleri temsil eder. Bu iki biçimin her ikisi de,
biçimin rastgele herhangi bir dizi ek ifadeye ölçeklenmesinin avantajına sahiptir.
Bu ifadeyi ziyaretçi aracılığıyla çalıştırırsanız, bu çıktıyı görürsünüz ve basit toplama ifadesinin
ilişkilendirilebilirolduğunu doğrulayın.
Bu örneği çalıştırmak ve tam ifade ağacına bakmak için kaynak ifade ağacında bir değişiklik yapmam gerekiyordu.
İfade ağacı tüm sabitleri içerdiğinde, ortaya çıkan ağaç yalnızca 10 sabit değerini içerir. Derleyici tüm ekleme
işlemini gerçekleştirir ve ifadeyi en basit biçimine düşürür. Özgün ağacı görmek için ifadede yalnızca bir değişken
eklemek yeterlidir:

Expression<Func<int, int>> sum = (a) => 1 + a + 3 + 4;

Bu Sum için bir ziyaretçi oluşturun ve ziyaretçi çalıştırın bu çıktıyı görürsünüz:

This expression is a/an Lambda expression type


The name of the lambda is <null>
The return type is System.Int32
The expression has 1 argument(s). They are:
This is an Parameter expression type
Type: System.Int32, Name: a, ByRef: False
The expression body is:
This binary expression is a Add expression
The Left argument is:
This binary expression is a Add expression
The Left argument is:
This binary expression is a Add expression
The Left argument is:
This is an Constant expression type
The type of the constant value is System.Int32
The value of the constant value is 1
The Right argument is:
This is an Parameter expression type
Type: System.Int32, Name: a, ByRef: False
The Right argument is:
This is an Constant expression type
The type of the constant value is System.Int32
The value of the constant value is 3
The Right argument is:
This is an Constant expression type
The type of the constant value is System.Int32
The value of the constant value is 4

Diğer örneklerden herhangi birini ziyaretçi kodu aracılığıyla da çalıştırabilir ve hangi ağacın temsil ettiğini
görebilirsiniz. Yukarıdaki sum3 ifadeye bir örnektir (derleyicinin sabiti bilgi işlem yapmasını engellemek için ek bir
parametre ile):

Expression<Func<int, int, int>> sum3 = (a, b) => (1 + a) + (3 + b);


Ziyaretçinin çıkışı şöyledir:

This expression is a/an Lambda expression type


The name of the lambda is <null>
The return type is System.Int32
The expression has 2 argument(s). They are:
This is an Parameter expression type
Type: System.Int32, Name: a, ByRef: False
This is an Parameter expression type
Type: System.Int32, Name: b, ByRef: False
The expression body is:
This binary expression is a Add expression
The Left argument is:
This binary expression is a Add expression
The Left argument is:
This is an Constant expression type
The type of the constant value is System.Int32
The value of the constant value is 1
The Right argument is:
This is an Parameter expression type
Type: System.Int32, Name: a, ByRef: False
The Right argument is:
This binary expression is a Add expression
The Left argument is:
This is an Constant expression type
The type of the constant value is System.Int32
The value of the constant value is 3
The Right argument is:
This is an Parameter expression type
Type: System.Int32, Name: b, ByRef: False

Ayraçların çıktının parçası olmadığına dikkat edin. İfade ağacında giriş ifadesindeki ayraçları temsil eden hiçbir
düğüm yok. İfade ağacının yapısı, önceliği iletmek için gereken tüm bilgileri içerir.

Bu örnekten genişletme
Örnek yalnızca en ilkel ifade ağaçları ile ilgilidir. Bu bölümde gördüğünüz kod yalnızca sabit tamsayıları ve ikili +
işlecini işler. Son bir örnek olarak, ziyaretçisini daha karmaşık bir ifadeyi işleyecek şekilde güncelleştirelim. Bunun
için bu işi yapalim:

Expression<Func<int, int>> factorial = (n) =>


n == 0 ?
1 :
Enumerable.Range(1, n).Aggregate((product, factor) => product * factor);

Bu kod matematik çarpınımı işlevi için olası bir uygulamayı temsil eder. Bu kodu yazdığım şekilde, deyimlere
lambda ifadeleri atayarak ifade ağaçları oluşturmanın iki sınırlaması vurgulanmıştır. İlk olarak, ifade lambdaları
kullanılamaz. Bu, içindeki C#döngüleri, blokları, if/else deyimlerini ve diğer denetim yapılarını kullanmıyorum
anlamına gelir. İfadeleri kullanma sınırlıyorum. İkinci olarak aynı ifadeyi özyinelemeli olarak çağıramıyorum. Ben
zaten bir temsilciyiysem, ancak ifade ağaç biçiminde çağıramıyorum. İfade ağaçları oluşturma bölümünde bu
sınırlamaları aşmaya yönelik teknikler öğreneceksiniz.
Bu ifadede, tüm bu türlerin düğümleri ile karşılaşırsınız:
1. Eşittir (ikili ifade)
2. Çarp (ikili ifade)
3. Koşullu (? ifadesini
4. Yöntem çağrısı Ifadesi ( Range() ve Aggregate() çağırma)
Ziyaretçi algoritmasını değiştirmek için bir yol, yürütmeyi sürdürmek ve default yan tümcesine her ulaşışınızda
düğüm türünü yazmaktır. Birkaç yinelemeden sonra potansiyel düğümlerin her birini gördünüz. Ardından,
ihtiyacınız olan her şey vardır. Sonuç şuna benzer olacaktır:

public static Visitor CreateFromExpression(Expression node)


{
switch(node.NodeType)
{
case ExpressionType.Constant:
return new ConstantVisitor((ConstantExpression)node);
case ExpressionType.Lambda:
return new LambdaVisitor((LambdaExpression)node);
case ExpressionType.Parameter:
return new ParameterVisitor((ParameterExpression)node);
case ExpressionType.Add:
case ExpressionType.Equal:
case ExpressionType.Multiply:
return new BinaryVisitor((BinaryExpression)node);
case ExpressionType.Conditional:
return new ConditionalVisitor((ConditionalExpression)node);
case ExpressionType.Call:
return new MethodCallVisitor((MethodCallExpression)node);
default:
Console.Error.WriteLine($"Node not processed yet: {node.NodeType}");
return default(Visitor);
}
}

ConditionalVisitor ve MethodCallVisitor bu iki düğümü işler:


public class ConditionalVisitor : Visitor
{
private readonly ConditionalExpression node;
public ConditionalVisitor(ConditionalExpression node) : base(node)
{
this.node = node;
}

public override void Visit(string prefix)


{
Console.WriteLine($"{prefix}This expression is a {NodeType} expression");
var testVisitor = Visitor.CreateFromExpression(node.Test);
Console.WriteLine($"{prefix}The Test for this expression is:");
testVisitor.Visit(prefix + "\t");
var trueVisitor = Visitor.CreateFromExpression(node.IfTrue);
Console.WriteLine($"{prefix}The True clause for this expression is:");
trueVisitor.Visit(prefix + "\t");
var falseVisitor = Visitor.CreateFromExpression(node.IfFalse);
Console.WriteLine($"{prefix}The False clause for this expression is:");
falseVisitor.Visit(prefix + "\t");
}
}

public class MethodCallVisitor : Visitor


{
private readonly MethodCallExpression node;
public MethodCallVisitor(MethodCallExpression node) : base(node)
{
this.node = node;
}

public override void Visit(string prefix)


{
Console.WriteLine($"{prefix}This expression is a {NodeType} expression");
if (node.Object == null)
Console.WriteLine($"{prefix}This is a static method call");
else
{
Console.WriteLine($"{prefix}The receiver (this) is:");
var receiverVisitor = Visitor.CreateFromExpression(node.Object);
receiverVisitor.Visit(prefix + "\t");
}

var methodInfo = node.Method;


Console.WriteLine($"{prefix}The method name is {methodInfo.DeclaringType}.{methodInfo.Name}");
// There is more here, like generic arguments, and so on.
Console.WriteLine($"{prefix}The Arguments are:");
foreach(var arg in node.Arguments)
{
var argVisitor = Visitor.CreateFromExpression(arg);
argVisitor.Visit(prefix + "\t");
}
}
}

Ve ifade ağacı için çıkış şu şekilde olur:


This expression is a/an Lambda expression type
The name of the lambda is <null>
The return type is System.Int32
The expression has 1 argument(s). They are:
This is an Parameter expression type
Type: System.Int32, Name: n, ByRef: False
The expression body is:
This expression is a Conditional expression
The Test for this expression is:
This binary expression is a Equal expression
The Left argument is:
This is an Parameter expression type
Type: System.Int32, Name: n, ByRef: False
The Right argument is:
This is an Constant expression type
The type of the constant value is System.Int32
The value of the constant value is 0
The True clause for this expression is:
This is an Constant expression type
The type of the constant value is System.Int32
The value of the constant value is 1
The False clause for this expression is:
This expression is a Call expression
This is a static method call
The method name is System.Linq.Enumerable.Aggregate
The Arguments are:
This expression is a Call expression
This is a static method call
The method name is System.Linq.Enumerable.Range
The Arguments are:
This is an Constant expression type
The type of the constant value is System.Int32
The value of the constant value is 1
This is an Parameter expression type
Type: System.Int32, Name: n, ByRef: False
This expression is a Lambda expression type
The name of the lambda is <null>
The return type is System.Int32
The expression has 2 arguments. They are:
This is an Parameter expression type
Type: System.Int32, Name: product, ByRef: False
This is an Parameter expression type
Type: System.Int32, Name: factor, ByRef: False
The expression body is:
This binary expression is a Multiply expression
The Left argument is:
This is an Parameter expression type
Type: System.Int32, Name: product, ByRef: False
The Right argument is:
This is an Parameter expression type
Type: System.Int32, Name: factor, ByRef: False

Örnek kitaplığı genişletme


Bu bölümdeki örneklerde, bir ifade ağacındaki düğümleri ziyaret etmek ve incelemek için temel teknikler
gösterilmektedir. Bir ifade ağacındaki düğümleri ziyaret ederek ve bunlara erişen temel görevlere odaklanmak için
ihtiyacınız olabilecek çok sayıda eylemi glossed.
Birincisi, ziyaretçiler yalnızca tamsayı olan sabitleri işler. Sabit değerler başka herhangi bir sayısal tür olabilir ve dil,
C# bu türler arasındaki dönüşümleri ve yükseltmeleri destekler. Bu kodun daha sağlam bir sürümü tüm bu
özellikleri yansıtır.
Son örnek bile olası düğüm türlerinin bir alt kümesini tanır. Yine de, başarısız olmasına neden olacak çok sayıda
ifade akışı yapabilirsiniz. Tam bir uygulama .NET Standard ExpressionVisitor adı altında bulunur ve tüm olası
düğüm türlerini işleyebilir.
Son olarak, bu makalede kullandığım kitaplık tanıtım ve öğrenme için oluşturulmuştur. En iyi duruma
getirilmemiştir. Bu yapıyı, yapıları çok açık hale getirmek ve düğümleri ziyaret etmek ve ne olduğunu çözümlemek
için kullanılan teknikleri vurgulamak için yazdım. Bir üretim uygulamasının performanstan daha fazla dikkat edin.
Bu sınırlamalara rağmen, ifade ağaçlarını okuyan ve anlayan algoritmalar yazmak için size iyi bir yol olmalıdır.
Next--Ifadeleri oluşturma
Ifade ağaçları oluşturma
30.10.2019 • 8 minutes to read • Edit Online

Önceki--Ifadeleri yorumlama
Şimdiye kadar gördüğünüz tüm ifade ağaçları C# derleyici tarafından oluşturulmuştur. Tek yapmanız gereken,
Expression<Func<T>> veya benzer bir tür olarak yazılmış bir değişkene atanan bir lambda ifadesi oluşturmaktır.
Bu, bir ifade ağacı oluşturmanın tek yolu değildir. Birçok senaryoda, çalışma zamanında bellekte bir ifade
oluşturmanız gerektiğini fark edebilirsiniz.
Ifade ağaçları oluşturma, bu ifade ağaçlarının sabit olması olgusuna göre karmaşıktır. Sabit olması, ağacın köke
kadar olan yaprakları oluşturmanız gerektiği anlamına gelir. İfade ağaçları oluşturmak için kullanacağınız API 'Ler
bu olguyu yansıtır: bir düğüm oluşturmak için kullanacağınız Yöntemler tüm alt öğelerini bağımsız değişken
olarak alır. Aşağıda, teknikleri göstermek için birkaç örnek yürülim.

Düğüm oluşturma
Yine de nispeten daha başlayalım. Bu bölümlerin tamamında üzerinde çalıştık ekleme ifadesini kullanacağız:

Expression<Func<int>> sum = () => 1 + 2;

Bu ifade ağacını oluşturmak için yaprak düğümleri oluşturmanız gerekir. Yaprak düğümler sabittir, bu sayede
düğümleri oluşturmak için Expression.Constant yöntemini kullanabilirsiniz:

var one = Expression.Constant(1, typeof(int));


var two = Expression.Constant(2, typeof(int));

Daha sonra, toplama ifadesi oluşturacaksınız:

var addition = Expression.Add(one, two);

Toplama ifadesini aldıktan sonra lambda ifadesini oluşturabilirsiniz:

var lambda = Expression.Lambda(addition);

Bağımsız değişken içermediğinden bu çok basit bir lambda ifadesidir. Bu bölümde daha sonra, bağımsız
değişkenlerin parametrelere nasıl eşlendiğini ve daha karmaşık ifadeler nasıl oluşturulacağını öğreneceksiniz.
Bu kadar basit olan ifadeler için tüm çağrıları tek bir deyim halinde birleştirebilirsiniz:

var lambda = Expression.Lambda(


Expression.Add(
Expression.Constant(1, typeof(int)),
Expression.Constant(2, typeof(int))
)
);

Ağaç oluşturma
Bu, bellekte bir ifade ağacı oluşturmanın temel larıdır. Daha karmaşık ağaçlar genellikle daha fazla düğüm türü ve
ağaçta daha fazla düğüm anlamına gelir. Daha sonra bir örnek daha çalıştıralım ve genellikle ifade ağaçları
oluştururken oluşturacağınız iki düğüm türü gösterelim: bağımsız değişken düğümleri ve yöntem çağrı
düğümleri.
Bu ifadeyi oluşturmak için bir ifade ağacı oluşturalım:

Expression<Func<double, double, double>> distanceCalc =


(x, y) => Math.Sqrt(x * x + y * y);

x ve y için parametre ifadeleri oluşturarak başlayacaksınız:

var xParameter = Expression.Parameter(typeof(double), "x");


var yParameter = Expression.Parameter(typeof(double), "y");

Çarpma ve ekleme ifadelerinin oluşturulması, zaten gördüğünüz kalıbı izler:

var xSquared = Expression.Multiply(xParameter, xParameter);


var ySquared = Expression.Multiply(yParameter, yParameter);
var sum = Expression.Add(xSquared, ySquared);

Sonra, Math.Sqrt çağrısı için bir yöntem çağrısı ifadesi oluşturmanız gerekir.

var sqrtMethod = typeof(Math).GetMethod("Sqrt", new[] { typeof(double) });


var distance = Expression.Call(sqrtMethod, sum);

Son olarak, yöntem çağrısını bir lambda ifadesine yerleştirir ve lambda ifadesinin bağımsız değişkenlerini
tanımladığınızdan emin olun:

var distanceLambda = Expression.Lambda(


distance,
xParameter,
yParameter);

Bu daha karmaşık örnekte, genellikle ifade ağaçları oluşturmanız için gereken birkaç teknik görürsünüz.
İlk olarak, parametreleri veya yerel değişkenleri kullanmadan önce bunları temsil eden nesneleri oluşturmanız
gerekir. Bu nesneleri oluşturduktan sonra, bunları, ihtiyacınız olan her yerde ifade ağacınızdaki bir şekilde
kullanabilirsiniz.
İkinci olarak, bir MethodInfo nesnesi oluşturmak için yansıma API 'lerinin bir alt kümesini kullanmanız gerekir;
böylece bu yönteme erişmek için bir ifade ağacı oluşturabilirsiniz. Kendinizi .NET Core platformunda bulunan
yansıma API 'Lerinin alt kümesiyle sınırlandırmalısınız. Bu teknikler yine de diğer ifade ağaçlarına genişletilir.

Derinlemesine kod derleme


Bu API 'Leri kullanarak neleri oluşturabileceğiniz sınırlı değilsiniz. Ancak, derlemek istediğiniz daha karmaşık
ifade ağacı, kodun yönetilmesi ve okunması daha zordur.
Bu kodun eşdeğeri olan bir ifade ağacı oluşturalım:
Func<int, int> factorialFunc = (n) =>
{
var res = 1;
while (n > 1)
{
res = res * n;
n--;
}
return res;
};

Yukarıda, ifade ağacını oluşturamadım, ancak yalnızca temsilciyi temsil ediyorum. Expression sınıfını kullanarak,
ifade lambdaları derleyebilirsiniz. Aynı işlevselliği oluşturmak için gereken kod aşağıda verilmiştir. while
döngüsünü derlemek için bir API olmadığından, koşullu bir test içeren bir döngü ve döngünün dışına bölmek için
bir etiket hedefi oluşturmanız gerekir.

var nArgument = Expression.Parameter(typeof(int), "n");


var result = Expression.Variable(typeof(int), "result");

// Creating a label that represents the return value


LabelTarget label = Expression.Label(typeof(int));

var initializeResult = Expression.Assign(result, Expression.Constant(1));

// This is the inner block that performs the multiplication,


// and decrements the value of 'n'
var block = Expression.Block(
Expression.Assign(result,
Expression.Multiply(result, nArgument)),
Expression.PostDecrementAssign(nArgument)
);

// Creating a method body.


BlockExpression body = Expression.Block(
new[] { result },
initializeResult,
Expression.Loop(
Expression.IfThenElse(
Expression.GreaterThan(nArgument, Expression.Constant(1)),
block,
Expression.Break(label, result)
),
label
)
);

Çarpınımı işlevi için ifade ağacını oluşturmaya yönelik kod çok daha uzun, daha karmaşıktır ve Etiketler ve break
deyimleri ve günlük kodlama görevlerimizde kaçınmak istiyoruz.
Bu bölüm için, ziyaretçi kodunu bu ifade ağacındaki her düğümü ziyaret etmek ve bu örnekte oluşturulan
düğümlerle ilgili bilgileri yazmak için güncelleştirdim. Örnek kodu DotNet/docs GitHub deposunda
görüntüleyebilir veya indirebilirsiniz . Örnekleri oluşturup çalıştırarak kendiniz için denemeler yapın. İndirme
yönergeleri için bkz. örnekler ve öğreticiler.

API 'Leri İnceleme


İfade ağacı API 'Leri, .NET Core 'ta gezinmek daha zordur, ancak bu kadar iyidir.Amaçları, karmaşık bir yetersiz
alma: çalışma zamanında kod üreten kod yazma. Bu C# diller, dilde kullanılabilen tüm denetim yapılarını
destekleme ve API 'lerin yüzey alanını makul şekilde küçük tutarak bir denge sağlamak için karmaşıktır. Bu
Bakiye, birçok denetim yapısının C# yapılarına göre değil, ancak derleyicinin bu üst düzey yapıların oluşturduğu
temel mantığı temsil eden yapılar tarafından temsil edildiği anlamına gelir.
Ayrıca, şu anda Expression sınıf yöntemleri kullanılarak C# doğrudan derlenemez ifadeler vardır. Genel olarak,
bunlar 5 ve C# C# 6 ' da eklenen en yeni işleçler ve ifadeler olacaktır. (Örneğin, async ifadeleri derlenemez ve
yeni ?. işleci doğrudan oluşturulamaz.)
İleri--Ifadeleri çevirme
Ifade ağaçları çevriliyor
30.10.2019 • 9 minutes to read • Edit Online

Previous--Ifadeleri derleme
Bu son bölümde, bu ifade ağacının değiştirilmiş bir kopyasını oluştururken bir ifade ağacındaki her bir düğümü
ziyaret etmeyi öğreneceksiniz. Bunlar, iki önemli senaryoda kullanacağınız tekniklerdir. Birincisi, başka bir ortama
çevrilebilmesi için bir ifade ağacı tarafından ifade edilen algoritmaları anlamaktır. İkincisi, oluşturulan algoritmayı
değiştirmek istediğinizde olur. Bu, günlük kaydı eklemek, Yöntem çağrılarını ele almak ve izlemek ya da başka
amaçlar olabilir.

Çeviri ziyaret ediyor


Bir ifade ağacını çevirmek için oluşturduğunuz kod, bir ağaçtaki tüm düğümleri ziyaret etmek için zaten
gördüğünüze ait bir uzantıdır. Bir ifade ağacını çevirirken, tüm düğümleri ziyaret edersiniz ve ziyaret edilirken yeni
ağacı derleyebilirsiniz. Yeni ağaç orijinal düğümlere veya ağaca yerleştirdiğiniz yeni düğümlere başvuru içerebilir.
Bu işlemi, bir ifade ağacını ziyaret ederek ve değişiklik düğümleri içeren yeni bir ağaç oluşturarak görelim. Bu
örnekte, her sabiti on kat daha büyük olan bir sabit ile değiştirin. Aksi takdirde, ifade ağacını bozulmadan
bırakıyoruz. Sabitin değerini okumak ve yeni bir sabitle değiştirmek yerine, sabit düğümü çarpma işlemini
gerçekleştiren yeni bir düğümle değiştirerek bu değişikliği yapacağız.
Burada, sabit bir düğüm bulduktan sonra, alt öğeleri orijinal sabit olan ve sabit 10 yeni bir çarpma düğümü
oluşturursunuz:

private static Expression ReplaceNodes(Expression original)


{
if (original.NodeType == ExpressionType.Constant)
{
return Expression.Multiply(original, Expression.Constant(10));
}
else if (original.NodeType == ExpressionType.Add)
{
var binaryExpression = (BinaryExpression)original;
return Expression.Add(
ReplaceNodes(binaryExpression.Left),
ReplaceNodes(binaryExpression.Right));
}
return original;
}

Özgün düğümü yenisiyle değiştirerek, değişikliklerinizi içeren yeni bir ağaç oluşturulur. Değiştirilmiş ağacı derleyip
yürüterek bunu doğrulayabiliriz.

var one = Expression.Constant(1, typeof(int));


var two = Expression.Constant(2, typeof(int));
var addition = Expression.Add(one, two);
var sum = ReplaceNodes(addition);
var executableFunc = Expression.Lambda(sum);

var func = (Func<int>)executableFunc.Compile();


var answer = func();
Console.WriteLine(answer);
Yeni bir ağaç oluşturmak, var olan ağaçtaki düğümleri ziyaret etme ve yeni düğümler oluşturma ve bunları ağaca
ekleme birleşimidir.
Bu örnek, ifade ağaçlarının sabit olmasının önemini gösterir. Yukarıda oluşturulan yeni ağacın yeni oluşturulan
düğümlerin bir karışımını ve var olan ağaçtaki düğümleri içerdiğini unutmayın. Bu, var olan ağaçtaki düğümler
değiştirilemediği için güvenlidir. Bu, önemli ölçüde bellek verimliliklerini sağlayabilir. Aynı düğümler bir ağacın
tamamında veya birden çok ifade ağacında kullanılabilir. Düğümler değiştirilemediğinden, her gerektiğinde aynı
düğüm yeniden kullanılabilir.

Çapraz geçiş ve yürütme


Ayrıca, ek düğüm ağacını gösteren ve sonucu hesaplayan ikinci bir ziyaretçi oluşturarak bunu doğrulayalım.
Şimdiye kadar gördüğünüz ziyaretçi üzerinde birkaç değişiklik yaparak bunu yapabilirsiniz. Bu yeni sürümde
ziyaretçi, toplama işleminin kısmi toplamını bu noktaya kadar döndürür. Sabit bir ifade için yalnızca sabit ifadenin
değeridir. Bir toplama ifadesi için, bu ağaçlar alındıktan sonra, sonuç sol ve sağ işlenenlerinin toplamıdır.

var one = Expression.Constant(1, typeof(int));


var two = Expression.Constant(2, typeof(int));
var three= Expression.Constant(3, typeof(int));
var four = Expression.Constant(4, typeof(int));
var addition = Expression.Add(one, two);
var add2 = Expression.Add(three, four);
var sum = Expression.Add(addition, add2);

// Declare the delegate, so we can call it


// from itself recursively:
Func<Expression, int> aggregate = null;
// Aggregate, return constants, or the sum of the left and right operand.
// Major simplification: Assume every binary expression is an addition.
aggregate = (exp) =>
exp.NodeType == ExpressionType.Constant ?
(int)((ConstantExpression)exp).Value :
aggregate(((BinaryExpression)exp).Left) + aggregate(((BinaryExpression)exp).Right);

var theSum = aggregate(sum);


Console.WriteLine(theSum);

Burada bir kod biraz daha vardır ancak kavramlar çok ulaşılabilir. Bu kod, alt öğeleri derinlemesine bir ilk aramada
ziyaret ediyor. Sabit bir düğümle karşılaştığında, ziyaretçi sabit değeri döndürür. Ziyaretçi her iki öğeyi de ziyaret
ettikten sonra bu alt ağaç için hesaplanan toplamı hesaplamıştır. Toplama düğümü artık toplamını hesaplaedebilir.
İfade ağacındaki tüm düğümler ziyaret edildikten sonra toplam hesaplanır. Örneği hata ayıklayıcıda çalıştırıp
yürütmeyi izleyerek yürütmeyi izleyebilirsiniz.
Düğümlerin nasıl çözümlenmekte olduğunu ve ağacın çapraz geçiş yaparak nasıl hesaplantığını izlemeyi daha
kolay hale getirir. Toplam yönteminin, tam olarak bir izleme bilgisi içeren güncelleştirilmiş bir sürümü aşağıda
verilmiştir:
private static int Aggregate(Expression exp)
{
if (exp.NodeType == ExpressionType.Constant)
{
var constantExp = (ConstantExpression)exp;
Console.Error.WriteLine($"Found Constant: {constantExp.Value}");
return (int)constantExp.Value;
}
else if (exp.NodeType == ExpressionType.Add)
{
var addExp = (BinaryExpression)exp;
Console.Error.WriteLine("Found Addition Expression");
Console.Error.WriteLine("Computing Left node");
var leftOperand = Aggregate(addExp.Left);
Console.Error.WriteLine($"Left is: {leftOperand}");
Console.Error.WriteLine("Computing Right node");
var rightOperand = Aggregate(addExp.Right);
Console.Error.WriteLine($"Right is: {rightOperand}");
var sum = leftOperand + rightOperand;
Console.Error.WriteLine($"Computed sum: {sum}");
return sum;
}
else throw new NotSupportedException("Haven't written this yet");
}

Aynı ifadede çalıştırmak aşağıdaki çıktıyı verir:

10
Found Addition Expression
Computing Left node
Found Addition Expression
Computing Left node
Found Constant: 1
Left is: 1
Computing Right node
Found Constant: 2
Right is: 2
Computed sum: 3
Left is: 3
Computing Right node
Found Addition Expression
Computing Left node
Found Constant: 3
Left is: 3
Computing Right node
Found Constant: 4
Right is: 4
Computed sum: 7
Right is: 7
Computed sum: 10
10

Çıktıyı izleyin ve yukarıdaki kodda izleyin. Kodun her bir düğümü nasıl ziyaret edebilmeli ve toplam ağaçta
gezinilerek toplamı nasıl hesapladığını ve toplamı bulabileceksiniz.
Şimdi, sum1 tarafından verilen ifadeyle farklı bir çalıştırmaya bakalım:

Expression<Func<int> sum1 = () => 1 + (2 + (3 + 4));

Bu ifadeyi inceleyerek çıkış şu şekildedir:


Found Addition Expression
Computing Left node
Found Constant: 1
Left is: 1
Computing Right node
Found Addition Expression
Computing Left node
Found Constant: 2
Left is: 2
Computing Right node
Found Addition Expression
Computing Left node
Found Constant: 3
Left is: 3
Computing Right node
Found Constant: 4
Right is: 4
Computed sum: 7
Right is: 7
Computed sum: 9
Right is: 9
Computed sum: 10
10

Nihai yanıt aynı olsa da, ağaç geçişi tamamen farklıdır. Ağaç, ilk olarak oluşan farklı işlemlerle oluşturulduğundan,
bu düğümler farklı bir sıraya göre yapılır.

Daha fazla bilgi


Bu örnek, bir ifade ağacı tarafından temsil edilen algoritmaları çapraz olarak geçirmek ve yorumlamak için
derleyerek kodun küçük bir alt kümesini gösterir. İfade ağaçlarını başka bir dile çeviren genel amaçlı bir kitaplık
oluşturmak için gereken tüm çalışmalar hakkında ayrıntılı bir açıklama için lütfen Bu seriyi Matt Warren ile okuyun.
Bir ifade ağacında bulabileceğiniz herhangi bir kodun nasıl çevrilebileceğini gösteren harika bir ayrıntıya gider.
Artık ifade ağaçlarının gerçek gücünü gördük. Bir kod kümesini inceleyebilir, bu koda istediğiniz değişiklikleri
yapabilir ve değiştirilen sürümü yürütebilirsiniz. İfade ağaçları sabit olduğundan, varolan ağaçların bileşenlerini
kullanarak yeni ağaçlar oluşturabilirsiniz. Bu, değiştirilen ifade ağaçları oluşturmak için gereken bellek miktarını en
aza indirir.
İleri--toplam
İfade ağaçları Özeti
30.10.2019 • 2 minutes to read • Edit Online

Önceki--Ifadeleri çevirme
Bu seride, kod verileri olarak yorumlayan ve bu koda göre yeni işlevsellik oluşturan dinamik programlar
oluşturmak için ifade ağaçlarını nasıl kullanabileceğinizi gördünüz.
Bir algoritmanın amacını anlamak için ifade ağaçlarını inceleyebilirsiniz. Bu kodu yalnızca inceleyebilirsiniz. Özgün
kodun değiştirilmiş sürümlerini temsil eden yeni ifade ağaçları oluşturabilirsiniz.
Ayrıca, bir algoritmaya bakmak ve bu algoritmayı başka bir dile veya ortama çevirmek için ifade ağaçlarını de
kullanabilirsiniz.

Sınırlamalar
İfade ağaçlarına düzgün C# çevriolmayan bazı yeni dil öğeleri vardır. İfade ağaçları await ifade veya async
lambda ifadesi içeremez. C# 6 sürümüne eklenen özelliklerin birçoğu tam olarak ifade ağaçlarında yazılmış şekilde
görünmez. Bunun yerine, eşdeğer, Önceki sözdiziminde ifade ağaçlarında daha yeni özellikler kullanıma
sunulacaktır. Bu işlem, düşündüğünüzden bir sınırlamanın büyük bir bölümü olmayabilir. Aslında, ifade ağaçlarını
yorumlayan kodunuzun, yeni dil özellikleri tanıtıldığında muhtemelen aynı zamanda çalışmaya devam ettiği
anlamına gelir.
Bu sınırlamalar da dahil olmak üzere, ifade ağaçları, veri yapısı olarak temsil edilen kodu yorumlama ve değiştirme
konusunda temel alan dinamik algoritmalar oluşturmanızı sağlar. Bu güçlü bir araçtır ve .NET ekosisteminin, Entity
Framework gibi zengin kitaplıkları sağlayan özelliklerden biridir.
Birlikte Çalışabilirlik (C# Programlama Kılavuzu)
4.11.2019 • 2 minutes to read • Edit Online

Birlikte çalışabilirlik, yönetilmeyen koddaki mevcut yatırımlardan korunmanızı ve avantajlarını yapmanızı sağlar.
Ortak dil çalışma zamanının (CLR ) denetimi altında çalışan koda yönetilen kodadı verılır ve CLR dışında çalışan
koda yönetilmeyen koddenir. COM, COM+, C++ bileşenler, ActiveX bileşenleri ve MICROSOFT Windows API,
yönetilmeyen kod örnekleridir.
.NET Framework platform çağırma Hizmetleri, System.Runtime.InteropServices ad alanı, C++ birlikte
ÇALıŞABILIRLIK ve com birlikte ÇALıŞABILIRLIĞI (com birlikte çalışma) aracılığıyla yönetilmeyen kodla birlikte
çalışabilirliğe izin verebilir.

Bu Bölümde
Birlikte Çalışabilirliğe Genel Bakış
Yönetilen kod ve yönetilmeyen kod C# arasında birlikte çalışma yöntemlerini açıklar.
Nasıl yapılır: Visual C# Özelliklerini Kullanarak Office Birlikte Çalışma Nesnelerine Erişim
Office programlama işlemini kolaylaştırmak için görselde C# tanıtılan özellikleri açıklar.
Nasıl yapılır: COM Birlikte Çalışma Programlamada Dizin Oluşturulmuş Özellikleri Kullanma
Parametreleri olan COM özelliklerine erişmek için dizinlenmiş özelliklerin nasıl kullanılacağını açıklar.
Nasıl yapılır: Wave Dosyasını Oynatmak için Platform Çağırma Kullanma
Windows işletim sisteminde bir. wav ses dosyası oynatmak için platform çağırma Hizmetleri ' nin nasıl
kullanılacağını açıklar.
İzlenecek yol: Office programlama
Çalışma kitabının bir bağlantısını içeren bir Excel çalışma kitabı ve Word belgesi oluşturmayı gösterir.
Örnek COM Sınıfı
Bir C# SıNıFıN bir com nesnesi olarak nasıl kullanıma sunuleceğini gösterir.

C# Dil Belirtimi
Daha fazla bilgi için bkz. C# dil belirtiminde temel kavramlar . Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
Marshal.ReleaseComObject
C# Programlama Kılavuzu
Yönetilmeyen Kod ile Birlikte Çalışma
İzlenecek yol: Office programlama
Kodunuzu XML açıklamalarıyla belgeleme
4.12.2019 • 34 minutes to read • Edit Online

XML belge açıklamaları, Kullanıcı tanımlı herhangi bir tür veya üyenin tanımının üzerine eklenen özel bir açıklama
türüdür. Bunlar, derleme zamanında bir XML belge dosyası oluşturmak için derleyici tarafından işlenebilecekleri için
özeldir. Derleyici tarafından oluşturulan XML dosyası, .NET derlemenizin yanı sıra, Visual Studio ve diğer IDE 'Ler,
türler veya üyeler hakkında hızlı bilgileri göstermek için IntelliSense kullanabilmesi için birlikte dağıtılabilir. Ayrıca,
XML dosyası, API başvuru Web siteleri oluşturmak için Docfx ve sandrole gibi araçlar aracılığıyla çalıştırılabilir.
Tüm diğer yorumlar gibi XML belgesi açıklamaları derleyici tarafından yok sayılır.
XML dosyasını, derleme zamanında aşağıdakilerden birini yaparak oluşturabilirsiniz:
Komut satırından .NET Core ile bir uygulama geliştiriyorsanız,. csproj proje dosyanızın <PropertyGroup>
bölümüne GenerateDocumentationFile öğesi ekleyebilirsiniz. Belge dosyasının yolunu doğrudan
DocumentationFile öğesikullanarak da belirtebilirsiniz. Aşağıdaki örnek, derleme ile aynı kök dosya adına
sahip proje dizininde bir XML dosyası oluşturur:

<GenerateDocumentationFile>true</GenerateDocumentationFile>

Bu, aşağıdaki gibi eşdeğerdir:

<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml</DocumentationFile>

Visual Studio 'Yu kullanarak bir uygulama geliştiriyorsanız, projeye sağ tıklayıp Özellikler' i seçin. Özellikler
iletişim kutusunda derleme sekmesini seçin ve XML belge dosyasınıdenetleyin. Derleyicinin dosyayı
yazdıkları konumu da değiştirebilirsiniz.
Komut satırından bir .NET Framework uygulaması derlerken, derlerken -doc derleyici seçeneğini ekleyin.
XML belge açıklamaları Üçlü eğik çizgi ( /// ) ve XML biçimli bir açıklama gövdesi kullanır. Örneğin:

/// <summary>
/// This class does something.
/// </summary>
public class SomeClass
{

Gidiş
Yeni geliştiricilerin, üçüncü taraf geliştiricilerin kullanması için ve katkıda bulunmak üzere çok basit bir matematik
kitaplığını belgeleme konusunda bilgi vereceğiz.
Basit matematik kitaplığı için kod aşağıda verilmiştir:
/*
The main Math class
Contains all methods for performing basic math functions
*/
public class Math
{
// Adds two integers and returns the result
public static int Add(int a, int b)
{
// If any parameter is equal to the max value of an integer
// and the other is greater than zero
if ((a == int.MaxValue && b > 0) || (b == int.MaxValue && a > 0))
throw new System.OverflowException();

return a + b;
}

// Adds two doubles and returns the result


public static double Add(double a, double b)
{
if ((a == double.MaxValue && b > 0) || (b == double.MaxValue && a > 0))
throw new System.OverflowException();

return a + b;
}

// Subtracts an integer from another and returns the result


public static int Subtract(int a, int b)
{
return a - b;
}

// Subtracts a double from another and returns the result


public static double Subtract(double a, double b)
{
return a - b;
}

// Multiplies two integers and returns the result


public static int Multiply(int a, int b)
{
return a * b;
}

// Multiplies two doubles and returns the result


public static double Multiply(double a, double b)
{
return a * b;
}

// Divides an integer by another and returns the result


public static int Divide(int a, int b)
{
return a / b;
}

// Divides a double by another and returns the result


public static double Divide(double a, double b)
{
return a / b;
}
}

Örnek kitaplık, int ve double veri türlerinde add , subtract , multiply ve divide dört önemli aritmetik işlemi
destekler.
Şimdi kitaplığınızı kullanan üçüncü taraf geliştiriciler için kodunuzda bir API başvuru belgesi oluşturabilmek, ancak
kaynak koda erişiminiz yok. Daha önce bahsedilen XML belge etiketleri bunu elde etmek için kullanılabilir. Artık C#
derleyicinin DESTEKLEDIĞI standart XML etiketlerine tanıtılıcaksınız.

<summary>
<summary> etiketi, bir tür veya üye hakkında kısa bilgiler ekler. Math sınıf tanımına ve ilk Add yöntemine ekleyerek
kullanımını göstereceğim. Kodunuzu geri kalanına uygulamayı ücretsiz olarak hissetmekten çekinmeyin.

/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main Math class.
/// Contains all methods for performing basic math functions.
/// </summary>
public class Math
{
// Adds two integers and returns the result
/// <summary>
/// Adds two integers and returns the result.
/// </summary>
public static int Add(int a, int b)
{
// If any parameter is equal to the max value of an integer
// and the other is greater than zero
if ((a == int.MaxValue && b > 0) || (b == int.MaxValue && a > 0))
throw new System.OverflowException();

return a + b;
}
}

<summary> etiketi çok önemlidir ve içeriği, IntelliSense 'de veya bir API başvuru belgesinde bulunan içerik veya üye
bilgilerinin birincil kaynağı olduğundan, bunu dahil etmenizi öneririz.

<açıklamalar >
<remarks> etiketi, <summary> etiketinin sağladığı türler veya Üyeler hakkındaki bilgileri tamamlar. Bu örnekte, bunu
yalnızca sınıfına eklersiniz.

/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main Math class.
/// Contains all methods for performing basic math functions.
/// </summary>
/// <remarks>
/// This class can add, subtract, multiply and divide.
/// </remarks>
public class Math
{

<returns>
<returns>etiketi bir yöntem bildiriminin dönüş değerini açıklar. Daha önce olduğu gibi, aşağıdaki örnek ilk Add
yönteminde <returns> etiketini gösterir. Diğer yöntemlerle aynı şekilde yapabilirsiniz.

// Adds two integers and returns the result


/// <summary>
/// Adds two integers and returns the result.
/// </summary>
/// <returns>
/// The sum of two integers.
/// </returns>
public static int Add(int a, int b)
{
// If any parameter is equal to the max value of an integer
// and the other is greater than zero
if ((a == int.MaxValue && b > 0) || (b == int.MaxValue && a > 0))
throw new System.OverflowException();

return a + b;
}

<value>
<value> etiketi, özellikler için kullanmanız dışında <returns> etiketine benzerdir. Math kitaplığınızın PI adında bir
statik özelliği olduğunu varsayarsak, bu etiketi nasıl kullanacağınızı aşağıda bulabilirsiniz:

/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main Math class.
/// Contains all methods for performing basic math functions.
/// </summary>
/// <remarks>
/// This class can add, subtract, multiply and divide.
/// These operations can be performed on both integers and doubles
/// </remarks>
public class Math
{
/// <value>Gets the value of PI.</value>
public static double PI { get; }
}

<örnek >
XML belgelerinize bir örnek eklemek için <example> etiketini kullanın. Bu, alt <code> etiketinin kullanılmasını içerir.
// Adds two integers and returns the result
/// <summary>
/// Adds two integers and returns the result.
/// </summary>
/// <returns>
/// The sum of two integers.
/// </returns>
/// <example>
/// <code>
/// int c = Math.Add(4, 5);
/// if (c > 10)
/// {
/// Console.WriteLine(c);
/// }
/// </code>
/// </example>
public static int Add(int a, int b)
{
// If any parameter is equal to the max value of an integer
// and the other is greater than zero
if ((a == int.MaxValue && b > 0) || (b == int.MaxValue && a > 0))
throw new System.OverflowException();

return a + b;
}

code etiketi, daha uzun örnekler için satır sonlarını ve girintiyi korur.

<paragraf >
İçeriği üst etiketi içinde biçimlendirmek için <para> etiketini kullanın. <para> , genellikle metni paragraflarına
bölmek için <remarks> veya <returns> gibi bir etiket içinde kullanılır. Sınıf tanımınız için <remarks> etiketinin
içeriğini biçimlendirebilirsiniz.

/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main Math class.
/// Contains all methods for performing basic math functions.
/// </summary>
/// <remarks>
/// <para>This class can add, subtract, multiply and divide.</para>
/// <para>These operations can be performed on both integers and doubles.</para>
/// </remarks>
public class Math
{

<c >
Biçimlendirme konusunda hala, metnin bir kısmını kod olarak işaretlemek için <c> etiketini kullanırsınız. <code>
etiketi, ancak satır içi gibi. Bir etiketin içeriğinin bir parçası olarak hızlı bir kod örneği göstermek istediğinizde yararlı
olur. Math sınıfının belgelerini güncelleştirelim.
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main <c>Math</c> class.
/// Contains all methods for performing basic math functions.
/// </summary>
public class Math
{

<özel durum >


<exception> etiketini kullanarak, geliştiricilerinizin bir yöntemin belirli özel durumları oluşturduğunu bilmesini
sağlayabilirsiniz. Math kitaplığınıza baktığınızda, her iki Add yönteminin da belirli bir koşul karşılanırsa bir özel
durum oluşturmasını sağlayabilirsiniz. Öyle değildir, ancak b parametresi sıfır ise tamsayı Divide yöntemi de
oluşturulur. Şimdi bu yönteme özel durum belgeleri ekleyin.

/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main <c>Math</c> class.
/// Contains all methods for performing basic math functions.
/// </summary>
public class Math
{
/// <summary>
/// Adds two integers and returns the result.
/// </summary>
/// <returns>
/// The sum of two integers.
/// </returns>
/// <example>
/// <code>
/// int c = Math.Add(4, 5);
/// if (c > 10)
/// {
/// Console.WriteLine(c);
/// }
/// </code>
/// </example>
/// <exception cref="System.OverflowException">Thrown when one parameter is max
/// and the other is greater than 0.</exception>
public static int Add(int a, int b)
{
if ((a == int.MaxValue && b > 0) || (b == int.MaxValue && a > 0))
throw new System.OverflowException();

return a + b;
}

/// <summary>
/// Adds two doubles and returns the result.
/// </summary>
/// <returns>
/// The sum of two doubles.
/// </returns>
/// <exception cref="System.OverflowException">Thrown when one parameter is max
/// and the other is greater than zero.</exception>
public static double Add(double a, double b)
public static double Add(double a, double b)
{
if ((a == double.MaxValue && b > 0) || (b == double.MaxValue && a > 0))
throw new System.OverflowException();

return a + b;
}

/// <summary>
/// Divides an integer by another and returns the result.
/// </summary>
/// <returns>
/// The division of two integers.
/// </returns>
/// <exception cref="System.DivideByZeroException">Thrown when a division by zero occurs.</exception>
public static int Divide(int a, int b)
{
return a / b;
}

/// <summary>
/// Divides a double by another and returns the result.
/// </summary>
/// <returns>
/// The division of two doubles.
/// </returns>
/// <exception cref="System.DivideByZeroException">Thrown when a division by zero occurs.</exception>
public static double Divide(double a, double b)
{
return a / b;
}
}

cref özniteliği geçerli derleme ortamında kullanılabilir bir özel duruma bir başvuruyu temsil eder. Bu, projede
veya başvurulan bir derlemede tanımlanmış herhangi bir tür olabilir. Değeri çözülemezse, derleyici bir uyarı
verebilir.

<bkz. >
<see> etiketi, başka bir kod öğesi için bir belge sayfasına tıklatılabilir bir bağlantı oluşturmanıza olanak sağlar.
Sonraki örnekte, iki Add yöntemi arasında tıklatılabilir bir bağlantı oluşturacağız.
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main <c>Math</c> class.
/// Contains all methods for performing basic math functions.
/// </summary>
public class Math
{
/// <summary>
/// Adds two integers and returns the result.
/// </summary>
/// <returns>
/// The sum of two integers.
/// </returns>
/// <example>
/// <code>
/// int c = Math.Add(4, 5);
/// if (c > 10)
/// {
/// Console.WriteLine(c);
/// }
/// </code>
/// </example>
/// <exception cref="System.OverflowException">Thrown when one parameter is max
/// and the other is greater than 0.</exception>
/// See <see cref="Math.Add(double, double)"/> to add doubles.
public static int Add(int a, int b)
{
if ((a == int.MaxValue && b > 0) || (b == int.MaxValue && a > 0))
throw new System.OverflowException();

return a + b;
}

/// <summary>
/// Adds two doubles and returns the result.
/// </summary>
/// <returns>
/// The sum of two doubles.
/// </returns>
/// <exception cref="System.OverflowException">Thrown when one parameter is max
/// and the other is greater than zero.</exception>
/// See <see cref="Math.Add(int, int)"/> to add integers.
public static double Add(double a, double b)
{
if ((a == double.MaxValue && b > 0) || (b == double.MaxValue && a > 0))
throw new System.OverflowException();

return a + b;
}
}

cref , geçerli derleme ortamında kullanılabilir olan bir türe veya üyesine başvuruyu temsil eden gerekli bir
özniteliktir. Bu, projede veya başvurulan bir derlemede tanımlanmış herhangi bir tür olabilir.

<seede >
<seealso> etiketini <see> etiketiyle aynı şekilde kullanırsınız. Tek fark, içeriğinin genellikle bir "Ayrıca bkz."
bölümüne yerleştirilme nedendir. Burada, tamsayı parametrelerini kabul eden sınıftaki diğer yöntemlere başvurmak
için tamsayı Add yöntemine bir seealso etiketi ekleyeceğiz:
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main <c>Math</c> class.
/// Contains all methods for performing basic math functions.
/// </summary>
public class Math
{
/// <summary>
/// Adds two integers and returns the result.
/// </summary>
/// <returns>
/// The sum of two integers.
/// </returns>
/// <example>
/// <code>
/// int c = Math.Add(4, 5);
/// if (c > 10)
/// {
/// Console.WriteLine(c);
/// }
/// </code>
/// </example>
/// <exception cref="System.OverflowException">Thrown when one parameter is max
/// and the other is greater than 0.</exception>
/// See <see cref="Math.Add(double, double)"/> to add doubles.
/// <seealso cref="Math.Subtract(int, int)"/>
/// <seealso cref="Math.Multiply(int, int)"/>
/// <seealso cref="Math.Divide(int, int)"/>
public static int Add(int a, int b)
{
if ((a == int.MaxValue && b > 0) || (b == int.MaxValue && a > 0))
throw new System.OverflowException();

return a + b;
}
}

cref özniteliği, geçerli derleme ortamında kullanılabilir olan bir türe veya üyesine başvuruyu temsil eder. Bu,
projede veya başvurulan bir derlemede tanımlanmış herhangi bir tür olabilir.

<param>
Metodun parametrelerini anlatmak için <param> etiketini kullanın. Double Add yöntemine bir örnek aşağıda
verilmiştir: etiketin açıkladığı parametre, gerekli name özniteliğinde belirtilir.
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main <c>Math</c> class.
/// Contains all methods for performing basic math functions.
/// </summary>
public class Math
{
/// <summary>
/// Adds two doubles and returns the result.
/// </summary>
/// <returns>
/// The sum of two doubles.
/// </returns>
/// <exception cref="System.OverflowException">Thrown when one parameter is max
/// and the other is greater than zero.</exception>
/// See <see cref="Math.Add(int, int)"/> to add integers.
/// <param name="a">A double precision number.</param>
/// <param name="b">A double precision number.</param>
public static double Add(double a, double b)
{
if ((a == double.MaxValue && b > 0) || (b == double.MaxValue && a > 0))
throw new System.OverflowException();

return a + b;
}
}

<typeparam >
<typeparam> etiketini <param> etiketi gibi kullanırsınız, ancak genel tür veya yöntem bildirimlerinde genel bir
parametreyi betimleyelim. Bir miktarın diğerinden daha büyük olup olmadığını denetlemek için Math sınıfınıza
hızlı genel bir yöntem ekleyin.

/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main <c>Math</c> class.
/// Contains all methods for performing basic math functions.
/// </summary>
public class Math
{
/// <summary>
/// Checks if an IComparable is greater than another.
/// </summary>
/// <typeparam name="T">A type that inherits from the IComparable interface.</typeparam>
public static bool GreaterThan<T>(T a, T b) where T : IComparable
{
return a.CompareTo(b) > 0;
}
}

<paramref >
Bazen, bir yöntemin <summary> bir etiketle ne olduğunu açıklayan ortasında olabilirsiniz ve bir parametreye
başvuru yapmak isteyebilirsiniz. <paramref> etiketi yalnızca bunun için harika. Double tabanlı Add yönteminizin
özetini güncelleştirelim. <param> etiketi gibi, gerekli name özniteliğinde parametre adı belirtilir.
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main <c>Math</c> class.
/// Contains all methods for performing basic math functions.
/// </summary>
public class Math
{
/// <summary>
/// Adds two doubles <paramref name="a"/> and <paramref name="b"/> and returns the result.
/// </summary>
/// <returns>
/// The sum of two doubles.
/// </returns>
/// <exception cref="System.OverflowException">Thrown when one parameter is max
/// and the other is greater than zero.</exception>
/// See <see cref="Math.Add(int, int)"/> to add integers.
/// <param name="a">A double precision number.</param>
/// <param name="b">A double precision number.</param>
public static double Add(double a, double b)
{
if ((a == double.MaxValue && b > 0) || (b == double.MaxValue && a > 0))
throw new System.OverflowException();

return a + b;
}
}

<typeparamref >
<typeparamref> etiketini <paramref> etiketi gibi kullanırsınız, ancak genel tür veya yöntem bildirimlerinde genel bir
parametreyi betimleyelim. Daha önce oluşturduğunuz genel yöntemi kullanabilirsiniz.

/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main <c>Math</c> class.
/// Contains all methods for performing basic math functions.
/// </summary>
public class Math
{
/// <summary>
/// Checks if an IComparable <typeparamref name="T"/> is greater than another.
/// </summary>
/// <typeparam name="T">A type that inherits from the IComparable interface.</typeparam>
public static bool GreaterThan<T>(T a, T b) where T : IComparable
{
return a.CompareTo(b) > 0;
}
}

<listesi >
Belge bilgilerini sıralı liste, sırasız liste veya tablo olarak biçimlendirmek için <list> etiketini kullanırsınız. Math
kitaplığınızın desteklediği her matematik işleminin sıralanmamış bir listesini oluşturun.
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main <c>Math</c> class.
/// Contains all methods for performing basic math functions.
/// <list type="bullet">
/// <item>
/// <term>Add</term>
/// <description>Addition Operation</description>
/// </item>
/// <item>
/// <term>Subtract</term>
/// <description>Subtraction Operation</description>
/// </item>
/// <item>
/// <term>Multiply</term>
/// <description>Multiplication Operation</description>
/// </item>
/// <item>
/// <term>Divide</term>
/// <description>Division Operation</description>
/// </item>
/// </list>
/// </summary>
public class Math
{

type özniteliğini sırasıyla number veya table olarak değiştirerek sıralı bir liste veya tablo yapabilirsiniz.
Tümünü bir araya getirme
Bu öğreticiyi takip ediyorsanız ve gereken yere etiketleri kodunuza uyguladıysanız, kodunuzun aşağıdakine benzer
şekilde görünmesi gerekir:

/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main <c>Math</c> class.
/// Contains all methods for performing basic math functions.
/// <list type="bullet">
/// <item>
/// <term>Add</term>
/// <description>Addition Operation</description>
/// </item>
/// <item>
/// <term>Subtract</term>
/// <description>Subtraction Operation</description>
/// </item>
/// <item>
/// <term>Multiply</term>
/// <description>Multiplication Operation</description>
/// </item>
/// <item>
/// <term>Divide</term>
/// <description>Division Operation</description>
/// </item>
/// </list>
/// </summary>
/// <remarks>
/// <para>This class can add, subtract, multiply and divide.</para>
/// <para>These operations can be performed on both integers and doubles.</para>
/// </remarks>
public class Math
{
// Adds two integers and returns the result
/// <summary>
/// Adds two integers <paramref name="a"/> and <paramref name="b"/> and returns the result.
/// </summary>
/// <returns>
/// The sum of two integers.
/// </returns>
/// <example>
/// <code>
/// int c = Math.Add(4, 5);
/// if (c > 10)
/// {
/// Console.WriteLine(c);
/// }
/// </code>
/// </example>
/// <exception cref="System.OverflowException">Thrown when one parameter is max
/// and the other is greater than 0.</exception>
/// See <see cref="Math.Add(double, double)"/> to add doubles.
/// <seealso cref="Math.Subtract(int, int)"/>
/// <seealso cref="Math.Multiply(int, int)"/>
/// <seealso cref="Math.Divide(int, int)"/>
/// <param name="a">An integer.</param>
/// <param name="b">An integer.</param>
public static int Add(int a, int b)
{
// If any parameter is equal to the max value of an integer
// and the other is greater than zero
if ((a == int.MaxValue && b > 0) || (b == int.MaxValue && a > 0))
throw new System.OverflowException();

return a + b;
}

// Adds two doubles and returns the result


/// <summary>
/// Adds two doubles <paramref name="a"/> and <paramref name="b"/> and returns the result.
/// </summary>
/// <returns>
/// The sum of two doubles.
/// </returns>
/// <example>
/// <code>
/// double c = Math.Add(4.5, 5.4);
/// if (c > 10)
/// {
/// Console.WriteLine(c);
/// }
/// </code>
/// </example>
/// <exception cref="System.OverflowException">Thrown when one parameter is max
/// and the other is greater than 0.</exception>
/// See <see cref="Math.Add(int, int)"/> to add integers.
/// <seealso cref="Math.Subtract(double, double)"/>
/// <seealso cref="Math.Multiply(double, double)"/>
/// <seealso cref="Math.Divide(double, double)"/>
/// <param name="a">A double precision number.</param>
/// <param name="b">A double precision number.</param>
public static double Add(double a, double b)
{
// If any parameter is equal to the max value of an integer
// and the other is greater than zero
if ((a == double.MaxValue && b > 0) || (b == double.MaxValue && a > 0))
throw new System.OverflowException();
return a + b;
}

// Subtracts an integer from another and returns the result


/// <summary>
/// Subtracts <paramref name="b"/> from <paramref name="a"/> and returns the result.
/// </summary>
/// <returns>
/// The difference between two integers.
/// </returns>
/// <example>
/// <code>
/// int c = Math.Subtract(4, 5);
/// if (c > 1)
/// {
/// Console.WriteLine(c);
/// }
/// </code>
/// </example>
/// See <see cref="Math.Subtract(double, double)"/> to subtract doubles.
/// <seealso cref="Math.Add(int, int)"/>
/// <seealso cref="Math.Multiply(int, int)"/>
/// <seealso cref="Math.Divide(int, int)"/>
/// <param name="a">An integer.</param>
/// <param name="b">An integer.</param>
public static int Subtract(int a, int b)
{
return a - b;
}

// Subtracts a double from another and returns the result


/// <summary>
/// Subtracts a double <paramref name="b"/> from another double <paramref name="a"/> and returns the
result.
/// </summary>
/// <returns>
/// The difference between two doubles.
/// </returns>
/// <example>
/// <code>
/// double c = Math.Subtract(4.5, 5.4);
/// if (c > 1)
/// {
/// Console.WriteLine(c);
/// }
/// </code>
/// </example>
/// See <see cref="Math.Subtract(int, int)"/> to subtract integers.
/// <seealso cref="Math.Add(double, double)"/>
/// <seealso cref="Math.Multiply(double, double)"/>
/// <seealso cref="Math.Divide(double, double)"/>
/// <param name="a">A double precision number.</param>
/// <param name="b">A double precision number.</param>
public static double Subtract(double a, double b)
{
return a - b;
}

// Multiplies two integers and returns the result


/// <summary>
/// Multiplies two integers <paramref name="a"/> and <paramref name="b"/> and returns the result.
/// </summary>
/// <returns>
/// The product of two integers.
/// </returns>
/// <example>
/// <code>
/// int c = Math.Multiply(4, 5);
/// if (c > 100)
/// if (c > 100)
/// {
/// Console.WriteLine(c);
/// }
/// </code>
/// </example>
/// See <see cref="Math.Multiply(double, double)"/> to multiply doubles.
/// <seealso cref="Math.Add(int, int)"/>
/// <seealso cref="Math.Subtract(int, int)"/>
/// <seealso cref="Math.Divide(int, int)"/>
/// <param name="a">An integer.</param>
/// <param name="b">An integer.</param>
public static int Multiply(int a, int b)
{
return a * b;
}

// Multiplies two doubles and returns the result


/// <summary>
/// Multiplies two doubles <paramref name="a"/> and <paramref name="b"/> and returns the result.
/// </summary>
/// <returns>
/// The product of two doubles.
/// </returns>
/// <example>
/// <code>
/// double c = Math.Multiply(4.5, 5.4);
/// if (c > 100.0)
/// {
/// Console.WriteLine(c);
/// }
/// </code>
/// </example>
/// See <see cref="Math.Multiply(int, int)"/> to multiply integers.
/// <seealso cref="Math.Add(double, double)"/>
/// <seealso cref="Math.Subtract(double, double)"/>
/// <seealso cref="Math.Divide(double, double)"/>
/// <param name="a">A double precision number.</param>
/// <param name="b">A double precision number.</param>
public static double Multiply(double a, double b)
{
return a * b;
}

// Divides an integer by another and returns the result


/// <summary>
/// Divides an integer <paramref name="a"/> by another integer <paramref name="b"/> and returns the result.
/// </summary>
/// <returns>
/// The quotient of two integers.
/// </returns>
/// <example>
/// <code>
/// int c = Math.Divide(4, 5);
/// if (c > 1)
/// {
/// Console.WriteLine(c);
/// }
/// </code>
/// </example>
/// <exception cref="System.DivideByZeroException">Thrown when <paramref name="b"/> is equal to 0.
</exception>
/// See <see cref="Math.Divide(double, double)"/> to divide doubles.
/// <seealso cref="Math.Add(int, int)"/>
/// <seealso cref="Math.Subtract(int, int)"/>
/// <seealso cref="Math.Multiply(int, int)"/>
/// <param name="a">An integer dividend.</param>
/// <param name="b">An integer divisor.</param>
public static int Divide(int a, int b)
{
{
return a / b;
}

// Divides a double by another and returns the result


/// <summary>
/// Divides a double <paramref name="a"/> by another double <paramref name="b"/> and returns the result.
/// </summary>
/// <returns>
/// The quotient of two doubles.
/// </returns>
/// <example>
/// <code>
/// double c = Math.Divide(4.5, 5.4);
/// if (c > 1.0)
/// {
/// Console.WriteLine(c);
/// }
/// </code>
/// </example>
/// <exception cref="System.DivideByZeroException">Thrown when <paramref name="b"/> is equal to 0.
</exception>
/// See <see cref="Math.Divide(int, int)"/> to divide integers.
/// <seealso cref="Math.Add(double, double)"/>
/// <seealso cref="Math.Subtract(double, double)"/>
/// <seealso cref="Math.Multiply(double, double)"/>
/// <param name="a">A double precision dividend.</param>
/// <param name="b">A double precision divisor.</param>
public static double Divide(double a, double b)
{
return a / b;
}
}

Kodınızdan, tıklatılabilir çapraz başvurularla ayrıntılı bir belge Web sitesi oluşturabilirsiniz. Ancak başka bir sorunla
karşılaşıyoruz: kodunuzun okunması zor oldu. Bu koda katkıda bulunmak isteyen herhangi bir geliştirici için bu bir
gece olacak şekilde, bu kadar çok bilgi vardır. Bu konuda size yardımcı olabilecek bir XML etiketi vardı:

<içerme >
<include> etiketi, belge açıklamalarını doğrudan kaynak kodu dosyanıza yerleştirmeyi tersine, kaynak kodunuzda
türleri ve üyeleri tanımlayan ayrı bir XML dosyasındaki açıklamalara başvurmanıza olanak sağlar.
Artık tüm XML etiketlerinizi docs.xml adlı ayrı bir XML dosyasına taşıyacağız. Dosyayı istediğiniz şekilde
adlandırabilirsiniz.

<docs>
<members name="math">
<Math>
<summary>
The main <c>Math</c> class.
Contains all methods for performing basic math functions.
</summary>
<remarks>
<para>This class can add, subtract, multiply and divide.</para>
<para>These operations can be performed on both integers and doubles.</para>
</remarks>
</Math>
<AddInt>
<summary>
Adds two integers <paramref name="a"/> and <paramref name="b"/> and returns the result.
</summary>
<returns>
The sum of two integers.
</returns>
<example>
<example>
<code>
int c = Math.Add(4, 5);
if (c > 10)
{
Console.WriteLine(c);
}
</code>
</example>
<exception cref="System.OverflowException">Thrown when one parameter is max
and the other is greater than 0.</exception>
See <see cref="Math.Add(double, double)"/> to add doubles.
<seealso cref="Math.Subtract(int, int)"/>
<seealso cref="Math.Multiply(int, int)"/>
<seealso cref="Math.Divide(int, int)"/>
<param name="a">An integer.</param>
<param name="b">An integer.</param>
</AddInt>
<AddDouble>
<summary>
Adds two doubles <paramref name="a"/> and <paramref name="b"/> and returns the result.
</summary>
<returns>
The sum of two doubles.
</returns>
<example>
<code>
double c = Math.Add(4.5, 5.4);
if (c > 10)
{
Console.WriteLine(c);
}
</code>
</example>
<exception cref="System.OverflowException">Thrown when one parameter is max
and the other is greater than 0.</exception>
See <see cref="Math.Add(int, int)"/> to add integers.
<seealso cref="Math.Subtract(double, double)"/>
<seealso cref="Math.Multiply(double, double)"/>
<seealso cref="Math.Divide(double, double)"/>
<param name="a">A double precision number.</param>
<param name="b">A double precision number.</param>
</AddDouble>
<SubtractInt>
<summary>
Subtracts <paramref name="b"/> from <paramref name="a"/> and returns the result.
</summary>
<returns>
The difference between two integers.
</returns>
<example>
<code>
int c = Math.Subtract(4, 5);
if (c > 1)
{
Console.WriteLine(c);
}
</code>
</example>
See <see cref="Math.Subtract(double, double)"/> to subtract doubles.
<seealso cref="Math.Add(int, int)"/>
<seealso cref="Math.Multiply(int, int)"/>
<seealso cref="Math.Divide(int, int)"/>
<param name="a">An integer.</param>
<param name="b">An integer.</param>
</SubtractInt>
<SubtractDouble>
<summary>
Subtracts a double <paramref name="b"/> from another double <paramref name="a"/> and returns the
result.
</summary>
<returns>
The difference between two doubles.
</returns>
<example>
<code>
double c = Math.Subtract(4.5, 5.4);
if (c > 1)
{
Console.WriteLine(c);
}
</code>
</example>
See <see cref="Math.Subtract(int, int)"/> to subtract integers.
<seealso cref="Math.Add(double, double)"/>
<seealso cref="Math.Multiply(double, double)"/>
<seealso cref="Math.Divide(double, double)"/>
<param name="a">A double precision number.</param>
<param name="b">A double precision number.</param>
</SubtractDouble>
<MultiplyInt>
<summary>
Multiplies two integers <paramref name="a"/> and <paramref name="b"/> and returns the result.
</summary>
<returns>
The product of two integers.
</returns>
<example>
<code>
int c = Math.Multiply(4, 5);
if (c > 100)
{
Console.WriteLine(c);
}
</code>
</example>
See <see cref="Math.Multiply(double, double)"/> to multiply doubles.
<seealso cref="Math.Add(int, int)"/>
<seealso cref="Math.Subtract(int, int)"/>
<seealso cref="Math.Divide(int, int)"/>
<param name="a">An integer.</param>
<param name="b">An integer.</param>
</MultiplyInt>
<MultiplyDouble>
<summary>
Multiplies two doubles <paramref name="a"/> and <paramref name="b"/> and returns the result.
</summary>
<returns>
The product of two doubles.
</returns>
<example>
<code>
double c = Math.Multiply(4.5, 5.4);
if (c > 100.0)
{
Console.WriteLine(c);
}
</code>
</example>
See <see cref="Math.Multiply(int, int)"/> to multiply integers.
<seealso cref="Math.Add(double, double)"/>
<seealso cref="Math.Subtract(double, double)"/>
<seealso cref="Math.Divide(double, double)"/>
<param name="a">A double precision number.</param>
<param name="b">A double precision number.</param>
</MultiplyDouble>
<DivideInt>
<summary>
<summary>
Divides an integer <paramref name="a"/> by another integer <paramref name="b"/> and returns the
result.
</summary>
<returns>
The quotient of two integers.
</returns>
<example>
<code>
int c = Math.Divide(4, 5);
if (c > 1)
{
Console.WriteLine(c);
}
</code>
</example>
<exception cref="System.DivideByZeroException">Thrown when <paramref name="b"/> is equal to 0.
</exception>
See <see cref="Math.Divide(double, double)"/> to divide doubles.
<seealso cref="Math.Add(int, int)"/>
<seealso cref="Math.Subtract(int, int)"/>
<seealso cref="Math.Multiply(int, int)"/>
<param name="a">An integer dividend.</param>
<param name="b">An integer divisor.</param>
</DivideInt>
<DivideDouble>
<summary>
Divides a double <paramref name="a"/> by another double <paramref name="b"/> and returns the
result.
</summary>
<returns>
The quotient of two doubles.
</returns>
<example>
<code>
double c = Math.Divide(4.5, 5.4);
if (c > 1.0)
{
Console.WriteLine(c);
}
</code>
</example>
<exception cref="System.DivideByZeroException">Thrown when <paramref name="b"/> is equal to 0.
</exception>
See <see cref="Math.Divide(int, int)"/> to divide integers.
<seealso cref="Math.Add(double, double)"/>
<seealso cref="Math.Subtract(double, double)"/>
<seealso cref="Math.Multiply(double, double)"/>
<param name="a">A double precision dividend.</param>
<param name="b">A double precision divisor.</param>
</DivideDouble>
</members>
</docs>

Yukarıdaki XML 'de, her üyenin belge yorumu, ne yapacaklarıyla doğrudan adlı bir etiketin içinde görünür. Kendi
stratejinizi seçebilirsiniz. XML yorumlarınıza artık ayrı bir dosyada sahip olduğunuza göre, kodunuzun <include>
etiketi kullanılarak nasıl daha okunaklı hale getirildikimi görelim:

/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <include file='docs.xml' path='docs/members[@name="math"]/Math/*'/>
public class Math
{
// Adds two integers and returns the result
/// <include file='docs.xml' path='docs/members[@name="math"]/AddInt/*'/>
public static int Add(int a, int b)
public static int Add(int a, int b)
{
// If any parameter is equal to the max value of an integer
// and the other is greater than zero
if ((a == int.MaxValue && b > 0) || (b == int.MaxValue && a > 0))
throw new System.OverflowException();

return a + b;
}

// Adds two doubles and returns the result


/// <include file='docs.xml' path='docs/members[@name="math"]/AddDouble/*'/>
public static double Add(double a, double b)
{
// If any parameter is equal to the max value of an integer
// and the other is greater than zero
if ((a == double.MaxValue && b > 0) || (b == double.MaxValue && a > 0))
throw new System.OverflowException();

return a + b;
}

// Subtracts an integer from another and returns the result


/// <include file='docs.xml' path='docs/members[@name="math"]/SubtractInt/*'/>
public static int Subtract(int a, int b)
{
return a - b;
}

// Subtracts a double from another and returns the result


/// <include file='docs.xml' path='docs/members[@name="math"]/SubtractDouble/*'/>
public static double Subtract(double a, double b)
{
return a - b;
}

// Multiplies two integers and returns the result


/// <include file='docs.xml' path='docs/members[@name="math"]/MultiplyInt/*'/>
public static int Multiply(int a, int b)
{
return a * b;
}

// Multiplies two doubles and returns the result


/// <include file='docs.xml' path='docs/members[@name="math"]/MultiplyDouble/*'/>
public static double Multiply(double a, double b)
{
return a * b;
}

// Divides an integer by another and returns the result


/// <include file='docs.xml' path='docs/members[@name="math"]/DivideInt/*'/>
public static int Divide(int a, int b)
{
return a / b;
}

// Divides a double by another and returns the result


/// <include file='docs.xml' path='docs/members[@name="math"]/DivideDouble/*'/>
public static double Divide(double a, double b)
{
return a / b;
}
}

Bu durumda: kodunuz okunabilir hale getirilir ve belge bilgisi kaybedilmiyor.


file öznitelik, belgeleri içeren XML dosyasının adını temsil eder.
path öznitelik, belirtilen file mevcut tag name bir XPath sorgusunu temsil eder.
name özniteliği, etiketteki açıklamaların önündeki ad belirticisini temsil eder.
name yerine kullanılabilecek id özniteliği, yorumların önündeki etiketin KIMLIĞINI temsil eder.
Kullanıcı tanımlı Etiketler
Yukarıda özetlenen tüm Etiketler, C# derleyici tarafından tanınan olanları temsil eder. Ancak, bir Kullanıcı kendi
etiketlerini tanımlayaücretsizdir. Sandrole gibi Araçlar <event> , <note> gibi ek Etiketler için destek getirme ve
hatta ad alanlarını belgelemedesteği. Özel veya şirket içi belge oluşturma araçları ayrıca standart Etiketler ve HTML
'den PDF 'ye birden çok çıktı biçimi ile kullanılabilir.

Öneri
Kodu belgeleme pek çok nedenden dolayı önerilir. Aşağıda, bazı en iyi yöntemler, genel kullanım örneği senaryoları
ve C# kodunuzda XML belge etiketlerini kullanırken bilmeniz gereken noktalar verilmiştir.
Tutarlılık açısından, herkese açık olarak görünen tüm türler ve üyeleri açıklanmalıdır. Bunu yapmanız
gerekiyorsa, bunu yapın.
Özel Üyeler ayrıca XML açıklamaları kullanılarak Belgelenebilir. Ancak bu, kitaplığınızın iç (potansiyel olarak
gizli) işleyişini kullanıma sunar.
İçerik IntelliSense için gerekli olduğundan, en azından, türlerin ve üyelerinin <summary> bir etiketi olmalıdır.
Belge metni tam uyarılarla biten tam tümceler kullanılarak yazılmalıdır.
Kısmi sınıflar tam olarak desteklenir ve belge bilgileri bu tür için tek bir girişte birleştirilir.
Derleyici <exception> , <include> , <param> , <see> , <seealso> ve <typeparam> etiketlerinin sözdizimini
doğrular.
Derleyici dosya yolları içeren parametreleri ve kodun diğer bölümlerine başvuruları doğrular.

Ayrıca bkz.
XML belge açıklamaları (C# Programlama Kılavuzu)
Belge açıklamaları için önerilen Etiketler (C# Programlama Kılavuzu)
C# sürümünde sürüm oluşturma
30.10.2019 • 9 minutes to read • Edit Online

Bu öğreticide .NET 'teki sürüm oluşturmanın ne anlama geldiğini öğreneceksiniz. Ayrıca, kitaplığınızın sürümü
oluşturulurken göz önünde bulundurmanız gereken faktörleri ve yeni bir kitaplık sürümüne yükseltmeyi
öğreneceksiniz.

Yazma kitaplıkları
Genel kullanım için .NET kitaplıkları oluşturmuş olan bir geliştirici olarak, büyük olasılıkla yeni güncelleştirmeleri
almanız gereken durumlarda olabilirsiniz. Bu süreç hakkında daha fazla bilgi için, var olan kodun kitaplığınızın yeni
sürümüne sorunsuz bir şekilde geçişini sağlamak için ihtiyacınız olduğu için çok önemlidir. Yeni bir sürüm
oluştururken göz önünde bulundurmanız gereken birkaç nokta vardır:
Anlamsal sürüm oluşturma
Anlamsal sürüm oluşturma (Short için semver), belirli kilometre taşı olaylarını belirtmek için kitaplığınızın
sürümlerine uygulanan bir adlandırma kuralıdır. İdeal olarak, kitaplığınıza verdiğiniz sürüm bilgileri, geliştiricilerin,
aynı kitaplığın eski sürümlerini kullanan projelerle uyumluluğunu belirlemesine yardımcı olmalıdır.
SemVer 'e en temel yaklaşım, 3 bileşen biçimi MAJOR.MINOR.PATCH , burada:
uyumsuz API değişiklikleri yaptığınızda MAJOR artırılır
MINOR , geriye doğru uyumlu bir şekilde işlevsellik eklediğinizde artırılır
geriye dönük olarak uyumlu hata düzeltmeleri yaptığınızda PATCH artırılır

Sürüm bilgilerini .NET kitaplığınıza uygularken yayın öncesi sürümler gibi başka senaryolar da belirtmek için de
çeşitli yollar vardır.
Geriye dönük uyumluluk
Kitaplığınızın yeni sürümlerini serbest bırakmakta önceki sürümlerle geriye dönük uyumluluk, büyük ihtimalle
önemli kaygılardan biri olacaktır. Önceki sürüme bağımlı olan kodun yeniden derlenmesi sırasında, yeni sürümle
birlikte çalışarak kitaplığınızın yeni bir sürümü önceki bir sürümle kaynak uyumludur. Eski sürüme bağımlı bir
uygulama, yeniden derleme olmadan yeni sürümle birlikte çalışarak kitaplığınızın yeni bir sürümü ikili uyumludur.
Kitaplığınızın eski sürümleriyle geriye dönük uyumluluğu sürdürmeye çalışırken göz önünde bulundurmanız
gereken bazı noktalar şunlardır:
Sanal Yöntemler: sanal bir yöntemi yeni sürümünüzde sanal olmayan yaptığınızda, bu yöntemi geçersiz kılan
projelerin güncelleştirilmesini sağlamak anlamına gelir. Bu çok büyük bir değişiklik ve kesinlikle önerilmez.
Yöntem imzaları: bir yöntem davranışının güncelleştirilmesi için, imzasını da değiştirmeniz gerekir, bunun yerine
bu yönteme çağrı yapan kodun çalışmaya devam etmesi için bir aşırı yükleme oluşturmanız gerekir.
Uygulamanın tutarlı kalması için yeni yöntem imzasını çağırmak üzere, eski yöntem imzasını her zaman
değiştirebilirsiniz.
Artık kullanılmıyor özniteliği: Bu özniteliği kodunuzda kullanım dışı olan ve gelecekteki sürümlerde kaldırılacak
olan sınıfları veya sınıf üyelerini belirtmek için kullanabilirsiniz. Bu, kitaplığınızı kullanan geliştiricilerin, son
değişiklikler için daha iyi hazırlanmasını sağlar.
İsteğe bağlı yöntem bağımsız değişkenleri: daha önce isteğe bağlı yöntem bağımsız değişkenlerini zorunlu
yaptığınızda veya varsayılan değerlerini değiştirdiğinizde, bu bağımsız değişkenleri içermeyen tüm kodun
güncellenmesi gerekecektir.
NOTE
Zorunlu bağımsız değişkenleri isteğe bağlı hale getirmek, özellikle yöntemin davranışını değiştirmiyorsa çok az etkiye sahip
olmalıdır.

Kullanıcılarınızın kitaplığınızın yeni sürümüne yükseltme yapmasını kolaylaştırır, daha önce yükseltebilecekleri
büyük olasılıkla daha kolay olur.
Uygulama yapılandırma dosyası
Bir .NET geliştiricisi olarak çoğu proje türünde bulunan app.config dosyası ile karşılaşmanız çok yüksek bir
şansınız vardır. Bu basit yapılandırma dosyası, yeni güncelleştirmelerin dağıtımını iyileştirmek için uzun bir yönteme
gidebilirler. Genellikle kitaplıklarınızı düzenli olarak değişen bilgiler app.config dosyasında depolandığından, bu
tür bilgiler güncelleştirilirken, eski sürümlerin yapılandırma dosyasının, yalnızca yeni bir sürüm ile değiştirilmesi
gereken bir şekilde tasarlayabilirsiniz. kitaplığın yeniden derlenmesi gereksinimi.

Kitaplıkları kullanma
Diğer geliştiriciler tarafından oluşturulan .NET kitaplıklarını tüketen bir geliştirici olarak, bir kitaplığın yeni bir
sürümünün projenizle tamamen uyumlu olabileceğini ve genellikle kendi kodunuzu bu değişikliklerle çalışacak
şekilde güncelleştirmek zorunda olduğunu fark edersiniz.
Sizin için Lucky ve C# .net ekosistemi, uygulamamızı, son değişiklikleri ortaya çıkaracak yeni kitaplıkların
sürümleriyle çalışacak şekilde kolayca güncelleştirmenize imkan tanıyan özellikler ve teknikler sunar.
Derleme bağlama yeniden yönlendirmesi
Uygulamanızın kullandığı bir kitaplığın sürümünü güncelleştirmek için app. config dosyasını kullanabilirsiniz.
Bağlama yeniden yönlendirmeolarak adlandırılan öğesine ekleyerek, uygulamanızı yeniden derlemek zorunda
kalmadan yeni kitaplık sürümünü kullanabilirsiniz. Aşağıdaki örnek, uygulamanızın app. config dosyasını, ilk olarak
derlenmiş olan 1.0.0 sürümü yerine ReferencedLibrary 1.0.1 Patch sürümünü kullanacak şekilde nasıl
güncelleşbileceğinizi gösterir.

<dependentAssembly>
<assemblyIdentity name="ReferencedLibrary" publicKeyToken="32ab4ba45e0a69a1" culture="en-us" />
<bindingRedirect oldVersion="1.0.0" newVersion="1.0.1" />
</dependentAssembly>

NOTE
Bu yaklaşım yalnızca ReferencedLibrary yeni sürümü uygulamanız ile ikili dosya uyumluysa çalışır. Uyumluluk belirlenirken
yapılan değişiklikler için yukarıdaki geriye dönük uyumluluk bölümüne bakın.

new
Bir temel sınıfın devralınan üyelerini gizlemek için new değiştiricisini kullanırsınız. Bu, türetilmiş sınıfların temel
sınıflarda güncelleştirmelere yanıt verebildiği bir yoldur.
Aşağıdaki örneği uygulayın:
public class BaseClass
{
public void MyMethod()
{
Console.WriteLine("A base method");
}
}

public class DerivedClass : BaseClass


{
public new void MyMethod()
{
Console.WriteLine("A derived method");
}
}

public static void Main()


{
BaseClass b = new BaseClass();
DerivedClass d = new DerivedClass();

b.MyMethod();
d.MyMethod();
}

Output

A base method
A derived method

Yukarıdaki örnekte, BaseClass``DerivedClass MyMethod metodunu nasıl gizlediğini görebilirsiniz. Bu, bir kitaplığın
yeni sürümündeki bir temel sınıf, türetilmiş sınıfınıza zaten mevcut olan bir üyeyi eklediğinde, temel sınıf üyesini
gizlemek için yalnızca türetilmiş sınıf üyeinizdeki new değiştiricisini kullanmanız gerektiğini gösterir.
new değiştirici belirtilmediğinde, türetilmiş bir sınıf varsayılan olarak bir temel sınıfta çakışan üyeleri gizleyecek,
ancak derleyici uyarısı üretilse de kod derlenmeye devam eder. Bu, yalnızca varolan bir sınıfa yeni üye eklemek,
kitaplığınızın bu yeni sürümünün hem kaynak hem de ikilinin buna bağlı kodla uyumlu olmasını sağlar.
override
override değiştirici, türetilmiş bir uygulamanın, bir temel sınıf üyesinin uygulamasını gizliyor yerine genişlettiği
anlamına gelir. Temel sınıf üyesine virtual değiştiricisine uygulanmış olması gerekir.
public class MyBaseClass
{
public virtual string MethodOne()
{
return "Method One";
}
}

public class MyDerivedClass : MyBaseClass


{
public override string MethodOne()
{
return "Derived Method One";
}
}

public static void Main()


{
MyBaseClass b = new MyBaseClass();
MyDerivedClass d = new MyDerivedClass();

Console.WriteLine("Base Method One: {0}", b.MethodOne());


Console.WriteLine("Derived Method One: {0}", d.MethodOne());
}

Output

Base Method One: Method One


Derived Method One: Derived Method One

override değiştiricisi derleme zamanında değerlendirilir ve geçersiz kılmak için bir sanal üye bulamazsa derleyici
bir hata oluşturur.
Ele alınan teknikler ve bunların kullanılacağı durumlar hakkında bilginiz varsa, bir kitaplığın sürümleri arasındaki
geçişin hızını kolaylaştırmak için uzun bir yol olacaktır.
Nasıl yapılır (C#)
8.11.2019 • 6 minutes to read • Edit Online

C# Kılavuzun nasıl yapılır bölümünde yaygın soruların hızlı yanıtlarını bulabilirsiniz. Bazı durumlarda, makaleler
birden çok bölümde listelenebilir. Birden çok arama yolu için bulmayı kolay hale getirmek istiyorduk.

Genel C# kavramlar
Yaygın C# geliştirici uygulamaları olan çeşitli ipuçları ve püf noktaları vardır.
Nesne Başlatıcısı kullanarak nesneleri başlatın.
Bir Yapı ve sınıfı bir yönteme geçirme arasındaki farkları öğrenin.
İşleç aşırı yüklemesi kullanın.
Özel bir genişletme yöntemi uygulayın ve çağırın.
Programcılar C# de My ad alanını vb. kullanmakisteyebilir.
Uzantı yöntemlerini kullanarak enum türü için yeni bir yöntem oluşturun.
Sınıf ve yapı üyeleri
Programınızı uygulamak için sınıflar ve yapılar oluşturursunuz. Bu teknikler, sınıfları veya yapıları yazarken yaygın
olarak kullanılır.
Otomatik uygulanan özellikler bildirin.
Okuma/yazma özelliklerini bildirin ve kullanın.
Sabitleri tanımlayın.
Dize çıktısı sağlamak için ToString yöntemini geçersiz kılın.
Soyut özellikleri tanımlayın.
Kodunuzu belgelemek için XML belge özelliklerini kullanın.
Genel arabiriminizi kısa tutmak için arabirim üyelerini açık bir şekilde uygulayın.
İki arabirimin üyelerini açıkça uygulayın.
Koleksiyonlarla çalışma
Bu makaleler, veri koleksiyonlarıyla çalışmanıza yardımcı olur.
Koleksiyon başlatıcısı ile bir sözlük başlatın.

Dizelerle çalışma
Dizeler, metni göstermek veya işlemek için kullanılan temel veri türüdür. Bu makaleler, dizelerin bulunduğu yaygın
uygulamaları gösterir.
Dizeleri karşılaştırın.
Bir dizenin Içeriğini değiştirme.
Bir dizenin bir sayıyı temsil edip etmediğini belirleme.
Dizeleri ayırmak için String.Split kullanın.
Birden çok dizeyi bir Içinde birleştirin.
Dizede metin arayın.

Türler arasında dönüştürme


Bir nesneyi farklı bir türe dönüştürmeniz gerekebilir.
Bir dizenin bir sayıyı temsil edip etmediğini belirleme.
Onaltılık sayıları ve sayıyı temsil eden dizeler arasında dönüştürme.
Bir dizeyi DateTime Dönüştür .
Bir Byte dizisini int 'e dönüştürün.
Bir dizeyi sayıya dönüştürür.
Farklı bir türe güvenle dönüştürmek için, as ve is Işleçlerini kullanarak model eşleştirmeyi kullanın.
Özel tür dönüştürmeleri tanımlayın.
Türün null yapılabilir bir değer türüolup olmadığını belirleme.
Null yapılabilen ve null yapılamayan değer türleri arasında dönüştürme.

Eşitlik ve sıralama karşılaştırmaları


Eşitlik için kendi kurallarını tanımlayan türler oluşturabilir veya bu tür nesneler arasında doğal bir sıralama
tanımlayabilirsiniz.
Başvuru tabanlı eşitlik Için test.
Bir tür için değer tabanlı eşitlik tanımlayın.

Özel durum işleme


.NET programları, özel durumlar oluşturarak bu yöntemlerin çalışmalarını başarıyla tamamlamamış olduğunu
bildirir. Bu makalelerde, özel durumlarla çalışmayı öğreneceksiniz.
try ve kullanarak özel durumları işleyin .
catch
finally yan tümceleri kullanarak kaynakları temizleme.
CLS olmayan (ortak dil belirtimi) özel durumlarından kurtarın.

Temsilciler ve olaylar
Temsilciler ve olaylar, gevşek olarak bağlanmış kod bloklarını içeren stratejiler için bir yetenek sağlar.
Temsilcileri bildirin, oluşturun ve kullanın.
Çok noktaya yayın temsilcileri birleştirin.
Olaylar, bildirimleri yayınlamak veya bunlara abone olmak için bir mekanizma sağlar.
Olaylara abone olma ve aboneliği kaldırma.
Arabirimlerde belirtilen olayları uygulayın.
Kodunuz olayları yayımladığında .NET Framework yönergelerine uygun.
Türetilmiş sınıflardan temel sınıflarda tanımlı olayları yükseltir.
Özel olay erişimcileri uygulayın.

LINQ uygulamaları
LINQ, LINQ sorgu ifadesi modelini destekleyen herhangi bir veri kaynağını sorgulamak için kod yazmanıza olanak
sağlar. Bu makaleler, stili anlamanıza ve farklı veri kaynaklarıyla çalışmanıza yardımcı olur.
Bir koleksiyonu sorgulayın.
Bir sorguda lambda Ifadeleri kullanın.
Sorgu ifadelerinde var kullanın.
Bir sorgudan öğe özelliklerinin alt kümelerini döndürün.
Karmaşık filtrelemeye sahip sorgular yazın.
Bir veri kaynağının öğelerini sıralayın.
Öğeleri birden çok anahtar üzerinde sıralayın.
Projeksiyon türünü denetleyin.
Kaynak dizisindeki bir değerin tekrarlamalarını say.
Ara değerleri hesaplayın.
Birden çok kaynaktaki verileri birleştirin.
İki sıra arasında ayarlanan farkı bulur.
Boş sorgu sonuçlarında hata ayıklayın.
LINQ Sorgularına özel yöntemler ekleyin.

Birden çok iş parçacığı ve zaman uyumsuz işleme


Modern programlar genellikle zaman uyumsuz işlemler kullanır. Bu makaleler, bu teknikleri kullanmayı
öğrenmenize yardımcı olur.
System.Threading.Tasks.Task.WhenAllkullanarak zaman uyumsuz performansı geliştirme .
async ve await kullanarak birden çok web isteğini paralel hale getirin .
Bir iş parçacığı havuzu kullanın.

Programınızın komut satırı bağımsız değişkenleri


Genellikle, C# programların komut satırı bağımsız değişkenleri vardır. Bu makaleler, bu komut satırı bağımsız
değişkenlerine erişmek ve bunları işlemek için size öğretir.
Tüm komut satırı bağımsız değişkenlerini for alın .
String. Split kullanarak dizeleri ayrıştırma (C# kılavuz)
25.11.2019 • 3 minutes to read • Edit Online

String.Split yöntemi, giriş dizesini bir veya daha fazla sınırlayıcı temelinde bölerek bir alt dizeler dizisi oluşturur.
Genellikle bir dizeyi sözcük sınırlarında ayırmanın en kolay yoludur. Ayrıca, diğer belirli karakter veya dizelerde
dizeleri ayırmak için de kullanılır.

NOTE
Bu makalede, C# örnekleri çalıştırmak Try.NET satır içi kod Çalıştırıcısı ve oyun alanı. Seçin çalıştırma bir etkileşimli
penceresinde bir örnek çalıştırmak için düğme. Kod yürüttükten sonra değiştirmek ve seçerek değiştirilmiş kodu çalıştırmak
çalıştırma yeniden. Değiştirilmiş ya da çalıştırmalarını etkileşimli pencerede kod ya da derleme başarısız olursa, tüm C#
Derleyici hata iletilerini etkileşimli pencere görüntüler.

Aşağıdaki kod, ortak bir tümceciği her sözcük için bir dizeler dizisine böler.

string phrase = "The quick brown fox jumps over the lazy dog.";
string[] words = phrase.Split(' ');

foreach (var word in words)


{
System.Console.WriteLine($"<{word}>");
}

Bir ayırıcı karakterinin her örneği döndürülen dizide bir değer üretir. Ardışık Ayırıcı karakterler boş dizeyi
döndürülen dizide bir değer olarak oluşturur. Bu, bir ayırıcı olarak boşluk kullanan aşağıdaki örnekte görebilirsiniz:

string phrase = "The quick brown fox jumps over the lazy dog.";
string[] words = phrase.Split(' ');

foreach (var word in words)


{
System.Console.WriteLine($"<{word}>");
}

Bu davranış, tablo verilerini temsil eden, virgülle ayrılmış değerler (CSV ) dosyaları gibi biçimlerin daha kolay
olmasını sağlar. Ardışık virgüller boş bir sütunu temsil eder.
Döndürülen dizide boş dizeleri hariç tutmak için isteğe bağlı bir StringSplitOptions.RemoveEmptyEntries
parametresi geçirebilirsiniz. Döndürülen koleksiyonun daha karmaşık işlenmesi için, LINQ kullanarak sonuç
sırasını değiştirebilirsiniz.
String.Split birden çok ayırıcı karakter kullanabilir. Aşağıdaki örnek boşluk, virgül, nokta, iki nokta üst üste ve
sekmelerini kullanır, bu karakterleri içeren bir dizide Split. Kodun alt kısmındaki döngü döndürülen dizideki her bir
sözcüğü görüntüler.
char[] delimiterChars = { ' ', ',', '.', ':', '\t' };

string text = "one\ttwo three:four,five six seven";


System.Console.WriteLine($"Original text: '{text}'");

string[] words = text.Split(delimiterChars);


System.Console.WriteLine($"{words.Length} words in text:");

foreach (var word in words)


{
System.Console.WriteLine($"<{word}>");
}

Herhangi bir ayırıcıdaki ardışık örnekler, çıkış dizisinde boş dize üretir:

char[] delimiterChars = { ' ', ',', '.', ':', '\t' };

string text = "one\ttwo :,five six seven";


System.Console.WriteLine($"Original text: '{text}'");

string[] words = text.Split(delimiterChars);


System.Console.WriteLine($"{words.Length} words in text:");

foreach (var word in words)


{
System.Console.WriteLine($"<{word}>");
}

String.Split dize dizisini alabilir (tek karakterler yerine hedef dizeyi ayrıştırmak için ayırıcılar olarak davranan
karakter dizileri).

string[] separatingStrings = { "<<", "..." };

string text = "one<<two......three<four";


System.Console.WriteLine($"Original text: '{text}'");

string[] words = text.Split(separatingStrings, System.StringSplitOptions.RemoveEmptyEntries);


System.Console.WriteLine($"{words.Length} substrings in text:");

foreach (var word in words)


{
System.Console.WriteLine(word);
}

Bu örnekleri, GitHub deponuzdakikoda bakarak deneyebilirsiniz. Ya da örnekleri zip dosyası olarakindirebilirsiniz.

Ayrıca bkz.
C# Programlama Kılavuzu
Dizeler
.NET normal Ifadeleri
Birden çok dizeyi birleştirme (C# kılavuz)
25.11.2019 • 5 minutes to read • Edit Online

Birleştirme , bir dizeyi başka bir dizenin sonuna ekleme işlemidir. Dizeleri + işlecini kullanarak birleştirebilirsiniz.
Dize sabit değerleri ve dize sabitleri için birleştirme, derleme zamanında oluşur; çalışma zamanı birleştirme
gerçekleşmez. Dize değişkenleri için, birleştirme yalnızca çalışma zamanında gerçekleşir.

NOTE
Bu makalede, C# örnekleri çalıştırmak Try.NET satır içi kod Çalıştırıcısı ve oyun alanı. Seçin çalıştırma bir etkileşimli
penceresinde bir örnek çalıştırmak için düğme. Kod yürüttükten sonra değiştirmek ve seçerek değiştirilmiş kodu çalıştırmak
çalıştırma yeniden. Değiştirilmiş ya da çalıştırmalarını etkileşimli pencerede kod ya da derleme başarısız olursa, tüm C#
Derleyici hata iletilerini etkileşimli pencere görüntüler.

Aşağıdaki örnek, kaynak kodda okunabilirliğini geliştirmek için bir uzun dize sabit değerini daha küçük dizelere
bölmek için birleştirme kullanır. Bu parçalar, derleme zamanında tek bir dizeye birleştirilir.Dahil edilen dizelerin
sayısından bağımsız olarak, çalışma zamanı performans maliyeti yoktur.

// Concatenation of literals is performed at compile time, not run time.


string text = "Historically, the world of data and the world of objects " +
"have not been well integrated. Programmers work in C# or Visual Basic " +
"and also in SQL or XQuery. On the one side are concepts such as classes, " +
"objects, fields, inheritance, and .NET Framework APIs. On the other side " +
"are tables, columns, rows, nodes, and separate languages for dealing with " +
"them. Data types often require translation between the two worlds; there are " +
"different standard functions. Because the object world has no notion of query, a " +
"query can only be represented as a string without compile-time type checking or " +
"IntelliSense support in the IDE. Transferring data from SQL tables or XML trees to " +
"objects in memory is often tedious and error-prone.";

System.Console.WriteLine(text);

Dize değişkenlerini birleştirmek için + veya += işleçlerini, dize ilişkilendirmeyi veya String.Format, String.Concat,
String.Join veya StringBuilder.Append yöntemlerini kullanabilirsiniz. + işleci kullanımı kolaydır ve sezgisel kod
sağlar. Tek bir ifadede birkaç + işleç kullansanız bile, dize içeriği yalnızca bir kez kopyalanır. Aşağıdaki kod, dizeleri
birleştirmek için + ve += işleçlerini kullanma örneklerini gösterir:

string userName = "<Type your name here>";


string dateString = DateTime.Today.ToShortDateString();

// Use the + and += operators for one-time concatenations.


string str = "Hello " + userName + ". Today is " + dateString + ".";
System.Console.WriteLine(str);

str += " How are you today?";


System.Console.WriteLine(str);

Bazı ifadelerde, aşağıdaki kodda gösterildiği gibi dize ilişkilendirmeyi kullanarak dizeleri birleştirmek daha kolay
olur:
string userName = "<Type your name here>";
string date = DateTime.Today.ToShortDateString();

// Use string interpolation to concatenate strings.


string str = $"Hello {userName}. Today is {date}.";
System.Console.WriteLine(str);

str = $"{str} How are you today?";


System.Console.WriteLine(str);

NOTE
Dize birleştirme işlemlerinde, C# derleyici null bir dizeyi boş bir dize ile aynı şekilde değerlendirir.

Dizeleri birleştirme yöntemi String.Format. Bu yöntem, az sayıda bileşen dizesinden bir dize oluştururken iyi sonuç
verir.
Diğer durumlarda dizeleri bir döngüde birleştiriyor olabilirsiniz; burada, hangi kaynak dizeleri birleştirmiş
olduğunuzu ve kaynak dizelerinin gerçek sayısı çok büyük olabilir. StringBuilder sınıfı bu senaryolar için
tasarlanmıştır. Aşağıdaki kod dizeleri birleştirmek için StringBuilder sınıfının Append yöntemini kullanır.

// Use StringBuilder for concatenation in tight loops.


var sb = new System.Text.StringBuilder();
for (int i = 0; i < 20; i++)
{
sb.AppendLine(i.ToString());
}
System.Console.WriteLine(sb.ToString());

Dize birleştirmesi veya StringBuilder sınıfı seçme nedenleri hakkında daha fazla bilgi edinebilirsiniz
Bir koleksiyondaki dizeleri birleştirmek için başka bir seçenek de String.Concat yöntemi kullanmaktır. Kaynak
dizelerin bir delikile ayrılması gerekiyorsa String.Join yöntemi kullanın. Aşağıdaki kod her iki yöntemi kullanarak
bir sözcük dizisini birleştirir:

string[] words = { "The", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog." };

var unreadablePhrase = string.Concat(words);


System.Console.WriteLine(unreadablePhrase);

var readablePhrase = string.Join(" ", words);


System.Console.WriteLine(readablePhrase);

En sonda, bir koleksiyondaki dizeleri birleştirmek için LINQ ve Enumerable.Aggregate yöntemi kullanabilirsiniz.
Bu yöntem, kaynak dizelerini bir lambda ifadesi kullanarak birleştirir. Lambda ifadesi, her bir dizeyi var olan
birikme ekleme işini yapar. Aşağıdaki örnek, dizideki her sözcük arasına bir boşluk ekleyerek bir sözcük dizisini
birleştirir:

string[] words = { "The", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog." };

var phrase = words.Aggregate((partialPhrase, word) =>$"{partialPhrase} {word}");


System.Console.WriteLine(phrase);

Bu örnekleri, GitHub deponuzdakikoda bakarak deneyebilirsiniz. Ya da örnekleri zip dosyası olarakindirebilirsiniz.


Ayrıca bkz.
String
StringBuilder
C# Programlama Kılavuzu
Dizeler
.NET 'teki tarih ve saat dizelerini ayrıştırma
31.10.2019 • 10 minutes to read • Edit Online

Nesneleri DateTime dönüştürmek için ayrıştırma dizeleri, tarihlerin ve saatlerin nasıl metin olarak temsil edildiği
hakkında bilgi belirtmenizi gerektirir. Farklı kültürler gün, ay ve yıl için farklı siparişler kullanır. Bazı zaman
temsilleri 24 saatlik bir saat kullanır, diğerleri "har" ve "PM" i belirler. Bazı uygulamaların yalnızca tarih olması
gerekir. Diğerlerinin yalnızca saat olması gerekir. Hala başkalarının hem tarih hem de saati belirtmesi gerekir.
Dizeleri DateTime nesnelerine dönüştüren Yöntemler, istediğiniz biçimler ve uygulamanızın ihtiyaç duyacağı bir
tarih ve saatin öğeleri hakkında ayrıntılı bilgi sağlamanıza olanak tanır. Metni doğru bir DateTimedönüştürmek için
üç alt görev vardır:
1. Tarih ve saati temsil eden metnin beklenen biçimini belirtmeniz gerekir.
2. Bir tarih saat biçimi için kültürü belirtebilirsiniz.
3. Metin temsilindeki eksik bileşenlerin tarih ve saat içinde nasıl ayarlanacağını belirtebilirsiniz.
Parse ve TryParse yöntemleri bir tarih ve saatin birçok yaygın temsilini dönüştürür. ParseExact ve TryParseExact
yöntemleri, bir tarih ve saat biçim dizesi tarafından belirtilen düzene uyan bir dize gösterimini dönüştürür.
(Ayrıntılar için Standart Tarih ve saat biçim dizeleri ve özel tarih ve saat biçim dizeleri hakkındaki makalelere bakın.)
Geçerli DateTimeFormatInfo nesnesi, metnin tarih ve saat olarak nasıl yorumlanacağı üzerinde daha fazla denetim
sağlar. DateTimeFormatInfo özellikleri, tarih ve saat ayırıcıları ve ay, gün ve eras adlarını ve "har" ve "PM"
gösterimlerinin biçimini anlatmaktadır. Geçerli iş parçacığı kültürü geçerli kültürü temsil eden bir
DateTimeFormatInfo sağlar. Belirli bir kültür veya özel ayarlar istiyorsanız, ayrıştırma yönteminin IFormatProvider
parametresini belirtirsiniz. IFormatProvider parametresi için bir kültürü veya DateTimeFormatInfo nesnesini
temsil eden bir CultureInfo nesnesi belirtin.
Bir tarih veya saati temsil eden metinde bazı bilgiler eksik olabilir. Örneğin, çoğu kişi "Mart 12" tarihini geçerli yılı
temsil eder. Benzer şekilde, "Mart 2018", 2018 yılında Mart ayının ayı temsil eder. Süreyi temsil eden metin
yalnızca saat, dakika ve bir har/PM belirtimi içerir. Ayrıştırma yöntemleri, makul Varsayılanları kullanarak bu eksik
bilgileri işler:
Yalnızca saat varsa, tarih kısmı geçerli tarihi kullanır.
Yalnızca tarih varsa, saat kısmı gece yarısı olur.
Yıl bir tarih içinde belirtilmediğinde, geçerli yıl kullanılır.
Ayın günü belirtilmediğinde ayın ilk adı kullanılır.
Tarih dizede varsa, bu, ayı ve günü veya yıldan birini içermelidir. Zaman varsa, saat ve dakika ya da har/PM
göstergesini içermelidir.
Bu varsayılan değerleri geçersiz kılmak için NoCurrentDateDefault sabiti belirtebilirsiniz. Bu sabiti kullandığınızda,
eksik yıl, ay veya gün özellikleri 1 değere ayarlanır. Parse kullanan son örnek bu davranışı gösterir.
Bir tarih ve saat bileşenine ek olarak, bir tarih ve saatin dize gösterimi, zamanın Eşgüdümlü Evrensel Saat (UTC ) ne
kadar farklı olduğunu gösteren bir uzaklığa sahip olabilir. Örneğin, "2/14/2007 5:32:00 -7:00" dizesi UTC 'den
önceki yedi saat olan bir zamanı tanımlar. Bir zaman içindeki dize gösteriminden bir konum atlanırsa, ayrıştırma,
Kind özelliği DateTimeKind.Unspecifiedolarak ayarlanmış bir DateTime nesnesi döndürür. Bir fark belirtilmişse,
ayrıştırma, Kind özelliği DateTimeKind.Local olarak ayarlanmış ve değeri makinenizin yerel saat dilimine
ayarlanmış olarak DateTime bir nesne döndürür. Ayrıştırma yöntemiyle bir DateTimeStyles değeri kullanarak bu
davranışı değiştirebilirsiniz.
Biçim sağlayıcısı, belirsiz bir sayısal tarihi yorumlamak için de kullanılır. "02/03/04" dizesi ile temsil edilen tarihin
hangi bileşenlerinin ay, gün ve yıl olduğunu net değildir. Bileşenler, biçim sağlayıcısındaki benzer Tarih biçimlerinin
sırasına göre yorumlanır.

MAZ
Aşağıdaki örnek, bir string DateTimedönüştürmek için DateTime.Parse yönteminin kullanımını gösterir. Bu
örnek, geçerli iş parçacığıyla ilişkili kültürü kullanır. Geçerli kültür ile ilişkili CultureInfo giriş dizesini ayrıştıramaz,
bir FormatException oluşturulur.

TIP
Bu makaledeki C# tüm örnekler tarayıcınızda çalışır. Çıktıyı görmek için Çalıştır düğmesine basın. Ayrıca, kendinizi denemek
için de düzenleyebilirsiniz.

NOTE
Bu örnekler, hem hem de C# vb. için GitHub docs deposunda mevcuttur. Ya da projeyi bir veya C# vbiçin bir ZipFile olarak
indirebilirsiniz.

string dateInput = "Jan 1, 2009";


DateTime parsedDate = DateTime.Parse(dateInput);
Console.WriteLine(parsedDate);
// Displays the following output on a system whose culture is en-US:
// 1/1/2009 12:00:00 AM

Dim MyString As String = "Jan 1, 2009"


Dim MyDateTime As DateTime = DateTime.Parse(MyString)
Console.WriteLine(MyDateTime)
' Displays the following output on a system whose culture is en-US:
' 1/1/2009 12:00:00 AM

Ayrıca, bir dizeyi ayrıştırdığınızda biçimlendirme kuralları kullanılan kültürü açık bir şekilde tanımlayabilirsiniz.
CultureInfo.DateTimeFormat özelliği tarafından döndürülen standart DateTimeFormatInfo nesnelerinden birini
belirtirsiniz. Aşağıdaki örnek bir DateTimebir Alman dizeyi ayrıştırmak için bir biçim sağlayıcısı kullanır. de-DE
kültürünü temsil eden bir CultureInfo oluşturur. Bu CultureInfo nesnesi bu dizenin başarıyla ayrıştırılmasını
sağlar. Bu, CurrentThreadCurrentCulture hangi ayarın olduğunu önceden açar.

CultureInfo MyCultureInfo = new CultureInfo("de-DE");


string MyString = "12 Juni 2008";
DateTime MyDateTime = DateTime.Parse(MyString, MyCultureInfo);
Console.WriteLine(MyDateTime);
// The example displays the following output:
// 6/12/2008 12:00:00 AM

Dim MyCultureInfo As New CultureInfo("de-DE")


Dim MyString As String = "12 Juni 2008"
Dim MyDateTime As DateTime = DateTime.Parse(MyString, MyCultureInfo)
Console.WriteLine(MyDateTime)
' The example displays the following output:
' 6/12/2008 12:00:00 AM

Ancak, özel biçim sağlayıcıları belirtmek için Parse yönteminin aşırı yüklerini kullanabilseniz de, yöntem standart
olmayan biçimlerin ayrıştırılmasını desteklemez. Standart olmayan biçimde ifade edilen bir tarih ve saati
ayrıştırmak için, bunun yerine ParseExact yöntemini kullanın.
Aşağıdaki örnek, belirtilmeyen alanlar için geçerli tarih ve saat bilgilerinin DateTime eklenmemesi gerektiğini
belirtmek için DateTimeStyles numaralandırmayı kullanır.

CultureInfo MyCultureInfo = new CultureInfo("de-DE");


string MyString = "12 Juni 2008";
DateTime MyDateTime = DateTime.Parse(MyString, MyCultureInfo,
DateTimeStyles.NoCurrentDateDefault);
Console.WriteLine(MyDateTime);
// The example displays the following output if the current culture is en-US:
// 6/12/2008 12:00:00 AM

Dim MyCultureInfo As New CultureInfo("de-DE")


Dim MyString As String = "12 Juni 2008"
Dim MyDateTime As DateTime = DateTime.Parse(MyString, MyCultureInfo,
DateTimeStyles.NoCurrentDateDefault)
Console.WriteLine(MyDateTime)
' The example displays the following output if the current culture is en-US:
' 6/12/2008 12:00:00 AM

ParseExact
DateTime.ParseExact yöntemi, belirtilen dize desenlerinden birine uyuyorsa bir dizeyi DateTime nesnesine
dönüştürür. Belirtilen formlardan biri olmayan bir dize bu yönteme geçirildiğinde, bir FormatException oluşturulur.
Standart Tarih ve saat biçimi belirticilerden birini ya da özel biçim belirticileri birleşimini belirtebilirsiniz. Özel
biçim belirticilerini kullanarak, özel bir tanıma dizesi oluşturmanız mümkündür. Belirticilerin açıklaması için
Standart Tarih ve saat biçimi dizeleri ve özel tarih ve saat biçim dizelerihakkındaki konulara bakın.
Aşağıdaki örnekte DateTime.ParseExact yöntemi ayrıştırmak için bir dize nesnesi geçti, ardından bir biçim
belirticisi ve ardından bir CultureInfo nesnesi. Bu ParseExact yöntemi yalnızca en-US kültürünün uzun tarih
modelini izleyen dizeleri ayrıştırabilirler.

CultureInfo MyCultureInfo = new CultureInfo("en-US");


string[] MyString = { " Friday, April 10, 2009", "Friday, April 10, 2009" };
foreach (string dateString in MyString)
{
try
{
DateTime MyDateTime = DateTime.ParseExact(dateString, "D", MyCultureInfo);
Console.WriteLine(MyDateTime);
}
catch (FormatException)
{
Console.WriteLine("Unable to parse '{0}'", dateString);
}
}
// The example displays the following output:
// Unable to parse ' Friday, April 10, 2009'
// 4/10/2009 12:00:00 AM
Dim MyCultureInfo As New CultureInfo("en-US")
Dim MyString() As String = {" Friday, April 10, 2009", "Friday, April 10, 2009"}
For Each dateString As String In MyString
Try
Dim MyDateTime As DateTime = DateTime.ParseExact(dateString, "D",
MyCultureInfo)
Console.WriteLine(MyDateTime)
Catch e As FormatException
Console.WriteLine("Unable to parse '{0}'", dateString)
End Try
Next
' The example displays the following output:
' Unable to parse ' Friday, April 10, 2009'
' 4/10/2009 12:00:00 AM

Parse ve ParseExact yöntemlerinin her bir aşırı yüklemesinin, dizenin biçimlendirmesi hakkında kültüre özgü
bilgiler sağlayan bir IFormatProvider parametresi de vardır. Bu IFormatProvider nesnesi,
CultureInfo.DateTimeFormat özelliği tarafından döndürülen standart bir kültürü veya DateTimeFormatInfo
nesnesini temsil eden bir CultureInfo nesnesidir. ParseExact Ayrıca bir veya daha fazla özel tarih ve saat biçimi
tanımlayan ek bir dize veya dize dizisi bağımsız değişkeni kullanır.

Ayrıca bkz.
Dizeleri Ayrıştırma
Biçimlendirme Türleri
.NET içinde Tür Dönüştürme
Standart Tarih ve saat biçimleri
Özel tarih ve saat biçim dizeleri
Dizeleri arama
11.12.2019 • 6 minutes to read • Edit Online

Dizelerde metin aramak için iki ana strateji kullanabilirsiniz. String sınıfının yöntemleri belirli metni arar. Normal
ifadeler metin halinde desenler arar.

NOTE
Bu makalede, C# örnekleri çalıştırmak Try.NET satır içi kod Çalıştırıcısı ve oyun alanı. Seçin çalıştırma bir etkileşimli
penceresinde bir örnek çalıştırmak için düğme. Kod yürüttükten sonra değiştirmek ve seçerek değiştirilmiş kodu çalıştırmak
çalıştırma yeniden. Değiştirilmiş ya da çalıştırmalarını etkileşimli pencerede kod ya da derleme başarısız olursa, tüm C#
Derleyici hata iletilerini etkileşimli pencere görüntüler.

System.String sınıfı için bir diğer ad olan dize türü, bir dizenin içeriğini aramak için bir dizi yararlı yöntem sağlar.
Bunlar arasında Contains, StartsWith, EndsWith, IndexOfLastIndexOf. System.Text.RegularExpressions.Regex
sınıfı, metinlerdeki desenleri aramak için zengin bir sözlük sağlar. Bu makalede, bu teknikleri ve gereksinimleriniz
için en iyi yöntemi nasıl seçebileceğinizi öğreneceksiniz.

Dize metin içeriyor mu?


String.Contains, String.StartsWith ve String.EndsWith yöntemleri belirli metin için bir dize arar. Aşağıdaki örnek,
bu yöntemlerin ve büyük/küçük harfe duyarsız arama kullanan bir varyasyonın her birini göstermektedir:

string factMessage = "Extension methods have all the capabilities of regular static methods.";

// Write the string and include the quotation marks.


Console.WriteLine($"\"{factMessage}\"");

// Simple comparisons are always case sensitive!


bool containsSearchResult = factMessage.Contains("extension");
Console.WriteLine($"Starts with \"extension\"? {containsSearchResult}");

// For user input and strings that will be displayed to the end user,
// use the StringComparison parameter on methods that have it to specify how to match strings.
bool ignoreCaseSearchResult = factMessage.StartsWith("extension",
System.StringComparison.CurrentCultureIgnoreCase);
Console.WriteLine($"Starts with \"extension\"? {ignoreCaseSearchResult} (ignoring case)");

bool endsWithSearchResult = factMessage.EndsWith(".", System.StringComparison.CurrentCultureIgnoreCase);


Console.WriteLine($"Ends with '.'? {endsWithSearchResult}");

Yukarıdaki örnekte bu yöntemlerin kullanılması için önemli bir nokta gösterilmektedir. Aramalar, varsayılan olarak
büyük/küçük harfe duyarlıdır . Büyük/küçük harfe duyarsız arama belirtmek için
StringComparison.CurrentCultureIgnoreCase enum değerini kullanırsınız.

Aranan metin bir dizede nerede oluşuyor?


IndexOf ve LastIndexOf yöntemleri, dizelerde metin de arar. Bu yöntemler, aranan metnin konumunu döndürür.
Metin bulunmazsa -1 döndürür. Aşağıdaki örnek, "Methods" sözcüğünün ilk ve son oluşumu için bir arama
gösterir ve içindeki metni görüntüler.
string factMessage = "Extension methods have all the capabilities of regular static methods.";

// Write the string and include the quotation marks.


Console.WriteLine($"\"{factMessage}\"");

// This search returns the substring between two strings, so


// the first index is moved to the character just after the first string.
int first = factMessage.IndexOf("methods") + "methods".Length;
int last = factMessage.LastIndexOf("methods");
string str2 = factMessage.Substring(first, last - first);
Console.WriteLine($"Substring between \"methods\" and \"methods\": '{str2}'");

Normal ifadeler kullanarak belirli bir metni bulma


System.Text.RegularExpressions.Regex sınıfı, dizelerde arama yapmak için kullanılabilir. Bu aramalar, basit ve
karmaşık metin desenlerinden karmaşıklığa göre değişebilir.
Aşağıdaki kod örneği, bir tümcede "The" veya "onların" sözcüğünü arar, büyük/küçük harf durumunu yoksayar.
Statik yöntem Regex.IsMatch aramayı gerçekleştirir. Aranacak dizeyi ve arama düzenlerini verirsiniz. Bu durumda,
üçüncü bir bağımsız değişken büyük/küçük harfe duyarsız arama belirler. Daha fazla bilgi için bkz.
System.Text.RegularExpressions.RegexOptions.
Arama deseninin aranacağı metin açıklanır. Aşağıdaki tabloda, arama deseninin her bir öğesi açıklanmaktadır.
(Aşağıdaki tablo, bir C# dizede \\ olarak kaçılması gereken tek \ kullanır).

KALIP AÇIKLAMA

the "The" metni Eşleştir

(EIR)? 0 veya 1 "EIR" tekrarını Eşleştir

\s boşluk karakteriyle Eşleştir

string[] sentences =
{
"Put the water over there.",
"They're quite thirsty.",
"Their water bottles broke."
};

string sPattern = "the(ir)?\\s";

foreach (string s in sentences)


{
Console.Write($"{s,24}");

if (System.Text.RegularExpressions.Regex.IsMatch(s, sPattern,
System.Text.RegularExpressions.RegexOptions.IgnoreCase))
{
Console.WriteLine($" (match for '{sPattern}' found)");
}
else
{
Console.WriteLine();
}
}
TIP
Tam bir dizeyi ararken string yöntemler genellikle daha iyi seçimlerdir. Normal ifadeler, bir kaynak dizesindeki bazı desenler
aranırken daha iyidir.

Bir dize bir düzene uyar mi?


Aşağıdaki kod, dizideki her bir dizenin biçimini doğrulamak için normal ifadeleri kullanır. Doğrulama, her bir
dizenin üç basamaklı rakam ile ayrıldığı bir telefon numarası biçimine sahip olmasını gerektirir, ilk iki grup üç
basamak içerir ve üçüncü grup dört basamak içerir. Arama deseninin ^\\d{3}-\\d{3}-\\d{4}$ normal ifadesi
kullanılır. Daha fazla bilgi için bkz. normal Ifade dili-hızlı başvuru.

KALIP AÇIKLAMA

^ dizenin başlangıcını eşleştirir

\d{3} tam 3 basamaklı karakterle eşleşir

- '-' karakteriyle eşleşir

\d{3} tam 3 basamaklı karakterle eşleşir

- '-' karakteriyle eşleşir

\d{4} tam 4 basamaklı karakterle eşleşir

$ dizenin sonuyla eşleşir


string[] numbers =
{
"123-555-0190",
"444-234-22450",
"690-555-0178",
"146-893-232",
"146-555-0122",
"4007-555-0111",
"407-555-0111",
"407-2-5555",
"407-555-8974",
"407-2ab-5555",
"690-555-8148",
"146-893-232-"
};

string sPattern = "^\\d{3}-\\d{3}-\\d{4}$";

foreach (string s in numbers)


{
Console.Write($"{s,14}");

if (System.Text.RegularExpressions.Regex.IsMatch(s, sPattern))
{
Console.WriteLine(" - valid");
}
else
{
Console.WriteLine(" - invalid");
}
}

Bu tek arama deseninin birçok geçerli dizesi eşleşiyor. Normal ifadeler, tek bir metin dizesi yerine bir düzene göre
arama veya doğrulama için daha iyidir.
Bu örnekleri, GitHub deponuzdakikoda bakarak deneyebilirsiniz. Ya da örnekleri zip dosyası olarakindirebilirsiniz.

Ayrıca bkz.
C# Programlama Kılavuzu
Dizeler
LINQ ve Dizeler
System.Text.RegularExpressions.Regex
Normal Ifadeleri .NET Framework
Normal İfade Dili - Hızlı Başvuru
.NET 'teki dizeleri kullanmak için en iyi uygulamalar
C# dize içeriklerini değiştirme
25.11.2019 • 9 minutes to read • Edit Online

Bu makalede, var olan bir string değiştirerek string oluşturmak için çeşitli teknikler gösterilmektedir. Gösterilen
tüm teknikler, değişikliklerin sonucunu yeni bir string nesne olarak döndürür. Bunu açıkça göstermek için
örneklerin hepsi, sonucu yeni bir değişkende depolar. Ardından, her bir örneği çalıştırdığınızda hem özgün string
hem de değişiklikten kaynaklanan string inceleyebilirsiniz.

NOTE
Bu makalede, C# örnekleri çalıştırmak Try.NET satır içi kod Çalıştırıcısı ve oyun alanı. Seçin çalıştırma bir etkileşimli
penceresinde bir örnek çalıştırmak için düğme. Kod yürüttükten sonra değiştirmek ve seçerek değiştirilmiş kodu çalıştırmak
çalıştırma yeniden. Değiştirilmiş ya da çalıştırmalarını etkileşimli pencerede kod ya da derleme başarısız olursa, tüm C#
Derleyici hata iletilerini etkileşimli pencere görüntüler.

Bu makalede çeşitli teknikler verilmiştir. Varolan metni değiştirebilirsiniz. Desen arayabilir ve eşleşen metni başka
metinle değiştirebilirsiniz. Bir dizeyi bir karakter dizisi olarak kabul edebilirsiniz. Beyaz alanı kaldırmak için
kullanışlı yöntemler de kullanabilirsiniz. Senaryonuza en yakından eşleşen teknikleri seçmeniz gerekir.

Metni Değiştir
Aşağıdaki kod, var olan metni bir değiştirme ile değiştirerek yeni bir dize oluşturur.

string source = "The mountains are behind the clouds today.";

// Replace one substring with another with String.Replace.


// Only exact matches are supported.
var replacement = source.Replace("mountains", "peaks");
Console.WriteLine($"The source string is <{source}>");
Console.WriteLine($"The updated string is <{replacement}>");

Yukarıdaki kod, dizelerin bu sabit özelliğini gösterir. Önceki örnekte, source özgün dizesinin değiştirilmediğini
görebilirsiniz. String.Replace yöntemi, değişiklikleri içeren yeni bir string oluşturur.
Replace yöntemi dizeleri ya da tek karakterleri değiştirebilir. Her iki durumda da, aranan metnin her oluşumu
değiştirilmiştir. Aşağıdaki örnek tüm ' ' karakterlerini '_' ile değiştirir:

string source = "The mountains are behind the clouds today.";

// Replace all occurrences of one char with another.


var replacement = source.Replace(' ', '_');
Console.WriteLine(source);
Console.WriteLine(replacement);

Kaynak dize değiştirilmez ve yeni bir dize değiştirme ile birlikte döndürülür.

Boşluğu Kırp
Baştaki veya sondaki boşlukları kaldırmak için String.Trim, String.TrimStartve String.TrimEnd yöntemlerini
kullanabilirsiniz. Aşağıdaki kod, her birine bir örnek gösterir. Kaynak dize değişmez; Bu yöntemler, değiştirilen
içeriğe sahip yeni bir dize döndürür.
// Remove trailing and leading white space.
string source = " I'm wider than I need to be. ";
// Store the results in a new string variable.
var trimmedResult = source.Trim();
var trimLeading = source.TrimStart();
var trimTrailing = source.TrimEnd();
Console.WriteLine($"<{source}>");
Console.WriteLine($"<{trimmedResult}>");
Console.WriteLine($"<{trimLeading}>");
Console.WriteLine($"<{trimTrailing}>");

Metni kaldır
String.Remove yöntemi kullanarak bir dizeden metin kaldırabilirsiniz. Bu yöntem, belirli bir dizinden başlayarak
birkaç karakteri kaldırır. Aşağıdaki örnek, bir dizeden metin kaldırmak için Remove tarafından izlenen
String.IndexOf nasıl kullanacağınızı gösterir:

string source = "Many mountains are behind many clouds today.";


// Remove a substring from the middle of the string.
string toRemove = "many ";
string result = string.Empty;
int i = source.IndexOf(toRemove);
if (i >= 0)
{
result= source.Remove(i, toRemove.Length);
}
Console.WriteLine(source);
Console.WriteLine(result);

Eşleşen desenleri Değiştir


Metin eşleştirme desenlerini, büyük olasılıkla bir desenle tanımlanan yeni metinle değiştirmek için Normal
ifadeleri kullanabilirsiniz. Aşağıdaki örnek, bir kaynak dizesindeki bir düzeni bulmak ve uygun büyük harfle
değiştirmek için System.Text.RegularExpressions.Regex sınıfını kullanır. Regex.Replace(String, String,
MatchEvaluator, RegexOptions) yöntemi, bağımsız değişkenlerinden biri olarak değiştirme mantığını sağlayan bir
işlevi alır. Bu örnekte, LocalReplaceMatchCase işlevi örnek yöntemin içinde belirtilen yerel bir işlevdir .
LocalReplaceMatchCase , doğru büyük küçük harfe sahip değiştirme dizesini oluşturmak için
System.Text.StringBuilder sınıfını kullanır.
Normal ifadeler, bilinen metinler yerine bir kalıbı izleyen metni aramak ve değiştirmek için kullanışlıdır.Daha fazla
ayrıntı için bkz. dizeleri arama . "The\s" arama deseninin "The" sözcüğünü ve ardından bir boşluk karakteri arar. Bu
düzenin bu bölümü, kaynak dizede "orada" ile eşleşmemesini sağlar. Normal ifade dili öğeleri hakkında daha fazla
bilgi için bkz. normal Ifade dili-hızlı başvuru.
string source = "The mountains are still there behind the clouds today.";

// Use Regex.Replace for more flexibility.


// Replace "the" or "The" with "many" or "Many".
// using System.Text.RegularExpressions
string replaceWith = "many ";
source = System.Text.RegularExpressions.Regex.Replace(source, "the\\s", LocalReplaceMatchCase,
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
Console.WriteLine(source);

string LocalReplaceMatchCase(System.Text.RegularExpressions.Match matchExpression)


{
// Test whether the match is capitalized
if (Char.IsUpper(matchExpression.Value[0]))
{
// Capitalize the replacement string
System.Text.StringBuilder replacementBuilder = new System.Text.StringBuilder(replaceWith);
replacementBuilder[0] = Char.ToUpper(replacementBuilder[0]);
return replacementBuilder.ToString();
}
else
{
return replaceWith;
}
}

StringBuilder.ToString yöntemi, StringBuilder nesnesindeki içeriğe sahip sabit bir dize döndürür.

Tek karakterleri değiştirme


Dizeden bir karakter dizisi oluşturabilir, dizinin içeriğini değiştirebilir ve sonra dizinin değiştirilen içeriğinden yeni
bir dize oluşturabilirsiniz.
Aşağıdaki örnek, bir dizedeki bir karakter kümesinin nasıl değiştirileceğini gösterir. İlk olarak, bir karakter dizisi
oluşturmak için ToCharArray() yöntemini kullanır. "Fox" sözcüğünün başlangıç dizinini bulmak için IndexOf
yöntemini kullanır. Sonraki üç karakter, farklı bir sözcükle değiştirilmiştir.Son olarak, güncelleştirilmiş karakter
dizisinden yeni bir dize oluşturulur.

string phrase = "The quick brown fox jumps over the fence";
Console.WriteLine(phrase);

char[] phraseAsChars = phrase.ToCharArray();


int animalIndex = phrase.IndexOf("fox");
if (animalIndex != -1)
{
phraseAsChars[animalIndex++] = 'c';
phraseAsChars[animalIndex++] = 'a';
phraseAsChars[animalIndex] = 't';
}

string updatedPhrase = new string(phraseAsChars);


Console.WriteLine(updatedPhrase);

Dizedeki güvenli olmayan değişiklikler


Güvenli olmayan kod kullanarak, bir dizeyi oluşturulduktan sonra "yerinde" değiştirebilirsiniz. Güvenli olmayan
kod, kodda belirli hata türlerini en aza indirmek için tasarlanan birçok .NET özelliğini atlar. Dize sınıfı sabit bir tür
olarak tasarlandığından, bir dizeyi yerinde değiştirmek için güvenli olmayan kod kullanmanız gerekir.
Oluşturulduktan sonra değeri değişmez. Güvenli olmayan kod, normal string yöntemleri kullanmadan bir
string tarafından kullanılan belleğe erişerek ve değiştirerek bu özelliği atlalar. Aşağıdaki örnek, güvenli olmayan
kod kullanarak bir dizeyi yerinde değiştirmek istediğiniz nadir durumlar için verilmiştir. Örnek, fixed anahtar
sözcüğünün nasıl kullanılacağını göstermektedir. fixed anahtar sözcüğü çöp toplayıcısının (GC ), kod, güvenli
olmayan işaretçi kullanılarak belleğe eriştiği sırada dize nesnesini bellekten taşımasını önler. Ayrıca C# derleyicinin
(Interns) dizelerini dahili olarak depoladığı şekilde, dizelerde güvenli olmayan işlemlerin olası bir yan etkisi
gösterilmektedir. Genel olarak, kesinlikle gerekli olmadığı müddetçe bu tekniği kullanmamanız gerekir. Daha fazla
bilgi için, güvenli olmayan ve düzeltilenmakalelerde daha fazla bilgi edinebilirsiniz. Intern için API başvurusu, dize
oluşturma hakkında bilgi içerir.

unsafe
{
// Compiler will store (intern)
// these strings in same location.
string helloOne = "Hello";
string helloTwo = "Hello";

// Change one string using unsafe code.


fixed (char* p = helloOne)
{
p[0] = 'C';
}

// Both strings have changed.


Console.WriteLine(helloOne);
Console.WriteLine(helloTwo);
}

Bu örnekleri, GitHub deponuzdakikoda bakarak deneyebilirsiniz. Ya da örnekleri zip dosyası olarakindirebilirsiniz.

Ayrıca bkz.
Normal Ifadeleri .NET Framework
Normal İfade Dili - Hızlı Başvuru
C# dizeleri karşılaştırma
25.11.2019 • 16 minutes to read • Edit Online

Dizeleri iki sorudan birini yanıtlayacak şekilde karşılaştırırsınız: "Bu iki dizeniz eşittir mi?" or "Bu dizeler
sıralandığında hangi sırada yerleştirilmesi gerekir?"
Bu iki soru, dize karşılaştırmaları etkileyen faktörlerle karmaşıktır:
Sıra veya dil karşılaştırması seçebilirsiniz.
Büyük/küçük harf önemli seçeneğini belirleyebilirsiniz.
Kültüre özgü karşılaştırmalar seçebilirsiniz.
Dil karşılaştırmaları kültür ve platforma bağımlıdır.

NOTE
Bu makalede, C# örnekleri çalıştırmak Try.NET satır içi kod Çalıştırıcısı ve oyun alanı. Seçin çalıştırma bir etkileşimli
penceresinde bir örnek çalıştırmak için düğme. Kod yürüttükten sonra değiştirmek ve seçerek değiştirilmiş kodu çalıştırmak
çalıştırma yeniden. Değiştirilmiş ya da çalıştırmalarını etkileşimli pencerede kod ya da derleme başarısız olursa, tüm C#
Derleyici hata iletilerini etkileşimli pencere görüntüler.

Dizeleri karşılaştırdığınızda, aralarında bir sıra tanımlarsınız. Karşılaştırmalar, bir dizi dizeyi sıralamak için kullanılır.
Sıra, bilinen bir sıra olduğunda, hem yazılım hem de insanların aranması daha kolay olur. Diğer karşılaştırmalar
dizelerin aynı olup olmadığını kontrol edebilir. Bu sameness denetimleri eşitlik ile benzerdir, ancak büyük/küçük
harf farklılıkları gibi bazı farklılıklar göz ardı edilebilir.

Varsayılan sıralı karşılaştırmalar


Varsayılan olarak en yaygın işlemler şunlardır:
String.CompareTo
String.Equals
String.Equality ve String.Inequality, diğer bir deyişle, eşitlik işleçleri sırasıyla == ve !=

büyük/küçük harfe duyarlı bir sıra karşılaştırması gerçekleştirin ve gerekirse geçerli kültürü kullanın. Aşağıdaki
örnek şunu gösterir:

string root = @"C:\users";


string root2 = @"C:\Users";

bool result = root.Equals(root2);


Console.WriteLine($"Ordinal comparison: <{root}> and <{root2}> are {(result ? "equal." : "not equal.")}");

result = root.Equals(root2, StringComparison.Ordinal);


Console.WriteLine($"Ordinal comparison: <{root}> and <{root2}> are {(result ? "equal." : "not equal.")}");

Console.WriteLine($"Using == says that <{root}> and <{root2}> are {(root == root2 ? "equal" : "not equal")}");

Varsayılan sıra karşılaştırma, dizeleri karşılaştırırken dile göre kuralları hesaba almaz. Her Char nesnesinin ikili
değerini iki dizelerdeki karşılaştırır. Sonuç olarak, varsayılan sıra karşılaştırması de büyük/küçük harfe duyarlıdır.
String.Equals ve == ve != işleçlerini eşitlik testinin String.CompareTo ve Compare(String, String) yöntemleri
kullanılarak dize karşılaştırmasından farklı olduğunu unutmayın. Eşitlik için testler, büyük/küçük harfe duyarlı bir
sıra karşılaştırması gerçekleştirirken, karşılaştırma yöntemleri geçerli kültürü kullanarak büyük/küçük harfe
duyarlı, kültüre duyarlı bir karşılaştırma gerçekleştirir. Varsayılan karşılaştırma yöntemleri genellikle farklı
karşılaştırma türleri gerçekleştirirken, gerçekleştirilecek karşılaştırma türünü açıkça belirten bir aşırı yükleme
çağırarak kodunuzun amacını her zaman açık yapmanızı öneririz.

Büyük/küçük harfe duyarsız sıralı karşılaştırmalar


String.Equals(String, StringComparison) yöntemi, StringComparison.OrdinalIgnoreCase StringComparison
değerini belirtmenizi sağlar büyük/küçük harfe duyarsız bir sıra karşılaştırması için. StringComparison bağımsız
değişkeni için bir StringComparison.OrdinalIgnoreCase değeri belirtirseniz, büyük/küçük harfe duyarsız sıralı
karşılaştırma gerçekleştiren bir statik String.Compare(String, String, StringComparison) yöntemi de vardır. Bunlar
aşağıdaki kodda gösterilmiştir:

string root = @"C:\users";


string root2 = @"C:\Users";

bool result = root.Equals(root2, StringComparison.OrdinalIgnoreCase);


bool areEqual = String.Equals(root, root2, StringComparison.OrdinalIgnoreCase);
int comparison = String.Compare(root, root2, comparisonType: StringComparison.OrdinalIgnoreCase);

Console.WriteLine($"Ordinal ignore case: <{root}> and <{root2}> are {(result ? "equal." : "not equal.")}");
Console.WriteLine($"Ordinal static ignore case: <{root}> and <{root2}> are {(areEqual ? "equal." : "not
equal.")}");
if (comparison < 0)
Console.WriteLine($"<{root}> is less than <{root2}>");
else if (comparison > 0)
Console.WriteLine($"<{root}> is greater than <{root2}>");
else
Console.WriteLine($"<{root}> and <{root2}> are equivalent in order");

Büyük/küçük harfe duyarsız bir sıra karşılaştırması gerçekleştirirken, bu yöntemler sabit kültürünbüyük/küçük harf
kurallarını kullanır.

Dil karşılaştırmaları
Dizeler aynı zamanda geçerli kültür için dil kuralları kullanılarak da sıralanmış olabilir. Bu bazen "sözcük sıralama
düzeni" olarak adlandırılır. Bir dil karşılaştırması gerçekleştirdiğinizde, alfasayısal olmayan bazı Unicode karakterler
atanmış özel ağırlıkya sahip olabilir. Örneğin, "-" tirein, "Co-op" ve "Coop" nin yanında sıralama düzeninde
görünmesini sağlayacak çok küçük bir ağırlığı olabilir. Ayrıca, bazı Unicode karakterler Char örnek dizisine eşdeğer
olabilir. Aşağıdaki örnek, "cadde içinde dans ettikleri" tümceciğini kullanır. Almanya 'da, bir dizede "ss" (U + 0073
U + 0073) ve başka bir dizedeki ' ß ' (U + 00DF ). Dilsel (Windows 'da), "ss", hem "en-US" hem de "de" de "de"
kültürleri için Alman Esszet: ' ß ' karakterine eşittir.
string first = "Sie tanzen auf der Straße.";
string second = "Sie tanzen auf der Strasse.";

Console.WriteLine($"First sentence is <{first}>");


Console.WriteLine($"Second sentence is <{second}>");

bool equal = String.Equals(first, second, StringComparison.InvariantCulture);


Console.WriteLine($"The two strings {(equal == true ? "are" : "are not")} equal.");
showComparison(first, second);

string word = "coop";


string words = "co-op";
string other = "cop";

showComparison(word, words);
showComparison(word, other);
showComparison(words, other);
void showComparison(string one, string two)
{
int compareLinguistic = String.Compare(one, two, StringComparison.InvariantCulture);
int compareOrdinal = String.Compare(one, two, StringComparison.Ordinal);
if (compareLinguistic < 0)
Console.WriteLine($"<{one}> is less than <{two}> using invariant culture");
else if (compareLinguistic > 0)
Console.WriteLine($"<{one}> is greater than <{two}> using invariant culture");
else
Console.WriteLine($"<{one}> and <{two}> are equivalent in order using invariant culture");
if (compareOrdinal < 0)
Console.WriteLine($"<{one}> is less than <{two}> using ordinal comparison");
else if (compareOrdinal > 0)
Console.WriteLine($"<{one}> is greater than <{two}> using ordinal comparison");
else
Console.WriteLine($"<{one}> and <{two}> are equivalent in order using ordinal comparison");
}

Bu örnek, dil karşılaştırmalarının işletim sistemine bağımlı yapısını gösterir. Etkileşimli pencere için ana bilgisayar
bir Linux ana bilgisayarı. Dil ve sıra karşılaştırmaları aynı sonuçları üretir. Aynı örneği bir Windows ana
bilgisayarında çalıştırdıysanız, aşağıdaki çıktıyı görürsünüz:

<coop> is less than <co-op> using invariant culture


<coop> is greater than <co-op> using ordinal comparison
<coop> is less than <cop> using invariant culture
<coop> is less than <cop> using ordinal comparison
<co-op> is less than <cop> using invariant culture
<co-op> is less than <cop> using ordinal comparison

Windows 'da, bir dil karşılaştırmadan sıralı karşılaştırmaya değiştirdiğinizde "COP", "Coop" ve "Co-op" sıralama
düzeni değişir. İki Alman cümle, farklı karşılaştırma türlerini kullanarak farklı şekilde de karşılaştırılır.

Belirli kültürleri kullanan karşılaştırmalar


Bu örnek, en-US ve de serbest kültür için CultureInfo nesnelerini depolar. Karşılaştırmalar, kültüre özgü bir
karşılaştırma sağlamak için CultureInfo nesnesi kullanılarak gerçekleştirilir.
Kullanılan kültür, dil karşılaştırmaları etkiler.Aşağıdaki örnek, "en-US" kültürünü ve "de-DE" kültürünü kullanarak
iki Alman cümle karşılaştırmasına ilişkin sonuçları gösterir:
string first = "Sie tanzen auf der Straße.";
string second = "Sie tanzen auf der Strasse.";

Console.WriteLine($"First sentence is <{first}>");


Console.WriteLine($"Second sentence is <{second}>");

var en = new System.Globalization.CultureInfo("en-US");

// For culture-sensitive comparisons, use the String.Compare


// overload that takes a StringComparison value.
int i = String.Compare(first, second, en, System.Globalization.CompareOptions.None);
Console.WriteLine($"Comparing in {en.Name} returns {i}.");

var de = new System.Globalization.CultureInfo("de-DE");


i = String.Compare(first, second, de, System.Globalization.CompareOptions.None);
Console.WriteLine($"Comparing in {de.Name} returns {i}.");

bool b = String.Equals(first, second, StringComparison.CurrentCulture);


Console.WriteLine($"The two strings {(b ? "are" : "are not")} equal.");

string word = "coop";


string words = "co-op";
string other = "cop";

showComparison(word, words, en);


showComparison(word, other, en);
showComparison(words, other, en);
void showComparison(string one, string two, System.Globalization.CultureInfo culture)
{
int compareLinguistic = String.Compare(one, two, en, System.Globalization.CompareOptions.None);
int compareOrdinal = String.Compare(one, two, StringComparison.Ordinal);
if (compareLinguistic < 0)
Console.WriteLine($"<{one}> is less than <{two}> using en-US culture");
else if (compareLinguistic > 0)
Console.WriteLine($"<{one}> is greater than <{two}> using en-US culture");
else
Console.WriteLine($"<{one}> and <{two}> are equivalent in order using en-US culture");
if (compareOrdinal < 0)
Console.WriteLine($"<{one}> is less than <{two}> using ordinal comparison");
else if (compareOrdinal > 0)
Console.WriteLine($"<{one}> is greater than <{two}> using ordinal comparison");
else
Console.WriteLine($"<{one}> and <{two}> are equivalent in order using ordinal comparison");
}

Kültüre duyarlı karşılaştırmalar genellikle kullanıcılara göre diğer dizeler ile kullanıcılara göre dize girişlerini
karşılaştırmak ve sıralamak için kullanılır. Bu dizelerin karakter ve sıralama kuralları, kullanıcının bilgisayarının
yerel ayarına bağlı olarak değişebilir. Aynı karakterleri içeren dizeler bile geçerli iş parçacığının kültürüne bağlı
olarak farklı şekilde sıralama gösterebilir. Ayrıca, bu örnek kodu bir Windows makinesinde yerel olarak deneyin ve
aşağıdaki sonuçları elde edersiniz:

<coop> is less than <co-op> using en-US culture


<coop> is greater than <co-op> using ordinal comparison
<coop> is less than <cop> using en-US culture
<coop> is less than <cop> using ordinal comparison
<co-op> is less than <cop> using en-US culture
<co-op> is less than <cop> using ordinal comparison

Dil karşılaştırmaları geçerli kültüre bağımlıdır ve işletim sistemine bağımlıdır. Dize karşılaştırmaları ile çalışırken
bunu dikkate almanız gerekir.

Dizelerdeki dil sıralaması ve arama dizeleri


Aşağıdaki örneklerde, geçerli kültüre bağlı bir dil karşılaştırması kullanarak bir dizideki dizelerin nasıl sıralanması
ve aranacağı gösterilmektedir. Bir System.StringComparer parametresi alan statik Array yöntemlerini kullanırsınız.
Bu örnek, geçerli kültürü kullanarak bir dize dizisinin nasıl sıralanacağını gösterir:

string[] lines = new string[]


{
@"c:\public\textfile.txt",
@"c:\public\textFile.TXT",
@"c:\public\Text.txt",
@"c:\public\testfile2.txt"
};

Console.WriteLine("Non-sorted order:");
foreach (string s in lines)
{
Console.WriteLine($" {s}");
}

Console.WriteLine("\n\rSorted order:");

// Specify Ordinal to demonstrate the different behavior.


Array.Sort(lines, StringComparer.CurrentCulture);

foreach (string s in lines)


{
Console.WriteLine($" {s}");
}

Dizi sıralandığında, bir ikili arama kullanarak girdi arayabilirsiniz. Bir ikili arama, koleksiyonun ortasında başlar ve
toplamanın hangi yarısını aranan dizeyi içereceği belirlenir. İzleyen her karşılaştırma, koleksiyonun kalan
bölümünü yarıya böler. Dizi StringComparer.CurrentCulture kullanılarak sıralanır. Yerel işlev ShowWhere dizenin
nerede bulunduğu hakkında bilgi gösterir. Dize bulunmazsa döndürülen değer, nerede bulunursa nerede olacağını
gösterir.
string[] lines = new string[]
{
@"c:\public\textfile.txt",
@"c:\public\textFile.TXT",
@"c:\public\Text.txt",
@"c:\public\testfile2.txt"
};
Array.Sort(lines, StringComparer.CurrentCulture);

string searchString = @"c:\public\TEXTFILE.TXT";


Console.WriteLine($"Binary search for <{searchString}>");
int result = Array.BinarySearch(lines, searchString, StringComparer.CurrentCulture);
ShowWhere<string>(lines, result);

Console.WriteLine($"{(result > 0 ? "Found" : "Did not find")} {searchString}");

void ShowWhere<T>(T[] array, int index)


{
if (index < 0)
{
index = ~index;

Console.Write("Not found. Sorts between: ");

if (index == 0)
Console.Write("beginning of sequence and ");
else
Console.Write($"{array[index - 1]} and ");

if (index == array.Length)
Console.WriteLine("end of sequence.");
else
Console.WriteLine($"{array[index]}.");
}
else
{
Console.WriteLine($"Found at index {index}.");
}
}

Koleksiyonlar içinde sıralı sıralama ve arama


Aşağıdaki kod dizeleri depolamak için System.Collections.Generic.List<T> Collection sınıfını kullanır. Dizeler
List<T>.Sort yöntemi kullanılarak sıralanır. Bu yöntem, iki dizeyi karşılaştıran ve sipariş eden bir temsilciye ihtiyaç
duyuyor. String.CompareTo yöntemi, bu karşılaştırma işlevini sağlar. Örneği çalıştırın ve siparişi gözlemleyin. Bu
sıralama işlemi, sıralı büyük/küçük harfe duyarlı sıralama kullanır. Statik String.Compare yöntemlerini farklı
karşılaştırma kuralları belirtmek için kullanacaksınız.
List<string> lines = new List<string>
{
@"c:\public\textfile.txt",
@"c:\public\textFile.TXT",
@"c:\public\Text.txt",
@"c:\public\testfile2.txt"
};

Console.WriteLine("Non-sorted order:");
foreach (string s in lines)
{
Console.WriteLine($" {s}");
}

Console.WriteLine("\n\rSorted order:");

lines.Sort((left, right) => left.CompareTo(right));


foreach (string s in lines)
{
Console.WriteLine($" {s}");
}

Sıralandığında, dizeler listesi bir ikili arama kullanılarak aranabilir. Aşağıdaki örnek, aynı karşılaştırma işlevi
kullanılarak listelenen sıralanmaların nasıl arandığını gösterir. Yerel işlev ShowWhere aranan metnin nerede
olduğunu gösterir veya şöyle olacaktır:
List<string> lines = new List<string>
{
@"c:\public\textfile.txt",
@"c:\public\textFile.TXT",
@"c:\public\Text.txt",
@"c:\public\testfile2.txt"
};
lines.Sort((left, right) => left.CompareTo(right));

string searchString = @"c:\public\TEXTFILE.TXT";


Console.WriteLine($"Binary search for <{searchString}>");
int result = lines.BinarySearch(searchString);
ShowWhere<string>(lines, result);

Console.WriteLine($"{(result > 0 ? "Found" : "Did not find")} {searchString}");

void ShowWhere<T>(IList<T> collection, int index)


{
if (index < 0)
{
index = ~index;

Console.Write("Not found. Sorts between: ");

if (index == 0)
Console.Write("beginning of sequence and ");
else
Console.Write($"{collection[index - 1]} and ");

if (index == collection.Count)
Console.WriteLine("end of sequence.");
else
Console.WriteLine($"{collection[index]}.");
}
else
{
Console.WriteLine($"Found at index {index}.");
}
}

Her zaman sıralama ve arama için aynı karşılaştırma türünü kullandığınızdan emin olun. Sıralama ve arama için
farklı karşılaştırma türleri kullanılması beklenmeyen sonuçlar veriyor.
System.Collections.Hashtable, System.Collections.Generic.Dictionary<TKey,TValue>ve
System.Collections.Generic.List<T> gibi koleksiyon sınıfları, öğelerin veya anahtarların türü string olduğunda bir
System.StringComparer parametresi alan oluşturuculara sahiptir. Genel olarak, mümkün olan her durumda bu
oluşturucuları kullanmanız ve StringComparer.Ordinal ya da StringComparer.OrdinalIgnoreCase ' i belirtmeniz
gerekir.

Başvuru eşitliği ve dize oluşturma


Örneklerden hiçbiri ReferenceEqualskullanılmadı. Bu yöntem, iki dizenin aynı nesne olup olmadığını belirler. Bu,
dize karşılaştırmalarında tutarsız sonuçlara yol açabilir. Aşağıdaki örnek, öğesinin dize özelliği olan C#özelliğini
gösterir. Bir program iki veya daha fazla özdeş dize değişkeni bildiriyorsa, derleyici bunları aynı konumda depolar.
ReferenceEquals yöntemini çağırarak, iki dizenin bellekteki aynı nesneye gerçekten başvurduğundan emin
olabilirsiniz. String.Copy yöntemini kullanarak, kullanmaktan kaçının. Kopya yapıldıktan sonra, aynı değere sahip
olsalar bile iki dize farklı depolama konumlarına sahiptir. a dizeleri göstermek için aşağıdaki örneği çalıştırın ve
b aynı depolama alanını paylaştıkları anlamına gelir . a ve c dizeleri değildir.
string a = "The computer ate my source code.";
string b = "The computer ate my source code.";

if (String.ReferenceEquals(a, b))
Console.WriteLine("a and b are interned.");
else
Console.WriteLine("a and b are not interned.");

string c = String.Copy(a);

if (String.ReferenceEquals(a, c))
Console.WriteLine("a and c are interned.");
else
Console.WriteLine("a and c are not interned.");

NOTE
Dizelerin eşitliğini test ettiğinizde, gerçekleştirmeyi planladığınız karşılaştırma türünü açıkça belirten yöntemleri kullanmanız
gerekir. Kodunuz çok daha sürdürülebilir ve okunabilir. System.String yöntemlerinin ve StringComparison bir numaralandırma
parametresi alan sınıfların System.Array aşırı yüklerini kullanın. Gerçekleştirilecek karşılaştırma türünü belirtirsiniz. Eşitlik için
test ettiğinizde == ve != işleçlerini kullanmaktan kaçının. String.CompareTo örnek yöntemleri her zaman sıralı büyük
küçük harfe duyarlı karşılaştırma gerçekleştirir. Genellikle dizeleri alfabetik olarak sıralamak için uygundur.

String.Intern yöntemini çağırarak bir dizeyi düzenleyebilir veya varolan bir dizeye başvuru alabilirsiniz. Bir dizenin
birbirine bağlı olup olmadığını anlamak için String.IsInterned yöntemini çağırın.

Ayrıca bkz.
System.Globalization.CultureInfo
System.StringComparer
Dizeler
Dizeleri Karşılaştırma
Uygulamaları Genelleştirme ve Yerelleştirme
Desenler ve as işleçlerini kullanarak güvenli bir şekilde
atama
25.11.2019 • 6 minutes to read • Edit Online

Nesneler çok biçimli olduğundan, bir taban sınıf türü değişkeni türetilmiş bir türütutmak mümkündür. Türetilmiş
türün örnek üyelerine erişmek için değeri türetilmiş türe dönüştürmek gerekir. Ancak, bir atama
InvalidCastExceptionoluşturma riskini oluşturur. C#yalnızca başarılı olacağı zaman bir tür dönüştürme
gerçekleştiren model eşleştirme deyimleri sağlar. C#Ayrıca, bir değerin belirli bir türde olup olmadığını test etmek
için de ve işlecini de sağlar .
Aşağıdaki kod, eşleşen is ifadesini gösterir. Bir yöntem bağımsız değişkenini test eden, olası bir türetilmiş tür
kümesinden biri olup olmadığını belirlemede yöntemler içerir:
class Animal
{
public void Eat() { Console.WriteLine("Eating."); }
public override string ToString()
{
return "I am an animal.";
}
}
class Mammal : Animal { }
class Giraffe : Mammal { }

class SuperNova { }

class Program
{
static void Main(string[] args)
{
Giraffe g = new Giraffe();
FeedMammals(g);

TestForMammals(g);

SuperNova sn = new SuperNova();


TestForMammals(sn);
}

static void FeedMammals(Animal a)


{
// Use the is operator to verify the type
// before performing a cast.
if (a is Mammal m)
{
m.Eat();
}
}

static void TestForMammals(object o)


{
// Alternatively, use the as operator and test for null
// before referencing the variable.
if (o is Mammal m)
{
Console.WriteLine(m.ToString());
}
else
{
// variable 'm' is not in scope here, and can't be used.
Console.WriteLine($"{o.GetType().Name} is not a Mammal");
}
}
}

Önceki örnekte, model eşleştirme sözdiziminin birkaç özelliği gösterilmektedir. if (a is Mammal m) ve


if (o is Mammal m) deyimleri, testi bir başlatma atamasıyla birleştirir. Atama yalnızca test başarılı olduğunda
gerçekleşir. Değişken m , yalnızca atandığı katıştırılmış if deyimindeki kapsamdadır. m aynı yöntemde daha
sonra erişemezsiniz. Etkileşimli pencerede deneyin.
Aşağıdaki örnek kodda gösterildiği gibi, null yapılabilir bir değer türünün bir değere sahip olup olmadığını test
etmek için aynı sözdizimini de kullanabilirsiniz:
class Program
{
static void Main(string[] args)
{
int i = 5;
PatternMatchingNullable(i);

int? j = null;
PatternMatchingNullable(j);

double d = 9.78654;
PatternMatchingNullable(d);

PatternMatchingSwitch(i);
PatternMatchingSwitch(j);
PatternMatchingSwitch(d);
}

static void PatternMatchingNullable(System.ValueType val)


{
if (val is int j) // Nullable types are not allowed in patterns
{
Console.WriteLine(j);
}
else if (val is null) // If val is a nullable type with no value, this expression is true
{
Console.WriteLine("val is a nullable type with the null value");
}
else
{
Console.WriteLine("Could not convert " + val.ToString());
}
}

static void PatternMatchingSwitch(System.ValueType val)


{
switch (val)
{
case int number:
Console.WriteLine(number);
break;
case long number:
Console.WriteLine(number);
break;
case decimal number:
Console.WriteLine(number);
break;
case float number:
Console.WriteLine(number);
break;
case double number:
Console.WriteLine(number);
break;
case null:
Console.WriteLine("val is a nullable type with the null value");
break;
default:
Console.WriteLine("Could not convert " + val.ToString());
break;
}
}
}

Önceki örnek, dönüşümlerle kullanılacak olan diğer model eşleme özelliklerini gösterir. null değeri için özel
olarak denetleyerek null deseninin bir değişkenini test edebilirsiniz. Değişkenin çalışma zamanı değeri null
olduğunda, bir türü denetleyen is bir bildirim her zaman false döndürür. is ifadesiyle eşleşen bir değer null
değer Nullable<int>``int? türüne izin vermez, ancak başka bir değer türü için test edebilirsiniz. Yukarıdaki
örnekteki is desenleri Nullable değer türleriyle sınırlı değildir. Bir başvuru türü değişkeninin bir null değere
sahip olup olmadığını test etmek için bu desenleri de kullanabilirsiniz.
Yukarıdaki örnek ayrıca, değişkenin birçok farklı türden biri olabileceği bir switch deyiminde model eşleştirme
is ifadesini nasıl kullanacağınızı gösterir.

Bir değişkenin verilen bir tür olup olmadığını test etmek istiyorsanız, ancak bunu yeni bir değişkene
atamadıysanız, başvuru türleri ve null yapılabilir türler için is ve as işleçlerini kullanabilirsiniz. Aşağıdaki kod,
bir değişken belirli bir türde ise test için, modelin bir parçası C# olan is ve as deyimlerinin nasıl kullanılacağını
gösterir:

class Animal
{
public void Eat() { Console.WriteLine("Eating."); }
public override string ToString()
{
return "I am an animal.";
}
}
class Mammal : Animal { }
class Giraffe : Mammal { }

class SuperNova { }

class Program
{
static void Main(string[] args)
{
// Use the is operator to verify the type.
// before performing a cast.
Giraffe g = new Giraffe();
UseIsOperator(g);

// Use the as operator and test for null


// before referencing the variable.
UseAsOperator(g);

// Use the as operator to test


// an incompatible type.
SuperNova sn = new SuperNova();
UseAsOperator(sn);

// Use the as operator with a value type.


// Note the implicit conversion to int? in
// the method body.
int i = 5;
UseAsWithNullable(i);

double d = 9.78654;
UseAsWithNullable(d);
}

static void UseIsOperator(Animal a)


{
if (a is Mammal)
{
Mammal m = (Mammal)a;
m.Eat();
}
}

static void UsePatternMatchingIs(Animal a)


{
if (a is Mammal m)
if (a is Mammal m)
{
m.Eat();
}
}

static void UseAsOperator(object o)


{
Mammal m = o as Mammal;
if (m != null)
{
Console.WriteLine(m.ToString());
}
else
{
Console.WriteLine($"{o.GetType().Name} is not a Mammal");
}
}

static void UseAsWithNullable(System.ValueType val)


{
int? j = val as int?;
if (j != null)
{
Console.WriteLine(j);
}
else
{
Console.WriteLine("Could not convert " + val.ToString());
}
}
}

Bu kodu model eşleştirme koduyla karşılaştırarak görebileceğiniz gibi, model eşleştirme sözdizimi, testi ve atamayı
tek bir bildirimde birleştirerek daha sağlam özellikler sağlar. Mümkün olan her seferinde model eşleştirme
sözdizimini kullanın.
Bu örnekleri, GitHub deponuzdakikoda bakarak deneyebilirsiniz. Ya da örnekleri zip dosyası olarakindirebilirsiniz.
.NET derleyici Platformu SDK'sı
23.10.2019 • 11 minutes to read • Edit Online

Söz dizimi ve kodun semantik doğrulama gibi derleyicileri uygulama kodu daha ayrıntılı bir modelini oluşturun.
Bunlar yürütülebilir çıkışı kaynak kodu oluşturmak için bu modeli kullanır. .NET derleyici Platformu SDK'sı, bu
model erişim sağlar. Gittikçe, biz tümleşik geliştirme ortamı (IDE ) özelliklerini kullanan yeniden düzenleme,
IntelliSense, akıllı yeniden adlandırma, "tüm başvuruları Bul" ve "Tanıma Git" gibi bizim üretkenliği artırmak için.
Biz, bizim kod kalitesini ve uygulama oluşturma, yardımcı olmak için kod oluşturucuları geliştirmek için kod
çözümleme araçları dayanır. Bu araçlar daha akıllıca kararlar alın gibi daha fazla ve daha fazla uygulama kodu
işlemek gibi yalnızca derleyiciler oluşturduğunuz modelin erişim. Roslyn API'leri çekirdek görev budur: siyah
kutularını açan açarak ve araçları ve zengin bilgi derleyiciler içinde paylaşmak için son kullanıcılara izin vererek
kodumuz hakkında sahip. Roslyn, aracılığıyla donuk kaynak kod içinde ve nesne kodu çıkış çevirmenler olan yerine
derleyiciler platformları olur: Kodla ilgili görevler araç ve uygulamalar için kullanabileceğiniz API'ler.

.NET derleyici Platformu SDK'sı kavramları


.NET derleyici Platformu SDK'sı kod odaklı araç ve uygulamalar oluşturmak için giriş engel önemli ölçüde azaltır.
C# ve VB dil ve C# ve VB etki alanına özgü diller katıştırma meta programlama kod oluşturma ve dönüştürme,
etkileşimli kullanmak gibi alanlarda yenilik için birçok fırsat oluşturur.
.NET derleyici Platformu SDK'sı oluşturmanıza olanak sağlayan Çözümleyicileri ve kod düzeltme bulun ve
kodlama hatalarını düzeltin. Çözümleyiciler kod yapısını ve söz dizimini anlamak ve düzeltilmesi gereken
yöntemler algılayın. Kod düzeltme çözümleyiciler tarafından bulunan kodlama hatalarını ele almak için bir veya
daha fazla önerilen düzeltmeleri sağlayabilir. Genellikle, bir çözümleyici ve ilişkili kod düzeltmeleri tek bir projede
birlikte paketlenmiştir.
Çözümleyicileri ve kod düzeltmeleri kod anlamak için statik çözümleme kullanın. Bunlar kodu çalıştırmayın ve diğer
test yararlar sağlar. Bunların ancak hatalar, kodlardan veya standart kılavuz doğrulama genellikle neden
uygulamaları işaret olabilir.
.NET derleyici Platformu SDK'sı tek bir inceleyin ve bir C# veya Visual Basic kod temeli anlamanıza olanak
sağlayan API kümesi sağlar. Bu tek bir kod temeli kullanabileceğinizden, çözümleyiciler yazabilirsiniz ve sözdizimsel
ve semantik analizi .NET derleyici Platformu SDK tarafından sağlanan API'leri yararlanarak daha kolay kodu
düzeltir. Derleyici tarafından yapılan çözümleme çoğaltmak büyük görevden serbest, proje veya kitaplığı için yaygın
kodlama hataları bulma ve düzeltme daha odaklı görevini üzerinde odaklanabilirsiniz.
Daha küçük bir avantajı, Çözümleyicileri ve kod düzeltmeleri daha küçük ve çok daha az bellek kendi yazdıysanız
bunlar kod projesinde anlamak için codebase daha Visual Studio'ya yüklendiğinde kullanmak içindir. Derleyici ve
Visual Studio tarafından kullanılan sınıfların yararlanarak kendi statik analiz araçları oluşturabilirsiniz. Bu,
takımınızın Çözümleyicileri kullanabilirsiniz ve IDE'nin performansı belirgin bir etkisi olmadan kod düzeltmeleri
anlamına gelir.
Çözümleyicileri ve kod düzeltmeleri yazmak için üç ana senaryo vardır:
1. Takım kod standartlarımız, koda zorla
2. Kitaplık paketleriyle rehberlik
3. Genel rehberlik

Takım kod standartlarımız, koda zorla


Birçok ekip, kodlama diğer takım üyeleri kod incelemeleriyle aracılığıyla zorlanır standartları vardır. Çözümleyicileri
ve kod düzeltmeleri bu işlem çok daha verimli olmasını sağlayabilir. Bir geliştirici çalışmalarını başkalarıyla ekipte
paylaştığında, kod incelemeleri gerçekleşir. Geliştirici açıklamaları almadan önce yeni bir özelliği tamamlamak için
gereken her zaman yatırım yapmış. Takımın yöntemler eşleşmeyen alışkanlıkları Geliştirici güçlendirir sırada hafta
Git.
Bir geliştirici kodu yazdığı gibi çözümleyiciler çalıştırın. Geliştirici yönergeleri hemen teşvik eder anında geri
bildirim alır. Geliştirici, prototip oluşturma başlar başlamaz uyumlu kod yazma alışkanlıkların. Özellik gözden
geçirmek, insanlar için hazır olduğunda, tüm standart Kılavuzu zorlandı.
Takımlar Çözümleyicileri oluşturabilirsiniz ve kod düzeltmeleri, takım kodlama uygulamaları ihlal en yaygın
yöntemleri arayın. Bu standartları zorlamak için her geliştiricinin makineye yüklenebilir.

Kitaplık paketleriyle rehberlik


NuGet üzerinde .NET geliştiricileri için kullanılabilen zengin kitaplıkları vardır. Bazı Microsoft bu geliyor, bazı
üçüncü taraf şirketlerden ve diğer topluluk üyelerinin ve destekledikleri. Geliştiriciler bu kitaplıkları ile başarılı
olduğunda bu kitaplıklar, daha fazla benimsenmesi ve daha yüksek incelemeleri alın.
Belgeleri sağlamanın yanı sıra Çözümleyicileri ve yaygın bir yanlış kullanımları kitaplığınızın bulun ve kod
düzeltmeleri sağlayabilir. Bu anlık düzeltmeler, geliştiricilerin daha hızlı bir şekilde başarılı yardımcı olur.
Çözümleyiciler paketleyebilir ve kitaplığınızı NuGet ile kodu düzeltir. Bu senaryoda, NuGet paketinizi yükleyen her
geliştiricinin Çözümleyicisi paketi de yüklenir. Kitaplığınızı kullanan tüm geliştiriciler hemen Kılavuzu takımınızdan
biçiminde hataları ve önerilen düzeltmeler hakkında anında geri bildirim alırsınız.

Genel rehberlik
.NET Geliştirici topluluğu iyi çalışma deneyimi desenleri ve en iyi önlenmesini desenleri algıladı. Çeşitli topluluk
üyeleri bu önerilen desenlerinin zorunlu Çözümleyicileri oluşturdunuz. Size daha fazla bilgi edinin olarak da her
zaman yeni fikirler yer yoktur.
Bu çözümleyici yüklenebilir Visual Studio Market ve Visual Studio kullanan geliştiriciler tarafından indirilir. Yeni dil
ve platform gelenlere kabul edilen uygulamaları hızlı bir şekilde öğrenin ve daha önce .NET YOLCULUĞUNA
üretken olun. Bunlar daha yaygın kullanılan haline topluluk bu yöntemler devralır.

Sonraki adımlar
.NET derleyici Platformu SDK'sı, kod oluşturma, analiz ve yeniden düzenleme için en son dil nesne modellerini
içerir. Bu bölüm .NET derleyici Platformu SDK'sı kavramsal bir genel bakış sağlar. Hızlı başlangıçlar, örnekler ve
öğreticiler bölümlerde daha ayrıntılı bilgi bulunabilir.
Bu beş konulardaki .NET derleyici Platformu SDK'sı kavramları hakkında daha fazla bilgi edinebilirsiniz:
Söz dizimi görselleştiricisi ile kod bulma
Derleyici API modelini anlama
Söz dizimi ile çalışma
Semantik ile çalışma
Bir çalışma alanı ile çalışma
Başlamak için yüklemeniz gerekecektir .NET derleyici Platformu SDK'sı:

Yükleme yönergeleri-Visual Studio Yükleyicisi


Visual Studio Yükleyicisi .net Compiler Platform SDK 'sını bulmanın iki farklı yolu vardır:
Visual Studio Yükleyicisi Iş yükleri görünümünü kullanarak yükler
.NET Compiler Platform SDK, Visual Studio uzantısı geliştirme iş yükünün bir parçası olarak otomatik olarak
seçilmemiş. Bunu isteğe bağlı bir bileşen olarak seçmeniz gerekir.
1. Visual Studio yükleyicisi Çalıştır
2. Değiştir 'i seçin
3. Visual Studio uzantısı geliştirme iş yükünü denetleyin.
4. Özet ağacında Visual Studio uzantısı geliştirme düğümünü açın.
5. .Net Compiler Platform SDK 'sıkutusunu işaretleyin. En son isteğe bağlı bileşenler altında bulacaksınız.
İsteğe bağlı olarak, dgml düzenleyicisinin grafikleri görselleştiricide görüntülemesini de istersiniz:
1. Özet ağacındaki bireysel bileşenler düğümünü açın.
2. Dgml Düzenleyicisi kutusunu işaretleyin
Visual Studio Yükleyicisi bireysel bileşenler sekmesini kullanarak yükler
1. Visual Studio yükleyicisi Çalıştır
2. Değiştir 'i seçin
3. Ayrı bileşenler sekmesini seçin
4. .Net Compiler Platform SDK 'sıkutusunu işaretleyin. Bu dosyayı derleyiciler, derleme araçları ve çalışma
zamanları bölümünün altında bulabilirsiniz.
İsteğe bağlı olarak, dgml düzenleyicisinin grafikleri görselleştiricide görüntülemesini de istersiniz:
1. Dgml Düzenleyicisikutusunu işaretleyin. Bunu kod araçları bölümünde bulabilirsiniz.
.NET derleyici Platformu SDK'sı modelini anlama
23.10.2019 • 6 minutes to read • Edit Online

Derleyiciler, şekilde insanlar genellikle farklı aşağıdaki yapılandırılmış kuralları okuma ve kod anlama yazdığınız
kod işleyin. Derleyiciler tarafından kullanılan modelini temel bir anlayış, Roslyn tabanlı araçlar oluştururken
kullandığınız API'leri anlamak için gereklidir.

Derleme işlem hattı işlevsel alanları


.NET derleyici Platformu SDK'sı sunan C# ve Visual Basic derleyicileri, geleneksel derleme işlem hattı yansıtan bir
API katmanı sağlayarak kullanıcı olarak analysis size kod.

Bu Ardışık düzenin her aşaması ayrı bir bileşendir. İlk olarak, ayrıştırma aşaması tokenizes ve kaynak metni dil
dilbilgisi aşağıdaki sözdizimine ayrıştırır. İkinci olarak, bildirimi aşaması, kaynak ve simgeleri adlı forma alınan
meta verileri analiz eder. Ardından, bağlama aşaması kodu sembol tanımlayıcıları eşleşir. Son olarak, emit aşaması
derleyicisi tarafından derlenen tüm bilgileri içeren bir bütünleştirilmiş kod yayar.

.NET derleyici Platformu SDK'sı, bu aşamaların her birine karşılık gelen, bu aşamada bilgilerine erişmesine izin
veren bir nesne modeli sunar. Ayrıştırma aşaması söz dizimi ağacı kullanıma sunar, bildirimi aşaması hiyerarşik
sembol tablosu kullanıma sunar, bağlama aşaması, derleyicinin anlam çözümleme sonucu kullanıma sunar ve emit
aşaması IL bayt kodları üreten bir API'dir.
Her derleyici bu bileşenlerin tek uçtan uca bir bütün olarak birleştirir.
Bu API'ler, Visual Studio tarafından kullanılan aynı olanlardır. Örneği için anahat oluşturma ve biçimlendirme
özellikleri kod söz dizimi ağacı kullanın, sembol tablosu, yeniden düzenlemeler Nesne Tarayıcısı ve gezinti
özelliklerini kullanmak ve Tanıma Git anlam modeli kullanın ve Düzenle ve devam et kullanır yayma API dahil
olmak üzere bunların tümü.

API katmanları
.NET derleyici SDK'sı API'leri iki ana katman oluşur: derleyici API'leri ve çalışma alanları API'leri.

Derleyici API'leri
Derleyici katman sözdizimsel ve semantik derleyici işlem hattının her aşamada kullanıma sunulan bilgilere karşılık
gelen nesne modellerini içerir. Derleyici katmanın, tek bir çağrı derleme başvuruları, derleyici seçenekleri ve kaynak
kodu dosyaları gibi bir derleyici değişmez bir anlık görüntüsünü de içerir. Temsil eden iki ayrı API vardır C# dil ve
Visual Basic dili. Bu iki API şeklinde benzerdir ancak her dil için yüksek kaliteli için uyarlanmış. Bu katman, Visual
Studio bileşenlerini bağımlılık yok.
Tanılama API'leri
Kendi analiz bir parçası olarak, derleyici tanılama söz dizimi, semantik, kadar her şeyi ve çeşitli uyarılar ve
bilgilendirici tanılama kesin atama hataları kapsayan bir dizi üretebilir. Derleyici API katmanı Tanılama kullanıcı
tanımlı Çözümleyicileri derleme işlemine takılı sağlayan genişletilebilir bir API aracılığıyla sunar. Kullanıcı tanımlı
StyleCop ya da FxCop, derleyici tarafından tanımlanan tanılama yanı sıra üretilecek gibi araçlar tarafından üretilen
olanlar gibi tanılama sağlar. Bu şekilde tanılama üretme doğal olarak MSBuild gibi araçlarla tümleştirme avantajına
sahiptir ve tanılama için bir yapıyı durdurma gibi deneyimleri bağımlı Visual Studio İlkesi ve düzenleyicide Canlı
dalgalı çizgiler gösteren kod önerme tabanlı ve düzeltir.
Betik yazma API'leri
Barındırma ve betik yazma API'leri derleyici katman parçasıdır. Kod parçacıkları yürütülüyor ve bir çalışma zamanı
yürütme bağlamı biriktirme için bunları kullanabilirsiniz. C# Etkileşimli REPL (okuma değerlendirmek yazdırma
döngü) bu API'lerini kullanır. REPL kullanmanızı sağlayan C# yazmanız gibi bir komut dosyası dili kod etkileşimli
olarak çalıştırmak.
Çalışma alanları API'leri
Çalışma alanları katman tüm çözümleri yeniden düzenleme ve kod analizi yapmak için başlangıç noktası olan
çalışma API içerir. Tek nesne modeline gerek kalmadan seçeneklerini yapılandırma dosyalarını ayrıştırmak derleyici
katman nesnesi modellerini doğrudan erişim sunan bir çözüm içindeki projeleri hakkındaki tüm bilgileri
düzenleme yönetmenize yardımcı olan veya projeden projeye bağımlılıkları yönetin .
Ayrıca, çalışma alanlarını Kod Analizi uygulaması ve bir ana bilgisayar ortamının içinde işlev araçları yeniden
düzenleme, Visual Studio IDE gibi bir API kümesi kullanılan yüzeyleri katman. Tüm başvuruları Bul, biçimlendirme
ve kod oluşturma API'ları verilebilir.
Bu katman, Visual Studio bileşenlerini bağımlılık yok.
Söz dizimi ile çalışma
24.10.2019 • 14 minutes to read • Edit Online

Sözdizimi ağacı , derleyici API 'leri tarafından kullanıma sunulan temel bir veri yapısıdır. Bu ağaçlar, kaynak
kodunun sözlü ve sözdizimsel yapısını temsil eder. Bunlar iki önemli amaca hizmet eder:
1. IDE, Eklentiler, kod analizi araçları ve yeniden düzenlemeler gibi araçlara izin vermek için, bir kullanıcının
projesindeki kaynak kodun sözdizimsel yapısını görmek ve işlemek için.
2. Yeniden düzenlemeler ve IDE gibi araçları etkinleştirmek için-doğrudan metin düzenlemeleri kullanmadan
kaynak kodu doğal bir şekilde oluşturmak, değiştirmek ve yeniden düzenlemek için. Ağaçlar oluşturup
düzenleyerek, araçlar kaynak kodu kolayca oluşturup yeniden düzenleyebilir.

Sözdizimi ağaçları
Sözdizimi ağaçları, derleme, kod analizi, bağlama, yeniden düzenleme, IDE özellikleri ve kod oluşturma için
kullanılan birincil yapıdır. Birinci olarak bilinen yapısal dil öğelerinden birinde tanımlanmadan ve
sınıflandırılmadan kaynak kodun hiçbir bölümü anlaşılmamıştır.
Sözdizimi ağaçları üç anahtar özniteliğe sahiptir. İlk öznitelik, söz dizimi ağaçlarının tüm kaynak bilgilerini tam
Aslına göre tutamadır. Bu, söz dizimi ağacının kaynak metinde bulunan her bilgi parçasını, her dilbilgisi yapısını,
her sözcük belirtecini ve diğer her şeyi (boşluk, açıklamalar ve Önişlemci yönergeleri dahil) içerdiği anlamına gelir.
Örneğin, kaynakta bahsedilen her bir sabit değer tam olarak yazıldığı gibi gösterilir. Söz dizimi ağaçları Ayrıca, söz
dizimi ağacındaki Atlanan veya eksik belirteçleri temsil ederek, program eksik veya hatalı biçimlendirilmiş
olduğunda kaynak kodundaki hataları da temsil eder.
Bu, söz dizimi ağaçlarının ikinci özniteliğini sunar. Ayrıştırıcıdan alınan bir sözdizimi ağacı, ayrıştırıldığına tam
metni üretebilir. Herhangi bir söz dizimi düğümünden, kök ağacın alt ağacının metin temsilini bu düğüme almak
mümkündür. Bu, söz dizimi ağaçlarının kaynak metni oluşturmak ve düzenlemek için bir yol olarak
kullanılabileceği anlamına gelir. Bir ağaç oluşturarak denk metin oluşturmuş ve bir sözdizimi ağacını düzenleyerek,
varolan bir ağaçtaki değişikliklerden daha fazla değişiklik yapmaktan yararlanarak, metni etkin bir şekilde
düzenlediğiniz bir ağaç oluşturabilirsiniz.
Söz dizimi ağaçlarının üçüncü özniteliği, sabit ve iş parçacığı açısından güvenlidir. Bu, bir ağaç alındıktan sonra
kodun geçerli durumunun anlık görüntüsüdür ve hiçbir değişiklik yapılmadığı anlamına gelir. Bu, birden çok
kullanıcının kilitleme veya çoğaltma olmadan farklı iş parçacıklarında aynı söz dizimi ağacıyla etkileşime geçmesini
sağlar. Ağaçlar sabittir ve hiçbir değişiklik doğrudan bir ağaca yapılamaz, ancak Fabrika yöntemleri ağacın ek anlık
görüntülerini oluşturarak sözdizimi ağaçları oluşturma ve değiştirme konusunda yardımcı olur. Ağaçlar, temel
düğümleri yeniden kullanma biçiminde etkilidir, bu nedenle yeni bir sürüm hızlı bir şekilde ve çok fazla bellekle
yeniden oluşturulabilir.
Sözdizimi ağacı, Terminal olmayan yapısal öğelerin üst diğer öğelerinden oluşan bir ağaç veri yapısıdır. Her bir
sözdizimi ağacı düğümlerin, belirteçlerin ve trivia oluşur.

Sözdizimi düğümleri
Sözdizimi düğümleri, söz dizimi ağaçlarının birincil öğelerinden biridir. Bu düğümler, bildirimler, deyimler, yan
tümceler ve ifadeler gibi sözdizimsel yapıları temsil eder. Her bir sözdizimi düğümleri kategorisi
Microsoft.CodeAnalysis.SyntaxNodetüretilen ayrı bir sınıf tarafından temsil edilir. Düğüm sınıfları kümesi
genişletilebilir değil.
Tüm sözdizimi düğümleri, söz dizimi ağacındaki Terminal olmayan düğümlerdir, bu da her zaman alt öğe olarak
diğer düğümleri ve belirteçleri oldukları anlamına gelir. Başka bir düğümün alt öğesi olarak, her düğümün
SyntaxNode.Parent özelliği aracılığıyla erişilebilen bir üst düğümü vardır. Düğümler ve ağaçlar sabit olduğundan,
düğümün üst öğesi hiçbir şekilde değişmez. Ağacın kökü null bir üst öğeye sahip.
Her düğümün bir SyntaxNode.ChildNodes() yöntemi vardır ve bu, kaynak metindeki konumlarına göre sıralı
sırada alt düğümlerin bir listesini döndürür. Bu liste belirteç içermiyor. Her düğüm Ayrıca, bu düğüm tarafından
kökü oluşturulan alt ağaçta var olan tüm düğümlerin, belirteçlerin veya bir listenin listesini temsil eden
DescendantNodes, DescendantTokensveya DescendantTrivia gibi alt öğeleri inceleme yöntemlerine sahiptir.
Ayrıca, her bir sözdizimi düğüm alt sınıfı, kesin belirlenmiş özellikler aracılığıyla aynı alt öğeleri gösterir. Örneğin,
bir BinaryExpressionSyntax node sınıfı ikili işleçlere özgü üç ek özelliğe sahiptir: Left, OperatorTokenve Right. Left
ve Right türü ExpressionSyntaxve OperatorToken türü SyntaxToken.
Bazı sözdizimi düğümlerinde isteğe bağlı alt öğeler vardır. Örneğin, bir IfStatementSyntax isteğe bağlı bir
ElseClauseSyntaxvardır. Alt öğe yoksa, özelliği null döndürür.

Sözdizimi belirteçleri
Sözdizimi belirteçleri, kodun en küçük sözdizimsel parçalarını temsil eden dil dilbilgisinde bulunan terminallerdir.
Bunlar hiçbir şekilde diğer düğümlerin veya belirteçlerin hiçbir üst öğesi değildir. Sözdizimi belirteçleri anahtar
sözcüklerden, tanımlayıcılardan, değişmez değerlerden ve noktalama işaretlerinden oluşur.
Verimlilik açısından, SyntaxToken türü bir CLR değer türüdür. Bu nedenle, sözdizimi düğümlerinden farklı olarak,
temsil edilen belirtecin türüne bağlı olarak anlamı olan özelliklerin karışımına sahip tüm belirteç türleri için tek bir
yapı vardır.
Örneğin, bir tamsayı sabit değeri bir sayısal değeri temsil eder. Belirtecin yayıldığı ham kaynak metnine ek olarak,
sabit değer belirtecinin, kodu çözülmüş tam sayı değerini belirten bir Value özelliği vardır. Bu özellik birçok temel
türden biri olabileceğinden Object olarak yazılır.
ValueText özelliği, Value özelliğiyle aynı bilgileri size bildirir; Ancak bu özellik her zaman Stringolarak yazılır. C#
Kaynak metindeki bir tanımlayıcı Unicode kaçış karakterleri içerebilir, ancak kaçış dizisinin sözdizimi tanımlayıcı
adının bir parçası olarak kabul edilmez. Bu nedenle, belirteç tarafından yayılan ham metin kaçış sırasını içerse de
ValueText özelliği değildir. Bunun yerine, kaçış tarafından tanımlanan Unicode karakterleri içerir. Örneğin, kaynak
metin \u03C0 olarak yazılmış bir tanımlayıcı içeriyorsa, bu belirtecin ValueText özelliği π döndürür.

Sözdizimi bilgi
Sözdizimi bilgi kaynak metnin, beyaz boşluk, açıklama ve Önişlemci yönergeleri gibi kodu normal şekilde anlamak
için büyük ölçüde önemli olan kısımlarını temsil eder. Sözdizimi belirteçleri gibi, bilgi değer türleridir. Tek
Microsoft.CodeAnalysis.SyntaxTrivia türü her türlü Tria 'nın açıklaması için kullanılır.
Bilgi normal dil sözdiziminin parçası olmadığından ve iki belirteç arasında bir yerde görünebildiğinden, bir
düğümün alt öğesi olarak sözdizimi ağacına dahil edilmez. Henüz, yeniden düzenleme gibi bir özellik uygularken
ve kaynak metinle tam uygunluğu sürdürmek için önemli olduklarından, söz dizimi ağacının bir parçası olarak
mevcuttur.
Bir belirtecin SyntaxToken.LeadingTrivia veya SyntaxToken.TrailingTrivia koleksiyonlarını inceleyerek, bilgi 'a
erişebilirsiniz. Kaynak metni ayrıştırıldığında, bilgi dizileri belirteçlerle ilişkilendirilir. Genel olarak, bir belirteç bir
sonraki belirtece kadar aynı satıra kadar herhangi bir tribiya benzer. Bu satırdan sonraki her türlü bir değer
aşağıdaki belirteçle ilişkilendirilir. Kaynak dosyadaki ilk simge, tüm başlangıç anlarını alır ve dosyadaki en son üç
sıra, sıfır genişliğine sahip olan dosya sonu belirtecine göre belirlenir.
Söz dizimi düğümleri ve belirteçlerden farklı olarak söz dizimi bilgi üst öğeleri yoktur. Henüz, ağacın bir parçası
olduklarından ve her biri tek bir belirteçle ilişkilendirildiği için, SyntaxTrivia.Token özelliğini kullanarak ilişkili olan
belirtece erişebilirsiniz.
Maları
Her düğüm, belirteç veya bilgi, kaynak metni içindeki konumunu ve içerdiği karakter sayısını bilir. Bir metin
konumu, sıfır tabanlı char dizin olan 32 bitlik bir tamsayı olarak temsil edilir. TextSpan nesnesi, her ikisi de
tamsayılar olarak gösterilen başlangıç konumu ve karakter sayısıdır. TextSpan sıfır uzunluğa sahipse, iki karakter
arasındaki bir konuma başvurur.
Her düğüm iki TextSpan özelliğe sahiptir: Span ve FullSpan.
Span özelliği, düğümün alt ağacındaki ilk belirtecin başından son belirtecin sonuna kadar olan metindir. Bu
yayılma, başında veya sonunda bir boşluk içermez.
FullSpan özelliği, düğümün normal yayılımını ve önünde ya da sondaki üç nokta yayılmasını içeren metin yaydır.
Örneğin:

if (x > 3)
{
|| // this is bad
|throw new Exception("Not right.");| // better exception?||
}

Bloğun içindeki deyimin düğümü, tek dikey çubuklar (|) ile belirtilen bir yayılım içeriyor.
throw new Exception("Not right."); karakterleri içerir. Tam yayılma, çift dikey çubuklar (| |) ile belirtilir. Yayılma ile
aynı karakterleri ve baştaki ve sondaki trivia ile ilişkili karakterleri içerir.

Farklı
Her düğüm, belirteç veya bilgi, temsil edilen tam sözdizimi öğesini tanımlayan System.Int32türünde bir
SyntaxNode.RawKind özelliğine sahiptir. Bu değer dile özgü bir numaralandırmaya atanabilir; Her dil C# veya vb,
tüm olası düğümleri, belirteçleri ve dilbilgisinde bilgi öğelerini listeleyen tek bir SyntaxKind numaralandırması
(sırasıylaMicrosoft.CodeAnalysis.CSharp.SyntaxKindveMicrosoft.CodeAnalysis.VisualBasic.SyntaxKind) vardır. Bu
dönüştürme CSharpExtensions.Kind veya VisualBasicExtensions.Kind uzantısı yöntemlerine erişerek otomatik
olarak yapılabilir.
RawKind özelliği, aynı düğüm sınıfını paylaşan sözdizimi düğümü türlerinin kolay bir şekilde kesinleştirilmesine
olanak sağlar. Belirteçler ve trivia için, bu özellik bir öğe türünü diğerinden ayırt etmenin tek yoludur.
Örneğin, tek bir BinaryExpressionSyntax sınıfı alt öğe olarak Left, OperatorTokenve Right sahiptir. Kind özelliği,
bunun AddExpression, SubtractExpressionveya MultiplyExpression tür bir sözdizimi düğümü olduğunu ayırt eder.

Hatalar
Kaynak metin sözdizimi hataları içerdiğinde bile, kaynağa gidiş olarak dönüşümlü bir tam sözdizimi ağacı
gösterilir. Ayrıştırıcı dilin tanımlı söz dizimi ile uyumlu olmayan kodla karşılaştığında, sözdizimi ağacı oluşturmak
için iki teknikten birini kullanır.
Birincisi, ayrıştırıcı belirli bir belirteç türünü beklediğinde ancak bulamazsa, belirtecin beklenildiği konumdaki
sözdizimi ağacına eksik bir belirteç eklenebilir. Eksik bir belirteç beklenen gerçek belirteci temsil eder, ancak boş bir
yayılma alanına sahiptir ve SyntaxNode.IsMissing özelliği true döndürüyor.
İkincisi, ayrıştırıcının ayrıştırmaya devam edebilecekleri bir konum bulana kadar belirteçleri atlayabilirler. Bu
durumda, atlanan belirteçler, türü SkippedTokensTriviaolan bir düğüm ile birlikte eklenir.
Semantik ile çalışma
23.10.2019 • 6 minutes to read • Edit Online

Sözdizimi ağaçları , kaynak kodunun sözlü ve sözdizimsel yapısını temsil eder. Bu bilgilerin tek başına, kaynaktaki
tüm bildirimleri ve mantığı tanımlamak için yeterli olmasına rağmen, ne başvurulduğunu belirlemek için yeterli
bilgi yok. Bir ad şunları temsil edebilir:
bir tür
bir alan
bir yöntemi
Yerel bir değişken
Bunların her biri benzersiz bir şekilde farklı olsa da, hangi tanımlayıcının gerçekten başvurduğu, genellikle dil
kurallarının derinlemesine bir şekilde anlaşılmasına ihtiyaç duyar.
Kaynak kodunda temsil edilen program öğeleri vardır ve programlar, derleme dosyalarında paketlenmiş daha
önceden derlenen kitaplıklara de başvurabilir. Kaynak kodu olmasa da hiçbir sözdizimi düğümü veya ağacı
derlemeler için kullanılabilir olmadığından, programlar bunların içindeki öğelere başvurabilirler.
Bu görevler için anlam modeligerekir.
Kaynak kodun sözdizimsel modelinin yanı sıra, bir anlam modeli, dil kurallarını kapsüller, bu da, başvurulan doğru
program öğesiyle tanımlayıcılarla doğru bir şekilde eşleşmenin kolay bir yolunu sunar.

Derleme
Derleme, tüm derleme başvurularını, derleyici seçeneklerini ve kaynak dosyaları C# içeren bir veya Visual Basic
programı derlemek için gereken her şeyin bir gösterimidir.
Tüm bu bilgiler tek bir yerde olduğundan, kaynak kodda bulunan öğeler daha ayrıntılı olarak açıklanabilir.
Derleme, belirtilen her tür, üye veya değişkeni bir sembol olarak temsil eder. Derleme, kaynak kodda belirtilen
veya bir derlemeden meta veriler olarak içeri aktarılan sembolleri bulmanıza ve ilişkilendirmede yardımcı olan
çeşitli yöntemler içerir.
Sözdizimi ağaçlarına benzer şekilde derlemeler sabittir. Bir derleme oluşturduktan sonra, sizin tarafınızdan veya
sizinle paylaştığınız başka bir kişi tarafından değiştirilemez. Bununla birlikte, mevcut bir derlemeden yeni bir
derleme oluşturabilir ve bunu yaptığınız gibi bir değişiklik belirtebilirsiniz. Örneğin, var olan bir derleme için her
şekilde aynı olan bir derleme oluşturabilirsiniz, ancak ek bir kaynak dosya veya derleme başvurusu içerebilir.

Simgeleri
Bir sembol, kaynak kodu tarafından tanımlanan veya bir derlemeden meta veri olarak içeri aktarılan ayrı bir öğeyi
temsil eder. Her ad alanı, tür, yöntem, özellik, alan, olay, parametre veya yerel değişken bir sembol ile temsil edilir.
Compilation Türdeki çeşitli yöntemler ve özellikler, sembolleri bulmanıza yardımcı olur.Örneğin, tanımlanmış bir
tür için ortak meta veri adıyla bir simge bulabilirsiniz. Tüm sembol tablosuna, genel ad alanı tarafından kök olarak
belirtilen bir sembol ağacı olarak da erişebilirsiniz.
Semboller ayrıca, derleyicinin diğer başvurulan semboller gibi kaynak veya meta verilerden belirlediği ek bilgileri
de içerir. Her bir sembol türü, ' den ISymboltüretilen ayrı bir arabirim tarafından temsil edilir ve derleyicinin
topladığı bilgileri ayrıntılarıyla açıklayan kendi yöntemleri ve özellikleri vardır. Bu özelliklerin birçoğu, diğer
simgelere doğrudan başvurur. Örneğin, IMethodSymbol.ReturnType özelliği, yöntem bildiriminin başvurduğu
gerçek tür sembolünü söyler.
Semboller, kaynak kodu ve meta veriler arasında ad alanları, türler ve üyelerin ortak bir gösterimini sunar.
Örneğin, kaynak kodda belirtilen bir yöntem ve meta verilerden içeri aktarılan bir yöntem, aynı özelliklerle bir
IMethodSymbol ile temsil edilir.
Semboller, System.Reflection API tarafından temsil edildiği gibi CLR türü sistemine benzerdir, ancak yalnızca daha
fazla türden daha fazla modelleyerek daha hızlıdır. Ad alanları, yerel değişkenler ve Etiketler tüm sembollerdir.
Ayrıca, semboller CLR kavramlarını değil, dil kavramlarının bir gösterimidir. Çok sayıda çakışma vardır ancak
birçok anlamlı ayrımda vardır. Örneğin, C# veya Visual Basic bir yineleyici yöntemi tek bir sembolüdür. Ancak,
yineleyici yöntemi CLR meta verilerine çevrildiğinde, bir tür ve birden çok yöntem olur.

Anlam modeli
Anlam modeli, tek bir kaynak dosya için tüm anlam bilgilerini temsil eder. Aşağıdakileri öğrenmek için
kullanabilirsiniz:
Kaynakta belirli bir konumda başvurulan semboller.
Herhangi bir ifadenin sonuç türü.
Hata ve uyarı olan tüm Tanılamalar.
Değişkenlerin kaynak bölgeler içinde ve dışında nasıl akar.
Daha belirgin soruların yanıtları.
Bir çalışma alanı ile çalışma
23.10.2019 • 4 minutes to read • Edit Online

Çalışma alanları katman tüm çözümleri yeniden düzenleme ve kod analizi yapmak için başlangıç noktasıdır. Bu
katman içinde çalışma API, bir çözüm içindeki projeleri hakkındaki tüm bilgileri tek nesne modeline, düzenleme
kaynak metni, söz dizimi ağacı, anlam modelleri gibi derleyici katman nesnesi modellerini doğrudan erişim sunan
yardımcı olur ve dosyaları ayrıştırma gerek olmadan derleme seçenekleri yapılandırın veya Projeler arası
bağımlılıkları yönetin.
Bir IDE gibi konak ortamlarından, açık olan çözüme karşılık gelen bir çalışma alanı sağlayın. Bu model bir IDE
dışında bir çözüm dosyası yükleyerek kullanmak mümkündür.

Çalışma alanı
Çözümünüzün proje koleksiyonu, her bir belge koleksiyonu olarak etkin bir temsili bir çalışma alanıdır. Bir çalışma
alanı, genellikle bir kullanıcı türleri olarak sürekli değişen veya özellikleri işleyen bir ana bilgisayar ortamına
bağlıdır.
Workspace Geçerli çözüm modeline erişim sağlar. Konak ortamında değişiklik olduğunda, ilgili olaylar, çalışma
alanı tetikler ve Workspace.CurrentSolution özellik güncelleştirilir. Örneğin, kullanıcı türleri kaynak belgeleri birine
karşılık gelen bir metin düzenleyicisinde çalışma çözümünün Genel modeli değiştiğini göstermek için bir olay ve
hangi belge değiştirildiği kullandığında. Ardından, yeni modelin doğruluğunu çözümleme, alanlarını anlam
vurgulama veya bir öneri bir kod değişikliği yapmadan bu değişiklikleri tepki verebilir.
Ayrıca, konak ortam bir uygulamada kullanılan veya ana bilgisayar ortamına bağlı olmayan tek başına çalışma
alanları oluşturabilirsiniz.

Çözümler, projeler, belgeleri


Bir çalışma alanında bir tuşa basıldığında her zaman değişebilir olsa da, yalıtım çözümde modelini çalışabilirsiniz.
Bir çözümü, projeleri ve belgeleri değişmez bir modeldir. Bu model çoğaltma kilitlenmesi veya paylaşılabilir
anlamına gelir. Bir çözüm örneğinden edindikten sonra Workspace.CurrentSolution özelliği, bu örneği hiçbir zaman
değiştirir. Ancak, gibi söz dizimi ağacı ve derlemeleri, ile çözümlerini mevcut çözümleri ve belirli değişiklikleri dayalı
yeni örneklerini oluşturarak değiştirebilirsiniz. Yaptığınız değişiklikleri yansıtacak şekilde çalışma almak için açıkça
değiştirilen çözümü çalışma alanına uygulamanız gerekir.
Bir proje, genel sabit çözüm modelin bir parçasıdır. Tüm kaynak kod belgelerini, ayrıştırma ve derleme
seçeneklerini ve hem derleme ve projeden projeye başvurular temsil eder. Bir projeden karşılık gelen derleme proje
bağımlılıkları belirlemeniz veya tüm kaynak dosyalarını ayrıştırmak gerek kalmadan erişebilir.
Bir belge ayrıca genel sabit çözüm modelin bir parçasıdır. Bir belge metin dosyası, söz dizimi ağacı ve anlam modeli
erişim bir tek bir kaynak dosyasını temsil eder.
Aşağıdaki şemada çalışma konağa ilişkisini temsilidir ortamı, araçları ve düzenlemeleri nasıl yapılır.
Özet
Roslyn derleyici API'leri ve çalışma alanları tam uygunlukta sahip olan ve kaynak kodunuz hakkında zengin bilgiler
sağlayan API kümesi sunan C# ve Visual Basic dillerini. .NET derleyici Platformu SDK'sı, kod odaklı bir araç ve
uygulamalar oluşturmak için giriş engel önemli ölçüde azaltır. C# ve VB dil ve C# ve VB etki alanına özgü diller
katıştırma meta programlama kod oluşturma ve dönüştürme, etkileşimli kullanmak gibi alanlarda yenilik için
birçok fırsat oluşturur.
Visual Studio 'da Roslyn sözdizimi görselleştiricisi ile
kodu araştırma
23.10.2019 • 16 minutes to read • Edit Online

Bu makalede, .NET Compiler Platform ("Roslyn") SDK 'sının bir parçası olarak gönderilen Syntax Visualizer aracına
genel bakış sunulmaktadır. Syntax Visualizer, sözdizimi ağaçlarını incelemenize ve keşfetmenize yardımcı olan bir
araç penceresidir. Analiz etmek istediğiniz kod modellerini anlamak için gerekli olan bir araçtır. Ayrıca, .NET
Compiler Platform ("Roslyn") SDK 'sını kullanarak kendi uygulamalarınızı geliştirirken hata ayıklama yardımıdır. İlk
çözümleyicinizi oluştururken bu aracı açın. Görselleştiricisi API 'Ler tarafından kullanılan modelleri anlamanıza
yardımcı olur. Kod incelemek ve sözdizimi ağaçlarını anlamak için, parça veya linqpad gibi araçları da
kullanabilirsiniz.

Yükleme yönergeleri-Visual Studio Yükleyicisi


Visual Studio Yükleyicisi .net Compiler Platform SDK 'sını bulmanın iki farklı yolu vardır:
Visual Studio Yükleyicisi Iş yükleri görünümünü kullanarak yükler
.NET Compiler Platform SDK, Visual Studio uzantısı geliştirme iş yükünün bir parçası olarak otomatik olarak
seçilmemiş. Bunu isteğe bağlı bir bileşen olarak seçmeniz gerekir.
1. Visual Studio yükleyicisi Çalıştır
2. Değiştir 'i seçin
3. Visual Studio uzantısı geliştirme iş yükünü denetleyin.
4. Özet ağacında Visual Studio uzantısı geliştirme düğümünü açın.
5. .Net Compiler Platform SDK 'sıkutusunu işaretleyin. En son isteğe bağlı bileşenler altında bulacaksınız.
İsteğe bağlı olarak, dgml düzenleyicisinin grafikleri görselleştiricide görüntülemesini de istersiniz:
1. Özet ağacındaki bireysel bileşenler düğümünü açın.
2. Dgml Düzenleyicisi kutusunu işaretleyin
Visual Studio Yükleyicisi bireysel bileşenler sekmesini kullanarak yükler
1. Visual Studio yükleyicisi Çalıştır
2. Değiştir 'i seçin
3. Ayrı bileşenler sekmesini seçin
4. .Net Compiler Platform SDK 'sıkutusunu işaretleyin. Bu dosyayı derleyiciler, derleme araçları ve çalışma
zamanları bölümünün altında bulabilirsiniz.
İsteğe bağlı olarak, dgml düzenleyicisinin grafikleri görselleştiricide görüntülemesini de istersiniz:
1. Dgml Düzenleyicisikutusunu işaretleyin. Bunu kod araçları bölümünde bulabilirsiniz.
Genel bakış makalesini okuyarak .net Compiler Platform SDK 'sında kullanılan kavramları öğrenmeye çalışın.
Sözdizimi ağaçları, düğümleri, belirteçleri ve trivia için bir giriş sağlar.

Syntax Visualizer
Syntax Visualizer , VISUAL Studio IDE içindeki geçerli etkin düzenleyici PENCERESINDE C# veya vb kod
dosyası için sözdizimi ağacının incelemesini mümkün. Görselleştirici,diğer Windows > Syntax Visualizer
görüntüle > ' ye tıklanarak başlatılabilir. Sağ üst köşedeki Hızlı başlatma araç çubuğunu da kullanabilirsiniz.
"Sözdizimi" yazın ve Syntax Visualizer açmak için komut görünmelidir.
Bu komut Syntax Visualizer kayan bir araç penceresi olarak açar. Bir kod Düzenleyicisi penceresi açık değilse,
aşağıdaki şekilde gösterildiği gibi görüntü boştur.

Bu araç penceresini, Visual Studio içinde, sol taraftaki gibi uygun bir konuma yerleştirin. Görselleştirici, geçerli kod
dosyası hakkındaki bilgileri gösterir.
Dosya > Yeni proje komutunu kullanarak yeni bir proje oluşturun. Bir VB veya C# proje oluşturabilirsiniz. Visual
Studio bu proje için ana kod dosyasını açtığında Görselleştirici kendisi için sözdizimi ağacını görüntüler. Bu Visual
Studio örneğinde var C# olan herhangi bir/vb dosyasını açabilirsiniz ve Görselleştirici bu dosyanın sözdizimi
ağacını görüntüler. Visual Studio içinde açık olan birden çok kod dosyanız varsa, Görselleştirici geçerli etkin kod
dosyası (klavye odağına sahip kod dosyası) için sözdizimi ağacını görüntüler.
C#
Visual Basic
Önceki görüntülerde gösterildiği gibi, Görselleştirici araç penceresi üstteki sözdizimi ağacını ve alt kısımdaki bir
özellik kılavuzunu görüntüler. Özellik Kılavuzu, öğenin .NET türü ve türü (ağacın syntaxkind içeren) dahil olmak
üzere ağaçta seçili olan öğenin özelliklerini görüntüler.
Sözdizimi ağaçları, düğüm, belirteçve bilgiolmak üzere üç öğe türünü kapsar. Söz dizimi Ile çalışma makalesinde bu
türler hakkında daha fazla bilgi edinebilirsiniz. Her türün öğeleri farklı bir renk kullanılarak temsil edilir. Kullanılan
renklere genel bakış için ' gösterge ' düğmesine tıklayın.
Ağaçtaki her öğe ayrıca kendi yayılma alanınıda görüntüler. Yayılma , metin dosyasındaki bu düğümün
indekslerini (başlangıç ve bitiş konumu). Yukarıdaki C# örnekte, seçili "usinganahtar sözcüğü [0.. 5)" belirtecinin,
beş karakter genişliğinde, [0.. 5) bir yayılımı vardır. "[..)" Gösterimi Başlangıç dizininin yayılma alanının parçası
olduğu, ancak bitiş dizininin olmadığı anlamına gelir.
Ağaçta gezinmek için iki yol vardır:
Ağaçtaki öğeler ' i genişletin veya tıklayın. Görselleştirici, kod düzenleyicisinde bu öğenin alanına karşılık gelen
metni otomatik olarak seçer.
Kod düzenleyicisinde metin ' e tıklayın veya seçin. Önceki VB örneğinde, kod düzenleyicisinde "Module
Module1" içeren satırı seçerseniz, görselleştiricisi otomatik olarak ağaçtaki karşılık gelen
Moduledeyimdüğümüne gider.
Görselleştirici, alanı düzenleyicide seçili olan metnin yayılımının en iyi şekilde eşleştiği ağaçtaki öğeyi vurgular.
Görselleştirici, etkin kod dosyasındaki değişikliklerle eşleşecek şekilde ağacı yeniler. Console.WriteLine() İçine
Main() bir çağrı ekleyin. Siz yazarken, görselleştiricisi ağacı yeniler.

Yazdıktan sonra Console. yazmayı duraklatın. Ağaçta, pembe renkte renkli bazı öğeler vardır. Bu noktada, yazılan
koddaki hatalar (' Tanılama ' olarak da bilinir) vardır. Bu hatalar, söz dizimi ağacındaki düğümlere, belirteçlere ve
üçlü öğesine eklenir. Görselleştirici, arka planı pembe olarak vurgulamada hangi öğelerin ekli hatalara sahip
olduğunu gösterir. Öğenin üzerine gelerek pembe renkte renklendirilmiş hataları inceleyebilirsiniz. Görselleştirici
yalnızca sözdizimsel hataları (yazılan kodun sözdizimiyle ilgili hatalar) görüntüler; hiçbir semantik hata
görüntülemez.

Sözdizimi grafikleri
Ağaçtaki herhangi bir öğeye sağ tıklayın ve yönlendirilmiş sözdizimi grafiğini görüntüle' ye tıklayın.
C#
Visual Basic
Görselleştirici, seçili öğede kökü belirtilen alt ağacın grafik temsilini görüntüler. C# Örnekteki Main() yönteme
karşılık gelen MethodDeclaration düğümü için aşağıdaki adımları deneyin. Görselleştiricisi aşağıdaki gibi
görünen bir sözdizimi grafiği görüntüler:

Söz dizimi grafik görüntüleyicisinde gösterge renklendirme şeması görüntüleme seçeneği vardır. Ayrıca söz konusu
öğeye karşılık gelen özellikleri görüntülemek için, söz dizimi grafiğinde tek tek öğelerin üzerine gelin.
Ağaçtaki farklı öğeler için sözdizimi grafiklerini art arda görüntüleyebilirsiniz ve grafikler her zaman Visual Studio
içindeki aynı pencerede görüntülenir. Bu pencereyi Visual Studio içinde uygun bir konuma yerleştirebilirsiniz,
böylece yeni bir sözdizimi grafiğini görüntülemek için sekmeler arasında geçiş yapmanız gerekmez. En alttaki kod
Düzenleyicisi pencereleri, genellikle kullanışlıdır.
Görselleştiricisi araç penceresi ve söz dizimi grafik penceresi ile kullanılacak yerleştirme düzeni aşağıda verilmiştir:

Diğer bir seçenek de, sözdizimi grafik penceresini ikinci bir monitöre bir çift izleyici kurulumuna koyulamıyor.

Semantiğini İnceleme
Syntax Visualizer, sembolleri ve anlam bilgilerini ilkel denetlemesini mümkün. Örnekteki Main () içine yazın
double x = 1 + 1; . C# Ardından, kod Düzenleyicisi penceresinde 1 + 1 ifadeyi seçin. Görselleştirici,
görselleştiricide AddExpression düğümünü vurgular. Bu AddExpression öğesine sağ tıklayın ve Görünüm
simgesine (varsa) tıklayın. Menü öğelerinin çoğunda "varsa" niteleyicisi olduğuna dikkat edin. Syntax Visualizer,
tüm düğümler için mevcut olmayan özellikler de dahil olmak üzere bir düğümün özelliklerini inceler.
Aşağıdaki şekilde gösterildiği gibi görselleştiricisi güncelleştirmelerinde Özellik Kılavuzu: İfade sembolü, Kind =
yöntemiIçeren bir SynthesizedIntrinsicOperatorSymbol .

Aynı AddExpression düğümü için TypeSymbol (varsa) görüntülemeyi deneyin. Aşağıdaki şekilde gösterildiği
gibi, Görselleştirici güncelleştirmelerinde bulunan Özellik Kılavuzu, seçili ifadenin Int32 türünün olduğunu
gösterir.

Aynı AddExpression düğümü Için dönüştürülmüş TypeSymbol (varsa) görüntülemeyi deneyin. Özellik
Kılavuzu, ifadenin Int32 türü olsa da, Double ifadenin dönüştürülmüş türünün Aşağıdaki şekilde gösterildiği gibi
olduğunu gösterir. Bu düğüm, dönüştürülmüş tür sembol bilgisini içerir, Int32 çünkü ifade, Double öğesine
dönüştürülmesi gereken bir bağlamda meydana gelir. Bu dönüştürme, atama Double işlecinin sol tarafındaki
değişken x için belirtilen türü karşılar.

Son olarak, aynı AddExpression düğümü Için sabit değeri (varsa) görüntülemeyi deneyin. Özellik Kılavuzu,
ifadenin değerinin değeri 2 olan bir derleme zamanı sabiti olduğunu gösterir.

Yukarıdaki örnek VB 'de de çoğaltılabilir. Bir Dim x As Double = 1 + 1 vb dosyası yazın. Kod Düzenleyicisi
penceresinde 1 + 1 ifadeyi seçin. Görselleştirici, görselleştiricide karşılık gelen AddExpression düğümünü
vurgular. Bu AddExpression için önceki adımları tekrarlayın ve özdeş sonuçlar görmeniz gerekir.
VB 'de daha fazla kod inceleyin. Ana VB dosyanızı aşağıdaki kodla güncelleştirin:
Imports C = System.Console

Module Program
Sub Main(args As String())
C.WriteLine()
End Sub
End Module

Bu kod, dosyanın en üstünde C bulunan türle System.Console eşleşen adlı bir diğer ad tanıtır ve bu diğer adı
içinde Main() kullanır. C Main() İçindeki Budiğeradınkullanımını,yöntemiiçindeseçin C.WriteLine() .
Görselleştiricisi görselleştiricide karşılık gelen IdentifierName düğümünü seçer. Bu düğüme sağ tıklayın ve
Görünüm simgesine (varsa) tıklayın. Özellik Kılavuzu, Bu tanımlayıcının aşağıdaki şekilde gösterildiği gibi türe
System.Console bağlandığını gösterir:

Aynı IdentifierName düğümü için bir diğer simge (varsa) görüntülemeyi deneyin. Özellik Kılavuzu,
tanımlayıcının C System.Console hedefe bağlanan ada sahip bir diğer ad olduğunu gösterir. Diğer bir deyişle,
özellik Kılavuzu tanımlayıcıya C karşılık gelen diğerad simgesiyle ilgili bilgiler sağlar.
Her türlü tanımlanmış türe, yönteme ve özelliğe karşılık gelen sembolü inceleyin. Görselleştirici içinde karşılık
gelen düğümü seçin ve Görünüm simgesine (varsa) tıklayın. Yöntemin gövdesi dahil Sub Main() olmak üzere
yöntemini seçin. Görselleştirici içindeki karşılık gelen alt blok düğümü Için Görünüm simgesine (varsa) tıklayın.
Özellik Kılavuzu, bu alt blok için methodsymbol 'ın dönüş türü Void olan Main ada sahip olduğunu gösterir.

Yukarıdaki VB örnekleri ' de C#kolayca çoğaltılabilir. Diğer ad using C = System.Console; içinyerineyazın


Imports C = System.Console . Yukarıdaki adımlar, Görselleştirici penceresinde özdeş sonuçlar elde ediyor C# .

Anlamsal İnceleme işlemleri yalnızca düğümlerde kullanılabilir. Belirteçler veya trivia üzerinde kullanılamaz. Tüm
düğümlerin incelemeye yönelik ilginç anlam bilgileri yoktur. Bir düğüm ilginç anlam bilgisine sahip olmadığında
Görünüm * simgesine (varsa) tıkladığınızda boş bir özellik ızgarası gösterilir.
Semantiğe genel bakış belgesinde semantik analizler gerçekleştirmek Için API 'ler hakkında daha fazla bilgi
edinebilirsiniz.
Sözdizimi Görselleştiricisini kapatma
Kaynak kodu incelemek için kullanmıyorsanız Görselleştirici penceresini kapatabilirsiniz. Sözdizimi görselleştiricisi,
kod içinde gezinerek, kaynak düzenlenirken ve değiştirirken görüntüsünü günceller. Bu, kullanmadığınız
durumlarda dikkat dağıtıcı alabilir.
Söz dizimi Analizi ile çalışmaya başlama
23.10.2019 • 21 minutes to read • Edit Online

Bu öğreticide, hakkında bilgi edineceksiniz söz dizimi API. API söz dizimi bir C# veya Visual Basic programını
açıklayan veri yapılarını erişim sağlar. Bu veri yapıları, tam olarak her boyutta herhangi bir programı gösterebilir
yeterli ayrıntı sahip. Bu yapılar, derleyin ve doğru bir şekilde çalışması eksiksiz programlar tanımlayabilirsiniz.
Düzenleyicide, yazarken tamamlanmamış Programlar'ne de tanımlayabilirsiniz.
Bu zengin ifade etkinleştirmek için söz dizimi API'nizi API ve veri yapıları karmaşık olması gerekmez. Veri yapısı
tipik bir "Merhaba Dünya" program için nasıl göründüğüne ile başlayalım:

using System;
using System.Collections.Generic;
using System.Linq;

namespace HelloWorld
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}

Önceki program metin bakın. Size tanıdık öğeleri kabul eder. Tek bir kaynak dosyası, tüm metni temsil eder veya
derleme biriminde. Bu kaynak dosyanın ilk üç satırlar yönergeleri kullanarak. Kalan kaynağı bulunan bir ad
alanı bildirimi. Alt ad alanı bildirimi içeren sınıf bildiriminin. Bir sınıf bildirimi içeren yöntem bildiriminde.
Söz dizimi API derleme biriminde temsil eden kök ile bir ağaç yapısı oluşturur. Ağaçtaki düğümler temsil kullanma
yönergeleri, ad alanı bildirimi ve programın diğer tüm öğeleri. En düşük düzey aşağı ağaç yapısını devam: "Hello
World!" dizesi olan bir dize değişmez değer belirteci diğer bir deyişle bir alt bir bağımsız değişken. Söz dizimi
API programı yapısını erişim sağlar. Belirli bir kod yöntemleri için sorgulayabilirsiniz kodu anlamak için tüm ağaçta
yürüyebilir ve mevcut ağaca değiştirerek yeni bir ağaç oluşturun.
Bu kısa bir açıklama söz dizimi API kullanılarak erişilebilen bilgi türünü genel bir bakış sağlar. Söz dizimi API'si
tanıdık kodu tanımlayan bir biçimsel API, yapıları daha C# ' tan bilmeniz doğrudur. Tüm özelliklerini kod satır
sonları, boşluk ve girintileme dahil olmak üzere nasıl biçimlendirildiğini hakkında bilgi içerir. Bu bilgileri kullanarak,
yazılan kod ve İnsan programlayıcıların kullandığı okuma veya derleyicinin tam olarak gösterebilir. Bu yapı
kullanarak derin anlamlı düzeyinde kaynak kodu ile etkileşimde bulunmanızı sağlar. Artık metin dizelerini, ancak
bir C# programı yapısını temsil eden veri değil.
Başlamak için yüklemeniz gerekecektir .NET derleyici Platformu SDK'sı:

Yükleme yönergeleri-Visual Studio Yükleyicisi


Visual Studio Yükleyicisi .net Compiler Platform SDK 'sını bulmanın iki farklı yolu vardır:
Visual Studio Yükleyicisi Iş yükleri görünümünü kullanarak yükler
.NET Compiler Platform SDK, Visual Studio uzantısı geliştirme iş yükünün bir parçası olarak otomatik olarak
seçilmemiş. Bunu isteğe bağlı bir bileşen olarak seçmeniz gerekir.
1. Visual Studio yükleyicisi Çalıştır
2. Değiştir 'i seçin
3. Visual Studio uzantısı geliştirme iş yükünü denetleyin.
4. Özet ağacında Visual Studio uzantısı geliştirme düğümünü açın.
5. .Net Compiler Platform SDK 'sıkutusunu işaretleyin. En son isteğe bağlı bileşenler altında bulacaksınız.
İsteğe bağlı olarak, dgml düzenleyicisinin grafikleri görselleştiricide görüntülemesini de istersiniz:
1. Özet ağacındaki bireysel bileşenler düğümünü açın.
2. Dgml Düzenleyicisi kutusunu işaretleyin
Visual Studio Yükleyicisi bireysel bileşenler sekmesini kullanarak yükler
1. Visual Studio yükleyicisi Çalıştır
2. Değiştir 'i seçin
3. Ayrı bileşenler sekmesini seçin
4. .Net Compiler Platform SDK 'sıkutusunu işaretleyin. Bu dosyayı derleyiciler, derleme araçları ve çalışma
zamanları bölümünün altında bulabilirsiniz.
İsteğe bağlı olarak, dgml düzenleyicisinin grafikleri görselleştiricide görüntülemesini de istersiniz:
1. Dgml Düzenleyicisikutusunu işaretleyin. Bunu kod araçları bölümünde bulabilirsiniz.

Sözdizimi ağacı anlama


Söz dizimi API herhangi bir C# kodunun yapısını çözümlemesi için kullanırsınız. Söz dizimi API Çözümleyicileri,
söz dizimi ağacı ve analiz etme ve söz dizimi ağacı oluşturmak için yardımcı programlar kullanıma sunar. Bu, belirli
bir söz dizimi öğeleri için kod arama veya bir program kodunu okuma nasıl olur.
Sözdizimi ağacı, C# ve Visual Basic programlar anlamak için C# ve Visual Basic derleyiciler tarafından kullanılan
bir veri yapısıdır. Söz dizimi ağacı bir proje veya F5'e bir geliştirici İsabetleri çalıştırır aynı ayrıştırıcı tarafından
oluşturulur. Sözdizimi ağacı tam uygunluklu dilini sahip; bir kod dosyası bilgilerinin her bit ağacında temsil edilir.
Sözdizimi ağacı için metin yazma ayrıştırıldığında küpte tam orijinal metni yeniden oluşturur. Söz dizimi ağacı
ayrıca, değişmez; oluşturulan bir söz dizimi ağacı hiçbir zaman değiştirilebilir. Ağaçları tüketicilerinin ağaçları kilit
veya diğer eşzamanlılık ölçüler olmadan birden çok iş parçacığı üzerinde hiçbir zaman veri değişikliği bilerek
çözümleyebilirsiniz. API'leri, var olan bir ağaç değiştirme sonucu olan yeni ağacı oluşturmak için kullanabilirsiniz.
Sözdizimi ağacı dört birincil yapı taşları şunlardır:
Microsoft.CodeAnalysis.SyntaxTree Sınıfının bir örneğini temsil eden bir tüm ayrıştırma ağacı. SyntaxTree dile
özgü türevleri sahip bir soyut sınıftır. Ayrıştırma yöntemlerinin kullandığınız
Microsoft.CodeAnalysis.CSharp.CSharpSyntaxTree (veya
Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxTree) C# veya vb metni ayrıştırılamıyor sınıfı
Microsoft.CodeAnalysis.SyntaxNode Örnekleri, bildirimleri, deyimler, yan tümceleri ve ifadeler gibi bir söz
dizimi yapıları temsil eden sınıf.
Microsoft.CodeAnalysis.SyntaxToken Yapısı, tek tek anahtar sözcük, tanımlayıcı, işleci veya noktalama temsil
eder.
Ve son olarak Microsoft.CodeAnalysis.SyntaxTrivia belirteçleri, ön işleme yönergeleri ve yorumları arasındaki
boşluk gibi bilgileri sözdizimsel olarak anlamsız bitlerini gösteren yapısı.
Meraklısına Notlar belirteç ve düğümleri tamamen her şeyi Visual Basic veya C# kod parçasını temsil eden bir
ağaç oluşturmak için hiyerarşik olarak oluşur. Bu yapı kullanarak görebilirsiniz Syntax Visualizer penceresi.
Visual Studio'da görünümü > diğer Windows > Syntax Visualizer. Örneğin, önceki C# kaynak dosyası
incelenirken kullanarak Syntax Visualizer gibi aşağıdaki şekilde görünüyor:
SyntaxNode: Mavi | SyntaxToken: Yeşil | SyntaxTrivia: Kırmızı
Bu ağaç yapısı giderek deyim, ifade, belirteci veya boşluk biti bir kod dosyasında bulabilirsiniz.
Herhangi bir şey söz dizimi API'lerini kullanarak bir kod dosyasında bulabilirsiniz, ancak çoğu senaryoda küçük
kod parçacıkları inceleme veya arama belirli deyimleri veya parçaları içerir. Tipik show izleyen iki örnek kodu veya
arama için tek deyimler yapısını göz atmak için kullanır.

Geçiş ağaçları
İki yolla bir sözdizimi ağacında düğümlerin inceleyebilirsiniz. Her düğüm incelemek için ağacı gezme veya belirli
öğeleri veya düğümleri için sorgulayabilirsiniz.
El ile geçişi
Bu örnek için tamamlanan kodu gördüğünüz GitHub depomuzda.
NOTE
Sözdizimi ağacı türleri devralma programı farklı konumlarda geçerli olan farklı bir sözdizimi öğeleri tanımlamak için kullanın.
Genellikle bu API'leri kullanarak, atama özellikleri veya belirli türetilen türler için koleksiyon üyelerini anlamına gelir. Aşağıdaki
örneklerde, atama ve atamaları açıkça yazılmış değişkenler kullanarak ayrı deyim olan. API dönüş türleri ve döndürülen
nesnelerin çalışma zamanı türü görmek için kodu okuyabilirsiniz. Uygulamada, türü örtük olarak belirlenmiş değişkenlerin ve
incelenmekte olan nesnelerin türünü tanımlamak için API adlara dayalı daha yaygındır.

Yeni C# oluşturma tek başına kod analizi aracı proje:


Visual Studio'da dosya > yeni > proje yeni proje iletişim kutusu görüntülenecek.
Altında Visual C# > genişletilebilirlik, seçin tek başına kod analizi aracı.
Projenizi adlandırın "SyntaxTreeManualTraversal" ve Tamam'a tıklayın.
Temel "Hello World!" analiz etmek için gideceğinizi daha önce gösterilen programı. İçinde bir sabit olarak Hello
World programı için metin ekleyin, Program sınıfı:

const string programText =


@"using System;
using System.Collections;
using System.Linq;
using System.Text;

namespace HelloWorld
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(""Hello, World!"");
}
}
}";

Ardından, oluşturmak için aşağıdaki kodu ekleyin söz dizimi ağacı kod metinde programText sabit. Aşağıdaki
satırı ekleyin, Main yöntemi:

SyntaxTree tree = CSharpSyntaxTree.ParseText(programText);


CompilationUnitSyntax root = tree.GetCompilationUnitRoot();

Bu iki satırı ağacı oluşturmak ve o ağaç kök düğümü alınamıyor. Şimdi Ağaçtaki düğümler inceleyebilirsiniz. Bu
satırları ekleyin, Main yöntemi ağaç kök düğümü özelliklerinin bazılarını görüntülemek için:

WriteLine($"The tree is a {root.Kind()} node.");


WriteLine($"The tree has {root.Members.Count} elements in it.");
WriteLine($"The tree has {root.Usings.Count} using statements. They are:");
foreach (UsingDirectiveSyntax element in root.Usings)
WriteLine($"\t{element.Name}");

Kodunuz hakkında bu ağaç kök düğümü bulunduğundan görmek için uygulamayı çalıştırın.
Genellikle, kod hakkında bilgi edinmek için ağacı gezme. Bu örnekte, API'leri keşfedin bildiğiniz kodu
çözümlediğiniz. İlk üye incelemek için aşağıdaki kodu ekleyin root düğüm:
MemberDeclarationSyntax firstMember = root.Members[0];
WriteLine($"The first member is a {firstMember.Kind()}.");
var helloWorldDeclaration = (NamespaceDeclarationSyntax)firstMember;

Bu üye bir Microsoft.CodeAnalysis.CSharp.Syntax.NamespaceDeclarationSyntax. Her şeyi kapsamı temsil eden


namespace HelloWorld bildirimi. Hangi düğümleri içinde bildirilen incelemek için aşağıdaki kodu ekleyin
HelloWorld ad alanı:

WriteLine($"There are {helloWorldDeclaration.Members.Count} members declared in this namespace.");


WriteLine($"The first member is a {helloWorldDeclaration.Members[0].Kind()}.");

Öğrendiklerinizi görmek için programı çalıştırın.


Bildirimi öğrendiğinize göre olan bir Microsoft.CodeAnalysis.CSharp.Syntax.ClassDeclarationSyntax, sınıf
bildiriminin incelemek için bu türdeki yeni bir değişken bildirir. Bu sınıf yalnızca bir üye içeriyor: Main yöntemi.
Bulmak için aşağıdaki kodu ekleyin Main yöntemi ve bunu bir
Microsoft.CodeAnalysis.CSharp.Syntax.MethodDeclarationSyntax.

var programDeclaration = (ClassDeclarationSyntax)helloWorldDeclaration.Members[0];


WriteLine($"There are {programDeclaration.Members.Count} members declared in the
{programDeclaration.Identifier} class.");
WriteLine($"The first member is a {programDeclaration.Members[0].Kind()}.");
var mainDeclaration = (MethodDeclarationSyntax)programDeclaration.Members[0];

Yöntemi bildirim düğümü yöntemi söz dizimi tüm bilgileri içerir. Şimdi dönüş türünü görüntüle Main yöntemi,
sayı ve bağımsız değişken türlerinin yanı sıra, yöntemin gövde metni. Aşağıdaki kodu ekleyin:

WriteLine($"The return type of the {mainDeclaration.Identifier} method is {mainDeclaration.ReturnType}.");


WriteLine($"The method has {mainDeclaration.ParameterList.Parameters.Count} parameters.");
foreach (ParameterSyntax item in mainDeclaration.ParameterList.Parameters)
WriteLine($"The type of the {item.Identifier} parameter is {item.Type}.");
WriteLine($"The body text of the {mainDeclaration.Identifier} method follows:");
WriteLine(mainDeclaration.Body.ToFullString());

var argsParameter = mainDeclaration.ParameterList.Parameters[0];

Bu program hakkındaki tüm bilgileri keşfettiğinize göre görmek için bir programı çalıştır:

The tree is a CompilationUnit node.


The tree has 1 elements in it.
The tree has 4 using statements. They are:
System
System.Collections
System.Linq
System.Text
The first member is a NamespaceDeclaration.
There are 1 members declared in this namespace.
The first member is a ClassDeclaration.
There are 1 members declared in the Program class.
The first member is a MethodDeclaration.
The return type of the Main method is void.
The method has 1 parameters.
The type of the args parameter is string[].
The body text of the Main method follows:
{
Console.WriteLine("Hello, World!");
}
Sorgu yöntemleri
Ağaçlarında geçiş yapma ek olarak, söz dizimi ağacı tanımlanan sorgu yöntemlerini kullanarak da keşfedebilirsiniz
Microsoft.CodeAnalysis.SyntaxNode. Bu yöntemleri herkes XPath ile tanıdık hemen biliyor olmanız gerekir. Hızlı
bir şekilde bir ağaç şeyi bulmak için bu yöntemleri LINQ ile kullanabilirsiniz. SyntaxNode Sorgu yöntemleri gibi
sahip DescendantNodes, AncestorsAndSelf ve ChildNodes.
Bu sorgu yöntemleri bağımsız değişkeni bulmak için kullanabileceğiniz Main ağacında doğru alternatif olarak
yöntemi. ' In altına aşağıdaki kodu ekleyin, Main yöntemi:

var firstParameters = from methodDeclaration in root.DescendantNodes()


.OfType<MethodDeclarationSyntax>()
where methodDeclaration.Identifier.ValueText == "Main"
select methodDeclaration.ParameterList.Parameters.First();

var argsParameter2 = firstParameters.Single();

WriteLine(argsParameter == argsParameter2);

İlk deyim bir LINQ ifadesini kullanır ve DescendantNodes önceki örnektekiyle aynı parametre bulmak için
yöntemi.
Programı çalıştırın ve LINQ ifade ağacında el ile doğru olarak aynı parametre bulundu görebilirsiniz.
Örnek kullanır WriteLine deyimleri, geçiş söz dizimi ağacı hakkında bilgi görüntülemek için. Ayrıca, hata
ayıklayıcısı altında tamamlanmış program çalıştırarak çok daha fazlasını öğrenebilirsiniz. Daha fazla özellik ve hello
world programı için oluşturulan söz dizimi ağacı parçası olan yöntem inceleyebilirsiniz.

Söz dizimi yürüyüşçüleri


Genellikle, örneğin, her özellik bildiriminde bir dosyada bir sözdizimi ağacındaki belirli bir türdeki tüm düğümleri
bulmak istediğiniz. Genişleterek Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker sınıf ve geçersiz kılma
VisitPropertyDeclaration(PropertyDeclarationSyntax) yöntemi, işlem her bir özellik bildirimi bir sözdizimi ağacında
yapısını önceden bilmeden. CSharpSyntaxWalker belirli bir tür olan CSharpSyntaxVisitor , yinelemeli bir düğüm ve
her alt ziyaret eder.
Bu örnekte uygulayan bir CSharpSyntaxWalker , söz dizimi ağacı inceler. Topladığı using bulduğu yönergeleri,
içeri aktarma olmayan bir System ad alanı.
Yeni C# oluşturma tek başına kod analizi aracı adlandırın; projesi "SyntaxWalker."
Bu örnek için tamamlanan kodu gördüğünüz GitHub depomuzda. Github'daki örnek bu eğiticide açıklananlarla
her iki proje içerir.
Önceki örnekte olduğu gibi metin analiz etmek için gideceğinizi programının tutmak için bir dize sabitine
tanımlayabilirsiniz:
const string programText =
@"using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;

namespace TopLevel
{
using Microsoft;
using System.ComponentModel;

namespace Child1
{
using Microsoft.Win32;
using System.Runtime.InteropServices;

class Foo { }
}

namespace Child2
{
using System.CodeDom;
using Microsoft.CSharp;

class Bar { }
}
}";

Bu kaynak metni içeren using yönergeleri dört farklı konumlar arasında dağılmış: dosya düzeyinde, üst düzey ad
alanı ve iki iç içe geçmiş ad alanı. Bu örneği kullanmak için bir çekirdek senaryosu vurgulanıyor
CSharpSyntaxWalker sorgu kod sınıfı. Her düğüm bildirimi kullanarak bulmak için kök sözdizimi ağacındaki
ziyaret etmek için hantal olabilir. Bunun yerine, türetilen bir sınıf oluşturun ve yalnızca geçerli düğüm ağaçta
kullanarak bir olduğunda çağrılan yöntemin yönergesi. Ziyaretçi herhangi bir düğüm türleri üzerinde herhangi bir
iş yapmaz. Bu tek bir yöntem her biri inceler using deyimleri olmayan ad uzayları koleksiyonu oluşturur System
ad alanı. Oluşturduğunuz bir CSharpSyntaxWalker tüm inceler using deyimleri, ancak yalnızca using deyimleri.
Program metni tanımladığınıza göre oluşturmak gereken bir SyntaxTree ve o ağaç kökünde alın:

SyntaxTree tree = CSharpSyntaxTree.ParseText(programText);


CompilationUnitSyntax root = tree.GetCompilationUnitRoot();

Ardından, yeni bir sınıf oluşturun. Visual Studio'da proje > Yeni Öğe Ekle. İçinde Yeni Öğe Ekle iletişim
kutusuna UsingCollector.cs dosya adı olarak.
Uygulamanız using ziyaretçi işlevindeki UsingCollector sınıfı. Başlangıç yaparak UsingCollector sınıfı türetilen
CSharpSyntaxWalker.

class UsingCollector : CSharpSyntaxWalker

Toplayacağınızı ad alanı düğümleri tutmak için depolama gerekir. Genel bir salt okunur özelliği bildirme
UsingCollector sınıfı; depolamak için bu değişkeni kullanın UsingDirectiveSyntax bulduğunuz düğümleri:

public ICollection<UsingDirectiveSyntax> Usings { get; } = new List<UsingDirectiveSyntax>();

Temel sınıfı, CSharpSyntaxWalker sözdizimi ağacı içindeki her bir düğümün ziyaret etmek için mantığını uygular.
Türetilmiş sınıf, ilgilendiğiniz belirli düğümler için çağrılan yöntemler geçersiz kılar. Bu durumda, tüm ilginizi çeken
using yönergesi. Geçersiz kılması gerekir yani VisitUsingDirective( UsingDirectiveSyntax) yöntemi. Bu yöntemin
bir bağımsız değişken bir Microsoft.CodeAnalysis.CSharp.Syntax.UsingDirectiveSyntax nesne. Ziyaretçi
kullanmanın önemli bir avantajı olmasıdır: Bunlar bağımsız değişken zaten belirli düğüm türüne geçersiz kılınan
yöntemleri çağırın. Microsoft.CodeAnalysis.CSharp.Syntax.UsingDirectiveSyntax Sınıfında bir Name içeri aktarılan
ad alanı adını depolar özelliği. Bu bir Microsoft.CodeAnalysis.CSharp.Syntax.NameSyntax. Aşağıdaki kodu ekleyin
VisitUsingDirective(UsingDirectiveSyntax) geçersiz kıl:

public override void VisitUsingDirective(UsingDirectiveSyntax node)


{
WriteLine($"\tVisitUsingDirective called with {node.Name}.");
if (node.Name.ToString() != "System" &&
!node.Name.ToString().StartsWith("System."))
{
WriteLine($"\t\tSuccess. Adding {node.Name}.");
this.Usings.Add(node);
}
}

Önceki örnekte, çeşitli eklediğiniz şekilde WriteLine deyimleri, bu yöntem bir anlayış, yardımcı olacak. Ne zaman
çağrılır ve her zaman için hangi bağımsız değişkenler geçirilir görebilirsiniz.
Son olarak, iki oluşturmak için kod satırı eklemeniz gerekir UsingCollector ve tüm toplama kök düğümünü ziyaret
using deyimleri. Ardından ekleyin bir foreach tümü döngü using deyimleri toplayıcınız bulundu:

var collector = new UsingCollector();


collector.Visit(root);
foreach (var directive in collector.Usings)
{
WriteLine(directive.Name);
}

Derleme ve programı çalıştırın. Aşağıdaki çıktıyı görmeniz gerekir:

VisitUsingDirective called with System.


VisitUsingDirective called with System.Collections.Generic.
VisitUsingDirective called with System.Linq.
VisitUsingDirective called with System.Text.
VisitUsingDirective called with Microsoft.CodeAnalysis.
Success. Adding Microsoft.CodeAnalysis.
VisitUsingDirective called with Microsoft.CodeAnalysis.CSharp.
Success. Adding Microsoft.CodeAnalysis.CSharp.
VisitUsingDirective called with Microsoft.
Success. Adding Microsoft.
VisitUsingDirective called with System.ComponentModel.
VisitUsingDirective called with Microsoft.Win32.
Success. Adding Microsoft.Win32.
VisitUsingDirective called with System.Runtime.InteropServices.
VisitUsingDirective called with System.CodeDom.
VisitUsingDirective called with Microsoft.CSharp.
Success. Adding Microsoft.CSharp.
Microsoft.CodeAnalysis
Microsoft.CodeAnalysis.CSharp
Microsoft
Microsoft.Win32
Microsoft.CSharp
Press any key to continue . . .

Tebrikler! Kullandığınız söz dizimi API C# belirli tür bulmak için ifadeleri ve bildirimleri C# kaynak kodu.
Anlamsal analiz ile çalışmaya başlama
23.10.2019 • 14 minutes to read • Edit Online

Bu öğreticide, sözdizimi API 'SI hakkında bilgi sahibi olduğunuz varsayılır. Sözdizimi analizi ile çalışmaya başlama
makalesi, yeterli giriş sağlar.
Bu öğreticide, sembol ve bağlama API 'lerinikeşfedebilirsiniz. Bu API 'Ler, bir programın anlam anlamı
hakkında bilgi sağlar. Bunlar, programınızda herhangi bir sembol tarafından temsil edilen türler hakkında soru
sormaya ve yanıt uygulamanıza olanak tanır.
.Net Compiler Platform SDK 'sınıyüklemeniz gerekir:

Yükleme yönergeleri-Visual Studio Yükleyicisi


Visual Studio Yükleyicisi .net Compiler Platform SDK 'sını bulmanın iki farklı yolu vardır:
Visual Studio Yükleyicisi Iş yükleri görünümünü kullanarak yükler
.NET Compiler Platform SDK, Visual Studio uzantısı geliştirme iş yükünün bir parçası olarak otomatik olarak
seçilmemiş. Bunu isteğe bağlı bir bileşen olarak seçmeniz gerekir.
1. Visual Studio yükleyicisi Çalıştır
2. Değiştir 'i seçin
3. Visual Studio uzantısı geliştirme iş yükünü denetleyin.
4. Özet ağacında Visual Studio uzantısı geliştirme düğümünü açın.
5. .Net Compiler Platform SDK 'sıkutusunu işaretleyin. En son isteğe bağlı bileşenler altında bulacaksınız.
İsteğe bağlı olarak, dgml düzenleyicisinin grafikleri görselleştiricide görüntülemesini de istersiniz:
1. Özet ağacındaki bireysel bileşenler düğümünü açın.
2. Dgml Düzenleyicisi kutusunu işaretleyin
Visual Studio Yükleyicisi bireysel bileşenler sekmesini kullanarak yükler
1. Visual Studio yükleyicisi Çalıştır
2. Değiştir 'i seçin
3. Ayrı bileşenler sekmesini seçin
4. .Net Compiler Platform SDK 'sıkutusunu işaretleyin. Bu dosyayı derleyiciler, derleme araçları ve çalışma
zamanları bölümünün altında bulabilirsiniz.
İsteğe bağlı olarak, dgml düzenleyicisinin grafikleri görselleştiricide görüntülemesini de istersiniz:
1. Dgml Düzenleyicisikutusunu işaretleyin. Bunu kod araçları bölümünde bulabilirsiniz.

Derlemeleri ve sembolleri anlama


.NET derleyici SDK ile daha fazla çalışırken, sözdizimi API 'SI ve anlam API 'SI arasındaki farklılıklarla ilgili bilgi
sahibi olursunuz. Sözdizimi API 'si , bir programın yapısına bakabilmeniz için izin verir. Ancak, genellikle bir
programın semantiği veya anlamı hakkında daha zengin bilgi istemeniz gerekir. Bir seyrek kod dosyası ya da VB
veya C# kod parçacığı, yalıtım halinde analiz edilebilir olsa da, "Bu değişkenin türü nedir" gibi sorular sormak için
anlamlı değildir. Bir tür adının anlamı derleme başvurularına, ad alanı içeri aktarmalara veya diğer kod dosyalarına
bağlı olabilir. Bu sorular, özellikle Microsoft.CodeAnalysis.Compilation sınıfı olan semantik APIkullanılarak
yanıtlanır.
Bir örneği Compilation , derleyici tarafından görülen tek bir projeye benzerdir ve bir Visual Basic veya C# program
derlemek için gereken her şeyi temsil eder. Derleme , Derlenecek kaynak dosyalar kümesi, derleme başvuruları ve
derleyici seçenekleri içerir. Bu bağlamdaki tüm diğer bilgileri kullanarak kodun anlamı hakkında neden olabilirsiniz.
, Türler, ad alanları, Üyeler ve ad ve diğer ifadelerin başvurduğu değişkenler gibi sembolleri bulmanıza
olanaktanır.Compilation Adları ve ifadeleri simgelerle Ilişkilendirme işlemine bağlamadenir.
Benzer Microsoft.CodeAnalysis.SyntaxTreeşekilde Compilation , dile özgü türevlerle soyut bir sınıftır. Bir derleme
örneği oluştururken, Microsoft.CodeAnalysis.CSharp.CSharpCompilation (veya
Microsoft.CodeAnalysis.VisualBasic.VisualBasicCompilation) sınıfında bir fabrika yöntemi çağırmanız gerekir.

Sembolleri sorgulama
Bu öğreticide, "Merhaba Dünya" programına tekrar göz atalım. Bu kez, bu sembollerin hangi türleri temsil ettiğini
anlamak için programdaki sembolleri sorgulayın. Bir ad alanındaki türleri sorgular ve bir tür üzerinde kullanılabilir
olan yöntemleri bulmayı öğrenin.
Bu örnek için tamamlanmış kodu GitHub depomuzabakabilirsiniz.

NOTE
Sözdizimi ağacı türleri, programdaki farklı konumlarda geçerli olan farklı sözdizimi öğelerini anlatmak için devralmayı kullanır.
Bu API 'Lerin kullanılması genellikle özellikleri veya koleksiyon üyelerini belirli türetilmiş türlere atama anlamına gelir. Aşağıdaki
örneklerde atama ve yayınlar, açıkça belirlenmiş değişkenler kullanılarak ayrı deyimlerdir. API 'nin dönüş türlerini ve
döndürülen nesnelerin çalışma zamanı türünü görmek için kodu okuyabilirsiniz. Uygulamada, örtük olarak yazılan değişkenleri
kullanmak daha yaygındır ve incelenen nesne türlerini belirtmek için API adlarını kullanır.

Yeni C# bir tek başına kod analizi araç projesi oluşturun:


Visual Studio 'da yeni proje iletişim kutusunu göstermek için Dosya > Yeni > Proje ' yi seçin.
Görsel C# genişletilebilirlik altında tek başına Kod Analizi Aracı ' nı seçin. >
Projenizi "Semantıhızlı başlangıç" olarak adlandırın ve Tamam ' a tıklayın.
Temel "Merhaba Dünya!" öğesini çözümleyeceğiz Program daha önce gösteriliyor. Merhaba Dünya programın
metnini sınıfınıza Program bir sabit olarak ekleyin:

const string programText =


@"using System;
using System.Collections.Generic;
using System.Text;

namespace HelloWorld
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(""Hello, World!"");
}
}
}";

Sonra, programText sabit içindeki kod metni için sözdizimi ağacını derlemek üzere aşağıdaki kodu ekleyin.
Aşağıdaki satırı Main yöntemine ekleyin:
SyntaxTree tree = CSharpSyntaxTree.ParseText(programText);

CompilationUnitSyntax root = tree.GetCompilationUnitRoot();

Ardından, zaten oluşturduğunuz CSharpCompilation ağaçtan bir oluşturun. "Merhaba Dünya" örneği String ve
Console türlerini temel alır. Derlemenizin bu iki türü bildiren derlemeye başvurmanız gerekir. Uygun derlemeye
başvuru dahil olmak üzere Main , sözdizimi ağacınızı oluşturmak için aşağıdaki satırı yöntemine ekleyin:

var compilation = CSharpCompilation.Create("HelloWorld")


.AddReferences(MetadataReference.CreateFromFile(
typeof(string).Assembly.Location))
.AddSyntaxTrees(tree);

CSharpCompilation.AddReferences Yöntemi, derlemeye başvurular ekler. MetadataReference.CreateFromFile


Yöntemi bir derlemeyi başvuru olarak yükler.

Anlam modelini sorgulama


Bir Compilation kez oluşturduktan sonra, bunun için bir SemanticModel SyntaxTree Compilationiçin bunu
isteyebilirsiniz. Anlamsal modeli, normalde IntelliSense 'ten alacağınız tüm bilgilerin kaynağı olarak
düşünebilirsiniz. Bir SemanticModel "Bu konumda kapsam içinde olan adlar nedir?", "Bu metin bloğunda hangi
değişkenler kullanılır?" ve "Bu ad/ifade ne ifade edilir?" gibi sorulara yanıt verebilir Anlam modeli oluşturmak için
bu ifadeyi ekleyin:

SemanticModel model = compilation.GetSemanticModel(tree);

Ad bağlama
SemanticModel , Öğesinden Compilation öğesini oluşturur .SyntaxTree Modeli oluşturduktan sonra, ilk using
yönergeyi bulmak için sorgulama yapabilir ve System ad alanı için sembol bilgilerini alabilirsiniz. Anlam modeli
oluşturmak ve ilk using Main ifadesinin simgesini almak için bu iki satırı yönteminizin içine ekleyin:

// Use the syntax tree to find "using System;"


UsingDirectiveSyntax usingSystem = root.Usings[0];
NameSyntax systemName = usingSystem.Name;

// Use the semantic model for symbol information:


SymbolInfo nameInfo = model.GetSymbolInfo(systemName);

Yukarıdaki kodda ad using System alanı Microsoft.CodeAnalysis.SymbolInfo için ilk yönergedeki adın nasıl
bağlanacağı gösterilmektedir. Yukarıdaki kod ayrıca kodun yapısını bulmak için sözdizimi modelini kullanmanızı
da gösterir; anlam modelini , anlamını anlamak için kullanabilirsiniz. Sözdizimi modeli using deyimindeki dizeyi
System bulur. Anlam modeli , System ad alanında tanımlanan türlerle ilgili tüm bilgileri içerir.

Nesnesinden özelliğini Microsoft.CodeAnalysis.ISymbol kullanarak elde edebilirsiniz. SymbolInfo


SymbolInfo.Symbol Bu özellik, bu ifadenin başvurduğu simgeyi döndürür. Her şeye başvurmaz (sayısal değişmez
değerler gibi), bu özellik olur null . Nullolmadığında,simgenintürünügösterir.SymbolInfo.Symbol ISymbol.Kind Bu
örnekte, ISymbol.Kind özelliği bir SymbolKind.Namespace. Main Yöntemine aşağıdaki kodu ekleyin. System Ad
alanı için sembolü alır ve System ad alanında belirtilen tüm alt ad alanlarını görüntüler:
var systemSymbol = (INamespaceSymbol)nameInfo.Symbol;
foreach (INamespaceSymbol ns in systemSymbol.GetNamespaceMembers())
{
Console.WriteLine(ns);
}

Programı çalıştırın ve aşağıdaki çıktıyı görmeniz gerekir:

System.Collections
System.Configuration
System.Deployment
System.Diagnostics
System.Globalization
System.IO
System.Numerics
System.Reflection
System.Resources
System.Runtime
System.Security
System.StubHelpers
System.Text
System.Threading
Press any key to continue . . .

NOTE
Çıktı, System ad alanının alt ad alanı olan her ad alanını içermez. Bu derlemede bulunan her ad alanını görüntüler, bu
derleme yalnızca bildirildiği derlemeye System.String başvurur. Diğer derlemelerde belirtilen ad alanları bu derleme
tarafından tanınmıyor

Bir ifadeyi bağlama


Yukarıdaki kod, bir ada bağlama yoluyla nasıl bir sembol bulunacağını gösterir. Bir C# programda adı olmayan
bağlanabilen başka ifadeler de vardır. Bu özelliği göstermek için bağlamaya basit bir dize değişmez değerine
erişelim.
"Merhaba Dünya" programı Microsoft.CodeAnalysis.CSharp.Syntax.LiteralExpressionSyntax, "Hello, World!"
öğesini içerir konsola görüntülenecek dize.
"Hello, World!" öğesini bulursunuz Programda tek dize sabit değerini bularak dize. Ardından, söz dizimi
düğümünü bulduktan sonra söz konusu düğümün tür bilgilerini anlamsal modelden alın. Aşağıdaki kodu Main
yönteminizin içine ekleyin:

// Use the syntax model to find the literal string:


LiteralExpressionSyntax helloWorldString = root.DescendantNodes()
.OfType<LiteralExpressionSyntax>()
.Single();

// Use the semantic model for type information:


TypeInfo literalInfo = model.GetTypeInfo(helloWorldString);

Struct, değişmez değer TypeInfo.Type türü hakkında anlam bilgisine erişim sağlayan bir özelliği içerir.
Microsoft.CodeAnalysis.TypeInfo Bu örnekte, string türü budur. Bu özelliği yerel bir değişkene atayan bir bildirim
ekleyin:

var stringTypeSymbol = (INamedTypeSymbol)literalInfo.Type;


Bu öğreticiyi tamamlaması için, string string döndüren türünde belirtilen tüm ortak yöntemlerin bir dizisini
oluşturan bir LINQ sorgusu oluşturalım. Bu sorgu karmaşıktır, bu yüzden satırı satıra göre oluşturalım ve sonra tek
bir sorgu olarak yeniden yapılandırma. Bu sorgunun kaynağı, string türde belirtilen tüm üyelerin sırasıdır:

var allMembers = stringTypeSymbol.GetMembers();

Bu kaynak sırası Özellikler ve alanlar da dahil olmak üzere tüm üyeleri içerir, bu nedenle
ImmutableArray<T>.OfType Microsoft.CodeAnalysis.IMethodSymbol nesne olan öğeleri bulmak için yöntemini
kullanarak filtreleyin:

var methods = allMembers.OfType<IMethodSymbol>();

Sonra, yalnızca ortak olan yöntemleri döndürmek için başka bir filtre ekleyin ve şunu döndürür string :

var publicStringReturningMethods = methods


.Where(m => m.ReturnType.Equals(stringTypeSymbol) &&
m.DeclaredAccessibility == Accessibility.Public);

Yalnızca ad özelliğini ve yalnızca herhangi bir aşırı yüklemeyi kaldırarak farklı adları seçin:

var distinctMethods = publicStringReturningMethods.Select(m => m.Name).Distinct();

Ayrıca, LINQ sorgu söz dizimini kullanarak tam sorgu oluşturabilir ve sonra tüm yöntem adlarını konsolda
görüntüleyebilirsiniz:

foreach (string name in (from method in stringTypeSymbol


.GetMembers().OfType<IMethodSymbol>()
where method.ReturnType.Equals(stringTypeSymbol) &&
method.DeclaredAccessibility == Accessibility.Public
select method.Name).Distinct())
{
Console.WriteLine(name);
}

Programı derleyin ve çalıştırın. Aşağıdaki çıktıyı görmeniz gerekir:


Join
Substring
Trim
TrimStart
TrimEnd
Normalize
PadLeft
PadRight
ToLower
ToLowerInvariant
ToUpper
ToUpperInvariant
ToString
Insert
Replace
Remove
Format
Copy
Concat
Intern
IsInterned
Press any key to continue . . .

Bu programın parçası olan semboller hakkındaki bilgileri bulmak ve göstermek için anlamsal API 'YI kullandınız.
Söz dizimi dönüştürme ile çalışmaya başlama
23.10.2019 • 20 minutes to read • Edit Online

Bu öğreticide kavrama oluşturur ve teknikleri incelediniz içinde söz dizimi Analizi ile çalışmaya başlama ve anlam
Analizi ile çalışmaya başlama hızlı başlangıçları. Henüz yapmadıysanız, bunu başlamadan önce bu hızlı
başlangıçların tamamlamanız gerekir.
Bu hızlı başlangıçta, oluşturma ve söz dizimi ağacı dönüştürmeye yönelik teknikleri keşfedin. Önceki hızlı
başlangıçlar, öğrendiğiniz teknikleri ile birlikte, ilk komut satırı yeniden düzenleme oluşturun!

Yükleme yönergeleri-Visual Studio Yükleyicisi


Visual Studio Yükleyicisi .net Compiler Platform SDK 'sını bulmanın iki farklı yolu vardır:
Visual Studio Yükleyicisi Iş yükleri görünümünü kullanarak yükler
.NET Compiler Platform SDK, Visual Studio uzantısı geliştirme iş yükünün bir parçası olarak otomatik olarak
seçilmemiş. Bunu isteğe bağlı bir bileşen olarak seçmeniz gerekir.
1. Visual Studio yükleyicisi Çalıştır
2. Değiştir 'i seçin
3. Visual Studio uzantısı geliştirme iş yükünü denetleyin.
4. Özet ağacında Visual Studio uzantısı geliştirme düğümünü açın.
5. .Net Compiler Platform SDK 'sıkutusunu işaretleyin. En son isteğe bağlı bileşenler altında bulacaksınız.
İsteğe bağlı olarak, dgml düzenleyicisinin grafikleri görselleştiricide görüntülemesini de istersiniz:
1. Özet ağacındaki bireysel bileşenler düğümünü açın.
2. Dgml Düzenleyicisi kutusunu işaretleyin
Visual Studio Yükleyicisi bireysel bileşenler sekmesini kullanarak yükler
1. Visual Studio yükleyicisi Çalıştır
2. Değiştir 'i seçin
3. Ayrı bileşenler sekmesini seçin
4. .Net Compiler Platform SDK 'sıkutusunu işaretleyin. Bu dosyayı derleyiciler, derleme araçları ve çalışma
zamanları bölümünün altında bulabilirsiniz.
İsteğe bağlı olarak, dgml düzenleyicisinin grafikleri görselleştiricide görüntülemesini de istersiniz:
1. Dgml Düzenleyicisikutusunu işaretleyin. Bunu kod araçları bölümünde bulabilirsiniz.

Değiştirilemezliği ve .NET derleyici platformu


Değiştirilemezlik olan .NET derleyici platformu temel de aynen geçerli. Sabit veri yapıları, oluşturuldukları sonra
değiştirilemez. Sabit veri yapılarını güvenli bir şekilde paylaşılan ve aynı anda birden fazla tüketici tarafından analiz
edilir. Tek bir tüketici başka bir öngörülemeyen şekillerde etkiler tehlike yoktur. Çözümleyici kilit veya diğer
eşzamanlılık ölçüleri gerek yoktur. Bu kural, söz dizimi ağacı, derlemeleri, simgeler, anlam modelleri ve
karşılaştığınız her veri yapısı için geçerlidir. Mevcut yapıları değiştirmek yerine yeni nesneleri eskilerle belirtilen
farklılıklar göre API'ler oluşturun. Bu kavramı dönüştürmeleri kullanma yeni ağacı oluşturmak için sözdizimi ağacı
için geçerlidir.
Oluşturma ve ağaçları dönüştürün
Söz dizimi dönüştürmeleri için iki stratejileri birini seçin. Fabrika yöntemleri değiştirmek için belirli düğümler ya
da yeni kod eklemek istediğiniz belirli konumları için arama yapıyorsanız, en iyi şekilde kullanılır. Yazıcılar olan bir
projenin tamamı, kod desenleri için tarama istediğinizde iyi istediğiniz değiştirin.
Düğümleri Fabrika yöntemleri ile oluşturma
İlk söz dizimi dönüşümü Fabrika yöntemleri gösterir. Değiştirilecek gideceğinizi bir using System.Collections;
deyimiyle bir using System.Collections.Generic; deyimi. Bu örnek nasıl oluşturabileceğinizi gösterir
Microsoft.CodeAnalysis.CSharp.CSharpSyntaxNode kullanarak nesneleri
Microsoft.CodeAnalysis.CSharp.SyntaxFactory Fabrika yöntemleri. Her tür için düğüm, belirteci, veya
Meraklısına Notlar o türün bir örneği oluşturan bir Üreteç yöntemi yoktur. Hiyerarşik olarak aşağıdan yukarıya
çıktısından düğümler tarafından söz dizimi ağacı oluşturmak. Ardından, var olan dönüştürme programı var olan
düğümleri oluşturduğunuz yeni ağaçta değiştirdiğiniz.
Visual Studio'yu başlatın ve yeni C# oluşturma tek başına kod analizi aracı proje. Visual Studio'da dosya > yeni
> proje yeni proje iletişim kutusu görüntülenecek. Altında Visual C# > genişletilebilirlik seçin bir tek başına
kod analizi aracı. Bu hızlı başlangıçta iki örnek projeler varsa, bu nedenle çözümünü arlandırın
SyntaxTransformationQuickStart, projeyi adlandırın ConstructionCS. Tamam'ı tıklatın.
Bu proje kullanan Microsoft.CodeAnalysis.CSharp.SyntaxFactory sınıfı oluşturmak için yöntemleri bir
Microsoft.CodeAnalysis.CSharp.Syntax.NameSyntax temsil eden System.Collections.Generic ad alanı.
Aşağıdakileri ekleyin üstüne yönergesi kullanarak Program.cs Fabrika yöntemleri içeri aktarmak için dosya
SyntaxFactory sınıfı ve yöntemlerinin Console böylece bunları daha sonra bunları nitelemeden kullanabilirsiniz:

using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;


using static System.Console;

Oluşturacağınız ad sözdizimi düğümleri temsil eden ağacı oluşturmak için using System.Collections.Generic;
deyimi. NameSyntax dört tür C# içinde görünen adları için temel sınıftır. Bu dört tür adları birlikte C# dilinde
görünebilir herhangi bir ad oluşturmak için Araçlar:
Microsoft.CodeAnalysis.CSharp.Syntax.NameSyntax, basit bir tek tanımlayıcı adları gibi temsil eden System ve
Microsoft .
Microsoft.CodeAnalysis.CSharp.Syntax.GenericNameSyntax, aşağıdaki gibi genel bir tür veya yöntem ad temsil
List<int> .
Microsoft.CodeAnalysis.CSharp.Syntax.QualifiedNameSyntax, formun tam adını temsil eden
<left-name>.<right-identifier-or-generic-name> gibi System.IO .
Microsoft.CodeAnalysis.CSharp.Syntax.AliasQualifiedNameSyntax, derleme extern diğer adı gibi kullanarak adı
temsil eden bir LibraryV2::Foo .

Kullandığınız IdentifierName(String) yöntemi oluşturmak için bir NameSyntax düğümü. Aşağıdaki kodu ekleyin,
Main yönteminde Program.cs :

NameSyntax name = IdentifierName("System");


WriteLine($"\tCreated the identifier {name.ToString()}");

Yukarıdaki kod oluşturur bir IdentifierNameSyntax nesnesi ve bir değişkene atar name . Roslyn API'leri birçoğu, iş
ile ilgili türleri daha kolay hale getirmek için temel sınıfları döndürür. Değişken name e NameSyntax, derleme
sırasında yeniden kullanılabilir QualifiedNameSyntax. Örneği oluşturmak gibi tür çıkarımı kullanmayın. Bu proje o
adımda otomatikleştirin.
Adı oluşturdunuz. Daha fazla düğüm oluşturarak ağacına oluşturmak için zamanı artık, bir QualifiedNameSyntax.
Yeni ağaç kullanan name adını ve yeni bir sol olarak IdentifierNameSyntax için Collections sağ tarafı olarak ad
alanı QualifiedNameSyntax. Aşağıdaki kodu ekleyin program.cs :

name = QualifiedName(name, IdentifierName("Collections"));


WriteLine(name.ToString());

Kodu yeniden çalıştırmak ve sonuçlarını görebilirsiniz. Kod temsil eden bir ağaç düğümleri oluşturuyorsunuz. Bu
düzen oluşturmak için devam edeceğiz QualifiedNameSyntax ad alanı için System.Collections.Generic . Aşağıdaki
kodu ekleyin Program.cs :

name = QualifiedName(name, IdentifierName("Generic"));


WriteLine(name.ToString());

Yeniden olduğunuz, ağacında eklenecek kodu görmek için programı çalıştırın.


Değiştirilmiş bir ağaç oluşturun
Bir ifade içeren bir küçük söz dizimi ağacı oluşturdunuz. Yeni düğümler oluşturma API'ları, tek deyimler veya diğer
küçük kod blokları oluşturmak için doğru seçimdir. Ancak, daha büyük kod bloklarını oluşturmak için düğümleri
değiştirin veya varolan bir ağacına düğümlerini eklemek yöntemlerini kullanmanız gerekir. Sözdizimi ağacı sabit
olduğunu unutmayın. Söz dizimi API var olan bir söz dizimi ağacı oluşturma sonra değiştirmek için herhangi bir
mekanizma sağlamaz. Bunun yerine, mevcut olanlara değişikliklere göre yeni ağaçları oluşturan yöntemleri sağlar.
With* öğesinden türetilen somut sınıflar, yöntemlerin tanımlandığı SyntaxNode veya genişletme yöntemleri
bildirilen SyntaxNodeExtensions sınıfı. Bu yöntemler, mevcut bir düğümün alt özellikleri için değişiklikleri
uygulayarak yeni bir düğüm oluşturur. Ayrıca, ReplaceNode genişletme yöntemi, bir alt düğüm ağaçtaki
değiştirmek için kullanılabilir. Bu yöntem ayrıca üst yeni oluşturulan alt öğeye işaret edecek şekilde güncelleştirir ve
tüm ağacı - olarak da bilinen bir işlem bu işlemi yineler yeniden dönen ağaç.
Sonraki adım, bir programın tamamındaki (küçük) temsil eden bir ağaç oluşturmak ve değiştirmek sağlamaktır.
Aşağıdaki kodu ekleyin başlangıcına Program sınıfı:

private const string sampleCode =


@"using System;
using System.Collections;
using System.Linq;
using System.Text;

namespace HelloWorld
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(""Hello, World!"");
}
}
}";

NOTE
Örnek kod System.Collections ad alanı değil System.Collections.Generic ad alanı.

Ardından, altına aşağıdaki kodu ekleyin Main yöntemi metni ayrıştırılamadı ve bir ağaç oluşturun:
SyntaxTree tree = CSharpSyntaxTree.ParseText(sampleCode);
var root = (CompilationUnitSyntax)tree.GetRoot();

Bu örnekte WithName(NameSyntax) adını değiştirmek için yöntemi bir UsingDirectiveSyntax önceki kodda
oluşturulan tek düğüm.
Yeni bir UsingDirectiveSyntax düğümü kullanan WithName(NameSyntax) güncelleştirilecek yöntemi
System.Collections önceki kodda oluşturduğunuz adıyla adı. ' In altına aşağıdaki kodu ekleyin Main yöntemi:

var oldUsing = root.Usings[1];


var newUsing = oldUsing.WithName(name);
WriteLine(root.ToString());

Programı çalıştırın ve çıktıyı dikkatle inceleyin. newusing Kök ağacında yerleştirilen edilmemiş. Özgün ağaç
değişmedi.
Aşağıdaki kodu kullanarak ekleme ReplaceNode yeni bir ağaç oluşturmak için genişletme yöntemi. Yeni ağaç
mevcut içeri aktarma güncelleştirilmiş ile değiştirerek sonucudur newUsing düğümü. Bu yeni ağaç varolan
atadığınız root değişkeni:

root = root.ReplaceNode(oldUsing, newUsing);


WriteLine(root.ToString());

Programı yeniden çalıştırın. Bu süre ağaç artık doğru şekilde içeri aktarır System.Collections.Generic ad alanı.
Ağaçları kullanarak dönüştürme SyntaxRewriters

With* Ve ReplaceNode yöntemleri sağlayan bireysel dalları söz dizimi ağacı dönüştürmek için kullanışlı anlamına
gelir. Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter Sınıfı bir sözdizimi ağacında birden çok dönüşümleri
gerçekleştirir. Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter Sınıftır öğesinin
Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor<TResult>. CSharpSyntaxRewriter Belirli bir türüne
dönüştürme uygulanan SyntaxNode. Dönüştürmeleri çoklu türleri için geçerli SyntaxNode söz dizimi ağacı içinde
göründükleri yere nesneleri. İkinci projenin Bu hızlı başlangıçta, bir komut satırı tür çıkarımı, her yerde kullanılabilir
yerel değişken bildirimlerinde türleri açık kaldıran yeniden düzenleme oluşturur.
Yeni C# oluşturma tek başına kod analizi aracı proje. Visual Studio'da sağ SyntaxTransformationQuickStart
çözüm düğümü. Seçin Ekle > yeni proje görüntülenecek yeni proje iletişim kutusu. Altında Visual C# >
genişletilebilirlik, seçin tek başına kod analizi aracı. Projenizi adlandırın TransformationCS ve Tamam'a tıklayın.
Türetilen bir sınıf oluşturmak için ilk adımıdır CSharpSyntaxRewriter Bağlantılarınızdaki gerçekleştirilecek. Projeye
yeni bir sınıf dosyası ekleyin. Visual Studio'da proje > sınıfı Ekle... . İçinde Yeni Öğe Ekle iletişim kutusuna
TypeInferenceRewriter.cs dosya adı olarak.

Aşağıdaki using yönergelerini TypeInferenceRewriter.cs dosyası:

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;

Ardından, olun TypeInferenceRewriter sınıfını genişleten CSharpSyntaxRewriter sınıfı:

public class TypeInferenceRewriter : CSharpSyntaxRewriter


Tutmak için özel bir salt okunur alanı bildirmek için aşağıdaki kodu ekleyin bir SemanticModel ve oluşturucuda
başlatır. Daha sonra tür çıkarımı kullanıldığı belirlemek için bu alana ihtiyacınız olacak:

private readonly SemanticModel SemanticModel;

public TypeInferenceRewriter(SemanticModel semanticModel) => SemanticModel = semanticModel;

Geçersiz kılma VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax) yöntemi:

public override SyntaxNode VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node)


{

NOTE
Roslyn API'leri birçoğu, döndürülen gerçek çalışma zamanı türlerinin temel sınıflardır dönüş türlerini bildirir. Birçok senaryoda
bir tür düğümünün başka tür bir düğüm tarafından tamamen - değiştirilebilir veya bile kaldırıldı. Bu örnekte,
VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax) yöntemi döndürür bir SyntaxNode, türetilmiş bir tür yerine
LocalDeclarationStatementSyntax. Bu dosyaları yeni bir döndürür LocalDeclarationStatementSyntax düğüm üzerinde var olan
bir alan.

Bu hızlı başlangıçta, yerel değişken bildirimlerini işler. Bunu diğer bildirimlerine gibi genişletilebiliyordu foreach
döngüleri for döngüleri LINQ ifadeleri ve lambda ifadeleri. Ayrıca bu dosyaları en basit şekliyle bildirimleri
yalnızca dönüştürür:

Type variable = expression;

Kendi kendinize araştırmak istiyorsanız, bu tür bir değişken bildirimleri için tamamlanan örnek genişletme göz
önünde bulundurun:

// Multiple variables in a single declaration.


Type variable1 = expression1,
variable2 = expression2;
// No initializer.
Type variable;

Gövdesi için aşağıdaki kodu ekleyin VisitLocalDeclarationStatement biçimlerinden birini bildirimleri yeniden
yazma atlamak için yöntemi:

if (node.Declaration.Variables.Count > 1)
{
return node;
}
if (node.Declaration.Variables[0].Initializer == null)
{
return node;
}

Hiçbir yeniden yazma döndürerek gerçekleşir, yöntemi gösterir node değiştirilmemiş parametresi. Bunların hiçbiri,
if ifadelerdir true, başlatma olası bir bildirimle düğümünü temsil eder. Belirtiminde belirtilen tür adı ayıklamak
için aşağıdaki deyimleri ekleyin ve onu kullanarak bağlama SemanticModel alan bir tür simgesi almak için:
VariableDeclaratorSyntax declarator = node.Declaration.Variables.First();
TypeSyntax variableTypeName = node.Declaration.Type;

ITypeSymbol variableType = (ITypeSymbol)SemanticModel


.GetSymbolInfo(variableTypeName)
.Symbol;

Şimdi, başlatıcı ifadesinin bağlamak için bu bildirimi ekleyin:

TypeInfo initializerInfo = SemanticModel.GetTypeInfo(declarator.Initializer.Value);

Son olarak, aşağıdaki ekleyin if mevcut tür adıyla değiştirilecek deyimi var Başlatıcı ifadesinin türü belirtilen tür
eşleşiyorsa anahtar sözcüğü:

if (variableType == initializerInfo.Type)
{
TypeSyntax varTypeName = IdentifierName("var")
.WithLeadingTrivia(variableTypeName.GetLeadingTrivia())
.WithTrailingTrivia(variableTypeName.GetTrailingTrivia());

return node.ReplaceNode(variableTypeName, varTypeName);


}
else
{
return node;
}

Koşul bildirimi Başlatıcı ifadesinin bir temel sınıf veya arabirim için tür dönüştürme için gereklidir. İstenirse, sol ve
sağ taraftaki atama türleri eşleşmiyor. Bu gibi durumlarda açık tür kaldırma programı semantiği değiştirirsiniz. var
bir anahtar sözcüğü yerine bir tanımlayıcı olarak çünkü belirtilen var bağlamsal bir anahtar sözcüktür. Baştaki ve
sondaki trivia (boşluk) eski tür adına aktarılırken var dikey boşluk ve girinti korumak için anahtar sözcüğü.
Kullanmak daha kolaydır ReplaceNode yerine With* dönüştürmek için LocalDeclarationStatementSyntax
gerçekten bildirim deyiminin en alt tür adı olduğu için.
Seçtiğiniz tamamlandı TypeInferenceRewriter . Şimdi geri dönüp, Program.cs örneği tamamlamak için dosya. Test
oluşturma Compilation ve elde SemanticModel almaktır. Kullanan SemanticModel denemek için
TypeInferenceRewriter . Bu adım son yaparsınız. Bu sırada test derlemeniz temsil eden bir yer tutucu değişken
bildirin:

Compilation test = CreateTestCompilation();

Biraz duraklattıktan sonra Raporlama görünür bir hata dalgalı görmelisiniz hiçbir CreateTestCompilation yöntem
vardır. Basın Ctrl + nokta ampul açın ve ardından çağırmak için Enter tuşuna basın metot taslağı oluşturmak
komutu. Bu komut için bir yöntem saptama oluşturacaktır CreateTestCompilation yönteminde Program sınıfı. Bu
yöntemi, daha sonra doldurmak için geri dönen:
Her yineleme yapmak için aşağıdaki kodu yazın SyntaxTree test Compilation. Her biri için yeni bir başlatma
TypeInferenceRewriter ile SemanticModel ağacı için:

foreach (SyntaxTree sourceTree in test.SyntaxTrees)


{
SemanticModel model = test.GetSemanticModel(sourceTree);

TypeInferenceRewriter rewriter = new TypeInferenceRewriter(model);

SyntaxNode newSource = rewriter.Visit(sourceTree.GetRoot());

if (newSource != sourceTree.GetRoot())
{
File.WriteAllText(sourceTree.FilePath, newSource.ToFullString());
}
}

İçinde foreach deyim, oluşturduğunuz her kaynak ağacının üzerinde dönüştürmeyi gerçekleştirmek için aşağıdaki
kodu ekleyin. Düzenlemeler yaptıysanız bu kod, yeni dönüştürülmüş ağacı koşullu olarak yazar. Tür çıkarımı
kullanarak basitleştirilmiş bir veya daha fazla yerel değişken bildirimleri karşılaşırsa, dosyaları yalnızca bir ağaç
değiştirmeniz gerekir:

SyntaxNode newSource = rewriter.Visit(sourceTree.GetRoot());

if (newSource != sourceTree.GetRoot())
{
File.WriteAllText(sourceTree.FilePath, newSource.ToFullString());
}

Altında dalgalı çizgiler görürsünüz File.WriteAllText kod. Ampul seçin ve gerekli Ekle using System.IO; deyimi.
Neredeyse hazırsınız! Bir kez sol adım vardır: test oluşturma Compilation. Tür çıkarımı hiç bu hızlı başlangıç
sırasında kullandığınız henüz olduğundan, mükemmel bir test çalışması alacağımızdı. Ne yazık ki, C# proje
dosyasından bir derleme oluşturma, bu kılavuzun kapsamı dışındadır değil. Neyse ki, yönergeleri dikkatle takip
ediyorsanız, yoktur ancak soluk. Öğesinin içeriğini değiştirin CreateTestCompilation yöntemini aşağıdaki kod ile. Bu
hızlı başlangıçta açıklanan proje tesadüfen eşleşen bir test derleme oluşturur:
String programPath = @"..\..\Program.cs";
String programText = File.ReadAllText(programPath);
SyntaxTree programTree =
CSharpSyntaxTree.ParseText(programText)
.WithFilePath(programPath);

String rewriterPath = @".\..\TypeInferenceRewriter.cs";


String rewriterText = File.ReadAllText(rewriterPath);
SyntaxTree rewriterTree =
CSharpSyntaxTree.ParseText(rewriterText)
.WithFilePath(rewriterPath);

SyntaxTree[] sourceTrees = { programTree, rewriterTree };

MetadataReference mscorlib =
MetadataReference.CreateFromFile(typeof(object).Assembly.Location);
MetadataReference codeAnalysis =
MetadataReference.CreateFromFile(typeof(SyntaxTree).Assembly.Location);
MetadataReference csharpCodeAnalysis =
MetadataReference.CreateFromFile(typeof(CSharpSyntaxTree).Assembly.Location);

MetadataReference[] references = { mscorlib, codeAnalysis, csharpCodeAnalysis };

return CSharpCompilation.Create("TransformationCS",
sourceTrees,
references,
new CSharpCompilationOptions(OutputKind.ConsoleApplication));

Parmaklarınızın arası ve projeyi çalıştırın. Visual Studio'da hata ayıklama > hata ayıklamayı Başlat. Visual
Studio tarafından projenizdeki dosyaları değişen sorulması gerekir. Tıklayın "Tümüne Evet" değiştirilmiş dosyalar
yeniden yüklemek için. Bunları, awesomeness gözlemlemek için inceleyin. Kod tüm bu açık ve gereksiz tür
tanımlayıcıları görünür ne kadar temizleyici unutmayın.
Tebrikler! Kullandığınız derleyici API'leri kendi söz dizimsel düzenlerini, C# projesinde tüm dosyaları arayan
yeniden düzenleme yazmak için bu desenleri eşleşir ve bunu dönüştüren kaynak kodu semantiği analiz eder. Artık
resmi olarak yazar yeniden düzenleme!
Öğretici: ilk çözümleyicinizi ve kod düzeltmesini
yazma
6.12.2019 • 40 minutes to read • Edit Online

.NET Compiler Platform SDK, kodu hedef C# veya Visual Basic özel uyarılar oluşturmak için gereken araçları
sağlar. Çözümleyici , kuralınızın ihlallerini algılayan kod içerir. Kod düzeltmenizi ihlalin giderdiği kodu içerir.
Uyguladığınız kurallar, kod yapısından, adlandırma kurallarına ve daha fazlasına yönelik kodlama stiline kadar
herhangi bir şey olabilir. .NET Compiler Platform, geliştiricilerin kod yazmakta olduğu şekilde analizler ve kodu
düzeltmek için tüm Visual Studio Kullanıcı arabirimi özelliklerini sağlar: düzenleyicide dalgalı çizgiler gösterme,
Visual Studio Hata Listesi dolduruluyor, "ampul" oluşturma öneriler ve önerilen düzeltmelerin zengin önizlemesini
gösterir.
Bu öğreticide, bir çözümleyici oluşturmayı ve Roslyn API 'lerini kullanarak bir kod düzeltmesini
inceleyebilirsiniz. Çözümleyici, kaynak kodu analizini gerçekleştirmek ve kullanıcıya bir sorun bildirmek için bir
yoldur. İsteğe bağlı olarak, bir çözümleyici kullanıcının kaynak kodunda bir değişikliği temsil eden bir kod
düzeltmesini de sağlayabilir. Bu öğreticide, const değiştiricisi kullanılarak bildirilebilecek ancak olmayan yerel
değişken bildirimlerini bulan bir çözümleyici oluşturulur. Eşlik eden kod düzeltilme const değiştiricisini eklemek
için bu bildirimleri değiştirir.

Prerequisites
Visual Studio 2017
Visual Studio 2019
.Net Compiler Platform SDK 'sını Visual Studio yükleyicisi aracılığıyla yüklemeniz gerekir:

Yükleme yönergeleri-Visual Studio Yükleyicisi


Visual Studio Yükleyicisi .net Compiler Platform SDK 'sını bulmanın iki farklı yolu vardır:
Visual Studio Yükleyicisi Iş yükleri görünümünü kullanarak yükler
.NET Compiler Platform SDK, Visual Studio uzantısı geliştirme iş yükünün bir parçası olarak otomatik olarak
seçilmemiş. Bunu isteğe bağlı bir bileşen olarak seçmeniz gerekir.
1. Visual Studio yükleyicisi Çalıştır
2. Değiştir 'i seçin
3. Visual Studio uzantısı geliştirme iş yükünü denetleyin.
4. Özet ağacında Visual Studio uzantısı geliştirme düğümünü açın.
5. .Net Compiler Platform SDK 'sıkutusunu işaretleyin. En son isteğe bağlı bileşenler altında bulacaksınız.
İsteğe bağlı olarak, dgml düzenleyicisinin grafikleri görselleştiricide görüntülemesini de istersiniz:
1. Özet ağacındaki bireysel bileşenler düğümünü açın.
2. Dgml Düzenleyicisi kutusunu işaretleyin
Visual Studio Yükleyicisi bireysel bileşenler sekmesini kullanarak yükler
1. Visual Studio yükleyicisi Çalıştır
2. Değiştir 'i seçin
3. Ayrı bileşenler sekmesini seçin
4. .Net Compiler Platform SDK 'sıkutusunu işaretleyin. Bu dosyayı derleyiciler, derleme araçları ve çalışma
zamanları bölümünün altında bulabilirsiniz.
İsteğe bağlı olarak, dgml düzenleyicisinin grafikleri görselleştiricide görüntülemesini de istersiniz:
1. Dgml Düzenleyicisikutusunu işaretleyin. Bunu kod araçları bölümünde bulabilirsiniz.
Çözümleyicinizi oluşturmak ve doğrulamak için birkaç adım vardır:
1. Çözümü oluşturun.
2. Çözümleyici adını ve açıklamasını kaydedin.
3. Rapor çözümleyici uyarıları ve önerileri.
4. Önerileri kabul etmek için kod düzeltmesini uygulayın.
5. Birim testler aracılığıyla Analizi geliştirme.

Çözümleyici şablonunu keşfet


Çözümleyici, kullanıcıya yerel sabitlere dönüştürülebileceği herhangi bir yerel değişken bildirimi bildirir. Örneğin,
aşağıdaki kodu göz önünde bulundurun:

int x = 0;
Console.WriteLine(x);

Yukarıdaki kodda x sabit bir değer atanır ve hiçbir şekilde değiştirilmez. const değiştirici kullanılarak
bildirilebilecek:

const int x = 0;
Console.WriteLine(x);

Bir değişkenin sabit bir şekilde yapılıp yapılmayacağını belirleme, değişken için sözdizimi analizi, başlatıcı ifadesinin
sabit Analizi ve değişkenin hiçbir şekilde yazılmaması için veri akışı analizi gerektirir. .NET Compiler Platform, bu
çözümlemenin daha kolay hale getirebilmesini sağlayan API 'Ler sağlar. İlk adım, C# kod düzeltilme projesi ile
yeni bir çözümleyici oluşturmaktır.
Visual Studio 'da yeni proje iletişim kutusunu göstermek için dosya > yeni > proje.. . öğesini seçin.
C# Görsel > genişletilebilirliğialtında, kod düzeltmesine sahip çözümleyici 'yi (.NET Standard) seçin.
Projenizi "Makeconst" olarak adlandırın ve Tamam ' a tıklayın.
Code düzeltmesini içeren çözümleyici, üç proje oluşturur: biri çözümleyici ve kod düzeltmesini içerir, ikincisi bir
birim testi projisidir ve üçüncüsü VSıX projisidir. Varsayılan başlangıç projesi VSıX projem ' dir. VSıX projesini
başlatmak için F5 tuşuna basın. Bu, yeni çözümleyicinizi yükleyen ikinci bir Visual Studio örneğini başlatır.

TIP
Çözümleyicinizi çalıştırdığınızda, Visual Studio 'nun ikinci bir kopyasını başlatabilirsiniz. Bu ikinci kopya ayarları depolamak için
farklı bir kayıt defteri kovanı kullanır. Bu, Visual Studio 'nun iki kopyasında görsel ayarları ayırt etmenize olanak sağlar. Visual
Studio 'nun deneysel çalıştırması için farklı bir tema seçebilirsiniz. Ayrıca, Visual Studio 'nun deneysel çalıştırmasını kullanarak
ayarlarınızı dolaşıyor veya Visual Studio hesabınızda oturum açmayın. Bu, ayarları farklı tutar.

Az önce başlattığınız ikinci Visual Studio örneğinde yeni C# bir konsol uygulaması projesi oluşturun (.NET Core
veya .NET Framework Project, kaynak düzeyinde çalışır.) Simgenin üzerine dalgalı alt çizgiyle gelin ve bir
çözümleyici tarafından sunulan uyarı metni görüntülenir.
Şablon, aşağıdaki şekilde gösterildiği gibi tür adında küçük harfler içeren her tür bildiriminde uyarı raporlayan bir
çözümleyici oluşturur:

Şablon Ayrıca, küçük harf karakter içeren herhangi bir tür adını tüm büyük harflere değiştiren bir kod düzeltmesini
de sağlar. Önerilen değişiklikleri görmek için uyarıyla birlikte görüntülenecek ampule tıklayabilirsiniz. Önerilen
değişiklikler kabul edildiğinde, tür adı ve çözümdeki bu türe yapılan tüm başvurular güncelleştirilir. İlk çözümleyici
'yi eylemde gördüğünüze göre, ikinci Visual Studio örneğini kapatın ve çözümleyici projenize geri dönün.
Visual Studio 'nun ikinci bir kopyasını başlatmanız ve çözümleyicinizdeki her değişikliği test etmek için yeni kod
oluşturmanız gerekmez. Şablon sizin için bir birim testi projesi de oluşturur. Bu proje iki test içerir. TestMethod1 , bir
tanılamayı tetiklemeden kodu çözümleyen testin tipik biçimini gösterir. TestMethod2 , bir tanılamayı tetikleyen testin
biçimini gösterir ve ardından önerilen bir kod düzeltmesini uygular. Çözümleyicinizi ve kod düzeltmesini
oluştururken, çalışmanızı doğrulamak üzere farklı kod yapıları için testler yazacaksınız. Çözümleyiciler için birim
testleri, Visual Studio ile etkileşimli olarak test edilmesine kıyasla çok daha hızlıdır.

TIP
Çözümleyici birim testleri, hangi kod yapılarının çözümleyicinizi tetikleyemediğini bildiğiniz ve bu harika bir araçtır. Visual
Studio 'nun başka bir kopyasına çözümleyicinizi yüklemek, henüz düşünmemiş olan yapıları keşfetmeye ve bulmaya yönelik
harika bir araçtır.

Çözümleyici kayıtları oluşturma


Şablon, MakeConstAnalyzer.cs dosyasında ilk DiagnosticAnalyzer sınıfını oluşturur. Bu ilk çözümleyici, her
çözümleyici 'nin iki önemli özelliğini gösterir.
Her Tanılama Çözümleyicisi, üzerinde çalıştığı dili açıklayan bir [DiagnosticAnalyzer] özniteliği sağlamalıdır.
Her Tanılama Çözümleyicisi DiagnosticAnalyzer sınıfından türetilmelidir.
Şablon, herhangi bir çözümleyici 'nin parçası olan temel özellikleri de gösterir:
1. Kaydetme eylemleri. Eylemler, çözümleyicinizi ihlalleri için kodu incelemek üzere tetiklemesi gereken kod
değişikliklerini temsil eder. Visual Studio, kayıtlı bir eylemle eşleşen kod düzenlemeleri algıladığında, çözümleyici
'nin kayıtlı yöntemini çağırır.
2. Tanılama oluşturun. Çözümleyicisi bir ihlal algıladığında, bu, ihlalin kullanıcısına bildirimde bulunan Visual
Studio 'Nun kullandığı bir tanılama nesnesi oluşturur.
DiagnosticAnalyzer.Initialize(AnalysisContext) yöntemi geçersiz kılmada eylemleri kaydedersiniz. Bu öğreticide,
yerel bildirimleri arayan sözdizimi düğümlerini ziyaret edeceğiz ve hangilerinin sabit değerlere sahip olduğunu
görürsünüz. Bir bildirim sabitlenebilir, çözümleyici bir tanılama oluşturup rapor eder.
İlk adım, kayıt sabitlerinin ve Initialize yönteminin, bu sabitlerin "const yap" çözümleyicisini belirtmesi için
güncelleştirilmesi yöntemidir. Dize sabitlerinin çoğu dize kaynak dosyasında tanımlanmıştır. Daha kolay
yerelleştirme için bu uygulamayı izlemeniz gerekir. Makeconst çözümleyici projesi için Resources. resx dosyasını
açın. Bu, kaynak düzenleyicisini görüntüler. Dize kaynaklarını aşağıdaki gibi güncelleştirin:
AnalyzerTitle "değişken sabit hale getirilebilir" olarak değiştirin.
AnalyzerMessageFormat , "sabit yapılabilir" olarak değiştirin.
AnalyzerDescription "sabit yap" olarak değiştirin.

Ayrıca, erişim değiştirici açılan public olarak değiştirin. Bu, birim testlerinde bu sabitleri kullanmayı kolaylaştırır.
İşiniz bittiğinde, kaynak Düzenleyicisi aşağıdaki şekilde görünür:

Geri kalan değişiklikler çözümleyici dosyasıdır. Visual Studio 'da MakeConstAnalyzer.cs açın. Semboller üzerinde
çalışan bir eylemden, söz dizimi üzerinde davranan bir eylemi değiştirin. MakeConstAnalyzerAnalyzer.Initialize
yönteminde, simgeleri semboller üzerinde kaydeden satırı bulun:

context.RegisterSymbolAction(AnalyzeSymbol, SymbolKind.NamedType);

Aşağıdaki satırla değiştirin:

context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.None);
context.EnableConcurrentExecution();
context.RegisterSyntaxNodeAction(AnalyzeNode, SyntaxKind.LocalDeclarationStatement);

Bu değişiklikten sonra AnalyzeSymbol yöntemini silebilirsiniz. Bu çözümleyici, SymbolKind.NamedType deyimlerini


değil SyntaxKind.LocalDeclarationStatementinceler. AnalyzeNode altında Red dalgalı çizgiler olduğuna dikkat edin.
Az önce eklediğiniz kod bildirilmemiş bir AnalyzeNode metoduna başvuruyor. Aşağıdaki kodu kullanarak bu
yöntemi bildirin:

private void AnalyzeNode(SyntaxNodeAnalysisContext context)


{
}

Aşağıdaki kodda gösterildiği gibi, Category MakeConstAnalyzer.cs Içinde "kullanım" olarak değiştirin:

private const string Category = "Usage";

Const olabilecek yerel bildirimleri bul


AnalyzeNode yönteminin ilk sürümünü yazmak zaman. const , ancak şu kod gibi değil, tek bir yerel bildirime
bakmalıdır:

int x = 0;
Console.WriteLine(x);

İlk adım, yerel bildirimleri bulledir. Aşağıdaki kodu MakeConstAnalyzer.csiçinde AnalyzeNode ekleyin:

var localDeclaration = (LocalDeclarationStatementSyntax)context.Node;

Bu atama, çözümleyici yerel bildirimlerinizde değişiklikler ve yalnızca yerel bildirimler için kaydedildiği için her
zaman başarılı olur. Başka hiçbir düğüm türü AnalyzeNode yöntemine bir çağrı tetiklemiyor. Sonra, herhangi bir
const değiştiricinin bildirimini denetleyin. Bunları bulursanız anında geri dönün. Aşağıdaki kod, yerel bildirimde
her türlü const değiştiricilerini arar:

// make sure the declaration isn't already const:


if (localDeclaration.Modifiers.Any(SyntaxKind.ConstKeyword))
{
return;
}

Son olarak, değişkenin const olup olmadığını denetlemeniz gerekir. Bu, başlatıldıktan sonra hiçbir şekilde
atanmadığından emin olmak anlamına gelir.
SyntaxNodeAnalysisContextkullanarak bazı semantik analizler gerçekleştirirsiniz. Yerel değişken bildiriminin const
yapılıp yapılmayacağını anlamak için context bağımsız değişkenini kullanırsınız. Tek bir kaynak dosyasındaki tüm
anlam bilgilerini temsil eden bir Microsoft.CodeAnalysis.SemanticModel. Anlam modelleriniiçeren makalede daha
fazla bilgi edinebilirsiniz. Microsoft.CodeAnalysis.SemanticModel, yerel bildirim bildiriminde veri akışı analizini
gerçekleştirmek için kullanacaksınız. Ardından, bu veri akışı analizinin sonuçlarını kullanarak yerel değişkenin başka
bir yerde yeni bir değerle yazılmadığından emin olun. Değişken için ILocalSymbol almak için GetDeclaredSymbol
uzantısı metodunu çağırın ve veri akışı analizinin DataFlowAnalysis.WrittenOutside koleksiyonu ile
içerilmediğinden emin olun. AnalyzeNode yönteminin sonuna aşağıdaki kodu ekleyin:

// Perform data flow analysis on the local declaration.


var dataFlowAnalysis = context.SemanticModel.AnalyzeDataFlow(localDeclaration);

// Retrieve the local symbol for each variable in the local declaration
// and ensure that it is not written outside of the data flow analysis region.
var variable = localDeclaration.Declaration.Variables.Single();
var variableSymbol = context.SemanticModel.GetDeclaredSymbol(variable);
if (dataFlowAnalysis.WrittenOutside.Contains(variableSymbol))
{
return;
}

Yeni eklenen kod, değişkenin değiştirilmediğinden emin olur ve bu nedenle const hale getirilebilir. Tanılamayı
yükseltme zamanı. Aşağıdaki kodu AnalyzeNode son satır olarak ekleyin:

context.ReportDiagnostic(Diagnostic.Create(Rule, context.Node.GetLocation()));

F5 'e basarak çözümleyicinizi çalıştırmak için ilerleme durumunu kontrol edebilirsiniz. Daha önce oluşturduğunuz
konsol uygulamasını yükleyebilir ve sonra şu test kodunu ekleyebilirsiniz:

int x = 0;
Console.WriteLine(x);

Ampul görünmelidir ve çözümleyici 'niz bir tanılama raporlemelidir. Ancak ampul, şablon tarafından oluşturulan
kod düzeltmesini hala kullanır ve bunun büyük bir durum oluşturabileceklerini söyler. Sonraki bölümde, kod
düzeltmesinin nasıl yazılacağı açıklanmaktadır.

Kod düzeltmesini yazın


Bir çözümleyici, bir veya daha fazla kod düzeltmesi sağlayabilir. Kod onarımı, bildirilen sorunu ele alan bir
düzenleme tanımlar. Oluşturduğunuz çözümleyici için, const anahtar sözcüğünü ekleyen bir kod düzeltmesini
sağlayabilirsiniz:
const int x = 0;
Console.WriteLine(x);

Kullanıcı onu düzenleyicide ampul kullanıcı arabiriminden seçer ve Visual Studio kodu değiştirir.
Şablon tarafından eklenen MakeConstCodeFixProvider.cs dosyasını açın. Bu kod onarımı, tanılama çözümleyici
'niz tarafından üretilen tanılama KIMLIĞI 'ne zaten kablolu, ancak doğru kod dönüşümünü uygulamıyor. Öncelikle
bazı şablon kodunu kaldırmalısınız. Başlık dizesini "sabit yap" olarak değiştirin:

private const string title = "Make constant";

Sonra MakeUppercaseAsync yöntemini silin. Artık geçerli değildir.


Tüm kod onarma sağlayıcıları CodeFixProvidertüretilir. Bunlar, kullanılabilir kod düzeltmelerini raporlamak için
CodeFixProvider.RegisterCodeFixesAsync(CodeFixContext) geçersiz kılar. RegisterCodeFixesAsync , arama
yaptığınız üst düğüm türünü, tanı ile eşleşecek şekilde bir LocalDeclarationStatementSyntax değiştirin:

var declaration =
root.FindToken(diagnosticSpan.Start).Parent.AncestorsAndSelf().OfType<LocalDeclarationStatementSyntax>
().First();

Sonra, bir kod düzeltmesini kaydetmek için son satırı değiştirin. Bu değişiklik, mevcut bir bildirime const
değiştiricisini eklemenin sonucu olan yeni bir belge oluşturur:

// Register a code action that will invoke the fix.


context.RegisterCodeFix(
CodeAction.Create(
title: title,
createChangedDocument: c => MakeConstAsync(context.Document, declaration, c),
equivalenceKey: title),
diagnostic);

MakeConstAsync sembol üzerinde yeni eklediğiniz kodda kırmızı dalgalı çizgiler fark edeceksiniz. Aşağıdaki kod gibi
bir MakeConstAsync bildirimi ekleyin:

private async Task<Document> MakeConstAsync(Document document,


LocalDeclarationStatementSyntax localDeclaration,
CancellationToken cancellationToken)
{
}

Yeni MakeConstAsync yönteminiz, kullanıcının kaynak dosyasını temsil eden Document, artık const bildirimi içeren
yeni bir Document dönüştürür.
Bildirim ifadesinin önüne eklemek için yeni bir const anahtar sözcük belirteci oluşturursunuz. Önce bildirim
bildiriminin ilk belirtecinden önde gelen her türlü boşluğu kaldırmayı ve const belirtecine eklemeyi dikkatli olun.
Aşağıdaki kodu MakeConstAsync yöntemine ekleyin:
// Remove the leading trivia from the local declaration.
var firstToken = localDeclaration.GetFirstToken();
var leadingTrivia = firstToken.LeadingTrivia;
var trimmedLocal = localDeclaration.ReplaceToken(
firstToken, firstToken.WithLeadingTrivia(SyntaxTriviaList.Empty));

// Create a const token with the leading trivia.


var constToken = SyntaxFactory.Token(leadingTrivia, SyntaxKind.ConstKeyword,
SyntaxFactory.TriviaList(SyntaxFactory.ElasticMarker));

Ardından, aşağıdaki kodu kullanarak const belirtecini bildirime ekleyin:

// Insert the const token into the modifiers list, creating a new modifiers list.
var newModifiers = trimmedLocal.Modifiers.Insert(0, constToken);
// Produce the new local declaration.
var newLocal = trimmedLocal
.WithModifiers(newModifiers)
.WithDeclaration(localDeclaration.Declaration);

Sonra, biçimlendirme kurallarıyla eşleşecek C# şekilde yeni bildirimi biçimlendirin. Değişikliklerinizi varolan kodla
eşleşecek şekilde biçimlendirmek daha iyi bir deneyim oluşturur. Mevcut koddan hemen sonra aşağıdaki ifadeyi
ekleyin:

// Add an annotation to format the new local declaration.


var formattedLocal = newLocal.WithAdditionalAnnotations(Formatter.Annotation);

Bu kod için yeni bir ad alanı gereklidir. Aşağıdaki using ifadesini dosyanın en üstüne ekleyin:

using Microsoft.CodeAnalysis.Formatting;

Son adım, düzenlemenizi yapmak için kullanılır. Bu işlemin üç adımı vardır:


1. Mevcut belgeye yönelik bir tanıtıcı alın.
2. Mevcut bildirimi yeni bildirimle değiştirerek yeni bir belge oluşturun.
3. Yeni belgeyi döndür.
MakeConstAsync yönteminin sonuna aşağıdaki kodu ekleyin:

// Replace the old local declaration with the new local declaration.
var oldRoot = await document.GetSyntaxRootAsync(cancellationToken);
var newRoot = oldRoot.ReplaceNode(localDeclaration, formattedLocal);

// Return document with transformed tree.


return document.WithSyntaxRoot(newRoot);

Kod düzeltmeizin denemeye hazırlanıyor. Visual Studio 'nun ikinci bir örneğinde çözümleyici projesini çalıştırmak
için F5 tuşuna basın. İkinci Visual Studio örneğinde, yeni C# bir konsol uygulaması projesi oluşturun ve ana
yönteme sabit değerlerle başlatılan birkaç yerel değişken bildirimi ekleyin. Bunların uyarı olarak
raporlandıklarından aşağıda gösterildiği gibi göreceksiniz.
Çok sayıda ilerleme yaptınız. const yapılabilecek bildirimlerin altında dalgalı çizgiler vardır. Ancak yine de devam
eden bir iş var. Bu, i ile başlayan bildirimlere const eklerseniz, sonra j ve son olarak k daha iyi bir şekilde
çalışacaktır. Ancak, k ile başlayan const değiştiricisini farklı bir sırada eklerseniz, çözümleyici 'niz hata oluşturur:
k , i ve j ikisi de zaten const olmadığı takdirde const bildirilemez. Değişkenlerin bildirilebilecek ve
başlatılabileceği farklı yolları işlediğinizden emin olmak için daha fazla analiz yapmanız gerekir.

Veri odaklı testler oluşturun


Çözümleyici ve kod düzeltmesizin const hale getirilebilir tek bir bildirimin basit bir durumunda çalışır. Bu
uygulamanın hata yaptığı çok sayıda olası bildirim deyimi vardır. Şablon tarafından yazılan birim testi kitaplığıyla
çalışarak bu durumları ele alacağız. Visual Studio 'nun ikinci bir kopyasını art arda açmadan çok daha hızlıdır.
Birim testi projesinde MakeConstUnitTests.cs dosyasını açın. Şablon, bir çözümleyici ve kod düzelme birimi testi
için iki ortak deseni izleyen iki test oluşturmuştur. TestMethod1 , çözümleyicinin ne zaman bir tanılama
bildirmemesini sağlayan bir testin modelini gösterir. TestMethod2 bir tanılamayı raporlamak ve kod düzeltmesini
çalıştırmak için bir model gösterir.
Çözümleyicinizi neredeyse her test için kod, bu iki desenden birini izler. İlk adımda, bu testlerin veri odaklı testler
olarak yeniden kullanılabilir. Daha sonra, farklı test girişlerini temsil etmek için yeni dize sabitleri ekleyerek yeni
testlerin oluşturulması kolay olur.
Verimlilik için ilk adım, veri odaklı testlerde iki testi yeniden düzenleme. Ardından, her yeni test için yalnızca birkaç
dize sabiti tanımlamanız gerekir. Yeniden düzenleme sırasında her iki yöntemi de daha iyi adlarla yeniden
adlandırın. TestMethod1 , herhangi bir tanılama işlemi yapılmasını sağlayan bu testle değiştirin:

[DataTestMethod]
[DataRow("")]
public void WhenTestCodeIsValidNoDiagnosticIsTriggered(string testCode)
{
VerifyCSharpDiagnostic(testCode);
}

Tanılamanın bir uyarı tetiklemesine neden olmaması gereken herhangi bir kod parçasını tanımlayarak, bu test için
yeni bir veri satırı oluşturabilirsiniz. VerifyCSharpDiagnostic bu aşırı yüklemesi, kaynak kodu parçası için hiçbir
Tanılama tetiklenmediğini geçirir.
Sonra TestMethod2 , bir Tanılamanın ortaya çıkarılmasını ve kaynak kod parçası için bir kod düzeltmesinin
uygulanmasını sağlayan bu testle değiştirin:
[DataTestMethod]
[DataRow(LocalIntCouldBeConstant, LocalIntCouldBeConstantFixed, 10, 13)]
public void WhenDiagnosticIsRaisedFixUpdatesCode(
string test,
string fixTest,
int line,
int column)
{
var expected = new DiagnosticResult
{
Id = MakeConstAnalyzer.DiagnosticId,
Message = new LocalizableResourceString(nameof(MakeConst.Resources.AnalyzerMessageFormat),
MakeConst.Resources.ResourceManager, typeof(MakeConst.Resources)).ToString(),
Severity = DiagnosticSeverity.Warning,
Locations =
new[] {
new DiagnosticResultLocation("Test0.cs", line, column)
}
};

VerifyCSharpDiagnostic(test, expected);

VerifyCSharpFix(test, fixTest);
}

Yukarıdaki kod ayrıca, beklenen tanılama sonucunu oluşturan kodda birkaç değişiklik yaptı. MakeConst
Çözümleyicisi 'nde kayıtlı olan genel sabitleri kullanır. Ayrıca, giriş ve sabit kaynak için iki dize sabiti kullanır.
Aşağıdaki dize sabitlerini UnitTest sınıfına ekleyin:

private const string LocalIntCouldBeConstant = @"


using System;

namespace MakeConstTest
{
class Program
{
static void Main(string[] args)
{
int i = 0;
Console.WriteLine(i);
}
}
}";

private const string LocalIntCouldBeConstantFixed = @"


using System;

namespace MakeConstTest
{
class Program
{
static void Main(string[] args)
{
const int i = 0;
Console.WriteLine(i);
}
}
}";

Geçirdiklerinden emin olmak için bu iki testi çalıştırın. Visual Studio 'da, **test > ** Windows > Test Gezgini' ni
seçerek Test Gezginini açın. Tümünü Çalıştır bağlantısına basın.
Geçerli bildirimler için testler oluşturma
Genel bir kural olarak, çözümleyicilerin olabildiğince çabuk çıkması gerekir ve en az iş yapılır. Visual Studio,
Kullanıcı kodu düzenlediği için kayıtlı çözümleyiciler çağırır. Yanıt verme bir anahtar gereksinimidir. Tanılamasını
yükseltmemelidir kod için birkaç test çalışması vardır. Çözümleyicisi zaten bu testlerin birini, bir değişkenin
başlatıldıktan sonra atandığı durumu işler. Bu durumu göstermek için testlerinize aşağıdaki dize sabitini ekleyin:

private const string VariableAssigned = @"


using System;

namespace MakeConstTest
{
class Program
{
static void Main(string[] args)
{
int i = 0;
Console.WriteLine(i++);
}
}
}";

Ardından, aşağıdaki kod parçacığında gösterildiği gibi bu test için bir veri satırı ekleyin:

[DataTestMethod]
[DataRow(""),
DataRow(VariableAssigned)]
public void WhenTestCodeIsValidNoDiagnosticIsTriggered(string testCode)

Bu test da geçer. Daha sonra, henüz işlememiş olan koşullar için sabitler ekleyin:
Zaten const olan bildirimler zaten const olduğundan:

private const string AlreadyConst = @"


using System;

namespace MakeConstTest
{
class Program
{
static void Main(string[] args)
{
const int i = 0;
Console.WriteLine(i);
}
}
}";

Başlatıcısı olmayan bildirimler, kullanılacak bir değer yoktur:


private const string NoInitializer = @"
using System;

namespace MakeConstTest
{
class Program
{
static void Main(string[] args)
{
int i;
i = 0;
Console.WriteLine(i);
}
}
}";

Başlatıcıya bir sabit olmadığı ve derleme zamanı sabitleri olmadıkları için bildirim:

private const string InitializerNotConstant = @"


using System;

namespace MakeConstTest
{
class Program
{
static void Main(string[] args)
{
int i = DateTime.Now.DayOfYear;
Console.WriteLine(i);
}
}
}";

Birden çok bildirime tek bir bildirimde C# izin verdiğinden daha karmaşık olabilir. Aşağıdaki test çalışması dize
sabitini göz önünde bulundurun:

private const string MultipleInitializers = @"


using System;

namespace MakeConstTest
{
class Program
{
static void Main(string[] args)
{
int i = 0, j = DateTime.Now.DayOfYear;
Console.WriteLine(i, j);
}
}
}";

i değişkeni sabit hale getirilebilir, ancak değişken j olamaz. Bu nedenle, bu ifade bir const bildirimi yapılamaz.
Tüm bu testlerin DataRow bildirimlerini ekleyin:
[DataTestMethod]
[DataRow(""),
DataRow(VariableAssigned),
DataRow(AlreadyConst),
DataRow(NoInitializer),
DataRow(InitializerNotConstant),
DataRow(MultipleInitializers)]
public void WhenTestCodeIsValidNoDiagnosticIsTriggered(string testCode)

Testlerinizi yeniden çalıştırın ve bu yeni test çalışmalarını başarısız görürsünüz.

Çözümleyicinizi doğru bildirimleri yoksayacak şekilde güncelleştirme


Bu koşullara uyan kodu filtrelemek için çözümleyicinizdeki AnalyzeNode metodunda bazı geliştirmeler yapmanız
gerekir. Bunlar ilgili tüm koşullardır, böylece benzer değişiklikler bu koşulların tümünü düzeltir. AnalyzeNode için
aşağıdaki değişiklikleri yapın:
Anlam analiziniz tek bir değişken bildirimi inceledi. Bu kodun, aynı bildirimde belirtilen tüm değişkenleri
incelediği bir foreach döngüsünde olması gerekir.
Her beyan edilen değişkenin bir başlatıcıya sahip olması gerekir.
Her bir derlenen değişkenin başlatıcısı bir derleme zamanı sabiti olmalıdır.
AnalyzeNode yönteminde özgün anlam analizini değiştirin:

// Perform data flow analysis on the local declaration.


var dataFlowAnalysis = context.SemanticModel.AnalyzeDataFlow(localDeclaration);

// Retrieve the local symbol for each variable in the local declaration
// and ensure that it is not written outside of the data flow analysis region.
var variable = localDeclaration.Declaration.Variables.Single();
var variableSymbol = context.SemanticModel.GetDeclaredSymbol(variable);
if (dataFlowAnalysis.WrittenOutside.Contains(variableSymbol))
{
return;
}

Aşağıdaki kod parçacığı ile:


// Ensure that all variables in the local declaration have initializers that
// are assigned with constant values.
foreach (var variable in localDeclaration.Declaration.Variables)
{
var initializer = variable.Initializer;
if (initializer == null)
{
return;
}

var constantValue = context.SemanticModel.GetConstantValue(initializer.Value);


if (!constantValue.HasValue)
{
return;
}
}

// Perform data flow analysis on the local declaration.


var dataFlowAnalysis = context.SemanticModel.AnalyzeDataFlow(localDeclaration);

foreach (var variable in localDeclaration.Declaration.Variables)


{
// Retrieve the local symbol for each variable in the local declaration
// and ensure that it is not written outside of the data flow analysis region.
var variableSymbol = context.SemanticModel.GetDeclaredSymbol(variable);
if (dataFlowAnalysis.WrittenOutside.Contains(variableSymbol))
{
return;
}
}

İlk foreach döngüsü, her değişken bildiriminde sözdizimsel analiz kullanılarak incelenir. İlk denetim, değişkenin bir
başlatıcıya sahip olduğunu garanti eder. İkinci denetim, başlatıcının bir sabit olduğunu garanti eder. İkinci döngünün
özgün anlam analizi vardır. Performans üzerinde daha fazla etkisi olduğundan anlam denetimleri ayrı bir döngüde
bulunur. Testlerinizi yeniden çalıştırın ve hepsini bir kez görmeniz gerekir.

Son Lehçe 'ı ekleyin


Neredeyse bitti. Çözümleyicinizi işlemek için birkaç koşul daha vardır. Visual Studio, Kullanıcı kod yazarken
Çözümleyicileri çağırır. Bu durum genellikle çözümleyicinizi derlenmeyen kod için çağrılacaktır. Tanılama
Çözümleyicisi 'nin AnalyzeNode yöntemi, sabit değerin değişken türüne dönüştürülebilir olup olmadığını kontrol
etmez. Bu nedenle, geçerli uygulama int ı = "abc" ' gibi yanlış bir bildirimi yerel bir sabit 'e dönüştürmelidir. Bu
koşul için bir kaynak dize sabiti ekleyin:

private const string DeclarationIsInvalid = @"


using System;

namespace MakeConstTest
{
class Program
{
static void Main(string[] args)
{
int x = ""abc"";
}
}
}";

Ayrıca, başvuru türleri düzgün işlenmez. Bir başvuru türü için izin verilen tek sabit değer null , bu
System.Stringolması dışında, dize sabit değerleri sağlar. Diğer bir deyişle const string s = "abc" geçerlidir, ancak
const object s = "abc" değildir. Bu kod parçacığı bu durumu doğrular:

private const string ReferenceTypeIsntString = @"


using System;

namespace MakeConstTest
{
class Program
{
static void Main(string[] args)
{
object s = ""abc"";
}
}
}";

Tam olarak, bir dize için sabit bildirim oluşturabilmeniz için başka bir test eklemeniz gerekir. Aşağıdaki kod
parçacığı, hem tanılamayı başlatan kodu hem de düzeltilme uygulandıktan sonra kodu tanımlar:

private const string ConstantIsString = @"


using System;

namespace MakeConstTest
{
class Program
{
static void Main(string[] args)
{
string s = ""abc"";
}
}
}";

private const string ConstantIsStringFixed = @"


using System;

namespace MakeConstTest
{
class Program
{
static void Main(string[] args)
{
const string s = ""abc"";
}
}
}";

Son olarak, bir değişken var anahtar sözcüğüyle bildirilirse, kod düzeltilmesi yanlış şeyi yapar ve C# dil tarafından
desteklenmeyen bir const var bildirimi oluşturur. Bu hatayı onarmak için, kod düzeltmesinin var anahtar
sözcüğünü çıkarılan türün adıyla değiştirmesini gerekir:
private const string DeclarationUsesVar = @"
using System;

namespace MakeConstTest
{
class Program
{
static void Main(string[] args)
{
var item = 4;
}
}
}";

private const string DeclarationUsesVarFixedHasType = @"


using System;

namespace MakeConstTest
{
class Program
{
static void Main(string[] args)
{
const int item = 4;
}
}
}";
private const string StringDeclarationUsesVar = @"
using System;

namespace MakeConstTest
{
class Program
{
static void Main(string[] args)
{
var item = ""abc"";
}
}
}";
private const string StringDeclarationUsesVarFixedHasType = @"
using System;

namespace MakeConstTest
{
class Program
{
static void Main(string[] args)
{
const string item = ""abc"";
}
}
}";

Bu değişiklikler her iki test için de veri satırı bildirimlerini güncelleştirir. Aşağıdaki kod, tüm veri satırı öznitelikleriyle
bu testleri gösterir:
//No diagnostics expected to show up
[DataTestMethod]
[DataRow(""),
DataRow(VariableAssigned),
DataRow(AlreadyConst),
DataRow(NoInitializer),
DataRow(InitializerNotConstant),
DataRow(MultipleInitializers),
DataRow(DeclarationIsInvalid),
DataRow(ReferenceTypeIsntString)]
public void WhenTestCodeIsValidNoDiagnosticIsTriggered(string testCode)
{
VerifyCSharpDiagnostic(testCode);
}

[DataTestMethod]
[DataRow(LocalIntCouldBeConstant, LocalIntCouldBeConstantFixed, 10, 13),
DataRow(ConstantIsString, ConstantIsStringFixed, 10, 13),
DataRow(DeclarationUsesVar, DeclarationUsesVarFixedHasType, 10, 13),
DataRow(StringDeclarationUsesVar, StringDeclarationUsesVarFixedHasType, 10, 13)]
public void WhenDiagosticIsRaisedFixUpdatesCode(
string test,
string fixTest,
int line,
int column)
{
var expected = new DiagnosticResult
{
Id = MakeConstAnalyzer.DiagnosticId,
Message = new LocalizableResourceString(nameof(MakeConst.Resources.AnalyzerMessageFormat),
MakeConst.Resources.ResourceManager, typeof(MakeConst.Resources)).ToString(),
Severity = DiagnosticSeverity.Warning,
Locations =
new[] {
new DiagnosticResultLocation("Test0.cs", line, column)
}
};

VerifyCSharpDiagnostic(test, expected);

VerifyCSharpFix(test, fixTest);
}

Neyse ki, yukarıdaki hataların tümü, az önce öğrendiğiniz tekniklerin kullanılmasıyla çözülebilir.
İlk hatayı onarmak için önce DiagnosticAnalyzer.cs açın ve her bir yerel bildirimin başlatıcılarının her birinin,
sabit değerlerle atanmasını sağlamak için her birinin kontrol edildiği foreach döngüsünü bulun. İlk foreach
döngüsünden hemen önce , yerel bildirimin belirtilen türü hakkında ayrıntılı bilgi almak için
context.SemanticModel.GetTypeInfo() çağırın:

var variableTypeName = localDeclaration.Declaration.Type;


var variableType = context.SemanticModel.GetTypeInfo(variableTypeName).ConvertedType;

Daha sonra, foreach döngüsünde, değişken türüne dönüştürülebilir olduğundan emin olmak için her başlatıcıyı
kontrol edin. Başlatıcının bir sabit olduğundan emin olduktan sonra aşağıdaki denetimi ekleyin:
// Ensure that the initializer value can be converted to the type of the
// local declaration without a user-defined conversion.
var conversion = context.SemanticModel.ClassifyConversion(initializer.Value, variableType);
if (!conversion.Exists || conversion.IsUserDefined)
{
return;
}

Sonraki değişiklik, son bir üzerinde derleme oluşturur. İlk foreach döngüsünün kapanış küme ayracından önce,
sabit bir dize veya null olduğunda yerel bildirimin türünü denetlemek için aşağıdaki kodu ekleyin.

// Special cases:
// * If the constant value is a string, the type of the local declaration
// must be System.String.
// * If the constant value is null, the type of the local declaration must
// be a reference type.
if (constantValue.Value is string)
{
if (variableType.SpecialType != SpecialType.System_String)
{
return;
}
}
else if (variableType.IsReferenceType && constantValue.Value != null)
{
return;
}

Var ' anahtar sözcüğünü doğru tür adıyla değiştirmek için kod düzeltme sağlayıcınızda bir bit daha daha kod
yazmalısınız. CodeFixProvider.cs'e geri dönün. Ekleyeceğiniz kod aşağıdaki adımları yapar:
Bildirimin bir var bildirimi olup olmadığını ve şu şekilde olduğunu kontrol edin:
Çıkarsanan tür için yeni bir tür oluşturun.
Tür bildiriminin bir diğer ad olmadığından emin olun. Varsa, const var bildirimi geçerlidir.
var bu programda bir tür adı olmadığından emin olun. ( Varsa, const var geçerlidir ).
Tam tür adını basitleştirme
Bu çok fazla kod gibi seslerden oluşur. Bu değildir. newLocal bildiren ve Başlatan satırı aşağıdaki kodla değiştirin.
newModifiers başlatıldıktan hemen sonra geçer:
// If the type of the declaration is 'var', create a new type name
// for the inferred type.
var variableDeclaration = localDeclaration.Declaration;
var variableTypeName = variableDeclaration.Type;
if (variableTypeName.IsVar)
{
var semanticModel = await document.GetSemanticModelAsync(cancellationToken);

// Special case: Ensure that 'var' isn't actually an alias to another type
// (e.g. using var = System.String).
var aliasInfo = semanticModel.GetAliasInfo(variableTypeName);
if (aliasInfo == null)
{
// Retrieve the type inferred for var.
var type = semanticModel.GetTypeInfo(variableTypeName).ConvertedType;

// Special case: Ensure that 'var' isn't actually a type named 'var'.
if (type.Name != "var")
{
// Create a new TypeSyntax for the inferred type. Be careful
// to keep any leading and trailing trivia from the var keyword.
var typeName = SyntaxFactory.ParseTypeName(type.ToDisplayString())
.WithLeadingTrivia(variableTypeName.GetLeadingTrivia())
.WithTrailingTrivia(variableTypeName.GetTrailingTrivia());

// Add an annotation to simplify the type name.


var simplifiedTypeName = typeName.WithAdditionalAnnotations(Simplifier.Annotation);

// Replace the type in the variable declaration.


variableDeclaration = variableDeclaration.WithType(simplifiedTypeName);
}
}
}
// Produce the new local declaration.
var newLocal = trimmedLocal.WithModifiers(newModifiers)
.WithDeclaration(variableDeclaration);

Simplifier türünü kullanmak için bir using ifade eklemeniz gerekir:

using Microsoft.CodeAnalysis.Simplification;

Testlerinizi çalıştırın ve hepsi başarılı olmalıdır. Tamamlanmış çözümleyicinizi çalıştırarak kendiniz kutlama yapın.
Visual Studio 'nun ikinci bir örneğinde, Roslyn önizleme uzantısı yüklenmiş olarak, çözümleyici projesini çalıştırmak
için CTRL + F5 tuşlarına basın.
İkinci Visual Studio örneğinde, yeni C# bir konsol uygulaması projesi oluşturun ve ana yönteme int x = "abc";
ekleyin. İlk hata düzelttiğinde, bu yerel değişken bildirimi için hiçbir uyarı bildirilmemelidir (ancak beklenen bir
derleyici hatası var).
Sonra, Main yöntemine object s = "abc"; ekleyin. İkinci hata düzelttiğinden uyarı bildirilmemelidir.
Son olarak, var anahtar sözcüğünü kullanan başka bir yerel değişken ekleyin. Bir uyarının bildirilmekte
olduğunu ve sol tarafta bir öneri göründüğünü görürsünüz.
Düzenleyici giriş işaretini dalgalı alt çizginin üzerine taşıyın ve CTRL + tuşlarına basın. önerilen kod düzeltmesini
göstermek için. Kod düzeltmesini seçtikten sonra, var olan ' anahtar sözcüğünün artık doğru şekilde işlendiğini
unutmayın.
Son olarak, aşağıdaki kodu ekleyin:
int i = 2;
int j = 32;
int k = i + j;

Bu değişikliklerden sonra, yalnızca ilk iki değişkene kırmızı dalgalı çizgiler alırsınız. i ve j``const ekleyin ve artık
const olabileceğinden k yeni bir uyarı alırsınız.

Tebrikler! Bir sorunu tespit etmek ve düzeltmek için hızlı bir düzeltme sağlamak üzere anında çalıştırılan kod
analizini gerçekleştiren ilk .NET Compiler Platform uzantınızı oluşturdunuz. Bu şekilde, .NET Compiler Platform
SDK 'nın (Roslyn API 'Ler) parçası olan kod API 'lerinin birçoğunu öğrendiniz. Çalışmalarımızı örnek GitHub
deponuzdaki tamamlanmış örnekle karşı denetleyebilirsiniz. Ya da tamamlanmış projenin ZIP dosyasını
indirebilirsiniz

Diğer kaynaklar
Sözdizimi analizini kullanmaya başlayın
Anlamsal analiz ile çalışmaya başlama
C#Programlama Kılavuzu
25.11.2019 • 2 minutes to read • Edit Online

Bu bölüm .NET Framework C# C# aracılığıyla erişilebilen temel dil özellikleri


ve özellikleri hakkında ayrıntılı bilgi sağlar.
Bu bölümün çoğu, C# ve genel programlama kavramlarını daha önce bildiğiniz
varsayılmaktadır. Programlama veya ile C#birlikte tam bir başlangıç
yapıyorsanız, önceden programlama bilgisi gerekli olmayan öğreticiler veya
.net-tarayıcı öğreticisiniziyaret etmek C# isteyebilirsiniz.
Belirli anahtar sözcükler, işleçler ve Önişlemci yönergeleri hakkında daha fazla
bilgi C# için bkz. başvuru. C# Dil belirtimi hakkında daha fazla bilgi için bkz C#
. dil belirtimi.

Program bölümleri
C# Programı İçinde
Ana() ve Komut Satırı Bağımsız Değişkenleri

Dil bölümleri
Deyimler, İfadeler ve İşleçler
Türler
Sınıflar ve Yapılar
Arabirimler
Sabit Listesi Türleri
Temsilciler
Diziler
Dizeler
Özellikler
Dizin Oluşturucular
Olaylar
Genel Türler
Yineleyiciler
LINQ sorgu Ifadeleri
Lambda İfadeleri
Ad Alanları
Güvenli Olmayan Kod ve İşaretçiler
XML Belge Açıklamaları
Platform bölümleri
Uygulama Etki Alanları
.NET’te bütünleştirilmiş kodlar
Öznitelikler
Koleksiyonlar
Özel Durumlar ve Özel Durum İşleme
Dosya sistemi ve kayıt defteri (C# Programlama Kılavuzu)
Birlikte çalışabilirlik
Yansıma

Ayrıca bkz.
C#Başvurunun
C# programı içinde
23.10.2019 • 2 minutes to read • Edit Online

Bölüm bir C# programın genel yapısını açıklar ve "Hello, World!" standardını içerir örneğinde.

Bu bölümde
Merhaba Dünya -- İlk Programınız
C# Programının Genel Yapısı
Tanımlayıcı adları
C# Kodlama Kuralları

İlgili bölümler
Kullanmaya başlamaC#
C# Programlama Kılavuzu
C#Başvurunun
Örnekler ve öğreticiler

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir kaynaktır.

Ayrıca bkz.
C# Programlama Kılavuzu
Merhaba Dünya--ilk programınız
1.11.2019 • 7 minutes to read • Edit Online

Bu makalede, geleneksel "Merhaba Dünya!" öğesini oluşturmak için Visual Studio 'Yu kullanacaksınız programda.
Visual Studio, .NET geliştirmesi için tasarlanan çok sayıda özelliği olan profesyonel tümleşik bir geliştirme
ortamıdır (IDE ). Bu programı oluşturmak için Visual Studio 'daki özelliklerden yalnızca birkaçını kullanacaksınız.
Visual Studio hakkında daha fazla bilgi edinmek için bkz. C#Visual ile çalışmaya başlama.

NOTE
Bilgisayarınız, aşağıdaki yönergelerde yer alan Visual Studio kullanıcı arabirimi öğelerinden bazıları için farklı adlar veya
konumlar gösterebilir. Sahip olduğunuz Visual Studio sürümü ve kullandığınız ayarlar bu öğeleri belirler. Daha fazla bilgi için
IDE'yi kişiselleştirme.

Yeni bir uygulama oluşturun


Windows
macOS
Visual Studio 'Yu başlatın. Windows 'da aşağıdaki görüntüyü görürsünüz:

Görüntünün sağ alt köşesinde Yeni proje oluştur ' u seçin. Visual Studio Yeni proje iletişim kutusunu görüntüler:
NOTE
Visual Studio 'Yu ilk kez başlattıysanız, son kullanılan proje şablonları listesi boştur.

Yeni proje iletişim kutusunda, "konsol uygulaması (.NET Core)" öğesini seçin ve ardından İleri' ye basın. Projenize
"HelloWorld" gibi bir ad verin ve ardından Oluştur' a basın.
Visual Studio, projenizi açar. Zaten temel bir "Merhaba Dünya!" örneğinde. Projenizi çalıştırmak için Ctrl + F5
tuşuna basın. Visual Studio, projenizi oluşturup kaynak kodu yürütülebilir dosyaya dönüştürür. Ardından, yeni
uygulamanızı çalıştıran bir komut penceresi başlatır. Pencerede aşağıdaki metni görmeniz gerekir:

Hello World!

C:\Program Files\dotnet\dotnet.exe (process 11964) exited with code 0.


Press any key to close this window . . .

Pencereyi kapatmak için bir tuşa basın.

Bir C# programın öğeleri


Bu programın önemli kısımlarını inceleyelim. İlk satır bir açıklama içerir. Karakterler // satırı geri kalanını
açıklamaya dönüştürür.

// A Hello World! program in C#.

Ayrıca, bir metin bloğunu /* ve */ karakterleri arasına ekleyerek açıklama ekleyebilirsiniz. Bu, aşağıdaki örnekte
gösterilir.
/* A "Hello World!" program in C#.
This program displays the string "Hello World!" on the screen. */

C# Konsol uygulaması, denetimin başladığı ve bittiği Main bir yöntem içermelidir. Main yöntemi, nesneleri
oluşturduğunuz ve diğer yöntemleri yürütebileceğiniz yerdir.
Main yöntemi, bir sınıf veya yapı içinde bulunan statik bir yöntemdir. Önceki "Merhaba Dünya!" örnek, Hello adlı
bir sınıfta bulunur. Main yöntemini aşağıdaki yöntemlerden biriyle bildirebilirsiniz:
void döndürebilir. Bu, programınızın bir değer döndürmeyeceği anlamına gelir.

static void Main()


{
//...
}

Ayrıca, bir tamsayı döndürebilir. Tamsayı, uygulamanız için Çıkış kodudur .

static int Main()


{
//...
return 0;
}

Dönüş türlerinden biri ile bağımsız değişken alabilir.

static void Main(string[] args)


{
//...
}

veya

static int Main(string[] args)


{
//...
return 0;
}

Main yönteminin parametresi, args , programı çağırmak için kullanılan komut satırı bağımsız değişkenlerini
içeren bir string dizidir.
Komut satırı bağımsız değişkenlerinin nasıl kullanılacağı hakkında daha fazla bilgi için, ana () ve komut satırı
bağımsız değişkenlerindeörneklere bakın.

Girdi ve çıktı
C#programlar genellikle .NET Framework çalışma zamanı kitaplığı tarafından sunulan giriş/çıkış hizmetlerini
kullanır. Deyimin System.Console.WriteLine("Hello World!"); WriteLine yöntemini kullanır. Bu, çalışma zamanı
kitaplığındaki Console sınıfının çıkış yöntemlerinden biridir. Dize parametresini standart çıkış akışında ve ardından
yeni bir satırla görüntüler. Diğer Console Yöntemler farklı giriş ve çıkış işlemleri için kullanılabilir. using System;
yönergesini programın başına eklerseniz, System sınıfları ve yöntemleri tamamen nitelemeden doğrudan
kullanabilirsiniz. Örneğin, System.Console.WriteLine yerine Console.WriteLine çağırabilirsiniz:
using System;

Console.WriteLine("Hello World!");

Giriş/çıkış yöntemleri hakkında daha fazla bilgi için bkz. System.IO.

Ayrıca bkz.
C# Programlama Kılavuzu
Örnekler ve öğreticiler
Ana() ve Komut Satırı Bağımsız Değişkenleri
Görsele BaşlarkenC#
C# Programının Genel Yapısı (C# Programlama
Kılavuzu)
4.11.2019 • 2 minutes to read • Edit Online

C#Programlar, bir veya daha fazla dosyadan oluşabilir. Her dosya sıfır veya daha fazla ad alanı içerebilir. Ad alanı,
diğer ad alanlarına ek olarak sınıflar, yapılar, arabirimler, numaralandırmalar ve temsilciler gibi türleri içerebilir.
Aşağıda, bu öğelerin tümünü içeren bir C# programın iskelet 'i verilmiştir.

// A skeleton of a C# program
using System;
namespace YourNamespace
{
class YourClass
{
}

struct YourStruct
{
}

interface IYourInterface
{
}

delegate int YourDelegate();

enum YourEnum
{
}

namespace YourNestedNamespace
{
struct YourStruct
{
}
}

class YourMainClass
{
static void Main(string[] args)
{
//Your program starts here...
}
}
}

İlgili Bölümler
Daha fazla bilgi için:
Sınıflar
Yapılar
Ad alanları
Arabirimler
Temsilciler

C# Dil Belirtimi
Daha fazla bilgi için bkz. C# dil belirtiminde temel kavramlar . Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
C# Programlama Kılavuzu
C# Programı İçinde
C#Başvurunun
Tanımlayıcı adları
23.10.2019 • 2 minutes to read • Edit Online

Tanımlayıcı , bir türe atadığınız addır (sınıf, arabirim, yapı, temsilci veya Enum), üye, değişken veya ad alanı.
Geçerli tanımlayıcılar şu kurallara uymalıdır:
Tanımlayıcılar bir harfle başlamalı veya _ .
Tanımlayıcılar Unicode harf karakterleri, ondalık basamak karakterleri, Unicode bağlantı karakterleri,
Unicode birleştiren karakterler veya Unicode biçimlendirme karakterlerini içerebilir. Unicode kategorileri
hakkında daha fazla bilgi için bkz. Unicode kategori veritabanı. Tanımlayıcıda @ öneki kullanarak, anahtar
C# sözcüklerle eşleşen tanımlayıcılar bildirebilirsiniz. @ Tanımlayıcı adının bir parçası değil. Örneğin, @if
adlı if bir tanımlayıcı bildirir. Bu tam tanımlayıcılar öncelikle diğer dillerde belirtilen tanımlayıcılarla birlikte
çalışabilirlik içindir.
Geçerli tanımlayıcıların tamamen tanımı için, C# dil belirtiminde tanımlayıcılar konusunabakın.

Adlandırma kuralları
Kuralların yanı sıra, .NET API 'Lerinde kullanılan bir dizi tanımlayıcı adlandırma kuralı vardır. Kural gereği, C#
programlar tür PascalCase adları, ad alanları ve tüm genel Üyeler için kullanır. Ayrıca, aşağıdaki kurallar
ortaktır:
Arabirim adları sermaye I ile başlar.
Öznitelik türleri kelimeyle Attribute biter.
Sabit listesi türleri, bayraklar için tekil bir ad ve bayraklar için bir çoğul ad kullanır.
Tanımlayıcılar iki ardışık _ karakter içermemelidir. Bu adlar derleyicinin ürettiği tanımlayıcılar için
ayrılmıştır.

C# Dil Belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
C# Programlama Kılavuzu
C# Programı İçinde
C#Başvurunun
Sınıflar
Yapılar
Ad Alanları
Arabirimler
Temsilciler
C# Kodlama Kuralları (C# Programlama Kılavuzu)
4.11.2019 • 12 minutes to read • Edit Online

Kodlama kuralları aşağıdaki amaçlara hizmet eder:


Bunlar, koda tutarlı bir görünüm oluşturur, böylece okuyucular düzene göre değil, içeriğe odaklanabilir.
Bu kullanıcılar, önceki deneyimle dayalı varsayımlar yaparak okuyucuların kodu daha hızlı anlamasına imkan
sağlar.
Kodu kopyalama, değiştirme ve sürdürme işlemlerini kolaylaştırır.
En iyi C# uygulamaları gösterir.
Bu konudaki yönergeler, Microsoft tarafından örnek ve belge geliştirmek için kullanılır.

Adlandırma Kuralları
Using yönergeleridahil olmayan kısa örneklerde ad alanı nitelikleri kullanın. Bir ad alanının bir projede
varsayılan olarak içeri aktarıldığını biliyorsanız, adları bu ad alanından tam olarak nitelemeniz gerekmez.
Nitelenmiş adlar, aşağıdaki örnekte gösterildiği gibi, tek bir satırda çok uzunsa bir nokta (.) sonrasında
bozulabilir.

var currentPerformanceCounterCategory = new System.Diagnostics.


PerformanceCounterCategory();

Visual Studio tasarımcı araçları kullanılarak oluşturulan nesnelerin adlarını, diğer yönergelere uyum
sağlamak için değiştirmeniz gerekmez.

Düzeni Kuralları
İyi düzen, kodunuzun yapısını vurgulamak ve kodun daha kolay okunmasını sağlamak için biçimlendirme kullanır.
Microsoft örnekleri ve örnekleri aşağıdaki kurallara uygun şekilde yapılır:
Varsayılan kod Düzenleyicisi ayarlarını (akıllı girintileme, dört karakterlik girintiler, sekmeler boşluk olarak
kaydedilir) kullanın. Daha fazla bilgi için bkz. Seçenekler, metin düzenleyici C#,, biçimlendirme.
Her satırda yalnızca bir ifade yazın.
Her satırda yalnızca bir bildirim yazın.
Devamlılık satırları otomatik olarak girintili değilse, bir sekme durağı (dört boşluk) için girinti yapın.
Yöntem tanımları ve özellik tanımları arasına en az bir boş satır ekleyin.
Aşağıdaki kodda gösterildiği gibi, bir ifadedeki tümceleri görünür hale getirmek için parantezleri kullanın.

if ((val1 > val2) && (val1 > val3))


{
// Take appropriate action.
}

Yorum Oluşturma Kuralları


Yorumu bir kod satırının sonuna değil, ayrı bir satıra yerleştirin.
Açıklama metnini büyük harfle Başlat.
Açıklama metnini noktayla bitirin.
Aşağıdaki örnekte gösterildiği gibi açıklama sınırlayıcısı (//) ve açıklama metni arasına bir boşluk ekleyin.

// The following declaration creates a query. It does not run


// the query.

Açıklamaların etrafında, biçimli yıldız işaretleri oluşturmayın.

Dil Kuralları
Aşağıdaki bölümlerde, C# takımın kod örneklerini ve örnekleri hazırlamak için izlediği uygulamalar açıklanır.
Dize Veri Türü
Aşağıdaki kodda gösterildiği gibi, kısa dizeleri birleştirmek için dize ilişkilendirmeyi kullanın.

string displayName = $"{nameList[n].LastName}, {nameList[n].FirstName}";

Döngülerde dizeleri eklemek için, özellikle büyük miktarlarda metinle çalışırken bir StringBuilder nesnesi
kullanın.

var phrase = "lalalalalalalalalalalalalalalalalalalalalalalalalalalalalala";


var manyPhrases = new StringBuilder();
for (var i = 0; i < 10000; i++)
{
manyPhrases.Append(phrase);
}
//Console.WriteLine("tra" + manyPhrases);

Örtülü Olarak Yazılan Yerel Değişkenler


Değişkenin türü atamanın sağ tarafından açık olduğunda veya kesin tür önemli olmadığında yerel
değişkenler için örtülü yazma kullanın.

// When the type of a variable is clear from the context, use var
// in the declaration.
var var1 = "This is clearly a string.";
var var2 = 27;
var var3 = Convert.ToInt32(Console.ReadLine());

Tür atamanın sağ tarafından görünmüyorsa, yok kullanmayın.

// When the type of a variable is not clear from the context, use an
// explicit type.
int var4 = ExampleClass.ResultSoFar();

Değişkenin türünü belirtmek için değişken adına güvenmeyin. Doğru olmayabilir.


// Naming the following variable inputInt is misleading.
// It is a string.
var inputInt = Console.ReadLine();
Console.WriteLine(inputInt);

Dinamikyerine var kullanmaktan kaçının.


For ve foreach döngüleri içindeki döngü değişkeninin türünü öğrenmek için örtük yazma kullanın.
Aşağıdaki örnek, for bildiriminde örtük yazma kullanır.

var phrase = "lalalalalalalalalalalalalalalalalalalalalalalalalalalalalala";


var manyPhrases = new StringBuilder();
for (var i = 0; i < 10000; i++)
{
manyPhrases.Append(phrase);
}
//Console.WriteLine("tra" + manyPhrases);

Aşağıdaki örnek, foreach bildiriminde örtük yazma kullanır.

foreach (var ch in laugh)


{
if (ch == 'h')
Console.Write("H");
else
Console.Write(ch);
}
Console.WriteLine();

İmzasız Veri Türü


Genel olarak, işaretsiz türler yerine int kullanın. int kullanımı genelinde C#yaygındır ve int kullandığınızda
diğer kitaplıklarla etkileşim kurmak daha kolaydır.
Diziler
Bildirim satırında dizileri başlattığınızda kısa sözdizimini kullanın.

// Preferred syntax. Note that you cannot use var here instead of string[].
string[] vowels1 = { "a", "e", "i", "o", "u" };

// If you use explicit instantiation, you can use var.


var vowels2 = new string[] { "a", "e", "i", "o", "u" };

// If you specify an array size, you must initialize the elements one at a time.
var vowels3 = new string[5];
vowels3[0] = "a";
vowels3[1] = "e";
// And so on.

Temsilciler
Bir temsilci türünün örneklerini oluşturmak için kısa sözdizimini kullanın.
// First, in class Program, define the delegate type and a method that
// has a matching signature.

// Define the type.


public delegate void Del(string message);

// Define a method that has a matching signature.


public static void DelMethod(string str)
{
Console.WriteLine("DelMethod argument: {0}", str);
}

// In the Main method, create an instance of Del.

// Preferred: Create an instance of Del by using condensed syntax.


Del exampleDel2 = DelMethod;

// The following declaration uses the full syntax.


Del exampleDel1 = new Del(DelMethod);

try-catch ve Özel Durum İşleme bölümünde Deyimleri kullanma


Çoğu özel durum işleme için try-catch ifadesini kullanın.

static string GetValueFromArray(string[] array, int index)


{
try
{
return array[index];
}
catch (System.IndexOutOfRangeException ex)
{
Console.WriteLine("Index is out of range: {0}", index);
throw;
}
}

C# Using ifadesinikullanarak kodunuzu kolaylaştırın. Yalnızca finally bloğundaki kodun Dispose


yöntemine yönelik bir çağrı olduğu bir try-finally deyiminiz varsa, bunun yerine bir using ifadesini kullanın.

// This try-finally statement only calls Dispose in the finally block.


Font font1 = new Font("Arial", 10.0f);
try
{
byte charset = font1.GdiCharSet;
}
finally
{
if (font1 != null)
{
((IDisposable)font1).Dispose();
}
}

// You can do the same thing with a using statement.


using (Font font2 = new Font("Arial", 10.0f))
{
byte charset = font2.GdiCharSet;
}
& & ve | | işleçler
Gereksiz karşılaştırmaları atlayarak özel durumları önlemek ve performansı artırmak için, aşağıdaki örnekte
gösterildiği gibi , karşılaştırmaları | gerçekleştirirken&| yerine && kullanın.

Console.Write("Enter a dividend: ");


var dividend = Convert.ToInt32(Console.ReadLine());

Console.Write("Enter a divisor: ");


var divisor = Convert.ToInt32(Console.ReadLine());

// If the divisor is 0, the second clause in the following condition


// causes a run-time error. The && operator short circuits when the
// first expression is false. That is, it does not evaluate the
// second expression. The & operator evaluates both, and causes
// a run-time error when divisor is 0.
if ((divisor != 0) && (dividend / divisor > 0))
{
Console.WriteLine("Quotient: {0}", dividend / divisor);
}
else
{
Console.WriteLine("Attempted division by 0 ends up here.");
}

Yeni İşleç
Aşağıdaki bildirimde gösterildiği gibi örtük olarak yazılan nesne örneğinin kısa biçimini kullanın.

var instance1 = new ExampleClass();

Önceki satır aşağıdaki bildirime eşdeğerdir.

ExampleClass instance2 = new ExampleClass();

Nesne oluşturma işlemini basitleştirmek için nesne başlatıcıları kullanın.

// Object initializer.
var instance3 = new ExampleClass { Name = "Desktop", ID = 37414,
Location = "Redmond", Age = 2.3 };

// Default constructor and assignment statements.


var instance4 = new ExampleClass();
instance4.Name = "Desktop";
instance4.ID = 37414;
instance4.Location = "Redmond";
instance4.Age = 2.3;

Olay İşleme
Daha sonra kaldırmanız gerekmeyen bir olay işleyicisi tanımlıyorsanız, bir lambda ifadesi kullanın.
public Form2()
{
// You can use a lambda expression to define an event handler.
this.Click += (s, e) =>
{
MessageBox.Show(
((MouseEventArgs)e).Location.ToString());
};
}

// Using a lambda expression shortens the following traditional definition.


public Form1()
{
this.Click += new EventHandler(Form1_Click);
}

void Form1_Click(object sender, EventArgs e)


{
MessageBox.Show(((MouseEventArgs)e).Location.ToString());
}

Statik Üyeler
Statik üyeleri, sınıf adı: ClassName. staticmember' i kullanarak çağırın. Bu uygulama, statik erişim Temizleme
yaparak kodu daha okunabilir hale getirir. Türetilmiş bir sınıf adına sahip bir temel sınıfta tanımlanan statik bir
üyeyi nitelemeyin. Kod derlense de, kod okunurluğu yanıltıcı olur ve türetilmiş sınıfa aynı ada sahip bir statik üye
eklerseniz kod daha sonra bozulabilir.
LINQ Sorguları
Sorgu değişkenleri için anlamlı adlar kullanın. Aşağıdaki örnek, Seattle 'da bulunan müşteriler için
seattleCustomers kullanır.

var seattleCustomers = from customer in customers


where customer.City == "Seattle"
select customer.Name;

Anonim türlerin özellik adlarının, Pascal büyük küçük harf kullanarak doğru şekilde büyük harfli olduğundan
emin olmak için diğer adları kullanın.

var localDistributors =
from customer in customers
join distributor in distributors on customer.City equals distributor.City
select new { Customer = customer, Distributor = distributor };

Sonuç içindeki Özellik adları belirsiz olduğunda özellikleri yeniden adlandırın. Örneğin, sorgunuz bir müşteri
adı ve bir dağıtıcı KIMLIĞI döndürürse, Name olarak bırakmak yerine ID , Name bir müşterinin adı
olduğunu ve ID bir dağıtıcı KIMLIĞI olduğunu açıklığa kavuşturacak şekilde yeniden adlandırın.

var localDistributors2 =
from customer in customers
join distributor in distributors on customer.City equals distributor.City
select new { CustomerName = customer.Name, DistributorID = distributor.ID };

Sorgu değişkenleri ve Aralık değişkenleri bildiriminde örtük yazma kullanın.


var seattleCustomers = from customer in customers
where customer.City == "Seattle"
select customer.Name;

Önceki örneklerde gösterildiği gibi, from yan tümcesinin altındaki sorgu yan tümcelerini hizalayın.
Daha sonra sorgu yan tümcelerinin azaltılmış ve filtrelenmiş veri kümesi üzerinde çalışmasını sağlamak için
diğer sorgu yan tümcelerinden önce WHERE yan tümceleri kullanın.

var seattleCustomers2 = from customer in customers


where customer.City == "Seattle"
orderby customer.Name
select customer;

İç koleksiyonlara erişmek için JOIN yan tümcesi yerine birden çok from yan tümcesini kullanın. Örneğin,
Student nesnelerinin bir koleksiyonu, her biri bir test puanları koleksiyonu içerebilir. Aşağıdaki sorgu
yürütüldüğünde, puanı alan öğrencinin son adıyla birlikte 90 ' ten fazla olan her puanı döndürür.

// Use a compound from to access the inner sequence within each element.
var scoreQuery = from student in students
from score in student.Scores
where score > 90
select new { Last = student.LastName, score };

Güvenlik
Güvenli kodlama yönergeleribölümündeki yönergeleri izleyin.

Ayrıca bkz.
Visual Basic kodlama kuralları
Güvenli Kodlama Yönergeleri
Main () ve komut satırı bağımsız değişkenleri (C#
Programlama Kılavuzu)
27.11.2019 • 3 minutes to read • Edit Online

Main yöntemi, bir C# uygulamanın giriş noktasıdır. (Kitaplıklar ve hizmetler, giriş noktası olarak bir Main
yöntemi gerektirmez.) Uygulama başlatıldığında Main yöntemi çağrılan ilk yöntemdir.
Bir C# programda yalnızca bir giriş noktası olabilir. Main yöntemine sahip birden fazla sınıfınız varsa, giriş
noktası olarak hangi Main yönteminin kullanılacağını belirtmek için programınızı /Main derleyici seçeneğiyle
derlemeniz gerekir. Daha fazla bilgi için bkz. -MainC# (derleyici seçenekleri).

class TestClass
{
static void Main(string[] args)
{
// Display the number of command line arguments.
Console.WriteLine(args.Length);
}
}

Genel Bakış
Main yöntemi, çalıştırılabilir programın giriş noktasıdır; Program denetiminin başladığı ve bittiği yerdir.
Main bir sınıf veya yapı içinde bildirilmiştir. Main statik olması ve genelolmaması gerekir. ( Önceki örnekte,
Private'ın varsayılan erişimini alır.) Kapsayan sınıf veya yapının statik olması gerekmez.
Main , C# 7,1, Task veya Task<int> dönüş türünden başlayarak void , int ya da olabilir.
Yalnızca Main bir Task veya Task<int> döndürürse, Main bildirimi async değiştiricisini içerebilir. Bunun
özellikle bir async void Main yöntemi dışladığı unutulmamalıdır.
Main yöntemi komut satırı bağımsız değişkenleri içeren bir string[] parametresiyle veya bu parametre
olmadan bildirilebilecek. Windows uygulamaları oluşturmak için Visual Studio kullanırken, parametresini el
ile ekleyebilir veya komut satırı bağımsız değişkenlerinialmak için GetCommandLineArgs() yöntemini
kullanabilirsiniz. Parametreler, sıfır dizinli komut satırı bağımsız değişkenleri olarak okunurdur. C ve C++'
nin aksine, programın adı args dizideki ilk komut satırı bağımsız değişkeni olarak değerlendirilmez, ancak
GetCommandLineArgs() yönteminin ilk öğesidir.
Geçerli Main imzalarının listesi aşağıda verilmiştir:

public static void Main() { }


public static int Main() { }
public static void Main(string[] args) { }
public static int Main(string[] args) { }
public static async Task Main() { }
public static async Task<int> Main() { }
public static async Task Main(string[] args) { }
public static async Task<int> Main(string[] args) { }

async ve Task ekleme Task<int> dönüş türleri, konsol uygulamalarının Main zaman uyumsuz işlemlere
await başlaması gerektiğinde program kodunu basitleştirir.
C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
csc.exe Kullanarak Komut Satırı Derleme
C# Programlama Kılavuzu
Yöntemler
C# Programı İçinde
Komut Satırı Bağımsız Değişkenleri (C# Programlama
Kılavuzu)
30.10.2019 • 4 minutes to read • Edit Online

Aşağıdaki yöntemlerden biriyle yöntemi tanımlayarak Main metoduna bağımsız değişkenler gönderebilirsiniz:

static int Main(string[] args)

static void Main(string[] args)

NOTE
Windows Forms uygulamasındaki Main yönteminde komut satırı bağımsız değişkenlerini etkinleştirmek için,
program.csiçinde Main imzasını el ile değiştirmeniz gerekir. Windows Forms Tasarımcısı tarafından oluşturulan kod, giriş
parametresi olmadan bir Main oluşturur. Ayrıca, bir konsolun veya Windows uygulamasındaki herhangi bir noktadan komut
satırı bağımsız değişkenlerine erişmek için Environment.CommandLine veya Environment.GetCommandLineArgs
kullanabilirsiniz.

Main yönteminin parametresi, komut satırı bağımsız değişkenlerini temsil eden bir String dizisidir. Genellikle
Length özelliğini test ederek bağımsız değişkenlerin mevcut olup olmadığını belirlersiniz, örneğin:

if (args.Length == 0)
{
System.Console.WriteLine("Please enter a numeric argument.");
return 1;
}

Ayrıca, Convert sınıfını veya Parse yöntemini kullanarak dize bağımsız değişkenlerini sayısal türlere
dönüştürebilirsiniz. Örneğin, aşağıdaki ifade Parse yöntemini kullanarak string bir long numarasına
dönüştürür:

long num = Int64.Parse(args[0]);

Ayrıca, Int64 diğer ad long C# türü kullanmak da mümkündür:

long num = long.Parse(args[0]);

Aynı şeyi yapmak için ToInt64 Convert sınıf yöntemini de kullanabilirsiniz:

long num = Convert.ToInt64(s);

Daha fazla bilgi için bkz. Parse ve Convert.

Örnek
Aşağıdaki örnek, bir konsol uygulamasında komut satırı bağımsız değişkenlerinin nasıl kullanılacağını gösterir.
Uygulama çalışma zamanında bir bağımsız değişken alır, bağımsız değişkeni bir tamsayıya dönüştürür ve sayının
faktöriyelini hesaplar. Bağımsız değişken sağlanmazsa, uygulama programın doğru kullanımını açıklayan bir ileti
yayınlar.
Uygulamayı bir komut isteminden derlemek ve çalıştırmak için aşağıdaki adımları izleyin:
1. Aşağıdaki kodu herhangi bir metin düzenleyicisine yapıştırın ve sonra dosyayı Factorial.csadlı bir metin
dosyası olarak kaydedin.
// Add a using directive for System if the directive isn't already present.

public class Functions


{
public static long Factorial(int n)
{
// Test for invalid input.
if ((n < 0) || (n > 20))
{
return -1;
}

// Calculate the factorial iteratively rather than recursively.


long tempResult = 1;
for (int i = 1; i <= n; i++)
{
tempResult *= i;
}
return tempResult;
}
}

class MainClass
{
static int Main(string[] args)
{
// Test if input arguments were supplied.
if (args.Length == 0)
{
Console.WriteLine("Please enter a numeric argument.");
Console.WriteLine("Usage: Factorial <num>");
return 1;
}

// Try to convert the input arguments to numbers. This will throw


// an exception if the argument is not a number.
// num = int.Parse(args[0]);
int num;
bool test = int.TryParse(args[0], out num);
if (!test)
{
Console.WriteLine("Please enter a numeric argument.");
Console.WriteLine("Usage: Factorial <num>");
return 1;
}

// Calculate factorial.
long result = Functions.Factorial(num);

// Print result.
if (result == -1)
Console.WriteLine("Input must be >= 0 and <= 20.");
else
Console.WriteLine($"The Factorial of {num} is {result}.");

return 0;
}
}
// If 3 is entered on command line, the
// output reads: The factorial of 3 is 6.

2. Başlat ekranından veya Başlat menüsünden bir Visual Studio Geliştirici komut istemi penceresi açın ve
ardından yeni oluşturduğunuz dosyayı içeren klasöre gidin.
3. Uygulamayı derlemek için aşağıdaki komutu girin.
csc Factorial.cs

Uygulamanızda hiçbir derleme hatası yoksa, çarpınımı. exe adlı bir yürütülebilir dosya oluşturulur.
4. 3 ' ün çarpımını hesaplamak için aşağıdaki komutu girin:
Factorial 3

5. Komut bu çıktıyı üretir: The factorial of 3 is 6.

NOTE
Visual Studio 'da bir uygulama çalıştırırken, hata ayıklama sayfasında, proje Tasarımcısı' nda komut satırı bağımsız
değişkenlerini belirtebilirsiniz.

Ayrıca bkz.
System.Environment
C# Programlama Kılavuzu
Ana() ve Komut Satırı Bağımsız Değişkenleri
Nasıl yapılır: Komut Satırı Bağımsız Değişkenlerini Görüntüleme
Ana() Dönüş Değerleri
Sınıflar
Nasıl yapılır: Komut satırı bağımsız değişkenlerini
görüntüleC# (Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Komut satırındaki bir çalıştırılabilir dosyaya girilen bağımsız değişkenlere, için Main isteğe bağlı bir parametre
üzerinden erişilebilir. Bağımsız değişkenler, dizeler dizisi biçiminde sağlanır.Dizinin her öğesi bir bağımsız
değişken içerir. Bağımsız değişkenler arasındaki beyaz boşluk kaldırılır. Örneğin, kurgusal bir yürütülebilirin şu
komut satırı çağırmaları göz önünde bulundurun:

KOMUT SATIRINDA GIRIŞ MAIN 'E GEÇIRILEN DIZELERIN DIZISI

çalıştırılabilir. exe a b c a

kenarı

yürütülebilir. exe 1 2 biriyle

ikiye

yürütülebilir. exe "1 2" üç "one two"

ünden

NOTE
Visual Studio 'da bir uygulama çalıştırırken, hata ayıklama sayfasında, proje Tasarımcısı' nda komut satırı bağımsız
değişkenlerini belirtebilirsiniz.

Örnek
Bu örnek, komut satırı uygulamasına geçirilen komut satırı bağımsız değişkenlerini görüntüler. Gösterilen çıktı,
yukarıdaki tablodaki ilk giriş içindir.
class CommandLine
{
static void Main(string[] args)
{
// The Length property provides the number of array elements.
Console.WriteLine($"parameter count = {args.Length}");

for (int i = 0; i < args.Length; i++)


{
Console.WriteLine($"Arg[{i}] = [{args[i]}]");
}
}
}
/* Output (assumes 3 cmd line args):
parameter count = 3
Arg[0] = [a]
Arg[1] = [b]
Arg[2] = [c]
*/

Ayrıca bkz.
C# Programlama Kılavuzu
csc.exe Kullanarak Komut Satırı Derleme
Ana() ve Komut Satırı Bağımsız Değişkenleri
Ana() Dönüş Değerleri
Main () dönüş değerleri (C# Programlama Kılavuzu)
6.12.2019 • 4 minutes to read • Edit Online

Main yöntemi void döndürebilir:

static void Main()


{
//...
}

Ayrıca, bir int döndürebilir:

static int Main()


{
//...
return 0;
}

Main dönüş değeri kullanılmazsa, void döndürme biraz daha basit bir koda izin verir. Ancak, bir tamsayı
döndürmek programın durum bilgilerini yürütülebilir dosyayı çağıran diğer programlarla veya betiklerine
iletmesine olanak sağlar. Main dönüş değeri, işlem için çıkış kodu olarak değerlendirilir. Main void
döndürüldüğünde çıkış kodu örtük olarak 0 olur. Aşağıdaki örnek, Main ' den dönüş değerine nasıl erişildiğini
gösterir.

Örnek
Bu örnek .NET Core komut satırı araçlarını kullanır. .NET Core komut satırı araçları hakkında bilginiz yoksa , bu
Başlarken konusunda bilgiedinebilirsiniz.
Program.cs içinde Main yöntemini aşağıdaki gibi değiştirin:

// Save this program as MainReturnValTest.cs.


class MainReturnValTest
{
static int Main()
{
//...
return 0;
}
}

Bir program Windows 'da yürütüldüğünde, Main işlevinden döndürülen herhangi bir değer bir ortam
değişkeninde depolanır. Bu ortam değişkeni bir toplu iş dosyasından ERRORLEVEL veya PowerShell 'den
$LastExitCode kullanılarak alınabilir.

DotNet clı dotnet build komutunu kullanarak uygulamayı oluşturabilirsiniz.


Sonra, uygulamayı çalıştırmak için bir PowerShell betiği oluşturun ve sonucu görüntüleyin. Aşağıdaki kodu bir
metin dosyasına yapıştırın ve projeyi içeren klasöre test.ps1 olarak kaydedin. PowerShell komut isteminde
test.ps1 yazarak PowerShell betiğini çalıştırın.

Kod sıfır döndürdüğünden, toplu iş dosyası başarıyı bildirir. Ancak, MainReturnValTest.cs değerini sıfır olmayan bir
değer döndürecek şekilde değiştirip programı yeniden derlerseniz, PowerShell betiğinin sonraki yürütmesi hata
bildirir.

dotnet run
if ($LastExitCode -eq 0) {
Write-Host "Execution succeeded"
} else
{
Write-Host "Execution Failed"
}
Write-Host "Return value = " $LastExitCode

Örnek çıktı
Execution succeeded
Return value = 0

Zaman uyumsuz ana dönüş değerleri


Zaman uyumsuz ana dönüş değerleri, derleyici tarafından oluşturulan koda Main zaman uyumsuz yöntemleri
çağırmak için gereken ortak kodu taşır. Daha önce, zaman uyumsuz kodu çağırmak ve programınızın zaman
uyumsuz işlem tamamlanana kadar çalıştığından emin olmak için bu yapıyı yazmanız gerekir:

public static void Main()


{
AsyncConsoleWork().GetAwaiter().GetResult();
}

private static async Task<int> AsyncConsoleWork()


{
// Main body here
return 0;
}

Şimdi bu, şu şekilde değiştirilebilir:

static async Task<int> Main(string[] args)


{
return await AsyncConsoleWork();
}

Yeni sözdiziminin avantajı, derleyicinin her zaman doğru kodu üretmesinin avantajına sahiptir.

Derleyicinin ürettiği kod


Uygulama giriş noktası bir Task veya Task<int> döndürdüğünde, derleyici uygulama kodunda belirtilen giriş
noktası yöntemini çağıran yeni bir giriş noktası oluşturur. Bu giriş noktasının $GeneratedMain çağrıldığı kabul
edildiğinde, derleyici bu giriş noktaları için aşağıdaki kodu üretir:
static Task Main() , derleyicinin private static void $GeneratedMain() => Main().GetAwaiter().GetResult();
eşdeğerini yaymasına neden olur
static Task Main(string[]) , derleyicinin
private static void $GeneratedMain(string[] args) => Main(args).GetAwaiter().GetResult(); eşdeğerini
yaymasına neden olur
static Task<int> Main() , derleyicinin
private static int $GeneratedMain() => Main().GetAwaiter().GetResult(); eşdeğerini yaymasına neden olur
static Task<int> Main(string[]) , derleyicinin
private static int $GeneratedMain(string[] args) => Main(args).GetAwaiter().GetResult(); eşdeğerini
yaymasına neden olur

NOTE
Örnekler Main yönteminde async değiştirici kullandıysanız, derleyici aynı kodu oluşturur.

Ayrıca bkz.
C# Programlama Kılavuzu
C#Başvurunun
Ana() ve Komut Satırı Bağımsız Değişkenleri
Nasıl yapılır: Komut Satırı Bağımsız Değişkenlerini Görüntüleme
Programlama kavramları (C#)
23.10.2019 • 2 minutes to read • Edit Online

Bu bölümde, C# dildeki programlama kavramları açıklanmaktadır.

Bu Bölümde
BAŞLIK AÇIKLAMA

.NET’te bütünleştirilmiş kodlar Derlemelerin nasıl oluşturulduğunu ve kullanıldığını açıklar.

Async ve await (C#) ile zaman uyumsuz programlama İçinde C# Async ve await anahtar sözcüklerini kullanarak
zaman uyumsuz çözümlerin nasıl yazılacağını açıklar. Bir
anlatım içerir.

Öznitelikler (C#) Öznitelikleri kullanarak türler, alanlar, Yöntemler ve özellikler


gibi programlama öğeleriyle ilgili ek bilgiler sağlamayı açıklar.

Arayan bilgileri (C#) Bir yöntemin çağıranı hakkında nasıl bilgi elde edileceğini
açıklar. Bu bilgiler, kaynak kodun dosya yolunu ve satır
numarasını ve arayanın üye adını içerir.

Koleksiyonlar (C#) .NET Framework tarafından sunulan bazı koleksiyon türlerini


açıklar. Basit koleksiyonların ve anahtar/değer çiftlerinin
koleksiyonlarının nasıl kullanılacağını gösterir.

Kovaryans ve değişken varyans (C#) Arabirimlerde ve temsilcilerde genel tür parametrelerinin örtük
dönüştürmesinin nasıl etkinleştirileceğini gösterir.

İfade ağaçları (C#) Yürütülebilir kodun dinamik olarak değiştirilmesini


etkinleştirmek için nasıl ifade ağaçları kullanabileceğinizi açıklar.

Yineleyiciler (C#) Koleksiyonlar arasında ilerlemek ve tek seferde bir öğe


döndürmek için kullanılan yineleyiciler açıklanmaktadır.

Dil ile tümleşik sorgu (LINQ) (C#) Dil sözdiziminde C#güçlü sorgu özelliklerini ve ilişkisel
VERITABANLARıNı, XML belgelerini, veri kümelerini ve bellek içi
koleksiyonları sorgulamak için modeli açıklar.

Nesne odaklı programlama (C#) Kapsülleme, devralma ve çok biçimlilik dahil olmak üzere,
nesne odaklı ortak kavramları açıklar.

Yansıma (C#) Bir türün örneğini dinamik olarak oluşturmak, türü var olan bir
nesneye bağlamak veya var olan bir nesneden türü almak ve
onun yöntemlerini çağırmak ya da kendi alanlarına ve
özelliklerine erişmek için yansıma kullanımını açıklar.

Serileştirme (C#) İkili, XML ve SOAP serileştirmesi içinde temel kavramları açıklar.

İlgili Bölümler
Performans İpuçları Uygulamanızın performansını artırmanıza yardımcı olabilecek
çeşitli temel kuralları açıklar.
Async ve await ile zaman uyumsuz programlama
29.11.2019 • 16 minutes to read • Edit Online

Görev zaman uyumsuz programlama modeli (TAP ), zaman uyumsuz kod üzerinde bir soyutlama sağlar. Her
zaman olduğu gibi, kodu deyimler dizisi olarak yazarsınız. Bu kodu, bir sonraki başlamadan önce her bir
deyimin tamamlansa da okuyabilirsiniz. Derleyici bir dizi dönüştürme gerçekleştirir, çünkü bu deyimlerden
bazıları işe başlayabilir ve devam eden işi temsil eden bir Task döndürebilir.
Bu sözdiziminin amacı: bir deyim dizisi gibi okuyan kodu etkinleştirin, ancak dış kaynak ayırmaya ve görevler
tamamlandığında çok daha karmaşık bir sırayla yürütülür. Kullanıcıların zaman uyumsuz görevler içeren
işlemlere yönelik yönergeler verme yöntemi benzerdir. Bu makalede, async ve await anahtar kelimeleriyle
ilgili bir dizi zaman uyumsuz yönergeler içeren kod hakkında neden olmasının nasıl daha kolay olduğunu
görmek için bir yönergeler örneği kullanacaksınız. Daha hızlı nasıl yapılacağını açıklamak için aşağıdaki listeye
benzer yönergeler yazın:
1. Kahve kupa dök.
2. Bir Pan, sonra da iki Yumura kadar bir kaydır.
3. Bacon üç dilimi.
4. İki adet içerik.
5. Bildirim 'e alın ve sıkıştı ekleyin.
6. Turuncu bir büyütece bir cam dök.
Pişirme deneyiminiz varsa, bu yönergeleri zaman uyumsuzolarak yürütebilirsiniz. Yumurlar için kaydırmayı
ısıncak ve sonra Bacon 'u başlatacak. Ekseyi Toaster ' a yerleştirip yumurtalar ' ı başlatın. İşlemin her adımında
bir görev başlatır, sonra ilgilenmeniz için uygun olan görevlere dikkat etmeniz gerekir.
Pişirme kahileri, paralel olmayan bir zaman uyumsuz çalışmaya yönelik iyi bir örnektir. Bir kişi (veya iş
parçacığı), tüm bu görevleri işleyebilir. Breakfast benzerleme vurguladı devam ederken bir kişi, ilk
tamamlanmadan önce sonraki görevi başlatarak zaman uyumsuz olarak zaman uyumsuz hale getirebilirsiniz.
Pişirme işlemi, birisinin onu izliyor olup olmadığı konusunda ilerler. Yumurlar için kaydırma işlemini
başlattığınızda, Bacon kızartma başlayabilirsiniz. Bacon başladıktan sonra, ekseyi Toaster 'a yerleştirebilirsiniz.
Paralel bir algoritma için birden çok ortak iş (veya iş parçacığı) gerekir. Bunlardan biri, bir, Bacon, vb. olur.Her
biri yalnızca bir göreve odaklanılmıştır. Her bir Cook (veya iş parçacığı), Bacon 'un çevrilmeye hazırlanması
veya bildirim açılanması için zaman uyumlu olarak engelleniyor.
Şimdi, deyimler olarak C# yazılan aynı yönergeleri göz önünde bulundurun:
static void Main(string[] args)
{
Coffee cup = PourCoffee();
Console.WriteLine("coffee is ready");
Egg eggs = FryEggs(2);
Console.WriteLine("eggs are ready");
Bacon bacon = FryBacon(3);
Console.WriteLine("bacon is ready");
Toast toast = ToastBread(2);
ApplyButter(toast);
ApplyJam(toast);
Console.WriteLine("toast is ready");
Juice oj = PourOJ();
Console.WriteLine("oj is ready");

Console.WriteLine("Breakfast is ready!");
}

Bilgisayarlar bu yönergeleri insanlar ile aynı şekilde yorumlamaz. Bir sonraki ifadeye geçmeden önce,
bilgisayar her bir bildirimde, iş tamamlanana kadar engeller. Bu, karşılanunan bir Breakfast oluşturur. Daha
sonraki görevler, önceki görevler tamamlanana kadar başlatılamaz. Daha uzun sürer ve bazı öğeler
sunulmadan önce soğuk hale gelir.
Bilgisayarın yukarıdaki yönergeleri zaman uyumsuz olarak yürütmesini istiyorsanız, zaman uyumsuz kod
yazmanız gerekir.
Bu sorunlar, bugün yazdığınız programlar için önemlidir.İstemci programları yazdığınızda, kullanıcı
ARABIRIMININ Kullanıcı girişine yanıt vermesini istersiniz. Uygulamanız, Web 'den veri indirirken bir
telefonu dondurulmuş hale döndürmemelidir. Sunucu programları yazdığınızda, iş parçacıklarının
engellenmesini istemezsiniz. Bu iş parçacıkları diğer isteklere hizmet verebilir. Zaman uyumsuz alternatifler
mevcut olduğunda zaman uyumlu kod kullanarak daha ucuz bir şekilde ölçeklendirme imkanına sahip
olabilirsiniz. Engellenen bu iş parçacıkları için ödeme yaparsınız.
Başarılı modern uygulamalar zaman uyumsuz kod gerektirir. Dil desteği olmadan, zaman uyumsuz kod gerekli
geri çağırmaları, tamamlanma olaylarını veya başka bir deyişle, kodun orijinal hedefini görünmez hale gelir.
Zaman uyumlu kodun avantajı, anlaşılması kolay bir işlemdir. Adım adım eylemler, taramayı ve anlamayı
kolaylaştırır. Geleneksel zaman uyumsuz modeller kodun temel eylemlerine değil, kodun zaman uyumsuz
yapısına odaklanmaya zorlanır.

Engelleme, yerine await


Yukarıdaki kodda kötü bir uygulama gösterilmektedir: zaman uyumsuz işlemleri gerçekleştirmek için zaman
uyumlu kod oluşturma. Yazıldığı gibi, bu kod başka herhangi bir işi yapmadan yürüten iş parçacığını engeller.
Görevlerden herhangi biri devam ederken bu işlem kesintiye uğramaz. Bu, ' ın içine yerleştirdikten sonra
Toaster ' ta başmış gibi olacaktır. Bildirim alınana kadar sizi konuşuyor olan herkesi yoksayabilirsiniz.
İş parçacığı, görevler çalışırken engellenmemesi için bu kodu güncelleyerek başlayalım. await anahtar
sözcüğü bir görevi başlatmak için engellenmeyen bir yöntem sağlar ve ardından bu görev tamamlandığında
yürütmeye devam eder. Bir Breakfast kodu oluştur 'un basit bir zaman uyumsuz sürümü aşağıdaki kod
parçacığına benzer:
static async Task Main(string[] args)
{
Coffee cup = PourCoffee();
Console.WriteLine("coffee is ready");
Egg eggs = await FryEggs(2);
Console.WriteLine("eggs are ready");
Bacon bacon = await FryBacon(3);
Console.WriteLine("bacon is ready");
Toast toast = await ToastBread(2);
ApplyButter(toast);
ApplyJam(toast);
Console.WriteLine("toast is ready");
Juice oj = PourOJ();
Console.WriteLine("oj is ready");

Console.WriteLine("Breakfast is ready!");
}

Bu kod, yumurtalar veya Bacon pişirirken engellenmez. Bu kod, diğer görevleri de başlatmayacaktır. Yine de
bildirim, siz de bir araya gelene kadar Toaster 'a yerleştirirsiniz. Ancak en azından, ilgilenmeniz istenen herkese
yanıt verirsiniz. Birden çok siparişin yerleştirildiği bir restoran içinde, ilk pişirme sırasında Cook bir daha hızlı
başlatılabilir.
Şimdi, henüz bitmemiş olan herhangi bir başlatılan görevi beklerken, Kahvalı üzerinde çalışan iş parçacığı
engellenmiyor. Bazı uygulamalarda, bu değişiklik gereklidir. Yalnızca bu değişikliğe sahip bir GUI uygulaması
kullanıcıya yanıt veriyor. Ancak, bu senaryo için daha fazla bilgi istersiniz. Her bileşen görevinin her ardışık
olarak yürütülmesini istemezsiniz. Önceki görevin tamamlanmasını beklerken önce her bir bileşen görevinin
başlatılması daha iyidir.

Görevleri eşzamanlı olarak Başlat


Birçok senaryoda, birkaç bağımsız görevi hemen başlatmak istersiniz. Ardından, her bir görev
tamamlandığında, daha önce hazırlanmaya devam edebilirsiniz. Kahhızlı benzerleme vurguladı, daha hızlı bir
şekilde daha hızlı bir şekilde daha hızlı bir şekilde yapılır. Her şeyin aynı anda kapatılmasını de sağlar. Sık
erişimli bir kahvaltı alacaksınız.
System.Threading.Tasks.Task ve ilgili türler, sürmekte olan görevlerle ilgili nedenlerle kullanabileceğiniz
sınıflardır. Bu sayede, aslında daha iyi bir şekilde daha çok benzeyen bir kod yazmanızı sağlar. Eggs, Bacon ve
bildirim ' ı aynı anda aşalım. Her biri bir eylem gerektirdiğinden, bu göreve dikkat etmeniz, sonraki eylemi ele
almanız ve daha sonra ilgilenmeniz gereken başka bir şey için await ' ı kapatmanız gerekir.
Bir görevi başlatır ve işi temsil eden Task nesnesine sahip olursunuz. Sonucuyla çalışmadan önce her görevi
await .

Bu değişiklikleri Breakfast kodunda yapalim. İlk adım, işlemler için görevleri her zaman beklerken depolamak
yerine depolarlar:
Coffee cup = PourCoffee();
Console.WriteLine("coffee is ready");
Task<Egg> eggsTask = FryEggs(2);
Egg eggs = await eggsTask;
Console.WriteLine("eggs are ready");
Task<Bacon> baconTask = FryBacon(3);
Bacon bacon = await baconTask;
Console.WriteLine("bacon is ready");
Task<Toast> toastTask = ToastBread(2);
Toast toast = await toastTask;
ApplyButter(toast);
ApplyJam(toast);
Console.WriteLine("toast is ready");
Juice oj = PourOJ();
Console.WriteLine("oj is ready");

Console.WriteLine("Breakfast is ready!");

Daha sonra, bir sonraki ve yumurlar için await deyimlerini, Breakfast sunmadan önce yönteminin sonuna
taşıyabilirsiniz:

Coffee cup = PourCoffee();


Console.WriteLine("coffee is ready");
Task<Egg> eggsTask = FryEggs(2);
Task<Bacon> baconTask = FryBacon(3);
Task<Toast> toastTask = ToastBread(2);
Toast toast = await toastTask;
ApplyButter(toast);
ApplyJam(toast);
Console.WriteLine("toast is ready");
Juice oj = PourOJ();
Console.WriteLine("oj is ready");

Egg eggs = await eggsTask;


Console.WriteLine("eggs are ready");
Bacon bacon = await baconTask;
Console.WriteLine("bacon is ready");

Console.WriteLine("Breakfast is ready!");

Yukarıdaki kod daha iyi çalışmaktadır. Tüm zaman uyumsuz görevleri aynı anda başlatabilirsiniz. Her bir
görevi yalnızca sonuçlara ihtiyacınız olduğunda bekleolursunuz. Yukarıdaki kod, farklı mikro hizmetlere istek
yapan bir Web uygulamasındaki koda benzer ve sonuçları tek bir sayfada birleştirir. Tüm istekleri hemen
yapar, sonra tüm bu görevleri await ve Web sayfasını oluşturabilirsiniz.

Görevlerle oluşturma
Bildirim hariç her şeyi aynı anda kah, daha hızlı bir şekilde hazırlayın. Bildirim, zaman uyumsuz bir işlemin
(Ekleyici) ve zaman uyumlu işlemlerin (alın ve sıkışan) bir bileşim haline getirilmesi. Bu kodun
güncelleştirilmesi önemli bir kavramı gösterir:

IMPORTANT
Zaman uyumsuz bir işlemin ardından zaman uyumlu iş tarafından oluşturulması zaman uyumsuz bir işlemdir. Başka bir
şekilde ifade edilen bir işlemin herhangi bir bölümü zaman uyumsuz ise, tüm işlem zaman uyumsuzdur.

Yukarıdaki kod, çalışan görevleri tutmak için Task veya Task<TResult> nesneleri kullanacağınızı gösterdi. Her
görevin sonucunu kullanmadan önce await . Sonraki adım, diğer çalışmanın birleşimini temsil eden
yöntemler oluşturmaktır. Kahvileri sunmadan önce, Butter ve sıkışmadan önce Ekleyici 'yi temsil eden görevi
beklemek istersiniz. Bu işi aşağıdaki kodla temsil edebilirsiniz:

async Task<Toast> MakeToastWithButterAndJamAsync(int number)


{
var toast = await ToastBreadAsync(number);
ApplyButter(toast);
ApplyJam(toast);
return toast;
}

Önceki yöntem imzasında async değiştiricisine sahiptir. Bu, bu yöntemin bir await bildiri içerdiğini
derleyiciye bildirir; zaman uyumsuz işlemler içerir. Bu yöntem, Ekleyici ve sıkışıklığı ekleyen görevi temsil eder.
Bu yöntem, bu üç işlemin oluşumunu temsil eden bir Task<TResult> döndürür. Kodun ana bloğu şu şekilde
olur:

static async Task Main(string[] args)


{
Coffee cup = PourCoffee();
Console.WriteLine("coffee is ready");
var eggsTask = FryEggsAsync(2);
var baconTask = FryBaconAsync(3);
var toastTask = MakeToastWithButterAndJamAsync(2);

var eggs = await eggsTask;


Console.WriteLine("eggs are ready");
var bacon = await baconTask;
Console.WriteLine("bacon is ready");
var toast = await toastTask;
Console.WriteLine("toast is ready");
Juice oj = PourOJ();
Console.WriteLine("oj is ready");

Console.WriteLine("Breakfast is ready!");

async Task<Toast> MakeToastWithButterAndJamAsync(int number)


{
var toast = await ToastBreadAsync(number);
ApplyButter(toast);
ApplyJam(toast);
return toast;
}
}

Önceki değişiklik, zaman uyumsuz kod ile çalışmak için önemli bir teknik gösterilmiştir. İşlemleri bir görevi
döndüren yeni bir yönteme ayırarak görevleri oluşturursunuz. Bu görevin ne zaman bekleme seçeneğini
belirleyebilirsiniz. Diğer görevleri eşzamanlı olarak başlatabilirsiniz.

Görevleri verimli olarak await


Önceki kodun sonundaki await deyimleri serisi Task sınıfının yöntemleri kullanılarak artırılabilir. Bu API
'lerden biri, aşağıdaki kodda gösterildiği gibi, bağımsız değişken listesindeki tüm görevler tamamlandığında
tamamlanan bir Task döndüren WhenAll.

await Task.WhenAll(eggsTask, baconTask, toastTask);


Console.WriteLine("eggs are ready");
Console.WriteLine("bacon is ready");
Console.WriteLine("toast is ready");
Console.WriteLine("Breakfast is ready!");
Başka bir seçenek de WhenAnykullanmaktır, bu, bağımsız değişkenlerden herhangi biri tamamlandığında
tamamlayan bir Task<Task> döndürür. Döndürülen görevi, zaten bitdiğinin farkında olacak şekilde beklede
olursunuz. Aşağıdaki kod, ilk görevin bitmesini beklemek ve sonra sonucunu işlemek için WhenAny nasıl
kullanabileceğinizi gösterir. Tamamlanan görevden elde edilen sonucu işledikten sonra, bu tamamlanmış
görevi WhenAny geçirilen görev listesinden kaldırırsınız.

var allTasks = new List<Task>{eggsTask, baconTask, toastTask};


while (allTasks.Any())
{
Task finished = await Task.WhenAny(allTasks);
if (finished == eggsTask)
{
Console.WriteLine("eggs are ready");
}
else if (finished == baconTask)
{
Console.WriteLine("bacon is ready");
}
else if (finished == toastTask)
{
Console.WriteLine("toast is ready");
}
allTasks.Remove(finished);
}
Juice oj = PourOJ();
Console.WriteLine("oj is ready");
Console.WriteLine("Breakfast is ready!");

Tüm bu değişiklikler yapıldıktan sonra Main nihai sürümü aşağıdaki kod gibi görünür:
static async Task Main(string[] args)
{
Coffee cup = PourCoffee();
Console.WriteLine("coffee is ready");
var eggsTask = FryEggsAsync(2);
var baconTask = FryBaconAsync(3);
var toastTask = MakeToastWithButterAndJamAsync(2);

var allTasks = new List<Task>{eggsTask, baconTask, toastTask};


while (allTasks.Any())
{
Task finished = await Task.WhenAny(allTasks);
if (finished == eggsTask)
{
Console.WriteLine("eggs are ready");
}
else if (finished == baconTask)
{
Console.WriteLine("bacon is ready");
}
else if (finished == toastTask)
{
Console.WriteLine("toast is ready");
}
allTasks.Remove(finished);
}
Juice oj = PourOJ();
Console.WriteLine("oj is ready");
Console.WriteLine("Breakfast is ready!");

async Task<Toast> MakeToastWithButterAndJamAsync(int number)


{
var toast = await ToastBreadAsync(number);
ApplyButter(toast);
ApplyJam(toast);
return toast;
}
}

Bu son kod zaman uyumsuzdur. Bu, bir kişinin ne kadar hızlı bir şekilde bir kahtacağını daha doğru yansıtır.
Yukarıdaki kodu, bu makaledeki ilk kod örneğiyle karşılaştırın. Temel eylemler, kodu okumayı hala temizler.Bu
kodu, bu makalenin başlangıcında bir daha hızlı hale getirmek için bu talimatları okuduğunuzdan aynı şekilde
okuyabilirsiniz. async ve await dil özellikleri, her birinin bu yazılı talimatları takip edebilmesini sağlar:
Başlangıç görevleri, yaptığınız gibi başlatın ve görevlerin tamamlanmasını beklemeyi engellemez.
Zaman uyumsuz görev programlama modeli
25.11.2019 • 28 minutes to read • Edit Online

Zaman uyumsuz programlama kullanarak performans sorunlarını önleyebilir ve uygulamanızın genel yanıt verme
becerisini geliştirebilirsiniz. Ancak, zaman uyumsuz uygulamalar yazmaya yönelik geleneksel teknikler karmaşık
olabilir ve bu nedenle yazılmaları, hataların ayıklanması ve bakım yapılması zorlaşabilir.
5, .NET Framework 4,5 ve üzeri, .NET Core ve Windows çalışma zamanı zaman uyumsuz destekten yararlanan,
zaman uyumsuz programlama ile basitleştirilmiş bir yaklaşım getirmiştir. C# Derleyici, normalde geliştiricinin
yaptığı zor işi yapar ve uygulamanız zaman uyumlu koda benzer bir mantıksal yapıyı korur. Sonuç olarak, zaman
uyumsuz programlama avantajlarının tamamını çok daha az çaba harcayarak elde edebilirsiniz.
Bu konu zaman uyumsuz programlamanın ne zaman ve nasıl kullanılması gerektiği hakkında genel bakış içerir ve
ayrıntılar ve örnekler içeren destek konularına bağlantılar sunar.

Zaman uyumsuz, yanıt hızını geliştirir


Asynchrony, Web erişimi gibi olası engelleme olasılığı olan etkinlikler için gereklidir. Web kaynağına erişim bazen
yavaş veya gecikmeli olabilir. Bu tür bir etkinlik zaman uyumlu bir işlemde engellenirse, uygulamanın tamamının
beklemesi gerekir. Uygulama, zaman uyumsuz bir işlemde olası engelleme görevi sona erinceye kadar web
kaynağına bağlı olmayan diğer işlerle devam eder.
Aşağıdaki tabloda, zaman uyumsuz programlamanın yanıt verme hızını geliştirdiği genel alanlar gösterilmektedir.
.NET ve Windows Çalışma Zamanı listelenen API 'Ler, zaman uyumsuz programlamayı destekleyen yöntemler
içerir.

ZAMAN UYUMSUZ YÖNTEMLERIYLE .NET ZAMAN UYUMSUZ YÖNTEMLERE SAHIP


UYGULAMA ALANI TÜRLERI WINDOWS ÇALIŞMA ZAMANI TÜRLERI

Web erişimi HttpClient SyndicationClient

Dosyalarla çalışma StreamWriter, StreamReader, XmlReader StorageFile

Görüntülerle çalışma MediaCapture, BitmapEncoder,


BitmapDecoder

WCF programlama Zaman Uyumlu ve Zaman Uyumsuz


İşlemler

Tüm kullanıcı arabirimi ilişkili faaliyetler genellikle tek bir iş parçacığını paylaştığından, zaman uyumsuzluğun
kullanıcı arabirimi iş parçacığına erişen uygulamalar için özellikle önem taşıdığı kanıtlanmıştır. Herhangi bir işlem
zaman uyumlu bir uygulamada engellenirse, tümü engellenir. Uygulamanız yanıt vermiyordur ve bunu
uygulamanın beklediği değil de başarısız olduğu şeklinde yorumlayabilirsiniz.
Zaman uyumsuz yöntemleri kullandığınızda, uygulama arabirime yanıt vermeye devam eder. Bir pencereyi yeniden
boyutlandırabilir veya simge durumuna küçültebilir ya da bitmesini beklemek istemiyorsanız kapatabilirsiniz.
Zaman uyumsuz tabanlı yaklaşım otomatik bir iletimin eşdeğerini, zaman uyumsuz işlemler tasarlarken
seçebileceğiniz seçenekler listesine ekler. Diğer bir deyişle, geleneksel zaman uyumsuz programlamanın tüm
avantajlarından yararlanabilirsiniz, buna rağmen geliştiricinin daha az çaba sarf etmesi gerekir.
Zaman uyumsuz yöntemlerin yazılması daha kolaydır
' Deki C# Async ve await anahtar sözcükleri zaman uyumsuz programlamanın kalbidir. Bu iki anahtar sözcüğü
kullanarak, bir zaman uyumlu Yöntem oluştururken neredeyse kolayca zaman uyumsuz bir yöntem oluşturmak için
.NET Framework, .NET Core veya Windows Çalışma Zamanı kaynaklarını kullanabilirsiniz. async anahtar
sözcüğünü kullanarak tanımladığınız zaman uyumsuz yöntemler, zaman uyumsuz yöntemlerolarak adlandırılır.
Aşağıdaki örnekte zaman uyumsuz bir yöntem gösterilmektedir. Kodda yer alan hemen hemen her şey size
tamamen tanıdık gelmiş olmalıdır.
Bu konunun sonunda bir Windows Presentation Foundation (WPF ) örnek dosyası bulabilirsiniz ve örneği zaman
uyumsuz örnek: "Async ve await Ile zaman uyumsuz programlama" kaynağındanindirebilirsiniz.

async Task<int> AccessTheWebAsync()


{
// You need to add a reference to System.Net.Http to declare client.
var client = new HttpClient();

// GetStringAsync returns a Task<string>. That means that when you await the
// task you'll get a string (urlContents).
Task<string> getStringTask = client.GetStringAsync("https://docs.microsoft.com/dotnet");

// You can do work here that doesn't rely on the string from GetStringAsync.
DoIndependentWork();

// The await operator suspends AccessTheWebAsync.


// - AccessTheWebAsync can't continue until getStringTask is complete.
// - Meanwhile, control returns to the caller of AccessTheWebAsync.
// - Control resumes here when getStringTask is complete.
// - The await operator then retrieves the string result from getStringTask.
string urlContents = await getStringTask;

// The return statement specifies an integer result.


// Any methods that are awaiting AccessTheWebAsync retrieve the length value.
return urlContents.Length;
}

Yukarıdaki örnekten birkaç uygulama öğrenebilirsiniz. Yöntem imzasıyla başlayın. async değiştiricisini içerir.
Dönüş türü Task<int> (daha fazla seçenek için bkz. "dönüş türleri" bölümü). Yöntem adı Async biter. Yönteminin
gövdesinde, GetStringAsync Task<string> döndürür. Bu, görevi await string ( urlContents ) alacağınız anlamına
gelir. Görevi beklerken önce, GetStringAsync``string kullanmayan çalışmayı yapabilirsiniz.
await işlecine yakın bir ilgi ödeyin. AccessTheWebAsync askıya alır;
getStringTask tamamlanana kadar AccessTheWebAsync devam edemiyor.
Bu arada, denetim AccessTheWebAsync çağırana döner.
getStringTask tamamlandığında Denetim burada sürdürülür.
await işleci daha sonra getStringTask``string sonucunu alır.

Return ifadesinde bir tamsayı sonucu belirtilir. AccessTheWebAsync bekleyen Yöntemler uzunluk değerini alır.
AccessTheWebAsync , çağırma GetStringAsync arasında yapamazsa ve tamamlanmasını beklerken, aşağıdaki tek
deyime çağırarak ve bekleyen kodunuzu basitleştirebilirsiniz.

string urlContents = await client.GetStringAsync("https://docs.microsoft.com/dotnet");

Aşağıdaki özellikler, önceki örneği nasıl zaman uyumsuz bir yöntem yaptığını özetler:
Yöntem imzası bir async değiştiricisi içerir.
Zaman uyumsuz yöntemin adı kurala göre "Async" soneki ile sona erer.
Dönüş türü aşağıdaki türlerden biridir:
yönteminizin TResult tür olan bir return ifadesine sahipseniz Task<TResult>.
yönteminizin Return bildirisi yoksa veya işleneni olmayan bir return ifadesine sahipse Task.
zaman uyumsuz bir olay işleyicisi yazıyorsanız void .
GetAwaiter yöntemi olan diğer herhangi bir tür (7,0 ile C# başlayarak).
Daha fazla bilgi için bkz. dönüş türleri ve parametreleri bölümü.
Yöntemi genellikle, beklenen zaman uyumsuz işlem tamamlanana kadar yöntemin devam edemediği bir
noktayı işaretleyen en az bir await ifadesi içerir. Bu sırada yöntem askıya alınır ve denetim yöntemi arayana
döner. Bu konunun sonraki bölümünde askıya alma noktasında neler olduğu gösterilmektedir.
Zaman uyumsuz yöntemlerde ne yapmak istediğinizi belirtmek için sağlanan anahtar sözcükleri ve türleri
kullanırsınız ve denetim, askıya alınan bir yöntemde await noktasına geldiğinde olması gerekenlerin izlenmesi dahil
olmak üzere geri kalan işlemleri derleyici yapar. Döngüler ve özel durum işleme gibi bazı rutin işlemlerin geleneksel
zaman uyumsuz kodla yapılması zor olabilir. Zaman uyumsuz bir yöntemde, bu öğeleri olabildiğince zaman
uyumlu çözümde yazarsınız ve sorun çözülür.
.NET Framework önceki sürümlerinde zaman uyumsuzluğu hakkında daha fazla bilgi için bkz. TPL ve geleneksel
.NET Framework zaman uyumsuz programlama.

Zaman uyumsuz bir yöntemde ne olur?


Zaman uyumsuz programlama ile ilgili olarak anlamanız gereken en önemli şey, denetim akışının yöntemden
yönteme nasıl geçtiğidir. Aşağıdaki diyagramda süreç boyunca size yol gösterir:

Diyagramdaki sayılar, Kullanıcı "Başlat" düğmesine tıkladığında başlatılan aşağıdaki adımlara karşılık gelir.
1. Bir olay işleyicisi, AccessTheWebAsync zaman uyumsuz yöntemini çağırır ve bekler.
2. AccessTheWebAsync bir HttpClient örneği oluşturur ve bir Web sitesinin içeriğini bir dize olarak indirmek için
GetStringAsync zaman uyumsuz yöntemini çağırır.
3. GetStringAsync ilerleme durumunu askıya alan bir sorun oluşur. Bir web sitesinin indirmesini veya başka bir
engelleyen etkinliği beklemesi gerekebilir. Kaynakları engellemeyi önlemek için GetStringAsync ,
AccessTheWebAsync çağıranına denetim verir.

GetStringAsync , TResult bir dize olduğu ve AccessTheWebAsync görevi getStringTask değişkenine atayan
bir Task<TResult>döndürür. Görev, iş tamamlandığında gerçek bir dize değeri üretme taahhüdünde
GetStringAsync çağrısı için devam eden işlemi temsil eder.

4. getStringTask henüz beklenmediği için, AccessTheWebAsync GetStringAsync son sonucuna bağlı olmayan
diğer çalışmalarla devam edebilir. Bu iş, zaman uyumlu Yöntem DoIndependentWork çağrısıyla temsil edilir.
5. DoIndependentWork , işini yapan ve çağırana döndüren zaman uyumlu bir yöntemdir.
6. AccessTheWebAsync , getStringTask bir sonuç olmadan yapabilmeden iş dışında çalışıyor. AccessTheWebAsync ,
indirilen dizenin uzunluğunu hesaplamak ve döndürmek istiyor, ancak yöntem dizeye gelinceye kadar bu
değeri hesaplayamaz.
Bu nedenle, AccessTheWebAsync ilerlemesini askıya almak ve denetimi AccessTheWebAsync çağıran yönteme
bırakmak için bir Await işleci kullanır. AccessTheWebAsync , çağırana bir Task<int> döndürür. Görev, indirilen
dizenin uzunluğu olan bir tamsayı sonucu verecek bir taahhüdü temsil eder.

NOTE
GetStringAsync (ve bu nedenle getStringTask ) AccessTheWebAsync önünde bekleden önce tamamlanırsa
denetim AccessTheWebAsync kalır. Çağrılan zaman uyumsuz işlem ( getStringTask ) zaten tamamlanmışsa ve
AccessTheWebAsync nihai sonucu beklemek zorunda değilse, AccessTheWebAsync askıya alma ve sonra geri dönme
gideri harcanacaktır.

Arayanın içinde (bu örnekte olay işleyicisi), işleme düzeni devam eder. Çağıran, sonucu beklemeden önce
AccessTheWebAsync sonucu üzerinde bağlı olmayan başka işler, veya arayanın anında bekleme yapması
istenebilir. Olay işleyicisi AccessTheWebAsync bekliyor ve AccessTheWebAsync GetStringAsync bekliyor.
7. GetStringAsync tamamlanır ve bir dize sonucu üretir. Dize sonucu, GetStringAsync çağrısı tarafından,
bekleneceğiniz şekilde döndürülmedi. (Metodun adım 3 ' te bir görevi zaten döndürdüğünü unutmayın.)
Bunun yerine, dize sonucu, yönteminin tamamlandığını temsil eden görevde saklanır getStringTask . Await
işleci getStringTask sonucu alır. Atama ekstresi, alınan sonucu urlContents atar.
8. AccessTheWebAsync dize sonucu olduğunda, yöntemi dizenin uzunluğunu hesaplayabilir. AccessTheWebAsync
çalışması da tamamlanır ve bekleyen olay işleyicisi de sürdürülür. Konunun sonundaki tam örnekte olay
işleyicisinin uzunluk sonucundaki değeri aldığını ve yazdığını onaylayabilirsiniz. Zaman uyumsuz
programlama konusunda yeniyseniz, zaman uyumlu ve zaman uyumsuz davranış arasındaki farkları
değerlendirmek için bir dakikanızı ayırın. Zaman uyumlu yöntem, işi tamamlandığında döndürür (5. adım),
ancak zaman uyumsuz bir yöntem işi askıya alındığında görev değeri döndürür (3 ve 6. adım). Zaman
uyumsuz yöntem çalışmasını tamamladığında görev tamamlandı olarak işaretlenir ve varsa sonuç görevde
depolanır.
Denetim akışı hakkında daha fazla bilgi için bkz. zaman uyumsuz programlarda denetim akışıC#().

API zaman uyumsuz yöntemleri


Zaman uyumsuz programlamayı destekleyen GetStringAsync gibi yöntemlerin nerede bulunacağını merak ediyor
olabilirsiniz. .NET Framework 4,5 veya üzeri ve .NET Core async ve await birlikte çalışan birçok üye içerir. Bunları,
üye adına eklenen "Async" sonekiyle ve Task ya da Task<TResult>dönüş türlerine göre tanıyabilirsiniz. Örneğin
System.IO.Stream sınıfı, CopyToAsync, ReadAsyncve WriteAsync zaman uyumlu yöntemler CopyTo, Readve
Writegibi yöntemleri içerir.
Windows Çalışma Zamanı ayrıca Windows uygulamalarında async ve await ile kullanabileceğiniz birçok yöntem
içerir. Daha fazla bilgi için bkz. UWP geliştirme için Iş parçacığı ve zaman uyumsuz programlama ve zaman
uyumsuz programlama (Windows Mağazası uygulamaları) ve hızlı başlangıç: Windows çalışma zamanı önceki
sürümlerini kullanıyorsanız, C# veya Visual Basic zaman uyumsuz API 'leri çağırma .

Akışları
Zaman uyumsuz yöntemlerin engelleyici olmayan işlemler olmaları amaçlanmıştır. Zaman uyumsuz bir yöntemde
await ifadesi, beklenen görev çalışırken geçerli iş parçacığını engellemez. Bunun yerine ifade, yöntemin geri
kalanını yöntemin devamı olarak imzalar ve denetimi zaman uyumsuz yöntemi arayan kişiye verir.
async ve await anahtar sözcükleri ek iş parçacıklarının oluşturulmasına neden olmaz. Zaman uyumsuz yöntem
kendi iş parçacığı üzerinde çalışmadığı için zaman uyumsuz yöntemler çoklu iş parçacığı kullanımı gerektirmez.
Yöntem geçerli eşitleme kapsamının üzerinde çalışır ve yalnızca yöntem etkin olduğunda iş parçacığındaki zamanı
kullanır. CPU 'ya bağlanan işi arka plan iş parçacığına taşımak için Task.Run kullanabilirsiniz, ancak arka plan iş
parçacığı yalnızca sonuçların kullanılabilir hale gelmesini bekleyen bir işlem konusunda yardımcı olmaz.
Zaman uyumsuz programlamaya zaman uyumsuz yaklaşım, hemen hemen her durumda varolan yaklaşımlara
tercih edilir. Özellikle, bu yaklaşım, kod daha basit olduğundan ve yarış koşullarına karşı koruma sağlamak zorunda
olmadığınızdan g/ç 'ye bağlanacak işlemler için BackgroundWorker sınıfından daha iyidir. Task.Run yöntemi ile
birlikte zaman uyumsuz programlama, CPU 'ya bağlanan işlemler için BackgroundWorker daha iyidir, çünkü
zaman uyumsuz programlama, kodunuzun iş parçacığı temelli olarak Task.Run aktardığı işten kod çalıştırmanın
koordinasyon ayrıntılarını ayırır.

Async ve await
Zaman uyumsuz değiştirici kullanarak bir yöntemin zaman uyumsuz bir yöntem olduğunu belirtirseniz, aşağıdaki
iki özelliği etkinleştirirsiniz.
İşaretlenen zaman uyumsuz yöntem, askıya alma noktaları belirlemek için await kullanabilir. await işleci
derleyiciye zaman uyumsuz yöntemin, zaman uyumsuz işlem tamamlanana kadar bu noktanın ötesine
devam edemeyeceğini söyler. Bu sırada denetim, zaman uyumsuz yönteminin arayanına döner.
Bir await ifadesinde zaman uyumsuz bir yöntemin askıya alınması yöntemden bir çıkış oluşturmaz ve
finally blokları çalışmaz.
İşaretli zaman uyumsuz yöntem, kendisinin çağırdığı yöntemler tarafından bekleniyor olabilir.
Zaman uyumsuz bir yöntem, genellikle bir await işlecinin bir veya daha fazla örneğini içerir, ancak await
ifadelerinin yokluğu bir derleyici hatasına neden olmaz. Zaman uyumsuz bir yöntem, askıya alma noktasını
işaretlemek için await işleci kullanmıyorsa, yöntem, async değiştiriciye rağmen zaman uyumlu bir yöntem olarak
yürütülür. Derleyici bu tür yöntemler için bir uyarı verir.
async ve await bağlamsal anahtar sözcüklerdir. Daha fazla bilgi ve örnek için aşağıdaki konulara bakın:
async
await

Dönüş türleri ve parametreleri


Zaman uyumsuz bir yöntem genellikle bir Task veya Task<TResult>döndürür. Zaman uyumsuz bir yöntem içinde,
başka bir zaman uyumsuz metoda yapılan çağrıdan döndürülen bir göreve await işleci uygulanır.
Yöntem TResult türünde bir işleneni belirten bir return bildirisini içeriyorsa, dönüş türü olarak Task<TResult>
belirtirsiniz.
Metodun Return ifadesine sahip olmaması veya bir işleneni döndürmeyen bir return ifadesine sahip olması
durumunda dönüş türü olarak Task kullanırsınız.
7,0 ile C# başlayarak, türün bir GetAwaiter yöntemi içermesi şartıyla, başka bir dönüş türü de belirtebilirsiniz.
ValueTask<TResult> bu tür bir örnektir. System. Threading. Tasks. Extension NuGet paketinde kullanılabilir.
Aşağıdaki örnek, bir Task<TResult> veya Taskdöndüren bir yöntemi nasıl bildirmenizi ve çağırakullanacağınızı
gösterir:

// Signature specifies Task<TResult>


async Task<int> GetTaskOfTResultAsync()
{
int hours = 0;
await Task.Delay(0);
// Return statement specifies an integer result.
return hours;
}

// Calls to GetTaskOfTResultAsync
Task<int> returnedTaskTResult = GetTaskOfTResultAsync();
int intResult = await returnedTaskTResult;
// or, in a single statement
int intResult = await GetTaskOfTResultAsync();

// Signature specifies Task


async Task GetTaskAsync()
{
await Task.Delay(0);
// The method has no return statement.
}

// Calls to GetTaskAsync
Task returnedTask = GetTaskAsync();
await returnedTask;
// or, in a single statement
await GetTaskAsync();

Döndürülmüş her görev, devam eden bir çalışmayı temsil eder. Bir görev, zaman uyumsuz işlemin durumu
hakkındaki bilgileri saklar ve sonunda, işlemden alınan nihai sonuca veya başarısız olursa işlemin neden olduğu bir
özel duruma ilişkin bilgileri içerir.
Zaman uyumsuz bir yöntem void dönüş türüne de sahip olabilir. Bu dönüş türü, öncelikle void dönüş türünün
gerekli olduğu olay işleyicilerini tanımlamak için kullanılır. Zaman uyumsuz olay işleyicileri, genellikle zaman
uyumsuz programlar için başlangıç noktası olarak hizmet eder.
void dönüş türüne sahip bir zaman uyumsuz yöntem beklenemez ve void döndüren bir yöntemi çağıran
yöntemin aldığı özel durumları yakalayabilir.
Zaman uyumsuz bir yöntem içinde, ref veya Out parametrelerini bildiremez, ancak yöntem bu parametrelere sahip
yöntemleri çağırabilir. Benzer şekilde, zaman uyumsuz bir yöntem başvuruya göre değer döndüremez, ancak
başvuru dönüş değerleri içeren yöntemler çağırabilir.
Daha fazla bilgi ve örnek için bkz. Async Return TypesC#(). Zaman uyumsuz yöntemlerde özel durumları yakalama
hakkında daha fazla bilgi için bkz. try-catch.
Windows Çalışma Zamanı programlamadaki zaman uyumsuz API 'Ler, görevlerle benzer olan aşağıdaki dönüş
türlerinden birine sahiptir:
Task<TResult> karşılık gelen IAsyncOperation<TResult>
Task karşılık gelen IAsyncAction
IAsyncActionWithProgress<TProgress>
IAsyncOperationWithProgress<TResult, TProgress>

Adlandırma kuralı
Kural gereği, genellikle zaman uyumsuz türler (örn. Task , Task<T> , ValueTask , ValueTask<T> ) döndüren
yöntemler "Async" ile biten adlara sahip olmalıdır. Zaman uyumsuz bir işlem Başlatan ancak bir awasever türü
döndürmeyen Yöntemler, "Async" ile biten adlara sahip olmamalıdır, ancak bu yöntemin işlemin sonucunu
döndürmeyeceğini veya oluşturmadığını önermek için "BEGIN", "Start" ya da başka bir fiil ile başlayabilir.
Bir olay, taban sınıf veya arabirim sözleşmesi farklı bir ad öneriyorsa kuralı yoksayabilirsiniz. Örneğin,
Button1_Click gibi yaygın olay işleyicilerini yeniden adlandırmamanız gerekir.

İlgili konular ve örnekler (Visual Studio)


BAŞLIK AÇIKLAMA ÖRNEK

İzlenecek yol: Async ve await (C#) Zaman uyumlu bir WPF çözümünü Zaman uyumsuz örnek: Web 'e erişme
kullanarak Web 'e erişme zaman uyumsuz bir WPF çözümüne yolu
nasıl dönüştüreceğinizi gösterir.
Uygulama bir dizi web sitesi indirir.

Task. WhenAll (C#) kullanarak zaman Önceki izlenecek yolu Task.WhenAll


uyumsuz izlenecek yolu genişletme ekler. WhenAll kullanımı, tüm
indirmeleri aynı anda başlatır.

Async ve await (C#) kullanarak birden Nasıl aynı anda birkaç görevi Zaman uyumsuz örnek: birden çok Web
çok web isteğini paralel hale getirme başlatacağınızı gösterir. Isteğini paralel hale getirme

Zaman uyumsuz dönüş türleriC#() Zaman uyumsuz yöntemlerin


döndürebileceği türleri gösterir ve her
türün ne zaman uygun olduğunu açıklar.

Zaman uyumsuz programlarda denetim Ayrıntılı olarak birbirini izleyenler Async örneği: zaman uyumsuz
akışı (C#) aracılığıyla denetim akışını izler ve programlarda denetim akışı
zaman uyumsuz bir program ifadesi
bekler.

Zaman uyumsuz uygulamanızda ince Zaman uyumsuz çözümünüze aşağıdaki Zaman uyumsuz örnek: uygulamanıza
ayar yapma (C#) işlevin nasıl ekleneceğini gösterir: Ince ayar yapma

zaman uyumsuz bir görevi veya görev


listesini Iptal etme - (C#)
zaman uyumsuz görevleri bir süre sonra
iptal - (C#)
- tamamlandıktan sonra kalan zaman
uyumsuz görevleri Iptal et (C#)
- birden çok zaman uyumsuz görev
başlatın ve bunları tamamlarsa (C#)
işleyin

Zaman uyumsuz uygulamalarda Çalışırken etkin bir zaman uyumsuz


yeniden girişi işleme (C#) işlemin yeniden başlatılma durumlarının
nasıl işleneceğini gösterir.
BAŞLIK AÇIKLAMA ÖRNEK

WhenAny: .NET Framework ve Windows Bir Windows Çalışma Zamanı Zaman uyumsuz örnek: .NET ile
Çalışma Zamanı arasında köprü yöntemiyle WhenAny kullanabilmeniz Windows Çalışma Zamanı arasında
oluşturma için, Windows Çalışma Zamanı .NET köprü oluşturma (AsTask ve WhenAny)
Framework ve IAsyncOperations
içindeki görev türleri arasında nasıl
köprü oluşturulacağını gösterir.

Zaman Uyumsuz İptal: .NET Framework Bir Windows Çalışma Zamanı Zaman uyumsuz örnek: .NET ve
ve Windows Çalışma Zamanı arasında yöntemiyle CancellationTokenSource Windows Çalışma Zamanı arasında
köprü oluşturma kullanabilmeniz için, Windows Çalışma köprü oluşturma (AsTask & Iptali)
Zamanı .NET Framework ve
IAsyncOperations içindeki görev türleri
arasında nasıl köprü oluşturulacağını
gösterir.

Dosya erişimi için Async Kullanma (C#) Dosyalara erişmek için zaman uyumsuz
yöntemin ve await işlecinin
kullanılmasına ilişkin avantajları listeler
ve gösterir.

Görev Tabanlı Zaman Uyumsuz Desen .NET Framework'te zaman uyumsuzluk


(TAP) için yeni bir düzen açıklar. Desenler Task
ve Task<TResult> türlerini temel alır.

Channel 9 ' da zaman uyumsuz videolar Zaman uyumsuz programlama hakkında


çeşitli videoların bağlantılarını sağlar.

Örnek Tamam
Aşağıdaki kod, bu makalede ele alınan WPF uygulamasından gelen MainWindow.xaml.cs dosyasıdır. Örneği zaman
uyumsuz örnek: "Async ve await Ile zaman uyumsuz programlama" kaynağındanindirebilirsiniz.

using System;
using System.Threading.Tasks;
using System.Windows;

// Add a using directive and a reference for System.Net.Http;


using System.Net.Http;

namespace AsyncFirstExample
{
public partial class MainWindow : Window
{
// Mark the event handler with async so you can use await in it.
private async void StartButton_Click(object sender, RoutedEventArgs e)
{
// Call and await separately.
//Task<int> getLengthTask = AccessTheWebAsync();
//// You can do independent work here.
//int contentLength = await getLengthTask;

int contentLength = await AccessTheWebAsync();

resultsTextBox.Text +=
$"\r\nLength of the downloaded string: {contentLength}.\r\n";
}

// Three things to note in the signature:


// - The method has an async modifier.
// - The method has an async modifier.
// - The return type is Task or Task<T>. (See "Return Types" section.)
// Here, it is Task<int> because the return statement returns an integer.
// - The method name ends in "Async."
async Task<int> AccessTheWebAsync()
{
// You need to add a reference to System.Net.Http to declare client.
var client = new HttpClient();

// GetStringAsync returns a Task<string>. That means that when you await the
// task you'll get a string (urlContents).
Task<string> getStringTask = client.GetStringAsync("https://docs.microsoft.com/dotnet");

// You can do work here that doesn't rely on the string from GetStringAsync.
DoIndependentWork();

// The await operator suspends AccessTheWebAsync.


// - AccessTheWebAsync can't continue until getStringTask is complete.
// - Meanwhile, control returns to the caller of AccessTheWebAsync.
// - Control resumes here when getStringTask is complete.
// - The await operator then retrieves the string result from getStringTask.
string urlContents = await getStringTask;

// The return statement specifies an integer result.


// Any methods that are awaiting AccessTheWebAsync retrieve the length value.
return urlContents.Length;
}

void DoIndependentWork()
{
resultsTextBox.Text += "\r\nWorking . . . . . . .\r\n";
}
}
}

// Sample Output:

// Working . . . . . . .

// Length of the downloaded string: 41564.

Ayrıca bkz.
async
await
Zaman uyumsuz programlama
Zaman uyumsuz genel bakış
İzlenecek yol: Async ve await (C#) kullanarak Web 'e
erişme
27.11.2019 • 25 minutes to read • Edit Online

Zaman uyumsuz programları, zaman uyumsuz/await özelliklerini kullanarak daha kolay ve daha canlı bir şekilde
yazabilirsiniz. Zaman uyumlu kod gibi görünen zaman uyumsuz kod yazabilir ve derleyicinin zaman uyumsuz
kodun genellikle sahip olduğu zor geri çağırma işlevlerini ve devamlılığını işlemesini sağlayabilirsiniz.
Zaman uyumsuz özellik hakkında daha fazla bilgi için bkz. Async ve await (C#) Ile zaman uyumsuz
programlama.
Bu izlenecek yol, bir Web sitesi listesindeki bayt sayısını toplayan bir zaman uyumlu Windows Presentation
Foundation (WPF ) uygulamasıyla başlar. İzlenecek yol, yeni özellikleri kullanarak uygulamayı zaman uyumsuz
bir çözüme dönüştürür.
Uygulamaları kendiniz derlemek istemiyorsanız, zaman uyumsuz örneği indirebilirsinizC# : Web 'e (ve Visual
Basic) erişme.

NOTE
Örnekleri çalıştırmak için, bilgisayarınızda Visual Studio 2012 veya daha yeni bir sürümü ve .NET Framework 4,5 ya da
daha yeni bir sürümü yüklü olmalıdır.

WPF uygulaması oluşturma


1. Visual Studio’yu çalıştırın.
2. Menü çubuğunda dosya > Yeni > Proje' yi seçin.
Yeni proje iletişim kutusu açılır.
3. Yüklü şablonlar bölmesinde, görsel C#' i seçin ve ardından Proje türleri listesinden WPF uygulaması '
nı seçin.
4. Ad metin kutusuna AsyncExampleWPF girin ve sonra Tamam düğmesini seçin.
Yeni proje Çözüm Gezginigörüntülenir.

Basit bir WPF MainWindow tasarımı


1. Visual Studio Code düzenleyicisinde MainWindow. xaml sekmesini seçin.
2. Araç kutusu penceresi görünür değilse, Görünüm menüsünü açın ve ardından araç kutusu' nu seçin.
3. MainWindow penceresine bir Button denetimi ve TextBox denetimi ekleyin.
4. TextBox denetimini vurgulayın ve Özellikler penceresinde aşağıdaki değerleri ayarlayın:
Name özelliğini resultsTextBox olarak ayarlayın.
Height özelliğini 250 olarak ayarlayın.
Width özelliğini 500 olarak ayarlayın.
Metin sekmesinde, Lucida Console veya Global tek boşluk gibi tek boşluklu bir yazı tipi belirtin.
5. Düğme denetimini vurgulayın ve Özellikler penceresinde aşağıdaki değerleri ayarlayın:
Name özelliğini startButton olarak ayarlayın.
İçerik özelliğinin değerini düğmeden başlaolarak değiştirin.
6. Metin kutusunu ve düğmeyi her ikisinin de MainWindow penceresinde görünmesi için konumlandırın.
WPF XAML Tasarımcısı hakkında daha fazla bilgi için, bkz. XAML Tasarımcısı kullanarak Kullanıcı
arabirimi oluşturma.

Başvuru ekleme
1. Çözüm Gezgini, projenizin adını vurgulayın.
2. Menü çubuğunda, proje > Başvuru Ekle' yi seçin.
Başvuru Yöneticisi iletişim kutusu görüntülenir.
3. İletişim kutusunun üst kısmında, projenizin .NET Framework 4,5 veya üstünü hedeflediğinden emin olun.
4. Derlemeler kategorisinde, zaten seçili değilse Framework ' ü seçin.
5. Ad listesinde, System .net. http onay kutusunu seçin.
6. İletişim kutusunu kapatmak için Tamam düğmesini seçin.

Gerekli yönergeleri kullanarak ekleme


1. Çözüm Gezgini' de, MainWindow.xaml.cs için kısayol menüsünü açın ve kodu görüntüle' yi seçin.
2. Zaten mevcut değilse, kod dosyasının en üstüne aşağıdaki using yönergelerini ekleyin.

using System.Net.Http;
using System.Net;
using System.IO;

Zaman uyumlu uygulama oluşturma


1. Tasarım penceresinde, MainWindow. xaml, MainWindow.xaml.cs içinde startButton_Click olay
işleyicisini oluşturmak için Başlat düğmesine çift tıklayın.
2. MainWindow.xaml.cs ' de, aşağıdaki kodu startButton_Click gövdesine kopyalayın:

resultsTextBox.Clear();
SumPageSizes();
resultsTextBox.Text += "\r\nControl returned to startButton_Click.";

Kod, uygulamayı yönlendiren yöntemi çağırır, SumPageSizes ve denetim startButton_Click döndüğünde


bir ileti görüntüler.
3. Zaman uyumlu çözüm kodu aşağıdaki dört yöntemi içerir:
SumPageSizes , SetUpURLList Web sayfası URL 'Lerinin bir listesini alır ve sonra her bir URL 'YI
işlemek için GetURLContents ve DisplayResults çağırır.
SetUpURLList , Web adreslerinin bir listesini oluşturan ve döndüren.
Her Web sitesinin içeriğini indiren ve bir bayt dizisi olarak içeriği döndüren GetURLContents .
her URL için bayt dizisindeki bayt sayısını görüntüleyen DisplayResults .
Aşağıdaki dört yöntemi kopyalayın ve ardından MainWindow.xaml.cs ' de startButton_Click olay
işleyicisi altına yapıştırın:

private void SumPageSizes()


{
// Make a list of web addresses.
List<string> urlList = SetUpURLList();

var total = 0;
foreach (var url in urlList)
{
// GetURLContents returns the contents of url as a byte array.
byte[] urlContents = GetURLContents(url);

DisplayResults(url, urlContents);

// Update the total.


total += urlContents.Length;
}

// Display the total count for all of the web addresses.


resultsTextBox.Text += $"\r\n\r\nTotal bytes returned: {total}\r\n";
}

private List<string> SetUpURLList()


{
var urls = new List<string>
{
"https://msdn.microsoft.com/library/windows/apps/br211380.aspx",
"https://msdn.microsoft.com",
"https://msdn.microsoft.com/library/hh290136.aspx",
"https://msdn.microsoft.com/library/ee256749.aspx",
"https://msdn.microsoft.com/library/hh290138.aspx",
"https://msdn.microsoft.com/library/hh290140.aspx",
"https://msdn.microsoft.com/library/dd470362.aspx",
"https://msdn.microsoft.com/library/aa578028.aspx",
"https://msdn.microsoft.com/library/ms404677.aspx",
"https://msdn.microsoft.com/library/ff730837.aspx"
};
return urls;
}

private byte[] GetURLContents(string url)


{
// The downloaded resource ends up in the variable named content.
var content = new MemoryStream();

// Initialize an HttpWebRequest for the current URL.


var webReq = (HttpWebRequest)WebRequest.Create(url);

// Send the request to the Internet resource and wait for


// the response.
// Note: you can't use HttpWebRequest.GetResponse in a Windows Store app.
using (WebResponse response = webReq.GetResponse())
{
// Get the data stream that is associated with the specified URL.
using (Stream responseStream = response.GetResponseStream())
{
// Read the bytes in responseStream and copy them to content.
responseStream.CopyTo(content);
}
}

// Return the result as a byte array.


// Return the result as a byte array.
return content.ToArray();
}

private void DisplayResults(string url, byte[] content)


{
// Display the length of each website. The string format
// is designed to be used with a monospaced font, such as
// Lucida Console or Global Monospace.
var bytes = content.Length;
// Strip off the "https://".
var displayURL = url.Replace("https://", "");
resultsTextBox.Text += $"\n{displayURL,-58} {bytes,8}";
}

Zaman uyumlu çözümü test etme


Programı çalıştırmak için F5 tuşunu seçin ve sonra Başlat düğmesini seçin.
Aşağıdaki listeye benzer bir çıktı görünmelidir:

msdn.microsoft.com/library/windows/apps/br211380.aspx 383832
msdn.microsoft.com 33964
msdn.microsoft.com/library/hh290136.aspx 225793
msdn.microsoft.com/library/ee256749.aspx 143577
msdn.microsoft.com/library/hh290138.aspx 237372
msdn.microsoft.com/library/hh290140.aspx 128279
msdn.microsoft.com/library/dd470362.aspx 157649
msdn.microsoft.com/library/aa578028.aspx 204457
msdn.microsoft.com/library/ms404677.aspx 176405
msdn.microsoft.com/library/ff730837.aspx 143474

Total bytes returned: 1834802

Control returned to startButton_Click.

Sayıları görüntülemenin birkaç saniye sürdiğine dikkat edin. Bu süre boyunca, Kullanıcı arabirimi iş parçacığı
istenen kaynakların indirilmesini beklerken engellenir. Sonuç olarak, Başlat düğmesini seçtikten sonra görüntü
penceresini taşıyamaz, ekranı kaplamaz, simge durumuna küçültebilir ya da kapatabilirsiniz. Bu çalışmalar, bayt
sayıları görünene kadar başarısız olur. Bir Web sitesi yanıt vermiyorsa, hangi sitenin başarısız olduğunun belirtii
olmaz. Beklemeyi durdurup programı kapatmanız zordur.

GetURLContents öğesini zaman uyumsuz bir metoda Dönüştür


1. Zaman uyumlu çözümü zaman uyumsuz bir çözüme dönüştürmek için en iyi GetURLContents ,
HttpWebRequest yöntemine GetResponse ve Stream CopyTo yöntemine yapılan çağrılar uygulamanın
Web 'e eriştiği yerdir. .NET Framework, her iki yöntemin de zaman uyumsuz sürümlerini sağlayarak
dönüştürmeyi kolaylaştırır.
GetURLContents ' de kullanılan yöntemler hakkında daha fazla bilgi için bkz. WebRequest.

NOTE
Bu izlenecek yolda bulunan adımları izleyerek bazı derleyici hataları görüntülenir. Bunları yoksayabilir ve İzlenecek
yol ile devam edebilirsiniz.

GetURLContentsüçüncü satırındaki GetResponse zaman uyumsuz, görev tabanlı GetResponseAsync


metoduna olan yöntemi değiştirin.
using (WebResponse response = webReq.GetResponseAsync())

2. GetResponseAsync Task<TResult>döndürür. Bu durumda, görev dönüş değişkeni TResult ,


WebResponsetürü vardır. Görev, istenen veriler indirildikten ve görevin tamamlanmasını çalıştırdıktan
sonra gerçek bir WebResponse nesnesi oluşturmak için bir taahhüddir.
Görevden WebResponse değerini almak için aşağıdaki kodda gösterildiği gibi, GetResponseAsync çağrısına
bir await işleci uygulayın.

using (WebResponse response = await webReq.GetResponseAsync())

await işleci, beklenen görev tamamlanana kadar, GetURLContents geçerli metodun yürütülmesini askıya
alır. Bu arada, Denetim geçerli yöntemi çağırana döner. Bu örnekte, geçerli yöntem GetURLContents ve
arayan SumPageSizes . Görev tamamlandığında, taahhüt edilen WebResponse nesnesi, beklenen görevin
değeri olarak üretilir ve response değişkenine atanır.
Önceki deyim, ne olacağını açıklamak için aşağıdaki iki ifadeye ayrılabilir.

//Task<WebResponse> responseTask = webReq.GetResponseAsync();


//using (WebResponse response = await responseTask)

webReq.GetResponseAsync çağrısı Task(Of WebResponse) veya Task<WebResponse> döndürür. Sonra,


WebResponse değerini almak için göreve bir Await işleci uygulanır.
Zaman uyumsuz yönteminiz görevin tamamlanmasına bağlı değilse, bu iki deyim arasında, zaman
uyumsuz metoda yapılan çağrıdan sonra ve await işleci uygulanmadan önce bu iki deyim arasında bu
işe devam edebilir. Örnekler için bkz. Async ve awaitC#() kullanarak birden çok web isteğini paralel hale
getirme ve Task. WhenAll (C#) kullanarak zaman uyumsuz izlenecek yolu genişletme.
3. Önceki adımda await işlecini eklediğiniz için bir derleyici hatası oluşur. İşleci yalnızca zaman uyumsuz
değiştiriciyle işaretlenen yöntemlerde kullanılabilir. CopyTo çağrısını CopyToAsync çağrısı ile değiştirmek
için dönüştürme adımlarını tekrarlarken hatayı yoksayın.
CopyToAsyncolarak çağrılan metodun adını değiştirin.
CopyTo veya CopyToAsync yöntemi, baytları bağımsız değişkenine content , ve anlamlı bir değer
döndürmez. Zaman uyumlu sürümde, CopyTo çağrısı bir değer döndürmeyen basit bir ifadedir.
Zaman uyumsuz sürüm CopyToAsync , bir Taskdöndürür. Görev, "Task (void)" gibi çalışır ve
yöntemin beklenmesine olanak sağlar. Aşağıdaki kodun gösterdiği gibi, CopyToAsync çağrısına
Await veya await uygulayın.

await responseStream.CopyToAsync(content);

Önceki ifade aşağıdaki iki kod satırını abbreviates.

// CopyToAsync returns a Task, not a Task<T>.


//Task copyTask = responseStream.CopyToAsync(content);

// When copyTask is completed, content contains a copy of


// responseStream.
//await copyTask;

4. GetURLContents her şey, yöntem imzasını ayarlamasıdır. await işlecini yalnızca zaman uyumsuz
değiştiriciyle işaretlenen yöntemlerde kullanabilirsiniz. Aşağıdaki kodun gösterdiği gibi, yöntemi zaman
uyumsuz bir yöntemolarak işaretlemek için değiştirici ekleyin.

private async byte[] GetURLContents(string url)

5. Zaman uyumsuz bir yöntemin dönüş türü, içinde C#yalnızca Task, Task<TResult>veya void olabilir.
Genellikle, void dönüş türü yalnızca bir zaman uyumsuz olay işleyicide kullanılır, burada void
gereklidir. Diğer durumlarda, tamamlanan yöntemin T türünde bir değer döndüren bir Return ifadesine
sahipse ve tamamlanmış Yöntem anlamlı bir değer döndürmezse Task kullandığınızda Task(T)
kullanırsınız. Task dönüş türünü anlamı "görev (void)" olarak düşünebilirsiniz.
Daha fazla bilgi için bkz. Async Return TypesC#().
GetURLContents yöntemi bir return ifadesine sahiptir ve ifade bir bayt dizisi döndürür. Bu nedenle, zaman
uyumsuz sürümün dönüş türü görev (T), burada T bir bayt dizisidir. Yöntem imzasında aşağıdaki
değişiklikleri yapın:
Dönüş türünü Task<byte[]> değiştirin.
Kurala göre, zaman uyumsuz metotların "Async" ile biten adları vardır. GetURLContentsAsync
yöntemi yeniden adlandırın.
Aşağıdaki kod bu değişiklikleri gösterir.

private async Task<byte[]> GetURLContentsAsync(string url)

Bu az değişiklikle, zaman uyumsuz bir metoda GetURLContents dönüştürmesi tamamlanmıştır.

Sumpageslikleri zaman uyumsuz bir metoda Dönüştür


1. SumPageSizes için önceki yordamdaki adımları tekrarlayın. İlk olarak, GetURLContents çağrısını zaman
uyumsuz bir çağrıya değiştirin.
Daha önce yapmadıysanız, GetURLContents GetURLContentsAsync olarak çağrılan metodun adını
değiştirin.
Bayt dizi değerini almak için GetURLContentsAsync döndüren göreve await uygulayın.
Aşağıdaki kod bu değişiklikleri gösterir.

byte[] urlContents = await GetURLContentsAsync(url);

Önceki atama, aşağıdaki iki kod satırını abbreviates.

// GetURLContentsAsync returns a Task<T>. At completion, the task


// produces a byte array.
//Task<byte[]> getContentsTask = GetURLContentsAsync(url);
//byte[] urlContents = await getContentsTask;

2. Yöntemin imzasında aşağıdaki değişiklikleri yapın:


Yöntemi async değiştiricisiyle işaretleyin.
Yöntem adına "Async" ekleyin.
SumPageSizesAsync T için bir değer döndürmediğinden, bu kez bir görev dönüş değişkeni yok.
(yöntemin hiçbir return bildirisi yok.) Ancak, yönteminin bir Task olması gerekir. Bu nedenle,
void yönteminin dönüş türünü Task olarak değiştirin.

Aşağıdaki kod bu değişiklikleri gösterir.

private async Task SumPageSizesAsync()

SumPageSizes SumPageSizesAsync dönüşümü tamamlanmıştır.

StartButton_Click zaman uyumsuz bir metoda Dönüştür


1. Daha önce yapmadıysanız, olay işleyicisinde SumPageSizes çağrılan yöntemin adını SumPageSizesAsync
olarak değiştirin.
2. SumPageSizesAsync zaman uyumsuz bir yöntem olduğundan, olay işleyicisindeki kodu, sonucu beklemek
için değiştirin.
SumPageSizesAsync çağrısı, GetURLContentsAsync``CopyToAsync çağrısını yansıtır. Çağrı bir Task(T) değil
Task döndürür.
Önceki yordamlarda olduğu gibi, çağrıyı tek bir deyim veya iki deyim kullanarak dönüştürebilirsiniz.
Aşağıdaki kod bu değişiklikleri gösterir.

// One-step async call.


await SumPageSizesAsync();

// Two-step async call.


//Task sumTask = SumPageSizesAsync();
//await sumTask;

3. İşlemi yanlışlıkla yeniden girmeye engel olmak için, Başlangıç düğmesini devre dışı bırakmak üzere
startButton_Click en üstüne aşağıdaki ifadeyi ekleyin.

// Disable the button until the operation is complete.


startButton.IsEnabled = false;

Olay işleyicisinin sonundaki düğmeyi yeniden etkinleştirebilirsiniz.

// Reenable the button in case you want to run the operation again.
startButton.IsEnabled = true;

Yeniden giriş hakkında daha fazla bilgi için bkz. zaman uyumsuz uygulamalarda yeniden girişi işlemeC#().
4. Son olarak, async değiştiricisini bildirime ekleyerek olay işleyicisinin SumPagSizesAsync bekleymasını
sağlayabilirsiniz.

private async void startButton_Click(object sender, RoutedEventArgs e)

Genellikle, olay işleyicilerinin adları değiştirilmez. Olay işleyicilerinin void döndürmesi gerektiğinden,
dönüş türü Task olarak değiştirilmez.
Projenin zaman uyumlu olarak zaman uyumsuz işlemeye dönüştürülmesi işlemi tamamlanır.

Zaman uyumsuz çözümü test etme


1. Programı çalıştırmak için F5 tuşunu seçin ve sonra Başlat düğmesini seçin.
2. Zaman uyumlu çözümün çıktısına benzeyen çıkış görünmelidir. Ancak, aşağıdaki farklılıklara dikkat edin.
İşlem tamamlandıktan sonra sonuçların hepsi aynı anda gerçekleşmiyor. Örneğin, her iki program
de startButton_Click metin kutusunu temizleyen bir çizgi içerir. Tek bir sonuç kümesi
görüntülendikten sonra Başlat düğmesini ikinci bir kez seçerseniz, çalıştırmalar arasındaki metin
kutusunu temizlemek amaç. Zaman uyumlu sürümde, metin kutusu yalnızca sayımlar ikinci kez
görüntülenmeden önce temizlenir, İndirmeler tamamlandığında ve Kullanıcı arabirimi iş parçacığı
başka iş yapmak için ücretsizdir. Zaman uyumsuz sürümde, Başlat düğmesini seçtikten sonra
metin kutusu hemen temizlenir.
En önemlisi, indirme sırasında UI iş parçacığı engellenmiyor. Web kaynakları indirilirken, sayıldıkça
ve görüntülenirken pencereyi taşıyabilir veya yeniden boyutlandırabilirsiniz. Web sitelerinden biri
yavaşsa veya yanıt vermiyorsa, Kapat düğmesini (sağ üst köşedeki kırmızı alanda bulunan x)
seçerek işlemi iptal edebilirsiniz.

GetURLContentsAsync yöntemini bir .NET Framework yöntemiyle


Değiştir
1. .NET Framework 4,5, kullanabileceğiniz birçok zaman uyumsuz yöntem sağlar. Bunlardan biri olan
HttpClient yöntemi, Bu izlenecek yol için yalnızca ihtiyacınız olan GetByteArrayAsync(String). Bunu,
önceki yordamda oluşturduğunuz GetURLContentsAsync yöntemi yerine kullanabilirsiniz.
İlk adım, yöntem SumPageSizesAsync``HttpClient bir nesne oluşturmaktır. Yönteminin başlangıcında
aşağıdaki bildirimi ekleyin.

// Declare an HttpClient object and increase the buffer size. The


// default buffer size is 65,536.
HttpClient client =
new HttpClient() { MaxResponseContentBufferSize = 1000000 };

2. SumPageSizesAsync, GetURLContentsAsync yönteminizin çağrısını HttpClient yöntemine yönelik bir çağrı


ile değiştirin.

byte[] urlContents = await client.GetByteArrayAsync(url);

3. Yazdığınız GetURLContentsAsync yöntemi kaldırın veya açıklamayı kaldırın.


4. Programı çalıştırmak için F5 tuşunu seçin ve sonra Başlat düğmesini seçin.
Projenin bu sürümünün davranışı, "zaman uyumsuz çözümü test etmek Için" yordamının açıklandığı,
ancak sizin de daha az çaba gösteren davranışla eşleşmelidir.

Örnek kod
Aşağıdaki kod, yazdığınız zaman uyumsuz GetURLContentsAsync yöntemi kullanılarak zaman uyumsuz bir
çözüme dönüştürme işleminin tam örneğini içerir. Özgün, zaman uyumlu çözüme kesinlikle benzediğine dikkat
edin.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

// Add the following using directives, and add a reference for System.Net.Http.
using System.Net.Http;
using System.IO;
using System.Net;

namespace AsyncExampleWPF
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}

private async void startButton_Click(object sender, RoutedEventArgs e)


{
// Disable the button until the operation is complete.
startButton.IsEnabled = false;

resultsTextBox.Clear();

// One-step async call.


await SumPageSizesAsync();

// Two-step async call.


//Task sumTask = SumPageSizesAsync();
//await sumTask;

resultsTextBox.Text += "\r\nControl returned to startButton_Click.\r\n";

// Reenable the button in case you want to run the operation again.
startButton.IsEnabled = true;
}

private async Task SumPageSizesAsync()


{
// Make a list of web addresses.
List<string> urlList = SetUpURLList();

var total = 0;

foreach (var url in urlList)


{
byte[] urlContents = await GetURLContentsAsync(url);

// The previous line abbreviates the following two assignment statements.

// GetURLContentsAsync returns a Task<T>. At completion, the task


// produces a byte array.
//Task<byte[]> getContentsTask = GetURLContentsAsync(url);
//byte[] urlContents = await getContentsTask;

DisplayResults(url, urlContents);

// Update the total.


total += urlContents.Length;
}
// Display the total count for all of the websites.
resultsTextBox.Text +=
$"\r\n\r\nTotal bytes returned: {total}\r\n";
$"\r\n\r\nTotal bytes returned: {total}\r\n";
}

private List<string> SetUpURLList()


{
List<string> urls = new List<string>
{
"https://msdn.microsoft.com/library/windows/apps/br211380.aspx",
"https://msdn.microsoft.com",
"https://msdn.microsoft.com/library/hh290136.aspx",
"https://msdn.microsoft.com/library/ee256749.aspx",
"https://msdn.microsoft.com/library/hh290138.aspx",
"https://msdn.microsoft.com/library/hh290140.aspx",
"https://msdn.microsoft.com/library/dd470362.aspx",
"https://msdn.microsoft.com/library/aa578028.aspx",
"https://msdn.microsoft.com/library/ms404677.aspx",
"https://msdn.microsoft.com/library/ff730837.aspx"
};
return urls;
}

private async Task<byte[]> GetURLContentsAsync(string url)


{
// The downloaded resource ends up in the variable named content.
var content = new MemoryStream();

// Initialize an HttpWebRequest for the current URL.


var webReq = (HttpWebRequest)WebRequest.Create(url);

// Send the request to the Internet resource and wait for


// the response.
using (WebResponse response = await webReq.GetResponseAsync())

// The previous statement abbreviates the following two statements.

//Task<WebResponse> responseTask = webReq.GetResponseAsync();


//using (WebResponse response = await responseTask)
{
// Get the data stream that is associated with the specified url.
using (Stream responseStream = response.GetResponseStream())
{
// Read the bytes in responseStream and copy them to content.
await responseStream.CopyToAsync(content);

// The previous statement abbreviates the following two statements.

// CopyToAsync returns a Task, not a Task<T>.


//Task copyTask = responseStream.CopyToAsync(content);

// When copyTask is completed, content contains a copy of


// responseStream.
//await copyTask;
}
}
// Return the result as a byte array.
return content.ToArray();
}

private void DisplayResults(string url, byte[] content)


{
// Display the length of each website. The string format
// is designed to be used with a monospaced font, such as
// Lucida Console or Global Monospace.
var bytes = content.Length;
// Strip off the "https://".
var displayURL = url.Replace("https://", "");
resultsTextBox.Text += $"\n{displayURL,-58} {bytes,8}";
}
}
}
}

Aşağıdaki kod, GetByteArrayAsync``HttpClient yöntemini kullanan çözümün tam örneğini içerir.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

// Add the following using directives, and add a reference for System.Net.Http.
using System.Net.Http;
using System.IO;
using System.Net;

namespace AsyncExampleWPF
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}

private async void startButton_Click(object sender, RoutedEventArgs e)


{
resultsTextBox.Clear();

// Disable the button until the operation is complete.


startButton.IsEnabled = false;

// One-step async call.


await SumPageSizesAsync();

//// Two-step async call.


//Task sumTask = SumPageSizesAsync();
//await sumTask;

resultsTextBox.Text += "\r\nControl returned to startButton_Click.\r\n";

// Reenable the button in case you want to run the operation again.
startButton.IsEnabled = true;
}

private async Task SumPageSizesAsync()


{
// Declare an HttpClient object and increase the buffer size. The
// default buffer size is 65,536.
HttpClient client =
new HttpClient() { MaxResponseContentBufferSize = 1000000 };

// Make a list of web addresses.


List<string> urlList = SetUpURLList();

var total = 0;

foreach (var url in urlList)


{
// GetByteArrayAsync returns a task. At completion, the task
// GetByteArrayAsync returns a task. At completion, the task
// produces a byte array.
byte[] urlContents = await client.GetByteArrayAsync(url);

// The following two lines can replace the previous assignment statement.
//Task<byte[]> getContentsTask = client.GetByteArrayAsync(url);
//byte[] urlContents = await getContentsTask;

DisplayResults(url, urlContents);

// Update the total.


total += urlContents.Length;
}

// Display the total count for all of the websites.


resultsTextBox.Text +=
$"\r\n\r\nTotal bytes returned: {total}\r\n";
}

private List<string> SetUpURLList()


{
List<string> urls = new List<string>
{
"https://msdn.microsoft.com/library/windows/apps/br211380.aspx",
"https://msdn.microsoft.com",
"https://msdn.microsoft.com/library/hh290136.aspx",
"https://msdn.microsoft.com/library/ee256749.aspx",
"https://msdn.microsoft.com/library/hh290138.aspx",
"https://msdn.microsoft.com/library/hh290140.aspx",
"https://msdn.microsoft.com/library/dd470362.aspx",
"https://msdn.microsoft.com/library/aa578028.aspx",
"https://msdn.microsoft.com/library/ms404677.aspx",
"https://msdn.microsoft.com/library/ff730837.aspx"
};
return urls;
}

private void DisplayResults(string url, byte[] content)


{
// Display the length of each website. The string format
// is designed to be used with a monospaced font, such as
// Lucida Console or Global Monospace.
var bytes = content.Length;
// Strip off the "https://".
var displayURL = url.Replace("https://", "");
resultsTextBox.Text += $"\n{displayURL,-58} {bytes,8}";
}
}
}

Ayrıca bkz.
Zaman uyumsuz örnek: Web Walkthrough 'A erişmeC# (ve Visual Basic)
async
await
Async ve await (C#) ile zaman uyumsuz programlama
Zaman uyumsuz dönüş türleriC#()
Görev tabanlı zaman uyumsuz programlama (TAP )
Task. WhenAll (C#) kullanarak zaman uyumsuz izlenecek yolu genişletme
Async ve await (C#) kullanarak birden çok web isteğini paralel hale getirme
Task. WhenAll (C#) kullanarak zaman uyumsuz
izlenecek yolu genişletme
25.11.2019 • 13 minutes to read • Edit Online

Zaman uyumsuz çözümün performansını şu şekilde artırabilirsiniz: Task.WhenAll yöntemi kullanılarak , Async ve
await (C#) kullanarak Web 'e erişme . Bu yöntem, bir görev koleksiyonu olarak temsil edilen birden çok zaman
uyumsuz işlemi zaman uyumsuz olarak bekler.
Gözden geçirmede, Web sitelerinin farklı oranlarda indirdiğini fark etmiş olabilirsiniz. Bazen Web sitelerinden biri
çok yavaş olduğundan, kalan tüm indirmeleri gecikmekte. Yönergede oluşturduğunuz zaman uyumsuz çözümleri
çalıştırdığınızda, beklemek istemiyorsanız programı kolayca sonlandırabilir, ancak daha iyi bir seçenek, tüm
indirmeleri aynı anda başlatıp daha hızlı karşıdan yüklemelerin devam etmesini sağlamak zorunda kalmadan
devam edebilir. gerekebilecek.
Task.WhenAll yöntemini bir görev koleksiyonuna uygularsınız. WhenAll uygulaması, koleksiyondaki her görev
tamamlanana kadar tamamlanmamış tek bir görev döndürür. Görevler paralel olarak çalışır, ancak ek iş parçacığı
oluşturulmaz. Görevler herhangi bir sırada tamamlanabilir.

IMPORTANT
Aşağıdaki yordamlar Izlenecek yol: Async ve await (C#) kullanılarak Web 'e erişimiçin geliştirilmiş zaman uyumsuz
uygulamalara yönelik uzantıları anlatmaktadır. Uygulamayı, izlenecek yolu tamamlayarak veya kodu Geliştirici kodu
örneklerindenindirerek geliştirebilirsiniz.
Örneği çalıştırmak için bilgisayarınızda Visual Studio 2012 veya sonraki bir sürümünün yüklü olması gerekir.

GetURLContentsAsync çözümünüze Task. WhenAll eklemek için


1. ProcessURLAsync yöntemini, Izlenecek yol: Async ve await (C#) kullanarak Web 'e erişmebölümünde
geliştirilen ilk uygulamaya ekleyin.
Kodu Geliştirici kodu örneklerindenIndirdiyseniz asyncwalkthrough projesini açın ve ardından
ProcessURLAsync MainWindow.xaml.cs dosyasına ekleyin.

İzlenecek yolu tamamlayarak kodu geliştirdiyseniz, GetURLContentsAsync yöntemini içeren


uygulamaya ProcessURLAsync ekleyin. Bu uygulama için MainWindow.xaml.cs dosyası, "Izlenecek
yol içindeki tüm kod örnekleri" bölümünde yer aldığı ilk örnektir.
ProcessURLAsync yöntemi, özgün izlenecek yolda SumPageSizesAsync foreach döngüsünün gövdesinde
eylemleri birleştirir. Yöntemi, belirtilen bir Web sitesinin içeriğini bir bayt dizisi olarak zaman uyumsuz
olarak indirir ve bayt dizisinin uzunluğunu görüntüler ve döndürür.

private async Task<int> ProcessURLAsync(string url)


{
var byteArray = await GetURLContentsAsync(url);
DisplayResults(url, byteArray);
return byteArray.Length;
}

2. Aşağıdaki kodun gösterdiği gibi, SumPageSizesAsync``foreach döngüsünü açıklama veya silme.


//var total = 0;
//foreach (var url in urlList)
//{
// byte[] urlContents = await GetURLContentsAsync(url);

// // The previous line abbreviates the following two assignment statements.


// // GetURLContentsAsync returns a Task<T>. At completion, the task
// // produces a byte array.
// //Task<byte[]> getContentsTask = GetURLContentsAsync(url);
// //byte[] urlContents = await getContentsTask;

// DisplayResults(url, urlContents);

// // Update the total.


// total += urlContents.Length;
//}

3. Bir görev koleksiyonu oluşturun. Aşağıdaki kod, ToArray yöntemi tarafından yürütüldüğünde, her bir Web
sitesinin içeriğini yükleyen bir görev koleksiyonu oluşturan bir sorgu tanımlar. Sorgu değerlendirildiğinde
görevler başlatılır.
urlList bildiriminden sonra SumPageSizesAsync aşağıdaki kodu yöntemine ekleyin.

// Create a query.
IEnumerable<Task<int>> downloadTasksQuery =
from url in urlList select ProcessURLAsync(url);

// Use ToArray to execute the query and start the download tasks.
Task<int>[] downloadTasks = downloadTasksQuery.ToArray();

4. Task.WhenAll, downloadTasks görevleri koleksiyonuna uygulayın. Task.WhenAll , görevler


koleksiyonundaki tüm görevler tamamlandığında tamamlanmış tek bir görev döndürür.
Aşağıdaki örnekte await ifadesi, WhenAll döndüren tek görevin tamamlanmasını bekler. İfade, her
tamsayının indirilen bir Web sitesinin uzunluğu olduğu bir tamsayılar dizisi olarak değerlendirilir. Önceki
adımda eklediğiniz koddan hemen sonra SumPageSizesAsync aşağıdaki kodu ekleyin.

// Await the completion of all the running tasks.


int[] lengths = await Task.WhenAll(downloadTasks);

//// The previous line is equivalent to the following two statements.


//Task<int[]> whenAllTask = Task.WhenAll(downloadTasks);
//int[] lengths = await whenAllTask;

5. Son olarak, tüm Web sitelerinin uzunluklarının toplamını hesaplamak için Sum yöntemini kullanın.
SumPageSizesAsync için aşağıdaki satırı ekleyin.

int total = lengths.Sum();

HttpClient. GetByteArrayAsync çözümüne Task. WhenAll eklemek için


1. Aşağıdaki ProcessURLAsync sürümünü, Izlenecek yol: Async ve await (C#) kullanarak Web 'e
erişmebölümünde geliştirilen ikinci uygulamaya ekleyin.
Kodu Geliştirici kodu örnekleri' nden indirdiyseniz, AsyncWalkthrough_HttpClient projesini açın ve
sonra MainWindow.xaml.cs dosyasına ProcessURLAsync ekleyin.
İzlenecek yolu tamamlayarak kodu geliştirdiyseniz, HttpClient.GetByteArrayAsync yöntemini
kullanan uygulamaya ProcessURLAsync ekleyin. Bu uygulama için MainWindow.xaml.cs dosyası,
"Izlenecek yol ile ilgili tüm kod örnekleri" bölümünde yer aldığı ikinci örnektir.
ProcessURLAsync yöntemi, özgün izlenecek yolda SumPageSizesAsync foreach döngüsünün gövdesinde
eylemleri birleştirir. Yöntemi, belirtilen bir Web sitesinin içeriğini bir bayt dizisi olarak zaman uyumsuz
olarak indirir ve bayt dizisinin uzunluğunu görüntüler ve döndürür.
Önceki yordamdaki ProcessURLAsync yönteminin tek farkı, client HttpClient örneğinin kullanımı.

async Task<int> ProcessURLAsync(string url, HttpClient client)


{
byte[] byteArray = await client.GetByteArrayAsync(url);
DisplayResults(url, byteArray);
return byteArray.Length;
}

2. Aşağıdaki kodun gösterdiği gibi SumPageSizesAsync``For Each veya foreach döngüsünü açıklama veya
silme.

//var total = 0;
//foreach (var url in urlList)
//{
// // GetByteArrayAsync returns a Task<T>. At completion, the task
// // produces a byte array.
// byte[] urlContent = await client.GetByteArrayAsync(url);

// // The previous line abbreviates the following two assignment


// // statements.
// Task<byte[]> getContentTask = client.GetByteArrayAsync(url);
// byte[] urlContent = await getContentTask;

// DisplayResults(url, urlContent);

// // Update the total.


// total += urlContent.Length;
//}

3. ToArray yöntemi tarafından yürütüldüğünde, her bir Web sitesinin içeriğini yükleyen bir görev
koleksiyonu oluşturan bir sorgu tanımlayın. Sorgu değerlendirildiğinde görevler başlatılır.
client ve urlList bildiriminin ardından aşağıdaki kodu yöntemine ekleyin SumPageSizesAsync .

// Create a query.
IEnumerable<Task<int>> downloadTasksQuery =
from url in urlList select ProcessURLAsync(url, client);

// Use ToArray to execute the query and start the download tasks.
Task<int>[] downloadTasks = downloadTasksQuery.ToArray();

4. Sonra, downloadTasks görevleri koleksiyonuna Task.WhenAll uygulayın. Task.WhenAll , görevler


koleksiyonundaki tüm görevler tamamlandığında tamamlanmış tek bir görev döndürür.
Aşağıdaki örnekte await ifadesi, WhenAll döndüren tek görevin tamamlanmasını bekler. İşlem
tamamlandığında, await ifade, her tamsayı indirilen bir Web sitesinin uzunluğu olduğu bir tamsayılar
dizisi olarak değerlendirilir. Önceki adımda eklediğiniz koddan hemen sonra SumPageSizesAsync aşağıdaki
kodu ekleyin.
// Await the completion of all the running tasks.
int[] lengths = await Task.WhenAll(downloadTasks);

//// The previous line is equivalent to the following two statements.


//Task<int[]> whenAllTask = Task.WhenAll(downloadTasks);
//int[] lengths = await whenAllTask;

5. Son olarak, tüm Web sitelerinin uzunluklarının toplamını almak için Sum yöntemini kullanın.
SumPageSizesAsync için aşağıdaki satırı ekleyin.

int total = lengths.Sum();

Task. WhenAll çözümlerini test etmek için


İki çözüm için, programı çalıştırmak için F5 tuşunu seçin ve ardından Başlat düğmesini seçin. Çıktı, Izlenecek
yol: AsyncC#ve await () kullanarak Web 'e erişmekiçin zaman uyumsuz çözümlerin çıktısına benzer olmalıdır.
Ancak, Web sitelerinin her seferinde farklı bir sırada görünmediğine dikkat edin.

Örnek
Aşağıdaki kod, Web 'den içerik indirmek için GetURLContentsAsync yöntemini kullanan projenin uzantılarını
gösterir.

// Add the following using directives, and add a reference for System.Net.Http.
using System.Net.Http;
using System.IO;
using System.Net;

namespace AsyncExampleWPF_WhenAll
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}

private async void startButton_Click(object sender, RoutedEventArgs e)


{
resultsTextBox.Clear();

// Two-step async call.


Task sumTask = SumPageSizesAsync();
await sumTask;

// One-step async call.


//await SumPageSizesAsync();

resultsTextBox.Text += "\r\nControl returned to startButton_Click.\r\n";


}

private async Task SumPageSizesAsync()


{
// Make a list of web addresses.
List<string> urlList = SetUpURLList();

// Create a query.
IEnumerable<Task<int>> downloadTasksQuery =
from url in urlList select ProcessURLAsync(url);

// Use ToArray to execute the query and start the download tasks.
Task<int>[] downloadTasks = downloadTasksQuery.ToArray();
// You can do other work here before awaiting.

// Await the completion of all the running tasks.


int[] lengths = await Task.WhenAll(downloadTasks);

//// The previous line is equivalent to the following two statements.


//Task<int[]> whenAllTask = Task.WhenAll(downloadTasks);
//int[] lengths = await whenAllTask;

int total = lengths.Sum();

//var total = 0;
//foreach (var url in urlList)
//{
// byte[] urlContents = await GetURLContentsAsync(url);

// // The previous line abbreviates the following two assignment statements.


// // GetURLContentsAsync returns a Task<T>. At completion, the task
// // produces a byte array.
// //Task<byte[]> getContentsTask = GetURLContentsAsync(url);
// //byte[] urlContents = await getContentsTask;

// DisplayResults(url, urlContents);

// // Update the total.


// total += urlContents.Length;
//}

// Display the total count for all of the websites.


resultsTextBox.Text +=
$"\r\n\r\nTotal bytes returned: {total}\r\n";
}

private List<string> SetUpURLList()


{
List<string> urls = new List<string>
{
"https://msdn.microsoft.com",
"https://msdn.microsoft.com/library/windows/apps/br211380.aspx",
"https://msdn.microsoft.com/library/hh290136.aspx",
"https://msdn.microsoft.com/library/ee256749.aspx",
"https://msdn.microsoft.com/library/hh290138.aspx",
"https://msdn.microsoft.com/library/hh290140.aspx",
"https://msdn.microsoft.com/library/dd470362.aspx",
"https://msdn.microsoft.com/library/aa578028.aspx",
"https://msdn.microsoft.com/library/ms404677.aspx",
"https://msdn.microsoft.com/library/ff730837.aspx"
};
return urls;
}

// The actions from the foreach loop are moved to this async method.
private async Task<int> ProcessURLAsync(string url)
{
var byteArray = await GetURLContentsAsync(url);
DisplayResults(url, byteArray);
return byteArray.Length;
}

private async Task<byte[]> GetURLContentsAsync(string url)


{
// The downloaded resource ends up in the variable named content.
var content = new MemoryStream();

// Initialize an HttpWebRequest for the current URL.


var webReq = (HttpWebRequest)WebRequest.Create(url);

// Send the request to the Internet resource and wait for


// the response.
using (WebResponse response = await webReq.GetResponseAsync())
{
// Get the data stream that is associated with the specified url.
using (Stream responseStream = response.GetResponseStream())
{
await responseStream.CopyToAsync(content);
}
}

// Return the result as a byte array.


return content.ToArray();

private void DisplayResults(string url, byte[] content)


{
// Display the length of each website. The string format
// is designed to be used with a monospaced font, such as
// Lucida Console or Global Monospace.
var bytes = content.Length;
// Strip off the "https://".
var displayURL = url.Replace("https://", "");
resultsTextBox.Text += $"\n{displayURL,-58} {bytes,8}";
}
}
}

Örnek
Aşağıdaki kod, Web 'den içerik indirmek için HttpClient.GetByteArrayAsync yöntemi kullanan projenin
uzantılarını gösterir.

// Add the following using directives, and add a reference for System.Net.Http.
using System.Net.Http;
using System.IO;
using System.Net;

namespace AsyncExampleWPF_HttpClient_WhenAll
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}

private async void startButton_Click(object sender, RoutedEventArgs e)


{
resultsTextBox.Clear();

// One-step async call.


await SumPageSizesAsync();

// Two-step async call.


//Task sumTask = SumPageSizesAsync();
//await sumTask;

resultsTextBox.Text += "\r\nControl returned to startButton_Click.\r\n";


}

private async Task SumPageSizesAsync()


{
// Make a list of web addresses.
List<string> urlList = SetUpURLList();
// Declare an HttpClient object and increase the buffer size. The
// default buffer size is 65,536.
HttpClient client = new HttpClient() { MaxResponseContentBufferSize = 1000000 };

// Create a query.
IEnumerable<Task<int>> downloadTasksQuery =
from url in urlList select ProcessURLAsync(url, client);

// Use ToArray to execute the query and start the download tasks.
Task<int>[] downloadTasks = downloadTasksQuery.ToArray();

// You can do other work here before awaiting.

// Await the completion of all the running tasks.


int[] lengths = await Task.WhenAll(downloadTasks);

//// The previous line is equivalent to the following two statements.


//Task<int[]> whenAllTask = Task.WhenAll(downloadTasks);
//int[] lengths = await whenAllTask;

int total = lengths.Sum();

//var total = 0;
//foreach (var url in urlList)
//{
// // GetByteArrayAsync returns a Task<T>. At completion, the task
// // produces a byte array.
// byte[] urlContent = await client.GetByteArrayAsync(url);

// // The previous line abbreviates the following two assignment


// // statements.
// Task<byte[]> getContentTask = client.GetByteArrayAsync(url);
// byte[] urlContent = await getContentTask;

// DisplayResults(url, urlContent);

// // Update the total.


// total += urlContent.Length;
//}

// Display the total count for all of the web addresses.


resultsTextBox.Text +=
$"\r\n\r\nTotal bytes returned: {total}\r\n";
}

private List<string> SetUpURLList()


{
List<string> urls = new List<string>
{
"https://msdn.microsoft.com",
"https://msdn.microsoft.com/library/hh290136.aspx",
"https://msdn.microsoft.com/library/ee256749.aspx",
"https://msdn.microsoft.com/library/hh290138.aspx",
"https://msdn.microsoft.com/library/hh290140.aspx",
"https://msdn.microsoft.com/library/dd470362.aspx",
"https://msdn.microsoft.com/library/aa578028.aspx",
"https://msdn.microsoft.com/library/ms404677.aspx",
"https://msdn.microsoft.com/library/ff730837.aspx"
};
return urls;
}

// The actions from the foreach loop are moved to this async method.
async Task<int> ProcessURLAsync(string url, HttpClient client)
{
byte[] byteArray = await client.GetByteArrayAsync(url);
DisplayResults(url, byteArray);
return byteArray.Length;
}
}

private void DisplayResults(string url, byte[] content)


{
// Display the length of each web site. The string format
// is designed to be used with a monospaced font, such as
// Lucida Console or Global Monospace.
var bytes = content.Length;
// Strip off the "https://".
var displayURL = url.Replace("https://", "");
resultsTextBox.Text += $"\n{displayURL,-58} {bytes,8}";
}
}
}

Ayrıca bkz.
Task.WhenAll
İzlenecek yol: Async ve await (C#) kullanarak Web 'e erişme
Async ve await (C#) kullanarak birden çok web
isteğini paralel hale getirme
25.11.2019 • 8 minutes to read • Edit Online

Zaman uyumsuz bir yöntemde görevler oluşturulduğunda başlatılır. Await işleci, görev bitene kadar işlemin
devam edemediği yöntemdeki noktada göreve uygulanır. Aşağıdaki örnekte gösterildiği gibi, genellikle bir görev,
oluşturulduktan hemen sonra beklediğinde.

var result = await someWebAccessMethodAsync(url);

Ancak, programın gerçekleştirmeye yönelik başka bir işi olması durumunda görevin tamamlanmasına bağlı
olmaması durumunda görevi bekleyen görev oluşturmayı ayırabilirsiniz.

// The following line creates and starts the task.


var myTask = someWebAccessMethodAsync(url);

// While the task is running, you can do other work that doesn't depend
// on the results of the task.
// . . . . .

// The application of await suspends the rest of this method until the task is complete.
var result = await myTask;

Bir görevi başlatma ve bekleme arasında başka görevler de başlatabilirsiniz. Ek görevler dolaylı olarak paralel
olarak çalışır, ancak ek iş parçacığı oluşturulmaz.
Aşağıdaki program, üç zaman uyumsuz Web yüklemesi başlatır ve ardından bunların çağrıldıkları sırayla bekler.
Programı çalıştırdığınızda, görevlerin Oluşturulma sırasında ve bekledikleri sırada her zaman bitmediğine dikkat
edin. Bunlar oluşturulduğunda çalışmaya başlar ve Yöntem await ifadelerine ulaşmadan önce bir veya daha fazla
görev bitebilirler.

NOTE
Bu projeyi tamamlayabilmeniz için, bilgisayarınızda Visual Studio 2012 veya üzeri ve .NET Framework 4,5 veya üzeri yüklü
olmalıdır.

Aynı anda birden çok görevi Başlatan başka bir örnek için, bkz. Task. WhenAllC#() kullanarak zaman uyumsuz
izlenecek yolu genişletme.
Bu örnek için kodu Geliştirici kodu örneklerindenindirebilirsiniz.
Projeyi ayarlamak için
1. WPF uygulaması ayarlamak için aşağıdaki adımları izleyin. Izlenecek yol: Async ve await (C#) kullanarak
Web 'e erişmekiçin bu adımlarla ilgili ayrıntılı yönergeleri bulabilirsiniz.
Metin kutusu ve düğme içeren bir WPF uygulaması oluşturun. Düğmeyi startButton adlandırın ve
metin kutusu resultsTextBox adlandırın.
System.Net.Httpiçin bir başvuru ekleyin.
MainWindow.xaml.cs dosyasında, System.Net.Http için bir using yönergesi ekleyin.
Kodu eklemek için
1. Tasarım penceresinde, MainWindow. xaml, MainWindow.xaml.cs içinde startButton_Click olay işleyicisini
oluşturmak için düğmeye çift tıklayın.
2. Aşağıdaki kodu kopyalayın ve MainWindow.xaml.cs içindeki startButton_Click gövdesine yapıştırın.

resultsTextBox.Clear();
await CreateMultipleTasksAsync();
resultsTextBox.Text += "\r\n\r\nControl returned to startButton_Click.\r\n";

Kod, uygulamayı yönlendiren CreateMultipleTasksAsync bir zaman uyumsuz yöntemi çağırır.


3. Aşağıdaki destek yöntemlerini projeye ekleyin:
ProcessURLAsync , bir Web sitesinin içeriğini bir bayt dizisi olarak indirmek için bir HttpClient
yöntemi kullanır. ProcessURLAsync support yöntemi, sonra dizinin uzunluğunu gösterir ve döndürür.
DisplayResults her bir URL için bayt dizisindeki bayt sayısını görüntüler. Bu ekranda, her görevin
indirilmesi tamamlandığında gösterilir.
Aşağıdaki yöntemleri kopyalayın ve MainWindow.xaml.cs içinde startButton_Click olay işleyicisinden
sonra yapıştırın.

async Task<int> ProcessURLAsync(string url, HttpClient client)


{
var byteArray = await client.GetByteArrayAsync(url);
DisplayResults(url, byteArray);
return byteArray.Length;
}

private void DisplayResults(string url, byte[] content)


{
// Display the length of each website. The string format
// is designed to be used with a monospaced font, such as
// Lucida Console or Global Monospace.
var bytes = content.Length;
// Strip off the "https://".
var displayURL = url.Replace("https://", "");
resultsTextBox.Text += $"\n{displayURL,-58} {bytes,8}";
}

4. Son olarak, aşağıdaki adımları gerçekleştiren CreateMultipleTasksAsync yöntemini tanımlayın.


Yöntemi, ProcessURLAsync GetByteArrayAsync yöntemine erişmeniz gereken HttpClient nesnesini
bildirir.
Yöntemi Task<TResult>türünde üç görev oluşturur ve başlatır; burada TResult bir tamsayıdır. Her
görev bittiğinde DisplayResults görevin URL 'sini ve indirilen içeriklerin uzunluğunu görüntüler.
Görevler zaman uyumsuz olarak çalıştığından, sonuçların göründüğü sıra, bildirildiği sırayla farklılık
gösterebilir.
Yöntemi her görevin tamamlanmasını bekler. Her bir await işleci, beklenen görev tamamlanana
kadar CreateMultipleTasksAsync yürütmeyi askıya alır. İşleci, her tamamlanan görevden
ProcessURLAsync çağrısından dönüş değerini de alır.

Görevler tamamlandığında ve tamsayı değerleri alınırsa, yöntemi web sitelerinin uzunluklarını


toplar ve sonucu görüntüler.
Aşağıdaki yöntemi kopyalayın ve çözümünüze yapıştırın.
private async Task CreateMultipleTasksAsync()
{
// Declare an HttpClient object, and increase the buffer size. The
// default buffer size is 65,536.
HttpClient client =
new HttpClient() { MaxResponseContentBufferSize = 1000000 };

// Create and start the tasks. As each task finishes, DisplayResults


// displays its length.
Task<int> download1 =
ProcessURLAsync("https://msdn.microsoft.com", client);
Task<int> download2 =
ProcessURLAsync("https://msdn.microsoft.com/library/hh156528(VS.110).aspx", client);
Task<int> download3 =
ProcessURLAsync("https://msdn.microsoft.com/library/67w7t67f.aspx", client);

// Await each task.


int length1 = await download1;
int length2 = await download2;
int length3 = await download3;

int total = length1 + length2 + length3;

// Display the total count for the downloaded websites.


resultsTextBox.Text += $"\r\n\r\nTotal bytes returned: {total}\r\n";
}

5. Programı çalıştırmak için F5 tuşunu seçin ve sonra Başlat düğmesini seçin.


Üç görevin her zaman aynı sırada bitmeyeceğini ve bunların tamamların oluşturulma sırası ve bekledikleri
sıra olması gerektiğini doğrulamak için programı birkaç kez çalıştırın.

Örnek
Aşağıdaki kod tam örneği içerir.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

// Add the following using directive, and add a reference for System.Net.Http.
using System.Net.Http;

namespace AsyncExample_MultipleTasks
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}

private async void startButton_Click(object sender, RoutedEventArgs e)


{
{
resultsTextBox.Clear();
await CreateMultipleTasksAsync();
resultsTextBox.Text += "\r\n\r\nControl returned to startButton_Click.\r\n";
}

private async Task CreateMultipleTasksAsync()


{
// Declare an HttpClient object, and increase the buffer size. The
// default buffer size is 65,536.
HttpClient client =
new HttpClient() { MaxResponseContentBufferSize = 1000000 };

// Create and start the tasks. As each task finishes, DisplayResults


// displays its length.
Task<int> download1 =
ProcessURLAsync("https://msdn.microsoft.com", client);
Task<int> download2 =
ProcessURLAsync("https://msdn.microsoft.com/library/hh156528(VS.110).aspx", client);
Task<int> download3 =
ProcessURLAsync("https://msdn.microsoft.com/library/67w7t67f.aspx", client);

// Await each task.


int length1 = await download1;
int length2 = await download2;
int length3 = await download3;

int total = length1 + length2 + length3;

// Display the total count for the downloaded websites.


resultsTextBox.Text += $"\r\n\r\nTotal bytes returned: {total}\r\n";
}

async Task<int> ProcessURLAsync(string url, HttpClient client)


{
var byteArray = await client.GetByteArrayAsync(url);
DisplayResults(url, byteArray);
return byteArray.Length;
}

private void DisplayResults(string url, byte[] content)


{
// Display the length of each website. The string format
// is designed to be used with a monospaced font, such as
// Lucida Console or Global Monospace.
var bytes = content.Length;
// Strip off the "https://".
var displayURL = url.Replace("https://", "");
resultsTextBox.Text += $"\n{displayURL,-58} {bytes,8}";
}
}
}

Ayrıca bkz.
İzlenecek yol: Async ve await (C#) kullanarak Web 'e erişme
Async ve await (C#) ile zaman uyumsuz programlama
Task. WhenAll (C#) kullanarak zaman uyumsuz izlenecek yolu genişletme
Zaman uyumsuz dönüş türleriC#()
23.10.2019 • 11 minutes to read • Edit Online

Zaman uyumsuz metotlar aşağıdaki dönüş türlerine sahip olabilir:


Task<TResult>, bir değer döndüren zaman uyumsuz bir yöntem için.
Task, bir işlem gerçekleştiren ancak değer döndüren zaman uyumsuz bir yöntem için.
void , bir olay işleyicisi için.
7,0 ile C# başlayarak, erişilebilir GetAwaiter bir yöntemi olan herhangi bir tür. GetAwaiter Yöntemi
tarafından döndürülen nesne System.Runtime.CompilerServices.ICriticalNotifyCompletion arabirimini
uygulamalıdır.
Zaman uyumsuz yöntemler hakkında daha fazla bilgi için bkz. Async ve await (C#) Ile zaman uyumsuz
programlama.
Her dönüş türü aşağıdaki bölümlerden birinde incelenir ve konunun sonunda her üç türü kullanan tam bir
örnek bulabilirsiniz.

Görev<tSonuç> dönüş türü


Dönüş türü, TResult işlenenin türü olan bir Return (C#) ifadesini içeren zaman uyumsuz bir yöntem için
kullanılır. Task<TResult>
Aşağıdaki örnekte, GetLeisureHours async yöntemi bir tamsayı döndüren bir return ifade içerir. Bu nedenle,
metot bildiriminin bir dönüş türü Task<int> belirtmesi gerekir. FromResult Async yöntemi, bir dize döndüren bir
işlem için yer tutucudur.
using System;
using System.Linq;
using System.Threading.Tasks;

public class Example


{
public static void Main()
{
Console.WriteLine(ShowTodaysInfo().Result);
}

private static async Task<string> ShowTodaysInfo()


{
string ret = $"Today is {DateTime.Today:D}\n" +
"Today's hours of leisure: " +
$"{await GetLeisureHours()}";
return ret;
}

static async Task<int> GetLeisureHours()


{
// Task.FromResult is a placeholder for actual work that returns a string.
var today = await Task.FromResult<string>(DateTime.Now.DayOfWeek.ToString());

// The method then can process the result in some way.


int leisureHours;
if (today.First() == 'S')
leisureHours = 16;
else
leisureHours = 5;

return leisureHours;
}
}
// The example displays output like the following:
// Today is Wednesday, May 24, 2017
// Today's hours of leisure: 5
// </Snippet >

Yöntemi içindeki bir leisureHours await ifadesi GetLeisureHours içinden çağrıldığında, await ifadesi yöntemi
tarafından döndürülen görevde depolanan tamsayı değerini (değeri) alır. GetLeisureHours ShowTodaysInfo
Await ifadeleri hakkında daha fazla bilgi için bkz. await.
Aşağıdaki kodda gösterildiği gibi GetLeisureHours await , çağrısını uygulamasından ayırarak bunun nasıl
gerçekleştiğini daha iyi anlayabilirsiniz. Yönteminin bildiriminden bekleyebileceğiniz GetLeisureHours için
hemen beklenen bir yönteme çağrı bir Task<int> döndürür. Görev örnekteki integerTask değişkenine atanır.
Bir olduğundan, Result türünde bir TResult özelliğiiçerir. Task<TResult> integerTask Bu durumda, TResult bir
tamsayı türünü temsil eder. Öğesine uygulandığında, Result await ifadesi öğesinin integerTask özelliğinin
içeriğini değerlendirir. integerTask await Değer ret değişkenine atanır.

IMPORTANT
Result Özelliği engelleyici bir özelliktir. Görevi tamamlanmadan önce ona erişmeye çalışırsanız, etkin olan iş parçacığı, görev
tamamlanana ve değer kullanılabilir olana kadar engellenir. Çoğu durumda, özelliğine doğrudan erişmek yerine kullanarak
await değere erişmeniz gerekir.
Önceki örnek, uygulamanın sonlandırılmadan önce yürütmeyi tamamlayabilmesi Result ShowTodaysInfo için ana iş
parçacığını engellemek üzere özelliğinin değerini almıştır.
var integerTask = GetLeisureHours();

// You can do other work that does not rely on integerTask before awaiting.

string ret = $"Today is {DateTime.Today:D}\n" +


"Today's hours of leisure: " +
$"{await integerTask}";

Görev dönüş türü


Bir return ifade içermeyen veya bir işleneni döndürmeyen bir return ifade içeren zaman uyumsuz yöntemler
genellikle dönüş türüne Tasksahiptir. Bu tür yöntemler void zaman uyumlu olarak çalıştırıldıklarında
döndürülür. Zaman uyumsuz bir yöntem Task için dönüş türü kullanırsanız, çağıran zaman uyumsuz yöntem
bitene kadar çağıranın tamamlanmasını await askıya almak için bir operatör kullanabilirsiniz.
Aşağıdaki örnekte, WaitAndApologize async yöntemi bir return ifade içermez, bu nedenle Yöntem bir Task
nesne döndürür. Bu, WaitAndApologize beklemenize olanak sağlar. Dönüş değeri olmadığından Task türün bir
Result özellik içermediğini unutmayın.

using System;
using System.Threading.Tasks;

public class Example


{
public static void Main()
{
DisplayCurrentInfo().Wait();
}

static async Task DisplayCurrentInfo()


{
await WaitAndApologize();
Console.WriteLine($"Today is {DateTime.Now:D}");
Console.WriteLine($"The current time is {DateTime.Now.TimeOfDay:t}");
Console.WriteLine("The current temperature is 76 degrees.");
}

static async Task WaitAndApologize()


{
// Task.Delay is a placeholder for actual work.
await Task.Delay(2000);
// Task.Delay delays the following line by two seconds.
Console.WriteLine("\nSorry for the delay. . . .\n");
}
}
// The example displays the following output:
// Sorry for the delay. . . .
//
// Today is Wednesday, May 24, 2017
// The current time is 15:25:16.2935649
// The current temperature is 76 degrees.

WaitAndApologize , zaman uyumlu void döndüren bir yöntem için çağırma deyimine benzer bir await ifadesi
yerine await deyimi kullanılarak bekletildi. Bu durumda await işlecinin uygulaması bir değer üretmez.
Önceki Task<TResult> örnekte olduğu gibi, aşağıdaki kodda gösterildiği gibi, WaitAndApologize çağrısını await
işlecinin uygulamasından ayırabilirsiniz. Ancak, bir Task Result özelliğine sahip olmadığını ve bir Task Await
işleci uygulandığında hiçbir değer üretilmediğini unutmayın.
Aşağıdaki kod, yöntemi çağıran WaitAndApologize görevin döndürdüğü görevi bekleten ayırır.

Task wait = WaitAndApologize();

string output = $"Today is {DateTime.Now:D}\n" +


$"The current time is {DateTime.Now.TimeOfDay:t}\n" +
$"The current temperature is 76 degrees.\n";
await wait;
Console.WriteLine(output);

Void dönüş türü


Dönüş türünü, void void dönüş türü gerektiren zaman uyumsuz olay işleyicilerde kullanırsınız. Değer
döndürmeyen olay işleyicileri dışındaki yöntemler için, döndüren Task void zaman uyumsuz bir yöntem
beklenmediği için bir yerine döndürmelidir. Bu tür bir yöntemi çağıran, çağrılan zaman uyumsuz yöntemin
tamamlanmasını beklemeden tamamlamaya devam edebilmelidir ve çağıranın, zaman uyumsuz yöntemin
ürettiği herhangi bir değerden veya özel durumlardan bağımsız olması gerekir.
Void döndüren zaman uyumsuz bir yöntemi çağıran, yöntemden oluşturulan özel durumları yakalayabilir ve bu
tür işlenmemiş özel durumlar uygulamanızın başarısız olmasına neden olabilir. Bir Task
veyaTask<TResult>döndüren zaman uyumsuz bir yöntemde özel durum oluşursa, özel durum döndürülen
görevde depolanır ve görev beklendiğinde yeniden oluşturulur. Bu nedenle, bir özel durum üretemeyen
herhangi bir zaman uyumsuz metodun, Task veya Task<TResult> dönüş türüne sahip olduğundan ve metoda
yapılan çağrıların beklenmediğinden emin olun.
Zaman uyumsuz yöntemlerde özel durumları yakalama hakkında daha fazla bilgi için, try-catch konusunun
zaman uyumsuz metotlar bölümünde özel durumlar bölümüne bakın.
Aşağıdaki örnek, zaman uyumsuz bir olay işleyicisinin davranışını gösterir. Örnek kodda, zaman uyumsuz bir
olay işleyicisinin ana iş parçacığının tamamlandığında bunu bilmesini sağlamalıdır. Ardından, ana iş parçacığı
programdan çıkmadan zaman uyumsuz bir olay işleyicisinin tamamlanmasını bekleyebilir.

using System;
using System.Threading.Tasks;

public class NaiveButton


{
public event EventHandler Clicked;

public void Click()


{
Console.WriteLine("Somebody has clicked a button. Let's raise the event...");
Clicked?.Invoke(this, EventArgs.Empty);
Console.WriteLine("All listeners are notified.");
}
}

public class AsyncVoidExample


{
static TaskCompletionSource<bool> tcs;

static async Task Main()


{
tcs = new TaskCompletionSource<bool>();
var secondHandlerFinished = tcs.Task;

var button = new NaiveButton();


button.Clicked += Button_Clicked_1;
button.Clicked += Button_Clicked_2_Async;
button.Clicked += Button_Clicked_3;
Console.WriteLine("About to click a button...");
button.Click();
Console.WriteLine("Button's Click method returned.");

await secondHandlerFinished;
}

private static void Button_Clicked_1(object sender, EventArgs e)


{
Console.WriteLine(" Handler 1 is starting...");
Task.Delay(100).Wait();
Console.WriteLine(" Handler 1 is done.");
}

private static async void Button_Clicked_2_Async(object sender, EventArgs e)


{
Console.WriteLine(" Handler 2 is starting...");
Task.Delay(100).Wait();
Console.WriteLine(" Handler 2 is about to go async...");
await Task.Delay(500);
Console.WriteLine(" Handler 2 is done.");
tcs.SetResult(true);
}

private static void Button_Clicked_3(object sender, EventArgs e)


{
Console.WriteLine(" Handler 3 is starting...");
Task.Delay(100).Wait();
Console.WriteLine(" Handler 3 is done.");
}
}

// Expected output:
// About to click a button...
// Somebody has clicked a button. Let's raise the event...
// Handler 1 is starting...
// Handler 1 is done.
// Handler 2 is starting...
// Handler 2 is about to go async...
// Handler 3 is starting...
// Handler 3 is done.
// All listeners are notified.
// Button's Click method returned.
// Handler 2 is done.

Genelleştirilmiş zaman uyumsuz dönüş türleri ve valuetask<TResult>


7,0 ile C# başlayarak, zaman uyumsuz bir yöntem erişilebilir GetAwaiter bir yöntemi olan herhangi bir tür
döndürebilir.
Task VeTask<TResult> başvuru türleri olduğundan, performans açısından kritik yollarda bellek ayırma, özellikle
de ayırmalar sıkı Döngülerde gerçekleşiyorsa performansı olumsuz etkileyebilir. Genelleştirilmiş dönüş türleri
için destek, ek bellek ayırmalarını önlemek için bir başvuru türü yerine hafif değer türü döndürebilmeniz
anlamına gelir.
.Net, System.Threading.Tasks.ValueTask<TResult> genelleştirilmiş bir görev döndüren değerin hafif bir
uygulama olarak yapısını sağlar. System.Threading.Tasks.ValueTask<TResult> Türünü kullanmak için,
System.Threading.Tasks.Extensions NuGet paketini projenize eklemeniz gerekir. Aşağıdaki örnek, iki zarın
değerini almak için ValueTask<TResult> yapısını kullanır.
using System;
using System.Threading.Tasks;

class Program
{
static Random rnd;

static void Main()


{
Console.WriteLine($"You rolled {GetDiceRoll().Result}");
}

private static async ValueTask<int> GetDiceRoll()


{
Console.WriteLine("...Shaking the dice...");
int roll1 = await Roll();
int roll2 = await Roll();
return roll1 + roll2;
}

private static async ValueTask<int> Roll()


{
if (rnd == null)
rnd = new Random();

await Task.Delay(500);
int diceRoll = rnd.Next(1, 7);
return diceRoll;
}
}
// The example displays output like the following:
// ...Shaking the dice...
// You rolled 8

Ayrıca bkz.
FromResult
İzlenecek yol: Async ve await (C#) kullanarak Web 'e erişme
Zaman uyumsuz programlarda denetim akışı (C#)
async
await
Zaman uyumsuz programlarda denetim akışı (C#)
23.10.2019 • 14 minutes to read • Edit Online

async Ve await anahtar sözcüklerini kullanarak zaman uyumsuz programları daha kolay bir şekilde yazabilir ve
koruyabilirsiniz. Ancak, programınızın nasıl çalıştığını anlamıyorsanız sonuçlar sizi şaşırtabilir. Bu konu, denetim
bir yöntemden diğerine ne zaman taşındığını ve her seferinde hangi bilgilerin aktarılacağını göstermek için basit
bir zaman uyumsuz program aracılığıyla denetim akışını izler.
Genel olarak, Async (C#) değiştiricisiyle zaman uyumsuz kod içeren yöntemleri işaretlersiniz. Zaman uyumsuz
değiştirici ile işaretlenmiş bir yöntemde, yöntemin, çağrılan zaman uyumsuz işlemin tamamlanmasını beklemek
için bekleyeceği yeri belirtmek için await (C#) işlecini kullanabilirsiniz. Daha fazla bilgi için bkz. Async ve await
(C#) Ile zaman uyumsuz programlama.
Aşağıdaki örnek, belirtilen bir Web sitesinin içeriğini bir dize olarak indirmek ve dizenin uzunluğunu göstermek
için zaman uyumsuz yöntemler kullanır. Örnek aşağıdaki iki yöntemi içerir.
startButton_Click , sonucu çağırır AccessTheWebAsync ve görüntüler.
AccessTheWebAsync, bir Web sitesinin içeriğini bir dize olarak indirir ve dizenin uzunluğunu döndürür.
AccessTheWebAsync , içeriğini indirmek HttpClient için zaman uyumsuz bir yöntem kullanır.
GetStringAsync(String)
Numaralandırılmış görüntüleme satırları programın nasıl çalıştığını anlamanıza yardımcı olmak ve işaretlenen
her bir noktada ne olduğunu açıklamak için programın tamamında stratejik noktalarda görünür. Görüntüleme
satırları "BIR"-"altı" olarak etiketlenir. Etiketler, programın bu kod satırlarına ulaştığı sırayı temsil eder.
Aşağıdaki kod programın bir ana hattını gösterir.
public partial class MainWindow : Window
{
// . . .
private async void startButton_Click(object sender, RoutedEventArgs e)
{
// ONE
Task<int> getLengthTask = AccessTheWebAsync();

// FOUR
int contentLength = await getLengthTask;

// SIX
resultsTextBox.Text +=
$"\r\nLength of the downloaded string: {contentLength}.\r\n";
}

async Task<int> AccessTheWebAsync()


{
// TWO
HttpClient client = new HttpClient();
Task<string> getStringTask =
client.GetStringAsync("https://msdn.microsoft.com");

// THREE
string urlContents = await getStringTask;

// FIVE
return urlContents.Length;
}
}

Etiketlenmiş konumların her biri, "BIR"-"ALTıDA", programın geçerli durumuyla ilgili bilgileri görüntüler.
Aşağıdaki çıktı üretilir:

ONE: Entering startButton_Click.


Calling AccessTheWebAsync.

TWO: Entering AccessTheWebAsync.


Calling HttpClient.GetStringAsync.

THREE: Back in AccessTheWebAsync.


Task getStringTask is started.
About to await getStringTask & return a Task<int> to startButton_Click.

FOUR: Back in startButton_Click.


Task getLengthTask is started.
About to await getLengthTask -- no caller to return to.

FIVE: Back in AccessTheWebAsync.


Task getStringTask is complete.
Processing the return statement.
Exiting from AccessTheWebAsync.

SIX: Back in startButton_Click.


Task getLengthTask is finished.
Result from AccessTheWebAsync is stored in contentLength.
About to display contentLength and exit.

Length of the downloaded string: 33946.

Programı ayarlama
Bu konunun kullandığı kodu MSDN 'den indirebilirsiniz veya kendiniz oluşturabilirsiniz.
NOTE
Örneği çalıştırmak için, bilgisayarınızda Visual Studio 2012 veya daha yeni bir sürümü ve .NET Framework 4,5 ya da daha
yeni bir sürümü yüklü olmalıdır.

Programı indir
Bu konu için uygulamayı zaman uyumsuz örnekten indirebilirsiniz: Zaman uyumsuz programlardadenetim akışı.
Aşağıdaki adımlar programı açın ve çalıştırın.
1. İndirilen dosyayı sıkıştırmasını açın ve ardından Visual Studio 'Yu başlatın.
2. Menü çubuğunda Dosya > Aç > Proje/çözüm' ı seçin.
3. Sıkıştırılmış örnek kodu tutan klasöre gidin, çözüm (. sln) dosyasını açın ve ardından projeyi derlemek ve
çalıştırmak için F5 tuşunu seçin.
Programı kendiniz oluşturun
Aşağıdaki Windows Presentation Foundation (WPF ) projesi bu konunun kod örneğini içerir.
Projeyi çalıştırmak için aşağıdaki adımları gerçekleştirin:
1. Visual Studio’yu çalıştırın.
2. Menü çubuğunda, dosya > yeni > proje.
Yeni proje iletişim kutusu açılır.
3. Yüklü > olanVisual C# Windows
MasaüstükategorisiniseçinveardındanprojeşablonlarılistesindenWPFuygulaması'nıseçin. >
4. Projenin AsyncTracer adı olarak girin ve Tamam düğmesini seçin.
Yeni proje Çözüm Gezginigörüntülenir.
5. Visual Studio Code düzenleyicisinde MainWindow. xaml sekmesini seçin.
Sekme görünür değilse, Çözüm Gezgini' de MainWindow. xaml için kısayol menüsünü açın ve kodu
görüntüle' yi seçin.
6. MainWindow. xaml ' nin xaml görünümünde, kodu aşağıdaki kodla değiştirin.

<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
x:Class="AsyncTracer.MainWindow"
Title="Control Flow Trace" Height="350" Width="592">
<Grid>
<Button x:Name="startButton" Content="Start
" HorizontalAlignment="Left" Margin="250,10,0,0" VerticalAlignment="Top" Width="75" Height="24"
Click="startButton_Click" d:LayoutOverrides="GridBox"/>
<TextBox x:Name="resultsTextBox" HorizontalAlignment="Left" TextWrapping="Wrap"
VerticalAlignment="Bottom" Width="576" Height="265" FontFamily="Lucida Console" FontSize="10"
VerticalScrollBarVisibility="Visible" Grid.ColumnSpan="3"/>
</Grid>
</Window>

Bir metin kutusu ve bir düğme içeren basit bir pencere, MainWindow. xaml Tasarım görünümünde
görünür.
7. İçin System.Net.Httpbir başvuru ekleyin.
8. Çözüm Gezgini' de, MainWindow.xaml.cs için kısayol menüsünü açın ve kodu görüntüle' yi seçin.
9. MainWindow.xaml.cs ' de, kodu aşağıdaki kodla değiştirin.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

// Add a using directive and a reference for System.Net.Http;


using System.Net.Http;

namespace AsyncTracer
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}

private async void startButton_Click(object sender, RoutedEventArgs e)


{
// The display lines in the example lead you through the control shifts.
resultsTextBox.Text += "ONE: Entering startButton_Click.\r\n" +
" Calling AccessTheWebAsync.\r\n";

Task<int> getLengthTask = AccessTheWebAsync();

resultsTextBox.Text += "\r\nFOUR: Back in startButton_Click.\r\n" +


" Task getLengthTask is started.\r\n" +
" About to await getLengthTask -- no caller to return to.\r\n";

int contentLength = await getLengthTask;

resultsTextBox.Text += "\r\nSIX: Back in startButton_Click.\r\n" +


" Task getLengthTask is finished.\r\n" +
" Result from AccessTheWebAsync is stored in contentLength.\r\n" +
" About to display contentLength and exit.\r\n";

resultsTextBox.Text +=
$"\r\nLength of the downloaded string: {contentLength}.\r\n";
}

async Task<int> AccessTheWebAsync()


{
resultsTextBox.Text += "\r\nTWO: Entering AccessTheWebAsync.";

// Declare an HttpClient object.


HttpClient client = new HttpClient();

resultsTextBox.Text += "\r\n Calling HttpClient.GetStringAsync.\r\n";

// GetStringAsync returns a Task<string>.


Task<string> getStringTask = client.GetStringAsync("https://msdn.microsoft.com");
resultsTextBox.Text += "\r\nTHREE: Back in AccessTheWebAsync.\r\n" +
" Task getStringTask is started.";

// AccessTheWebAsync can continue to work until getStringTask is awaited.

resultsTextBox.Text +=
"\r\n About to await getStringTask and return a Task<int> to
startButton_Click.\r\n";

// Retrieve the website contents when task is complete.


string urlContents = await getStringTask;

resultsTextBox.Text += "\r\nFIVE: Back in AccessTheWebAsync." +


"\r\n Task getStringTask is complete." +
"\r\n Processing the return statement." +
"\r\n Exiting from AccessTheWebAsync.\r\n";

return urlContents.Length;
}
}
}

10. Programı çalıştırmak için F5 tuşunu seçin ve sonra Başlat düğmesini seçin.
Aşağıdaki çıktı görüntülenir:

ONE: Entering startButton_Click.


Calling AccessTheWebAsync.

TWO: Entering AccessTheWebAsync.


Calling HttpClient.GetStringAsync.

THREE: Back in AccessTheWebAsync.


Task getStringTask is started.
About to await getStringTask & return a Task<int> to startButton_Click.

FOUR: Back in startButton_Click.


Task getLengthTask is started.
About to await getLengthTask -- no caller to return to.

FIVE: Back in AccessTheWebAsync.


Task getStringTask is complete.
Processing the return statement.
Exiting from AccessTheWebAsync.

SIX: Back in startButton_Click.


Task getLengthTask is finished.
Result from AccessTheWebAsync is stored in contentLength.
About to display contentLength and exit.

Length of the downloaded string: 33946.

Programı izleme
Adım BIR ve ıkı
İlk iki görüntüleme satırı startButton_Click yolu çağrı AccessTheWebAsync olarak izler ve AccessTheWebAsync
zaman uyumsuz HttpClient yöntemi GetStringAsync(String)çağırır. Aşağıdaki görüntüde yönteminden
yöntemine yapılan çağrılar özetlenmektedir.
Hem hem de AccessTheWebAsync client.GetStringAsyncöğesinindönüş türü. Task<TResult> İçin
AccessTheWebAsync , TResult bir tamsayıdır. İçin GetStringAsync , TResult bir dizedir. Zaman uyumsuz yöntem
dönüş türleri hakkında daha fazla bilgi için bkz. Async ReturnC#Types ().
Bir görev döndüren zaman uyumsuz yöntem, Denetim çağırana geri dönzaman bir görev örneği döndürür.
Çağrılan yöntemde bir await işleçle karşılaşıldığında veya çağrılan yöntem sona erdiğinde, denetim zaman
uyumsuz bir yöntemden çağırana döner. "Üç" ile "ALTıDAN" Etiketlenmiş görüntüleme satırları işlemin bu
bölümünü izler.
Üçüncü adım
İçinde AccessTheWebAsync , zaman uyumsuz yöntemi GetStringAsync(String) hedef Web sayfasının içeriğini
indirmek için çağırılır. Denetim, ' client.GetStringAsync den AccessTheWebAsync client.GetStringAsync ' a döner.
Yöntemi, getStringTask içindeki AccessTheWebAsync değişkenine atanan bir dize görevi döndürür.
client.GetStringAsync Örnek programda aşağıdaki satır, ve atama için client.GetStringAsync çağrıyı gösterir.

Task<string> getStringTask = client.GetStringAsync("https://msdn.microsoft.com");

Son olarak gerçek bir dize oluşturmak client.GetStringAsync için görevi bir Promise olarak düşünebilirsiniz. Bu
sırada, bu, AccessTheWebAsync ' de taahhüt edilen client.GetStringAsync dizeye bağlı değilse, bu iş, bekleme
sırasında client.GetStringAsync devam edebilir. Örnekte, "üç" olarak etiketlenen aşağıdaki çıktı satırları,
bağımsız iş yapmak için fırsatı temsil eder

THREE: Back in AccessTheWebAsync.


Task getStringTask is started.
About to await getStringTask & return a Task<int> to startButton_Click.

Aşağıdaki ifade, ne zaman AccessTheWebAsync beklediğinde getStringTask ' de ilerlemeyi askıya alır.

string urlContents = await getStringTask;

Aşağıdaki görüntüde denetim client.GetStringAsync getStringTask akışını, bir await işlecinin uygulamasına
getStringTask ve oluşturma işleminden öğesine kadar gösterir.
Await ifadesi dönüşene AccessTheWebAsync kadar client.GetStringAsync askıya alır. Bu sırada denetim, '
AccessTheWebAsync startButton_Click ın çağıranına döner.

NOTE
Genellikle, zaman uyumsuz bir yöntem çağrısını hemen bekleolursunuz. Örneğin, aşağıdaki atama, oluşturan ve daha sonra
bekleyen getStringTask önceki kodun yerini alır:
string urlContents = await client.GetStringAsync("https://msdn.microsoft.com");

Bu konuda, Await işleci daha sonra Denetim akışını program aracılığıyla işaretleyen çıkış satırlarına uyum sağlayacak şekilde
uygulanır.

4. adım
AccessTheWebAsync Tarafından Task<int> belirtilen dönüş türü. Bu nedenle, askıya alındığında, için
startButton_Click bir tamsayı görevi döndürür. AccessTheWebAsync Döndürülen görevin getStringTask
olmadığını anlamalısınız. Döndürülen görev, AccessTheWebAsync askıya alınan yöntemde ne yapılması gerektiğini
temsil eden yeni bir tamsayı görevi. Görev tamamlandığında bir tamsayı üretmek AccessTheWebAsync için görevi
bir taahhüddir.
Aşağıdaki ifade bu görevi getLengthTask değişkenine atar.

Task<int> getLengthTask = AccessTheWebAsync();

' De olduğu startButton_Click gibi, görev beklenene kadar zaman uyumsuz görevin (
AccessTheWebAsync
getLengthTask ) sonuçlarına bağlı olmayan çalışmaya devam edebilir. Aşağıdaki çıktı satırları bu işi temsil eder.

FOUR: Back in startButton_Click.


Task getLengthTask is started.
About to await getLengthTask -- no caller to return to.

İlerleme durumu, beklediğinde getLengthTask askıya alınır. startButton_Click Aşağıdaki atama açıklaması
tamamlanana kadar startButton_Click AccessTheWebAsync askıya alınır.

int contentLength = await getLengthTask;

Aşağıdaki AccessTheWebAsync çizimde, oklar bir getLengthTask değerin atanması için içindeki Await ifadesinden
denetim akışını gösterir ve startButton_Click ardından beklenene kadar getLengthTask normal işleme gelir.
4.
5. adım
AccessTheWebAsync İşlemin tamamlandığını client.GetStringAsync işaret ederse, içindeki işleme askıya alma
işleminden serbest bırakılır ve await ifadesinin ötesinde devam edebilir. Aşağıdaki çıktı satırları işleme sürdürme
temsil eder.

FIVE: Back in AccessTheWebAsync.


Task getStringTask is complete.
Processing the return statement.
Exiting from AccessTheWebAsync.

Return ifadesinin urlContents.Length işleneni, AccessTheWebAsync döndüren görevde saklanır. Await ifadesi bu
değeri içindeki getLengthTask startButton_Click öğesinden alır.
Aşağıdaki görüntüde (ve client.GetStringAsync getStringTask ) sonra denetimin aktarımı gösterilmektedir.
AccessTheWebAsync tamamlandı olarak çalışır ve denetimi startButton_Click ' a döner, bu da tamamlamayı
bekliyor.
Altı adım
İşlemin tamamlandığını startButton_Async işaret ederse, işleme ' de await ifadesinin ötesinde devam edebilir.
AccessTheWebAsync Aslında programın daha fazla şey yoktur.

Aşağıdaki çıktı satırları içinde startButton_Async işleme sürdürme temsil eder:

SIX: Back in startButton_Click.


Task getLengthTask is finished.
Result from AccessTheWebAsync is stored in contentLength.
About to display contentLength and exit.

Await ifadesi ' de getLengthTask AccessTheWebAsync return deyiminin işleneni olan Integer değerinden alır.
Aşağıdaki ifade bu değeri contentLength değişkenine atar.

int contentLength = await getLengthTask;

Aşağıdaki görüntüde ' den AccessTheWebAsync 'e startButton_Click denetim dönüşü gösterilmektedir.
Ayrıca bkz.
Async ve await (C#) ile zaman uyumsuz programlama
Zaman uyumsuz dönüş türleriC#()
İzlenecek yol: Async ve await (C#) kullanarak Web 'e erişme
Zaman uyumsuz örnek: Zaman uyumsuz programlarda denetim akışı (C# ve Visual Basic)
Zaman uyumsuz uygulamanızda ince ayar yapma
(C#)
25.11.2019 • 2 minutes to read • Edit Online

Task türünün kullanılabilir hale getiren yöntemleri ve özellikleri kullanarak zaman uyumsuz uygulamalarınıza
duyarlık ve esneklik ekleyebilirsiniz. Bu bölümdeki konularda, Task.WhenAll ve Task.WhenAnygibi
CancellationToken ve önemli Task yöntemleri kullanan örnekler gösterilmektedir.
WhenAnyve WhenAll kullanarak, birden çok görevi daha kolay başlatabilir ve tek bir görevi izleyerek
tamamlanmasını deneyebilirsiniz.
WhenAny , bir koleksiyondaki herhangi bir görev tamamlandığında tamamlanan bir görev döndürür.
kullanan örnekler için bkz. kalan zaman uyumsuz görevleri bir işlem tamamlandıktan sonra iptal
WhenAny
etmeC#() ve birden çok zaman uyumsuz görev başlatın ve bunları tamamlarsaC#() işlemyapın.
WhenAll , bir koleksiyondaki tüm görevler tamamlandığında tamamlanan bir görev döndürür.
Daha fazla bilgi ve WhenAll kullanan bir örnek için, bkz. Task. WhenAllC#() kullanarak zaman uyumsuz
izlenecek yolu genişletme.
Bu bölüm aşağıdaki örnekleri içerir.
Zaman uyumsuz bir görevi veya görev listesini (C#) iptal edin.
Zaman uyumsuz görevleri bir süre sonra iptal et (C#)
Tamamlandıktan sonra kalan zaman uyumsuz görevleri iptal et (C#)
Birden çok zaman uyumsuz görev başlatın ve bunları tamamlarsa (C#) işleyin

NOTE
Örnekleri çalıştırmak için, bilgisayarınızda Visual Studio 2012 veya daha yeni bir sürümü ve .NET Framework 4,5 ya da daha
yeni bir sürümü yüklü olmalıdır.

Projeler, aşağıdaki görüntüde gösterildiği gibi, işlemi başlatan bir düğme ve bunu iptal eden bir düğme içeren bir
kullanıcı arabirimi oluşturur. Düğmeler startButton ve cancelButton olarak adlandırılır.

Tüm Windows Presentation Foundation (WPF ) projelerini zaman uyumsuz örnekten indirebilirsiniz:
uygulamanızı hassas bir şekilde ayarlama.

Ayrıca bkz.
Async ve await (C#) ile zaman uyumsuz programlama
Zaman uyumsuz bir görevi veya görev listesini iptal
etme (C#)
23.10.2019 • 13 minutes to read • Edit Online

Bir zaman uyumsuz uygulamayı, bitmesini beklemek istemiyorsanız iptal etmek için kullanabileceğiniz bir düğme
ayarlayabilirsiniz. Bu konudaki örnekleri izleyerek, bir Web sitesinin veya Web sitesi listesinin içeriğini yükleyen
bir uygulamaya iptal düğmesi ekleyebilirsiniz.
Örnekler, zaman uyumsuz uygulamanızı (C#) ayrıntılı olarak ayarlamaya yönelik kullanıcı arabirimini kullanır.

NOTE
Örnekleri çalıştırmak için, bilgisayarınızda Visual Studio 2012 veya daha yeni bir sürümü ve .NET Framework 4,5 ya da daha
yeni bir sürümü yüklü olmalıdır.

Bir görevi iptal etme


İlk örnek, iptal düğmesini tek bir indirme göreviyle ilişkilendirir. Uygulama içerik indirirken düğmeyi seçerseniz,
indirme iptal edilir.
Örneği indirin
Tüm Windows Presentation Foundation (WPF ) projesini zaman uyumsuz örnekten indirebilirsiniz: Uygulamanızı
hassas ayarlamalar yapın ve ardından aşağıdaki adımları izleyin.
1. İndirdiğiniz dosyayı sıkıştırmasını açın ve ardından Visual Studio 'Yu başlatın.
2. Menü çubuğunda Dosya > Aç > Proje/çözüm' ı seçin.
3. Proje Aç iletişim kutusunda, açtığınız örnek kodu tutan klasörü açın ve ardından AsyncFineTuningCS için
çözüm (. sln) dosyasını açın.
4. Çözüm Gezgini' de,,,, Iptal eden görev projesi için kısayol menüsünü açın ve ardından Başlangıç projesi
olarak ayarla' yı seçin.
5. Projeyi çalıştırmak için F5 tuşuna basın (veya, projeyi hata ayıklamadan çalıştırmak için CTRL+F5
tuşlarına basın).

TIP
Projeyi indirmek istemiyorsanız, bu konunun sonundaki MainWindow.xaml.cs dosyalarını gözden geçirebilirsiniz.

Örneği oluşturun
Aşağıdaki değişiklikler bir Web sitesini indiren uygulamaya bir iptal düğmesi ekler. Örneği indirmek veya
derlemek istemiyorsanız, bu konunun sonundaki "tüm örnekler" bölümünde son ürünü gözden geçirebilirsiniz.
Yıldız işaretleri koddaki değişiklikleri işaretler.
Örneği kendiniz oluşturmak için, "örneği Indirme" bölümündeki yönergeleri izleyin, ancak Başlangıç projesi
olarak, 1. aşama yerine startercode ' u seçin.
Ardından, bu projenin MainWindow.xaml.cs dosyasına aşağıdaki değişiklikleri ekleyin.
1. Kendisine erişen CancellationTokenSource tüm yöntemler cts için kapsam içinde olan bir değişken
bildirin.

public partial class MainWindow : Window


{
// ***Declare a System.Threading.CancellationTokenSource.
CancellationTokenSource cts;

2. İptal düğmesi için aşağıdaki olay işleyicisini ekleyin. Olay işleyicisi, Kullanıcı iptali
CancellationTokenSource.Cancel istediğinde bildirimde cts bulunan yöntemini kullanır.

// ***Add an event handler for the Cancel button.


private void cancelButton_Click(object sender, RoutedEventArgs e)
{
if (cts != null)
{
cts.Cancel();
}
}

3. Başlat düğmesi startButton_Click için olay işleyicisinde aşağıdaki değişiklikleri yapın.


CancellationTokenSource , cts İçin örneğini oluşturun.

// ***Instantiate the CancellationTokenSource.


cts = new CancellationTokenSource();

Belirtilen bir Web sitesinin AccessTheWebAsync içeriğini yükleyen çağrısında,


CancellationTokenSource.Token özelliğini cts bağımsız değişken olarak gönderin. Özelliği Token ,
iptal isteniyorsa iletiyi yayar. Kullanıcı indirme işlemini iptal etmeyi seçerse bir ileti görüntüleyen bir
catch bloğu ekleyin. Aşağıdaki kod değişiklikleri gösterir.

try
{
// ***Send a token to carry the message if cancellation is requested.
int contentLength = await AccessTheWebAsync(cts.Token);
resultsTextBox.Text += $"\r\nLength of the downloaded string: {contentLength}.\r\n";
}
// *** If cancellation is requested, an OperationCanceledException results.
catch (OperationCanceledException)
{
resultsTextBox.Text += "\r\nDownload canceled.\r\n";
}
catch (Exception)
{
resultsTextBox.Text += "\r\nDownload failed.\r\n";
}

4. İçinde AccessTheWebAsync , bir Web HttpClient.GetAsync(String, CancellationToken) sitesinin içeriğini


indirmek GetAsync için HttpClient türünde yönteminin aşırı yüklemesini kullanın. İkinci bağımsız değişken
olarak ct , AccessTheWebAsync parametresini geçirin. CancellationToken Kullanıcı iptal düğmesini seçerse,
belirteç iletiyi taşır.
Aşağıdaki kod, içindeki AccessTheWebAsync değişiklikleri gösterir.
// ***Provide a parameter for the CancellationToken.
async Task<int> AccessTheWebAsync(CancellationToken ct)
{
HttpClient client = new HttpClient();

resultsTextBox.Text += "\r\nReady to download.\r\n";

// You might need to slow things down to have a chance to cancel.


await Task.Delay(250);

// GetAsync returns a Task<HttpResponseMessage>.


// ***The ct argument carries the message if the Cancel button is chosen.
HttpResponseMessage response = await
client.GetAsync("https://msdn.microsoft.com/library/dd470362.aspx", ct);

// Retrieve the website contents from the HttpResponseMessage.


byte[] urlContents = await response.Content.ReadAsByteArrayAsync();

// The result of the method is the length of the downloaded website.


return urlContents.Length;
}

5. Programı iptal ederseniz, aşağıdaki çıktıyı üretir.

Ready to download.
Length of the downloaded string: 158125.

Program içeriği indirmeyi bitirmeden iptal düğmesini seçerseniz, program aşağıdaki çıktıyı üretir.

Ready to download.
Download canceled.

Görev listesini iptal etme


Aynı CancellationTokenSource örneği her görevle ilişkilendirerek, daha fazla görevi iptal etmek için önceki örneği
genişletebilirsiniz. İptal düğmesini seçerseniz, henüz tamamlanmamış tüm görevleri iptal edersiniz.
Örneği indirin
Tüm Windows Presentation Foundation (WPF ) projesini zaman uyumsuz örnekten indirebilirsiniz: Uygulamanızı
hassas ayarlamalar yapın ve ardından aşağıdaki adımları izleyin.
1. İndirdiğiniz dosyayı sıkıştırmasını açın ve ardından Visual Studio 'Yu başlatın.
2. Menü çubuğunda Dosya > Aç > Proje/çözüm' ı seçin.
3. Proje Aç iletişim kutusunda, açtığınız örnek kodu tutan klasörü açın ve ardından AsyncFineTuningCS için
çözüm (. sln) dosyasını açın.
4. Çözüm Gezgini' de,,,,,, ,, iptal eden bir proje projesi için kısayol menüsünü açın ve Başlangıç projesi
olarak ayarla' yı seçin.
5. Projeyi çalıştırmak için F5 tuşunu seçin.
Projeyi hata ayıklamadan çalıştırmak için CTRL+F5 tuşlarını seçin.
Projeyi indirmek istemiyorsanız, bu konunun sonundaki MainWindow.xaml.cs dosyalarını gözden geçirebilirsiniz.
Örneği oluşturun
Örneği kendiniz genişletmek için, "örneği Indirme" bölümündeki yönergeleri izleyin, ancak Başlangıç
projesiolarak iptal eden ' i seçin. Aşağıdaki değişiklikleri bu projeye ekleyin. Yıldız işaretleri programdaki
değişiklikleri işaretler.
1. Web adreslerinin bir listesini oluşturmak için bir yöntem ekleyin.

// ***Add a method that creates a list of web addresses.


private List<string> SetUpURLList()
{
List<string> urls = new List<string>
{
"https://msdn.microsoft.com",
"https://msdn.microsoft.com/library/hh290138.aspx",
"https://msdn.microsoft.com/library/hh290140.aspx",
"https://msdn.microsoft.com/library/dd470362.aspx",
"https://msdn.microsoft.com/library/aa578028.aspx",
"https://msdn.microsoft.com/library/ms404677.aspx",
"https://msdn.microsoft.com/library/ff730837.aspx"
};
return urls;
}

2. İçindeki AccessTheWebAsync yöntemi çağırın.

// ***Call SetUpURLList to make a list of web addresses.


List<string> urlList = SetUpURLList();

3. Listesindeki her bir Web adresini AccessTheWebAsync işlemek için aşağıdaki döngüsünü ekleyin.

// ***Add a loop to process the list of web addresses.


foreach (var url in urlList)
{
// GetAsync returns a Task<HttpResponseMessage>.
// Argument ct carries the message if the Cancel button is chosen.
// ***Note that the Cancel button can cancel all remaining downloads.
HttpResponseMessage response = await client.GetAsync(url, ct);

// Retrieve the website contents from the HttpResponseMessage.


byte[] urlContents = await response.Content.ReadAsByteArrayAsync();

resultsTextBox.Text +=
$"\r\nLength of the downloaded string: {urlContents.Length}.\r\n";
}

4. , AccessTheWebAsync Uzunlukları gösterdiği için yöntemin herhangi bir şey döndürmesi gerekmez. Return
ifadesini kaldırın ve yöntemin dönüş türünü Task Task<TResult>yerine olarak değiştirin.

async Task AccessTheWebAsync(CancellationToken ct)

Bir ifadesi yerine deyimi startButton_Click kullanarak yöntemini çağırın.

await AccessTheWebAsync(cts.Token);

5. Programı iptal ederseniz, aşağıdaki çıktıyı üretir.


Length of the downloaded string: 35939.

Length of the downloaded string: 237682.

Length of the downloaded string: 128607.

Length of the downloaded string: 158124.

Length of the downloaded string: 204890.

Length of the downloaded string: 175488.

Length of the downloaded string: 145790.

Downloads complete.

İndirmeler tamamlanmadan önce iptal düğmesini seçerseniz, çıkış, iptalden önce tamamlanan
indirmelerin uzunluklarını içerir.

Length of the downloaded string: 35939.

Length of the downloaded string: 237682.

Length of the downloaded string: 128607.

Downloads canceled.

Tüm örnekler
Aşağıdaki bölümler, önceki örneklerin her birine ilişkin kodu içerir.İçin System.Net.Httpbir başvuru eklemeniz
gerektiğini unutmayın.
Projeleri zaman uyumsuz örnekten indirebilirsiniz: Uygulamanızıhassas bir şekilde ayarlama.
Örnek-bir görevi Iptal etme
Aşağıdaki kod, tek bir görevi iptal eden örnek için tüm MainWindow.xaml.cs dosyasıdır.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

// Add a using directive and a reference for System.Net.Http.


using System.Net.Http;

// Add the following using directive for System.Threading.

using System.Threading;
namespace CancelATask
{
public partial class MainWindow : Window
{
{
// ***Declare a System.Threading.CancellationTokenSource.
CancellationTokenSource cts;

public MainWindow()
{
InitializeComponent();
}

private async void startButton_Click(object sender, RoutedEventArgs e)


{
// ***Instantiate the CancellationTokenSource.
cts = new CancellationTokenSource();

resultsTextBox.Clear();

try
{
// ***Send a token to carry the message if cancellation is requested.
int contentLength = await AccessTheWebAsync(cts.Token);
resultsTextBox.Text +=
$"\r\nLength of the downloaded string: {contentLength}.\r\n";
}
// *** If cancellation is requested, an OperationCanceledException results.
catch (OperationCanceledException)
{
resultsTextBox.Text += "\r\nDownload canceled.\r\n";
}
catch (Exception)
{
resultsTextBox.Text += "\r\nDownload failed.\r\n";
}

// ***Set the CancellationTokenSource to null when the download is complete.


cts = null;
}

// ***Add an event handler for the Cancel button.


private void cancelButton_Click(object sender, RoutedEventArgs e)
{
if (cts != null)
{
cts.Cancel();
}
}

// ***Provide a parameter for the CancellationToken.


async Task<int> AccessTheWebAsync(CancellationToken ct)
{
HttpClient client = new HttpClient();

resultsTextBox.Text += "\r\nReady to download.\r\n";

// You might need to slow things down to have a chance to cancel.


await Task.Delay(250);

// GetAsync returns a Task<HttpResponseMessage>.


// ***The ct argument carries the message if the Cancel button is chosen.
HttpResponseMessage response = await
client.GetAsync("https://msdn.microsoft.com/library/dd470362.aspx", ct);

// Retrieve the website contents from the HttpResponseMessage.


byte[] urlContents = await response.Content.ReadAsByteArrayAsync();

// The result of the method is the length of the downloaded website.


return urlContents.Length;
}
}

// Output for a successful download:


// Output for a successful download:

// Ready to download.

// Length of the downloaded string: 158125.

// Or, if you cancel:

// Ready to download.

// Download canceled.
}

Örnek-görev listesini Iptal etme


Aşağıdaki kod, bir görev listesini iptal eden örnek için tüm MainWindow.xaml.cs dosyasıdır.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

// Add a using directive and a reference for System.Net.Http.


using System.Net.Http;

// Add the following using directive for System.Threading.


using System.Threading;

namespace CancelAListOfTasks
{
public partial class MainWindow : Window
{
// Declare a System.Threading.CancellationTokenSource.
CancellationTokenSource cts;

public MainWindow()
{
InitializeComponent();
}

private async void startButton_Click(object sender, RoutedEventArgs e)


{
// Instantiate the CancellationTokenSource.
cts = new CancellationTokenSource();

resultsTextBox.Clear();

try
{
await AccessTheWebAsync(cts.Token);
// ***Small change in the display lines.
resultsTextBox.Text += "\r\nDownloads complete.";
}
catch (OperationCanceledException)
{
resultsTextBox.Text += "\r\nDownloads canceled.";
}
catch (Exception)
{
resultsTextBox.Text += "\r\nDownloads failed.";
}

// Set the CancellationTokenSource to null when the download is complete.


cts = null;
}

// Add an event handler for the Cancel button.


private void cancelButton_Click(object sender, RoutedEventArgs e)
{
if (cts != null)
{
cts.Cancel();
}
}

// Provide a parameter for the CancellationToken.


// ***Change the return type to Task because the method has no return statement.
async Task AccessTheWebAsync(CancellationToken ct)
{
// Declare an HttpClient object.
HttpClient client = new HttpClient();

// ***Call SetUpURLList to make a list of web addresses.


List<string> urlList = SetUpURLList();

// ***Add a loop to process the list of web addresses.


foreach (var url in urlList)
{
// GetAsync returns a Task<HttpResponseMessage>.
// Argument ct carries the message if the Cancel button is chosen.
// ***Note that the Cancel button can cancel all remaining downloads.
HttpResponseMessage response = await client.GetAsync(url, ct);

// Retrieve the website contents from the HttpResponseMessage.


byte[] urlContents = await response.Content.ReadAsByteArrayAsync();

resultsTextBox.Text +=
$"\r\nLength of the downloaded string: {urlContents.Length}.\r\n";
}
}

// ***Add a method that creates a list of web addresses.


private List<string> SetUpURLList()
{
List<string> urls = new List<string>
{
"https://msdn.microsoft.com",
"https://msdn.microsoft.com/library/hh290138.aspx",
"https://msdn.microsoft.com/library/hh290140.aspx",
"https://msdn.microsoft.com/library/dd470362.aspx",
"https://msdn.microsoft.com/library/aa578028.aspx",
"https://msdn.microsoft.com/library/ms404677.aspx",
"https://msdn.microsoft.com/library/ff730837.aspx"
};
return urls;
}
}

// Output if you do not choose to cancel:

//Length of the downloaded string: 35939.

//Length of the downloaded string: 237682.

//Length of the downloaded string: 128607.

//Length of the downloaded string: 158124.


//Length of the downloaded string: 204890.

//Length of the downloaded string: 175488.

//Length of the downloaded string: 145790.

//Downloads complete.

// Sample output if you choose to cancel:

//Length of the downloaded string: 35939.

//Length of the downloaded string: 237682.

//Length of the downloaded string: 128607.

//Downloads canceled.
}

Ayrıca bkz.
CancellationTokenSource
CancellationToken
Async ve await (C#) ile zaman uyumsuz programlama
Zaman uyumsuz uygulamanızda ince ayar yapma (C#)
Zaman uyumsuz örnek: Uygulamanızda ince ayar yapma
Zaman uyumsuz görevleri bir süre sonra iptal et (C#)
23.10.2019 • 6 minutes to read • Edit Online

İşlemin bitmesini beklemek istemiyorsanız CancellationTokenSource.CancelAfter yöntemini kullanarak bir süre


sonra zaman uyumsuz bir işlemi iptal edebilirsiniz. Bu yöntem, CancelAfter ifadesi tarafından belirlenen süre
içinde tamamlanmamış olan ilişkili görevlerin iptalini zamanlar.
Bu örnek, bir Web sitesi listesini indirmek ve her birinin içerik uzunluğunu göstermek için zaman uyumsuz bir
görevi veyaC#görev listesini () iptal etmek üzere geliştirilmiş koda ekler.

NOTE
Örnekleri çalıştırmak için, bilgisayarınızda Visual Studio 2012 veya daha yeni bir sürümü ve .NET Framework 4,5 ya da daha
yeni bir sürümü yüklü olmalıdır.

Örneği indirin
Tüm Windows Presentation Foundation (WPF ) projesini zaman uyumsuz örnekten indirebilirsiniz: Uygulamanızı
hassas ayarlamalar yapın ve ardından aşağıdaki adımları izleyin.
1. İndirdiğiniz dosyayı sıkıştırmasını açın ve ardından Visual Studio 'Yu başlatın.
2. Menü çubuğunda Dosya > Aç > Proje/çözüm' ı seçin.
3. Proje Aç iletişim kutusunda, açtığınız örnek kodu tutan klasörü açın ve ardından AsyncFineTuningCS için
çözüm (. sln) dosyasını açın.
4. Çözüm Gezgini, zaman hatası ve ardından Başlangıç projesi olarak ayarla' yı seçin.
5. Projeyi çalıştırmak için F5 tuşunu seçin. (Veya, projeyi hata ayıklamadan çalıştırmak için CTRL+F5 tuşuna
basın).
6. Çıktının tüm Web siteleri, Web sitesi veya bazı Web siteleri için çıktıyı gösterebileceğini doğrulamak için
programı birkaç kez çalıştırın.
Projeyi indirmek istemiyorsanız, bu konunun sonundaki MainWindow.xaml.cs dosyasını gözden geçirebilirsiniz.

Örneği oluşturun
Bu konudaki örnek, bir görev listesini iptal etmek için zaman uyumsuz bir görevi veya görev listesini (C#) iptal
etmek üzere geliştirilmiş projeye ekler. Örnek, aynı kullanıcı arabirimini kullanır, ancak iptal düğmesi açıkça
kullanılmaz.
Örneği kendiniz oluşturmak için, "örneği Indirme" bölümündeki yönergeleri izleyin, ancak Başlangıç
projesiolarak iptal eden ınlıftasks ' ı seçin. Bu konudaki değişiklikleri bu projeye ekleyin.
Görevler iptal edildi olarak işaretlenmeden önce en uzun süreyi belirtmek için, aşağıdaki örnekte gösterildiği gibi
CancelAfter öğesine startButton_Click bir çağrı ekleyin. Toplama, yıldız işareti ile işaretlenir.
private async void startButton_Click(object sender, RoutedEventArgs e)
{
// Instantiate the CancellationTokenSource.
cts = new CancellationTokenSource();

resultsTextBox.Clear();

try
{
// ***Set up the CancellationTokenSource to cancel after 2.5 seconds. (You
// can adjust the time.)
cts.CancelAfter(2500);

await AccessTheWebAsync(cts.Token);
resultsTextBox.Text += "\r\nDownloads succeeded.\r\n";
}
catch (OperationCanceledException)
{
resultsTextBox.Text += "\r\nDownloads canceled.\r\n";
}
catch (Exception)
{
resultsTextBox.Text += "\r\nDownloads failed.\r\n";
}

cts = null;
}

Çıktının tüm Web siteleri, Web sitesi veya bazı Web siteleri için çıktıyı gösterebileceğini doğrulamak için programı
birkaç kez çalıştırın. Aşağıdaki çıktı bir örnektir.

Length of the downloaded string: 35990.

Length of the downloaded string: 407399.

Length of the downloaded string: 226091.

Downloads canceled.

Örnek Tamam
Aşağıdaki kod, örnek için MainWindow.xaml.cs dosyasının tüm metinkodudur. Yıldız işaretleri bu örnek için
eklenen öğeleri işaretler.
İçin System.Net.Httpbir başvuru eklemeniz gerektiğini unutmayın.
Projeyi zaman uyumsuz örnekten indirebilirsiniz: Uygulamanızıhassas bir şekilde ayarlama.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
// Add a using directive and a reference for System.Net.Http.
using System.Net.Http;

// Add the following using directive.


using System.Threading;

namespace CancelAfterTime
{
public partial class MainWindow : Window
{
// Declare a System.Threading.CancellationTokenSource.
CancellationTokenSource cts;

public MainWindow()
{
InitializeComponent();
}

private async void startButton_Click(object sender, RoutedEventArgs e)


{
// Instantiate the CancellationTokenSource.
cts = new CancellationTokenSource();

resultsTextBox.Clear();

try
{
// ***Set up the CancellationTokenSource to cancel after 2.5 seconds. (You
// can adjust the time.)
cts.CancelAfter(2500);

await AccessTheWebAsync(cts.Token);
resultsTextBox.Text += "\r\nDownloads succeeded.\r\n";
}
catch (OperationCanceledException)
{
resultsTextBox.Text += "\r\nDownloads canceled.\r\n";
}
catch (Exception)
{
resultsTextBox.Text += "\r\nDownloads failed.\r\n";
}

cts = null;
}

// You can still include a Cancel button if you want to.


private void cancelButton_Click(object sender, RoutedEventArgs e)
{
if (cts != null)
{
cts.Cancel();
}
}

async Task AccessTheWebAsync(CancellationToken ct)


{
// Declare an HttpClient object.
HttpClient client = new HttpClient();

// Make a list of web addresses.


List<string> urlList = SetUpURLList();

foreach (var url in urlList)


{
// GetAsync returns a Task<HttpResponseMessage>.
// Argument ct carries the message if the Cancel button is chosen.
// Note that the Cancel button cancels all remaining downloads.
HttpResponseMessage response = await client.GetAsync(url, ct);
HttpResponseMessage response = await client.GetAsync(url, ct);

// Retrieve the website contents from the HttpResponseMessage.


byte[] urlContents = await response.Content.ReadAsByteArrayAsync();

resultsTextBox.Text +=
$"\r\nLength of the downloaded string: {urlContents.Length}.\r\n";
}
}

private List<string> SetUpURLList()


{
List<string> urls = new List<string>
{
"https://msdn.microsoft.com",
"https://msdn.microsoft.com/library/windows/apps/br211380.aspx",
"https://msdn.microsoft.com/library/hh290136.aspx",
"https://msdn.microsoft.com/library/ee256749.aspx",
"https://msdn.microsoft.com/library/ms404677.aspx",
"https://msdn.microsoft.com/library/ff730837.aspx"
};
return urls;
}
}

// Sample Output:

// Length of the downloaded string: 35990.

// Length of the downloaded string: 407399.

// Length of the downloaded string: 226091.

// Downloads canceled.
}

Ayrıca bkz.
Async ve await (C#) ile zaman uyumsuz programlama
İzlenecek yol: Async ve await (C#) kullanarak Web 'e erişme
Zaman uyumsuz bir görevi veya görev listesini iptal etme (C#)
Zaman uyumsuz uygulamanızda ince ayar yapma (C#)
Zaman uyumsuz örnek: Uygulamanızda ince ayar yapma
Tamamlandıktan sonra kalan zaman uyumsuz
görevleri iptal et (C#)
23.10.2019 • 9 minutes to read • Edit Online

Task.WhenAny Yöntemini birCancellationTokenile birlikte kullanarak, bir görev tamamlandığında kalan tüm
görevleri iptal edebilirsiniz. Yöntemi WhenAny , bir görev koleksiyonu olan bir bağımsız değişken alır. Yöntemi tüm
görevleri başlatır ve tek bir görev döndürür. Koleksiyondaki herhangi bir görev tamamlandığında tek görev
tamamlanır.
Bu örnek, bir iptal belirtecinin, görev koleksiyonundan sona ermesini ve WhenAny kalan görevleri iptal etmek için
ilk görevi tutmak üzere ile birlikte nasıl kullanılacağını gösterir. Her görev bir Web sitesinin içeriğini indirir. Örnek,
tamamlanacak ilk indirmenin içeriklerinin uzunluğunu görüntüler ve diğer indirmeleri iptal eder.

NOTE
Örnekleri çalıştırmak için, bilgisayarınızda Visual Studio 2012 veya daha yeni bir sürümü ve .NET Framework 4,5 ya da daha
yeni bir sürümü yüklü olmalıdır.

Örnek indiriliyor
Tüm Windows Presentation Foundation (WPF ) projesini zaman uyumsuz örnekten indirebilirsiniz: Uygulamanızı
hassas ayarlamalar yapın ve ardından aşağıdaki adımları izleyin.
1. İndirdiğiniz dosyayı sıkıştırmasını açın ve ardından Visual Studio 'Yu başlatın.
2. Menü çubuğunda Dosya, Aç, Proje/çözüm' ü seçin.
3. Proje Aç iletişim kutusunda, açtığınız örnek kodu tutan klasörü açın ve ardından AsyncFineTuningCS için
çözüm (. sln) dosyasını açın.
4. Çözüm Gezgini' de, ınkıfteronetask projesinin kısayol menüsünü açın ve ardından Başlangıç projesi
olarak ayarla' yı seçin.
5. Projeyi çalıştırmak için F5 tuşunu seçin.
Projeyi hata ayıklamadan çalıştırmak için CTRL + F5 tuşlarını seçin.
6. İlk olarak farklı indirmelerin bitmesini doğrulamak için programı birkaç kez çalıştırın.
Projeyi indirmek istemiyorsanız, bu konunun sonundaki MainWindow.xaml.cs dosyasını gözden geçirebilirsiniz.

Örnek oluşturma
Bu konudaki örnek, bir görev listesini iptal etmek için zaman uyumsuz bir görevi veya görev listesini (C#) iptal
etmek üzere geliştirilmiş projeye ekler. Örnek, aynı kullanıcı arabirimini kullanır, ancak iptal düğmesi açıkça
kullanılmaz.
Örneği kendiniz oluşturmak için, "örneği Indirme" bölümündeki yönergeleri izleyin, ancak Başlangıç
projesiolarak iptal eden ınlıftasks ' ı seçin. Bu konudaki değişiklikleri bu projeye ekleyin.
"MainWindow.xaml.cs & lt; & lt; & lt; & lt; & lt; 3} dosya dosyasında, içindeki AccessTheWebAsync her bir Web sitesi
için işleme adımlarını aşağıdaki zaman uyumsuz metoda taşıyarak geçişi başlatın.
// ***Bundle the processing steps for a website into one async method.
async Task<int> ProcessURLAsync(string url, HttpClient client, CancellationToken ct)
{
// GetAsync returns a Task<HttpResponseMessage>.
HttpResponseMessage response = await client.GetAsync(url, ct);

// Retrieve the website contents from the HttpResponseMessage.


byte[] urlContents = await response.Content.ReadAsByteArrayAsync();

return urlContents.Length;
}

' AccessTheWebAsync De, bu örnek bir sorgu ToArray , yöntem ve WhenAny bir dizi görev oluşturmak ve başlatmak
için yöntemini kullanır. Dizi için olan WhenAny uygulaması, bir görev dizisinde tamamlamaya ulaşmak üzere ilk
görevi değerlendiren tek bir görev döndürür.
İçinde AccessTheWebAsync aşağıdaki değişiklikleri yapın. Yıldız işaretleri kod dosyasındaki değişiklikleri işaretler.
1. Döngüyü not edin veya silin.
2. Yürütüldüğünde, genel görevlerden oluşan bir koleksiyon üreten bir sorgu oluşturun. Her çağrısı
ProcessURLAsync , TResult bir, Task<TResult> bir tamsayı olan bir döndürür.

// ***Create a query that, when executed, returns a collection of tasks.


IEnumerable<Task<int>> downloadTasksQuery =
from url in urlList select ProcessURLAsync(url, client, ct);

3. Sorguyu ToArray yürütmek ve görevleri başlatmak için çağırın. Bir WhenAny sonraki adımda yönteminin
uygulaması sorguyu yürütür ve görevleri kullanmadan ToArray başlatır, ancak diğer yöntemler de
çalışmayabilir. En güvenli yöntem, sorgunun yürütülmesini açıkça zorlamaktır.

// ***Use ToArray to execute the query and start the download tasks.
Task<int>[] downloadTasks = downloadTasksQuery.ToArray();

4. Görevler WhenAny koleksiyonunda çağırın. WhenAny bir Task(Of Task(Of Integer)) veya Task<Task<int>>
döndürür. Diğer bir deyişle WhenAny , tek Task(Of Integer) veya Task<int> bekleniyor bir görevi
döndürür. Bu tek görev, koleksiyondaki ilk görevin sona ermesini sağlar. Önce tamamlanan görev öğesine
firstFinishedTask atanır. Türü firstFinishedTask Task<TResult> ProcessURLAsync , öğesinin dönüş türü
olduğu için bir tamsayıdır. TResult

// ***Call WhenAny and then await the result. The task that finishes
// first is assigned to firstFinishedTask.
Task<int> firstFinishedTask = await Task.WhenAny(downloadTasks);

5. Bu örnekte, yalnızca ilk olarak sona erki görevi ilgileniyorsunuz. Bu nedenle,


CancellationTokenSource.Cancel kalan görevleri iptal etmek için kullanın.

// ***Cancel the rest of the downloads. You just want the first one.
cts.Cancel();

6. Son olarak, firstFinishedTask indirilen içeriğin uzunluğunu almak için Await.


var length = await firstFinishedTask;
resultsTextBox.Text += $"\r\nLength of the downloaded website: {length}\r\n";

İlk olarak farklı indirmelerin bitmesini doğrulamak için programı birkaç kez çalıştırın.

Tam Örnek
Aşağıdaki kod, örnek için tüm MainWindow.xaml.cs dosyasıdır. Yıldız işaretleri bu örnek için eklenen öğeleri
işaretler.
İçin System.Net.Httpbir başvuru eklemeniz gerektiğini unutmayın.
Projeyi zaman uyumsuz örnekten indirebilirsiniz: Uygulamanızıhassas bir şekilde ayarlama.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

// Add a using directive and a reference for System.Net.Http.


using System.Net.Http;

// Add the following using directive.


using System.Threading;

namespace CancelAfterOneTask
{
public partial class MainWindow : Window
{
// Declare a System.Threading.CancellationTokenSource.
CancellationTokenSource cts;

public MainWindow()
{
InitializeComponent();
}

private async void startButton_Click(object sender, RoutedEventArgs e)


{
// Instantiate the CancellationTokenSource.
cts = new CancellationTokenSource();

resultsTextBox.Clear();

try
{
await AccessTheWebAsync(cts.Token);
resultsTextBox.Text += "\r\nDownload complete.";
}
catch (OperationCanceledException)
{
resultsTextBox.Text += "\r\nDownload canceled.";
}
catch (Exception)
{
{
resultsTextBox.Text += "\r\nDownload failed.";
}

// Set the CancellationTokenSource to null when the download is complete.


cts = null;
}

// You can still include a Cancel button if you want to.


private void cancelButton_Click(object sender, RoutedEventArgs e)
{
if (cts != null)
{
cts.Cancel();
}
}

// Provide a parameter for the CancellationToken.


async Task AccessTheWebAsync(CancellationToken ct)
{
HttpClient client = new HttpClient();

// Call SetUpURLList to make a list of web addresses.


List<string> urlList = SetUpURLList();

// ***Comment out or delete the loop.


//foreach (var url in urlList)
//{
// // GetAsync returns a Task<HttpResponseMessage>.
// // Argument ct carries the message if the Cancel button is chosen.
// // ***Note that the Cancel button can cancel all remaining downloads.
// HttpResponseMessage response = await client.GetAsync(url, ct);

// // Retrieve the website contents from the HttpResponseMessage.


// byte[] urlContents = await response.Content.ReadAsByteArrayAsync();

// resultsTextBox.Text +=
// $"\r\nLength of the downloaded string: {urlContents.Length}.\r\n";
//}

// ***Create a query that, when executed, returns a collection of tasks.


IEnumerable<Task<int>> downloadTasksQuery =
from url in urlList select ProcessURLAsync(url, client, ct);

// ***Use ToArray to execute the query and start the download tasks.
Task<int>[] downloadTasks = downloadTasksQuery.ToArray();

// ***Call WhenAny and then await the result. The task that finishes
// first is assigned to firstFinishedTask.
Task<int> firstFinishedTask = await Task.WhenAny(downloadTasks);

// ***Cancel the rest of the downloads. You just want the first one.
cts.Cancel();

// ***Await the first completed task and display the results.


// Run the program several times to demonstrate that different
// websites can finish first.
var length = await firstFinishedTask;
resultsTextBox.Text += $"\r\nLength of the downloaded website: {length}\r\n";
}

// ***Bundle the processing steps for a website into one async method.
async Task<int> ProcessURLAsync(string url, HttpClient client, CancellationToken ct)
{
// GetAsync returns a Task<HttpResponseMessage>.
HttpResponseMessage response = await client.GetAsync(url, ct);

// Retrieve the website contents from the HttpResponseMessage.


byte[] urlContents = await response.Content.ReadAsByteArrayAsync();
return urlContents.Length;
}

// Add a method that creates a list of web addresses.


private List<string> SetUpURLList()
{
List<string> urls = new List<string>
{
"https://msdn.microsoft.com",
"https://msdn.microsoft.com/library/hh290138.aspx",
"https://msdn.microsoft.com/library/hh290140.aspx",
"https://msdn.microsoft.com/library/dd470362.aspx",
"https://msdn.microsoft.com/library/aa578028.aspx",
"https://msdn.microsoft.com/library/ms404677.aspx",
"https://msdn.microsoft.com/library/ff730837.aspx"
};
return urls;
}
}
// Sample output:

// Length of the downloaded website: 158856

// Download complete.
}

Ayrıca bkz.
WhenAny
Zaman uyumsuz uygulamanızda ince ayar yapma (C#)
Async ve await (C#) ile zaman uyumsuz programlama
Zaman uyumsuz örnek: Uygulamanızda ince ayar yapma
Birden çok zaman uyumsuz görev başlatın ve bunları
tamamlarsa (C#) işleyin
23.11.2019 • 7 minutes to read • Edit Online

Task.WhenAnykullanarak, aynı anda birden çok görev başlatabilir ve bunları, başlatıldıkları sırada işlemek yerine,
bir kez işlem tamamlanır.
Aşağıdaki örnek, bir görev koleksiyonu oluşturmak için bir sorgu kullanır. Her görev belirtilen bir Web sitesinin
içeriğini indirir. Bir while döngüsünün her yinelemesinde, bir WhenAny çağrısı, ilk önce indirmeyi izleyen görevler
koleksiyonundaki görevi döndürür. Bu görev koleksiyondan kaldırılır ve işlenir. Döngü, koleksiyon daha fazla
görev içerene kadar yinelenir.

NOTE
Örnekleri çalıştırmak için, bilgisayarınızda Visual Studio (2012 veya üzeri) ve .NET Framework 4,5 ya da daha yeni bir sürümü
yüklü olmalıdır.

Örnek çözüm indirin


Tüm Windows Presentation Foundation (WPF ) projesini zaman uyumsuz örnekten indirebilirsiniz: uygulamanızı
Ince ayar yapın ve ardından aşağıdaki adımları izleyin.

TIP
Projeyi indirmek istemiyorsanız, bunun yerine bu konunun sonundaki MainWindow.xaml.cs dosyasını gözden geçirebilirsiniz.

1. İndirdiğiniz dosyaları . zip dosyasından ayıklayın ve ardından Visual Studio 'yu başlatın.
2. Menü çubuğunda dosya > > Proje/çözüm Aç ' ı seçin.
3. Proje Aç iletişim kutusunda, indirdiğiniz örnek kodu tutan klasörü açın ve ardından
AsyncFineTuningCS/AsyncFineTuningVBiçin çözüm ( . sln) dosyasını açın.
4. Çözüm Gezgini' de, Processtasksastheyıfinish projesinin kısayol menüsünü açın ve ardından
Başlangıç projesi olarak ayarla' yı seçin.
5. Programı hata ayıklamayla çalıştırmak için F5 tuşunu seçin veya programı hata ayıklamadan çalıştırmak
için CTRL+F5 tuşlarına basın.
6. İndirilen uzunluklarının her zaman aynı sırada görünmediğini doğrulamak için projeyi birkaç kez çalıştırın.

Programı kendiniz oluşturun


Bu örnek, bir tane tamamlandıktan sonra kalan zaman uyumsuz görevleri iptal etmeC#bölümünde geliştirilen
koda ekler () ve aynı kullanıcı arabirimini kullanır.
Örneği kendiniz oluşturmak için, örnek ' i karşıdan yükleme bölümündeki yönergeleri izleyin, ancak başlangıç
projesi olarak, bir erteleme görevi ayarlayın. Bu konudaki değişiklikleri bu projedeki AccessTheWebAsync
yöntemine ekleyin. Değişiklikler yıldız işaretiyle işaretlenir.
Bu görev projesi, yürütüldüğünde bir görev koleksiyonu oluşturduğunda zaten bir sorgu içeriyor. Aşağıdaki
koddaki ProcessURLAsync her bir çağrı, TResult bir tamsayı olduğu Task<TResult>döndürür:

IEnumerable<Task<int>> downloadTasksQuery = from url in urlList select ProcessURL(url, client, ct);

Projenin MainWindow.xaml.cs dosyasında AccessTheWebAsync yönteminde aşağıdaki değişiklikleri yapın:


ToArrayyerine Enumerable.ToList uygulayarak sorguyu yürütün.

List<Task<int>> downloadTasks = downloadTasksQuery.ToList();

Koleksiyondaki her görev için aşağıdaki adımları gerçekleştiren bir while döngüsü ekleyin:
1. Bir WhenAny çağrısını, son indirme işleminin sona ermesi için koleksiyondaki ilk görevi tanımlamak
üzere bekler.

Task<int> firstFinishedTask = await Task.WhenAny(downloadTasks);

2. Bu görevi koleksiyondan kaldırır.

downloadTasks.Remove(firstFinishedTask);

3. Await firstFinishedTask , bir ProcessURLAsync çağrısıyla döndürülür. firstFinishedTask değişkeni,


TReturn bir tamsayı olduğu bir Task<TResult>. Görev zaten tamamlanmış, ancak aşağıdaki örnekte
gösterildiği gibi, indirilen Web sitesinin uzunluğunu almak için bu işlemi beklediniz. Görev hata
verdiyse, await AggregateException oluşturacak Result özelliğini okumaktan farklı olarak,
AggregateException depolanan ilk alt özel durumu oluşturur.

int length = await firstFinishedTask;


resultsTextBox.Text += $"\r\nLength of the download: {length}";

İndirilen uzunluklarının her zaman aynı sırada görünmediğini doğrulamak için programı birkaç kez çalıştırın.
Cau t i on

Az sayıda görevle ilgili sorunları gidermek için örnekte açıklandığı gibi bir döngüde WhenAny kullanabilirsiniz.
Ancak, işlemek için çok sayıda göreviniz varsa diğer yaklaşımlar daha etkilidir. Daha fazla bilgi ve örnek için bkz.
görevleri tamamladıklarında işleme.

Örnek Tamam
Aşağıdaki kod, örnek için MainWindow.xaml.cs dosyasının tüm metinkodudur. Yıldız işaretleri bu örnek için
eklenen öğeleri işaretler. Ayrıca, System.Net.Httpiçin bir başvuru eklemeniz gerektiğini unutmayın.
Projeyi zaman uyumsuz örnekten indirebilirsiniz: uygulamanızı hassas bir şekilde ayarlama.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

// Add a using directive and a reference for System.Net.Http.


using System.Net.Http;

// Add the following using directive.


using System.Threading;

namespace ProcessTasksAsTheyFinish
{
public partial class MainWindow : Window
{
// Declare a System.Threading.CancellationTokenSource.
CancellationTokenSource cts;

public MainWindow()
{
InitializeComponent();
}

private async void startButton_Click(object sender, RoutedEventArgs e)


{
resultsTextBox.Clear();

// Instantiate the CancellationTokenSource.


cts = new CancellationTokenSource();

try
{
await AccessTheWebAsync(cts.Token);
resultsTextBox.Text += "\r\nDownloads complete.";
}
catch (OperationCanceledException)
{
resultsTextBox.Text += "\r\nDownloads canceled.\r\n";
}
catch (Exception)
{
resultsTextBox.Text += "\r\nDownloads failed.\r\n";
}

cts = null;
}

private void cancelButton_Click(object sender, RoutedEventArgs e)


{
if (cts != null)
{
cts.Cancel();
}
}

async Task AccessTheWebAsync(CancellationToken ct)


{
HttpClient client = new HttpClient();

// Make a list of web addresses.


List<string> urlList = SetUpURLList();

// ***Create a query that, when executed, returns a collection of tasks.


IEnumerable<Task<int>> downloadTasksQuery =
from url in urlList select ProcessURL(url, client, ct);

// ***Use ToList to execute the query and start the tasks.


List<Task<int>> downloadTasks = downloadTasksQuery.ToList();

// ***Add a loop to process the tasks one at a time until none remain.
// ***Add a loop to process the tasks one at a time until none remain.
while (downloadTasks.Count > 0)
{
// Identify the first task that completes.
Task<int> firstFinishedTask = await Task.WhenAny(downloadTasks);

// ***Remove the selected task from the list so that you don't
// process it more than once.
downloadTasks.Remove(firstFinishedTask);

// Await the completed task.


int length = await firstFinishedTask;
resultsTextBox.Text += $"\r\nLength of the download: {length}";
}
}

private List<string> SetUpURLList()


{
List<string> urls = new List<string>
{
"https://msdn.microsoft.com",
"https://msdn.microsoft.com/library/windows/apps/br211380.aspx",
"https://msdn.microsoft.com/library/hh290136.aspx",
"https://msdn.microsoft.com/library/dd470362.aspx",
"https://msdn.microsoft.com/library/aa578028.aspx",
"https://msdn.microsoft.com/library/ms404677.aspx",
"https://msdn.microsoft.com/library/ff730837.aspx"
};
return urls;
}

async Task<int> ProcessURL(string url, HttpClient client, CancellationToken ct)


{
// GetAsync returns a Task<HttpResponseMessage>.
HttpResponseMessage response = await client.GetAsync(url, ct);

// Retrieve the website contents from the HttpResponseMessage.


byte[] urlContents = await response.Content.ReadAsByteArrayAsync();

return urlContents.Length;
}
}
}

// Sample Output:

// Length of the download: 226093


// Length of the download: 412588
// Length of the download: 175490
// Length of the download: 204890
// Length of the download: 158855
// Length of the download: 145790
// Length of the download: 44908
// Downloads complete.

Ayrıca bkz.
WhenAny
Zaman uyumsuz uygulamanızda ince ayar yapma (C#)
Async ve await (C#) ile zaman uyumsuz programlama
Zaman uyumsuz örnek: uygulamanıza Ince ayar yapma
Zaman uyumsuz uygulamalarda yeniden girişi işleme
(C#)
24.10.2019 • 25 minutes to read • Edit Online

Uygulamanıza zaman uyumsuz kod eklediğinizde, işlem tamamlanmadan önce zaman uyumsuz bir işlemi yeniden
girmeye işaret eden yeniden giriş yapmayı göz önünde bulundurmalı ve muhtemelen engellemeniz gerekir.
Yeniden giriş için olanaklar tanımlamazsanız ve işleyemezseniz, bu durum beklenmedik sonuçlara neden olabilir.
Bu konuda
Yeniden giriş tanıma
Yeniden giriş işleme
Başlat düğmesini devre dışı bırak
Işlemi iptal edin ve yeniden başlatın
Birden çok Işlemi çalıştırma ve çıktıyı sıraya alma
Örnek uygulamayı inceleme ve çalıştırma

NOTE
Örneği çalıştırmak için, bilgisayarınızda Visual Studio 2012 veya daha yeni bir sürümü ve .NET Framework 4,5 ya da daha
yeni bir sürümü yüklü olmalıdır.

NOTE
Aktarım Katmanı Güvenliği (TLS) sürüm 1,2 artık uygulama geliştirmede kullanılacak en düşük sürümdür. Uygulamanız 4,7
sürümünden önceki bir .NET Framework sürümünü hedefliyorsa, lütfen .NET Framework Aktarım Katmanı Güvenliği (TLS) en
iyi uygulamaları için aşağıdaki makaleye bakın

Yeniden giriş tanıma


Bu konudaki örnekte, kullanıcılar bir dizi Web sitesini indiren ve indirilen toplam bayt sayısını hesaplayan bir
zaman uyumsuz uygulamayı başlatmak için bir Başlat düğmesi seçer. Örneğin zaman uyumlu bir sürümü, bir
kullanıcının düğmeyi kaç kez seçtiğinden bağımsız olarak aynı şekilde yanıt verir, çünkü ilk kez sonra, uygulama
çalışmaya bitene kadar UI iş parçacığı bu olayları yoksayar. Ancak zaman uyumsuz bir uygulamada, UI iş parçacığı
yanıt vermeye devam eder ve tamamlanmadan önce zaman uyumsuz işlemi yeniden girebilirsiniz.
Aşağıdaki örnek, Kullanıcı Başlat düğmesini yalnızca bir kez seçerse beklenen çıktıyı gösterir. İndirilen Web
sitelerinin listesi, her sitenin bayt cinsinden boyutu ile görüntülenir. Toplam bayt sayısı sonda görüntülenir.
1. msdn.microsoft.com/library/hh191443.aspx 83732
2. msdn.microsoft.com/library/aa578028.aspx 205273
3. msdn.microsoft.com/library/jj155761.aspx 29019
4. msdn.microsoft.com/library/hh290140.aspx 117152
5. msdn.microsoft.com/library/hh524395.aspx 68959
6. msdn.microsoft.com/library/ms404677.aspx 197325
7. msdn.microsoft.com 42972
8. msdn.microsoft.com/library/ff730837.aspx 146159

TOTAL bytes returned: 890591

Ancak Kullanıcı düğmeyi birden çok kez seçerse, olay işleyicisi sürekli olarak çağrılır ve yükleme işlemi her
seferinde yeniden girilir. Sonuç olarak, birkaç zaman uyumsuz işlem aynı anda çalışır, çıkış sonuçları birbirine
bırakır ve toplam bayt sayısı kafa karıştırıcı olur.

1. msdn.microsoft.com/library/hh191443.aspx 83732
2. msdn.microsoft.com/library/aa578028.aspx 205273
3. msdn.microsoft.com/library/jj155761.aspx 29019
4. msdn.microsoft.com/library/hh290140.aspx 117152
5. msdn.microsoft.com/library/hh524395.aspx 68959
1. msdn.microsoft.com/library/hh191443.aspx 83732
2. msdn.microsoft.com/library/aa578028.aspx 205273
6. msdn.microsoft.com/library/ms404677.aspx 197325
3. msdn.microsoft.com/library/jj155761.aspx 29019
7. msdn.microsoft.com 42972
4. msdn.microsoft.com/library/hh290140.aspx 117152
8. msdn.microsoft.com/library/ff730837.aspx 146159

TOTAL bytes returned: 890591

5. msdn.microsoft.com/library/hh524395.aspx 68959
1. msdn.microsoft.com/library/hh191443.aspx 83732
2. msdn.microsoft.com/library/aa578028.aspx 205273
6. msdn.microsoft.com/library/ms404677.aspx 197325
3. msdn.microsoft.com/library/jj155761.aspx 29019
4. msdn.microsoft.com/library/hh290140.aspx 117152
7. msdn.microsoft.com 42972
5. msdn.microsoft.com/library/hh524395.aspx 68959
8. msdn.microsoft.com/library/ff730837.aspx 146159

TOTAL bytes returned: 890591

6. msdn.microsoft.com/library/ms404677.aspx 197325
7. msdn.microsoft.com 42972
8. msdn.microsoft.com/library/ff730837.aspx 146159

TOTAL bytes returned: 890591

Bu çıkışın sonuna kadar kayarak bu çıktıyı üreten kodu gözden geçirebilirsiniz. Çözümü yerel bilgisayarınıza
indirerek ve ardından WebsiteDownload projesini çalıştırarak veya kendi projenizi oluşturmak için bu konunun
sonundaki kodu kullanarak kodu deneyebilirsiniz. Daha fazla bilgi ve yönergeler için bkz. Örnek uygulamayı
inceleme ve çalıştırma.

Yeniden giriş işleme


Uygulamanızın ne yaptığını istediğinize bağlı olarak çeşitli yollarla yeniden giriş gerçekleştirebilirsiniz. Bu konu
aşağıdaki örnekleri sunmaktadır:
Başlat düğmesini devre dışı bırak
İşlem çalışırken kullanıcının kesintiye uğramaması için Başlat düğmesini devre dışı bırakın.
Işlemi iptal edin ve yeniden başlatın
Kullanıcı Başlat düğmesini yeniden seçtiğinde çalışmaya devam eden tüm işlemleri iptal edin ve son
istenen işlemin devam etmesine izin verin.
Birden çok Işlemi çalıştırma ve çıktıyı sıraya alma
Tüm istenen işlemlerin zaman uyumsuz olarak çalışmasına izin verin, ancak her bir işlemin sonuçlarının bir
arada ve sırayla görünmesi için çıktının görüntülenmesini koordine edin.
Başlat düğmesini devre dışı bırak
@No__t_1 olay işleyicisinin en üstündeki düğmeyi devre dışı bırakarak, bir işlem çalışırken Başlat düğmesini
engelleyebilirsiniz. Böylece, kullanıcılar uygulamayı yeniden çalıştırabilmeleri için işlem bittiğinde düğmeyi bir
finally bloğu içinden yeniden etkinleştirebilirsiniz.

Bu senaryoyu ayarlamak için, Örnek uygulamayı gözden geçirmek ve çalıştırmakiçin belirtilen temel kodda
aşağıdaki değişiklikleri yapın. Ayrıca, tamamlanmış uygulamayı zaman uyumsuz örneklerden indirebilirsiniz: .net
masaüstü uygulamalarında yeniden girişyapabilirsiniz. Projenin adı DisableStartButton olur.

private async void StartButton_Click(object sender, RoutedEventArgs e)


{
// This line is commented out to make the results clearer in the output.
//ResultsTextBox.Text = "";

// ***Disable the Start button until the downloads are complete.


StartButton.IsEnabled = false;

try
{
await AccessTheWebAsync();
}
catch (Exception)
{
ResultsTextBox.Text += "\r\nDownloads failed.";
}
// ***Enable the Start button in case you want to run the program again.
finally
{
StartButton.IsEnabled = true;
}
}

Değişikliklerin bir sonucu olarak, AccessTheWebAsync Web sitelerini indirirken işlem yeniden girilemez.
Işlemi iptal edin ve yeniden başlatın
Başlat düğmesini devre dışı bırakmak yerine düğmeyi etkin tutabilirsiniz, ancak kullanıcı bu düğmeyi yeniden
seçerse, zaten çalışmakta olan işlemi iptal edin ve en son başlatılan işlemin devam etmesine izin verin.
İptal hakkında daha fazla bilgi için bkz. zaman uyumsuz uygulamanızda Ince ayar yapmaC#().
Bu senaryoyu ayarlamak için, Örnek uygulamayı gözden geçirmek ve çalıştırmakiçin belirtilen temel kodda
aşağıdaki değişiklikleri yapın. Ayrıca, tamamlanmış uygulamayı zaman uyumsuz örneklerden indirebilirsiniz: .net
masaüstü uygulamalarında yeniden girişyapabilirsiniz. Projenin adı, geçersiz bir şekilde başlatılır.
1. Tüm yöntemler için kapsam içindeki bir CancellationTokenSource değişken cts bildirin.

public partial class MainWindow : Window // Or class MainPage


{
// *** Declare a System.Threading.CancellationTokenSource.
CancellationTokenSource cts;
2. @No__t_0, bir işlemin zaten devam edilip edilmeyeceğini saptayın. @No__t_0 değeri null ise, zaten etkin bir
işlem yoktur. Değer null değilse, zaten çalışmakta olan işlem iptal edilir.

// *** If a download process is already underway, cancel it.


if (cts != null)
{
cts.Cancel();
}

3. @No__t_0 geçerli işlemi temsil eden farklı bir değere ayarlayın.

// *** Now set cts to a new value that you can use to cancel the current process
// if the button is chosen again.
CancellationTokenSource newCTS = new CancellationTokenSource();
cts = newCTS;

4. @No__t_0 sonunda geçerli işlem tamamlanmıştır, cts değerini null olarak ayarlayın.

// *** When the process is complete, signal that another process can begin.
if (cts == newCTS)
cts = null;

Aşağıdaki kod StartButton_Click tüm değişiklikleri gösterir. Ekler yıldız işaretiyle işaretlenir.

private async void StartButton_Click(object sender, RoutedEventArgs e)


{
// This line is commented out to make the results clearer in the output.
//ResultsTextBox.Clear();

// *** If a download process is already underway, cancel it.


if (cts != null)
{
cts.Cancel();
}

// *** Now set cts to cancel the current process if the button is chosen again.
CancellationTokenSource newCTS = new CancellationTokenSource();
cts = newCTS;

try
{
// ***Send cts.Token to carry the message if there is a cancellation request.
await AccessTheWebAsync(cts.Token);

}
// *** Catch cancellations separately.
catch (OperationCanceledException)
{
ResultsTextBox.Text += "\r\nDownloads canceled.\r\n";
}
catch (Exception)
{
ResultsTextBox.Text += "\r\nDownloads failed.\r\n";
}
// *** When the process is complete, signal that another process can proceed.
if (cts == newCTS)
cts = null;
}

@No__t_0, aşağıdaki değişiklikleri yapın.


@No__t_0 iptal belirtecini kabul etmek için bir parametre ekleyin.
@No__t_1 bir CancellationToken bağımsız değişkenini kabul ettiğinden Web sitelerini indirmek için
GetAsync yöntemi kullanın.
İndirilen her Web sitesinin sonuçlarını göstermek için DisplayResults çağrılmadan önce, geçerli işlemin
iptal edildiğini doğrulamak için ct denetleyin.

Aşağıdaki kod, yıldız işaretiyle işaretlenen bu değişiklikleri gösterir.

// *** Provide a parameter for the CancellationToken from StartButton_Click.


async Task AccessTheWebAsync(CancellationToken ct)
{
// Declare an HttpClient object.
HttpClient client = new HttpClient();

// Make a list of web addresses.


List<string> urlList = SetUpURLList();

var total = 0;
var position = 0;

foreach (var url in urlList)


{
// *** Use the HttpClient.GetAsync method because it accepts a
// cancellation token.
HttpResponseMessage response = await client.GetAsync(url, ct);

// *** Retrieve the website contents from the HttpResponseMessage.


byte[] urlContents = await response.Content.ReadAsByteArrayAsync();

// *** Check for cancellations before displaying information about the


// latest site.
ct.ThrowIfCancellationRequested();

DisplayResults(url, urlContents, ++position);

// Update the total.


total += urlContents.Length;
}

// Display the total count for all of the websites.


ResultsTextBox.Text +=
$"\r\n\r\nTOTAL bytes returned: {total}\r\n";
}

Bu uygulama çalışırken Başlat düğmesini birkaç kez seçerseniz, aşağıdaki çıktıya benzeyen sonuçlar üretmelidir.
1. msdn.microsoft.com/library/hh191443.aspx 83732
2. msdn.microsoft.com/library/aa578028.aspx 205273
3. msdn.microsoft.com/library/jj155761.aspx 29019
4. msdn.microsoft.com/library/hh290140.aspx 122505
5. msdn.microsoft.com/library/hh524395.aspx 68959
6. msdn.microsoft.com/library/ms404677.aspx 197325
Download canceled.

1. msdn.microsoft.com/library/hh191443.aspx 83732
2. msdn.microsoft.com/library/aa578028.aspx 205273
3. msdn.microsoft.com/library/jj155761.aspx 29019
Download canceled.

1. msdn.microsoft.com/library/hh191443.aspx 83732
2. msdn.microsoft.com/library/aa578028.aspx 205273
3. msdn.microsoft.com/library/jj155761.aspx 29019
4. msdn.microsoft.com/library/hh290140.aspx 117152
5. msdn.microsoft.com/library/hh524395.aspx 68959
6. msdn.microsoft.com/library/ms404677.aspx 197325
7. msdn.microsoft.com 42972
8. msdn.microsoft.com/library/ff730837.aspx 146159

TOTAL bytes returned: 890591

Kısmi listeleri ortadan kaldırmak için, kullanıcının işlemi her yeniden başlattığı her seferinde metin kutusunu
temizlemek üzere StartButton_Click içindeki ilk kod satırının açıklamasını kaldırın.
Birden çok Işlemi çalıştırma ve çıktıyı sıraya alma
Bu üçüncü örnek, Kullanıcı Başlat düğmesini her seçtiğinde uygulamanın başka bir zaman uyumsuz işlem
başlatması ve tüm işlemlerin tamamlamada çalışması için en karmaşıktır. Tüm istenen işlemler, listeden zaman
uyumsuz olarak Web sitelerini indirir, ancak işlemlerden alınan çıkış sıralı olarak sunulur. Diğer bir deyişle, gerçek
indirme etkinliği araya eklemeli, bu da bir yandan yeniden giriş, ancak her grup için sonuçların listesi ayrı olarak
sunulur.
İşlemler, görüntüleme işlemi için bir ağ geçidi denetleyicisi görevi gören küresel bir Task pendingWork paylaşır.
Bu senaryoyu ayarlamak için, Örnek uygulamayı gözden geçirmek ve çalıştırmakiçin belirtilen temel kodda
aşağıdaki değişiklikleri yapın. Ayrıca, tamamlanmış uygulamayı zaman uyumsuz örneklerden indirebilirsiniz: .net
masaüstü uygulamalarında yeniden girişyapabilirsiniz. Projenin adı örneği indirip queueresults.
Aşağıdaki çıktıda, Kullanıcı Başlat düğmesini yalnızca bir kez seçerse sonuç gösterilmektedir. Harf etiketi,, sonucun
Başlangıç düğmesinin seçildiği ilk sefer olduğunu gösterir. Sayılar, indirme hedefleri listesindeki URL 'lerin
sırasını gösterir.

#Starting group A.
#Task assigned for group A.

A-1. msdn.microsoft.com/library/hh191443.aspx 87389


A-2. msdn.microsoft.com/library/aa578028.aspx 209858
A-3. msdn.microsoft.com/library/jj155761.aspx 30870
A-4. msdn.microsoft.com/library/hh290140.aspx 119027
A-5. msdn.microsoft.com/library/hh524395.aspx 71260
A-6. msdn.microsoft.com/library/ms404677.aspx 199186
A-7. msdn.microsoft.com 53266
A-8. msdn.microsoft.com/library/ff730837.aspx 148020

TOTAL bytes returned: 918876

#Group A is complete.

Kullanıcı Başlat düğmesini üç kez seçerse, uygulama aşağıdaki satırlara benzer bir çıktı üretir. Numara işareti (#)
ile başlayan bilgi satırları, uygulamanın ilerlemesini izler.

#Starting group A.
#Task assigned for group A.

A-1. msdn.microsoft.com/library/hh191443.aspx 87389


A-2. msdn.microsoft.com/library/aa578028.aspx 207089
A-3. msdn.microsoft.com/library/jj155761.aspx 30870
A-4. msdn.microsoft.com/library/hh290140.aspx 119027
A-5. msdn.microsoft.com/library/hh524395.aspx 71259
A-6. msdn.microsoft.com/library/ms404677.aspx 199185

#Starting group B.
#Task assigned for group B.

A-7. msdn.microsoft.com 53266

#Starting group C.
#Task assigned for group C.

A-8. msdn.microsoft.com/library/ff730837.aspx 148010

TOTAL bytes returned: 916095

B-1. msdn.microsoft.com/library/hh191443.aspx 87389


B-2. msdn.microsoft.com/library/aa578028.aspx 207089
B-3. msdn.microsoft.com/library/jj155761.aspx 30870
B-4. msdn.microsoft.com/library/hh290140.aspx 119027
B-5. msdn.microsoft.com/library/hh524395.aspx 71260
B-6. msdn.microsoft.com/library/ms404677.aspx 199186

#Group A is complete.

B-7. msdn.microsoft.com 53266


B-8. msdn.microsoft.com/library/ff730837.aspx 148010

TOTAL bytes returned: 916097

C-1. msdn.microsoft.com/library/hh191443.aspx 87389


C-2. msdn.microsoft.com/library/aa578028.aspx 207089

#Group B is complete.

C-3. msdn.microsoft.com/library/jj155761.aspx 30870


C-4. msdn.microsoft.com/library/hh290140.aspx 119027
C-5. msdn.microsoft.com/library/hh524395.aspx 72765
C-6. msdn.microsoft.com/library/ms404677.aspx 199186
C-7. msdn.microsoft.com 56190
C-8. msdn.microsoft.com/library/ff730837.aspx 148010

TOTAL bytes returned: 920526

#Group C is complete.

Grup A tamamlanmadan önce B ve C grupları başlar, ancak her grubun çıktısı ayrı olarak görünür.Önce Grup A
'nın tüm çıktıları, ardından Grup B için tüm çıktılar ve sonra Grup C için tüm çıktılar görüntülenir. Uygulama her
zaman grupları sırayla görüntüler ve her grup için her zaman tek tek Web siteleri hakkındaki bilgileri URL 'Ler
listesinde görünecek şekilde görüntüler.
Ancak, indirmelerin gerçekten gerçekleştiği sırayı tahmin edemezseniz. Birden çok grup başlatıldıktan sonra,
oluşturdukları yükleme görevlerinin hepsi etkindir. -1 ' in B -1 ' den önce indirileceğini varsaymazsınız ve-1 ' in-2 '
den önce indirildiğini varsaymazsınız.
Genel tanımlar
Örnek kod, tüm metotlardan görülebilen aşağıdaki iki genel bildirimi içerir.
public partial class MainWindow : Window // Class MainPage in Windows Store app.
{
// ***Declare the following variables where all methods can access them.
private Task pendingWork = null;
private char group = (char)('A' - 1);

@No__t_0 değişkeni, pendingWork , görüntüleme sürecini fazla görür ve herhangi bir grubun başka bir grubun
görüntüleme işlemini kesintiye uğramasını önler. @No__t_0 karakter değişkeni, sonuçların beklenen sırada
göründüğünü doğrulamak için farklı gruplardan çıktıyı Etiketler.
Click olay Işleyicisi
@No__t_0 olay işleyicisi, Kullanıcı Başlat düğmesini her seçtiğinde grup harfini artırır. Ardından işleyici, indirme
işlemini çalıştırmak için AccessTheWebAsync çağırır.

private async void StartButton_Click(object sender, RoutedEventArgs e)


{
// ***Verify that each group's results are displayed together, and that
// the groups display in order, by marking each group with a letter.
group = (char)(group + 1);
ResultsTextBox.Text += $"\r\n\r\n#Starting group {group}.";

try
{
// *** Pass the group value to AccessTheWebAsync.
char finishedGroup = await AccessTheWebAsync(group);

// The following line verifies a successful return from the download and
// display procedures.
ResultsTextBox.Text += $"\r\n\r\n#Group {finishedGroup} is complete.\r\n";
}
catch (Exception)
{
ResultsTextBox.Text += "\r\nDownloads failed.";
}
}

AccessTheWebAsync yöntemi
Bu örnek AccessTheWebAsync iki yönteme ayırır. İlk yöntem AccessTheWebAsync , bir grup için tüm indirme
görevlerini başlatır ve görüntüleme işlemini denetlemek için pendingWork ayarlar. Yöntemi, aynı anda tüm indirme
görevlerini başlatmak için bir dil tümleşik sorgu (LINQ sorgusu) ve ToArray kullanır.
AccessTheWebAsync , her indirmenin tamamlanmasını beklemek için FinishOneGroupAsync çağırır ve uzunluğunu
görüntüler.
, AccessTheWebAsync pendingWork atanan bir görevi döndürür. Bu değer, görev
FinishOneGroupAsync
tamamlanmadan önce başka bir işlem kesintiye uğramasını önler.
private async Task<char> AccessTheWebAsync(char grp)
{
HttpClient client = new HttpClient();

// Make a list of the web addresses to download.


List<string> urlList = SetUpURLList();

// ***Kick off the downloads. The application of ToArray activates all the download tasks.
Task<byte[]>[] getContentTasks = urlList.Select(url => client.GetByteArrayAsync(url)).ToArray();

// ***Call the method that awaits the downloads and displays the results.
// Assign the Task that FinishOneGroupAsync returns to the gatekeeper task, pendingWork.
pendingWork = FinishOneGroupAsync(urlList, getContentTasks, grp);

ResultsTextBox.Text += $"\r\n#Task assigned for group {grp}. Download tasks are active.\r\n";

// ***This task is complete when a group has finished downloading and displaying.
await pendingWork;

// You can do other work here or just return.


return grp;
}

FinishOneGroupAsync yöntemi
Bu yöntem bir gruptaki indirme görevleri boyunca geçiş yapar, her birini bekliyor, indirilen Web sitesinin
uzunluğunu görüntülüyor ve uzunluğu toplamına ekliyor.
@No__t_0 ilk ifade, yöntemi girerken, zaten görüntüleme işleminde olan veya zaten bekleyen bir işlemi
etkilemediğinden emin olmak için pendingWork kullanır. Bu tür bir işlem devam ediyorsa, giriş işleminin
tamamlanmasını beklemesi gerekir.

private async Task FinishOneGroupAsync(List<string> urls, Task<byte[]>[] contentTasks, char grp)


{
// ***Wait for the previous group to finish displaying results.
if (pendingWork != null) await pendingWork;

int total = 0;

// contentTasks is the array of Tasks that was created in AccessTheWebAsync.


for (int i = 0; i < contentTasks.Length; i++)
{
// Await the download of a particular URL, and then display the URL and
// its length.
byte[] content = await contentTasks[i];
DisplayResults(urls[i], content, i, grp);
total += content.Length;
}

// Display the total count for all of the websites.


ResultsTextBox.Text +=
$"\r\n\r\nTOTAL bytes returned: {total}\r\n";
}

Ilgi çekici noktaları


Çıktıda diyez işareti (#) ile başlayan bilgi satırları bu örneğin nasıl çalıştığını açıklığa kavuşturacak.
Çıktıda aşağıdaki desenler gösterilmektedir.
Bir grup, önceki bir grup çıktısını görüntülerken başlatılabilir, ancak önceki grubun çıktısının
görüntülenmediği kesintiye uğramaz.
#Starting group A.
#Task assigned for group A. Download tasks are active.

A-1. msdn.microsoft.com/library/hh191443.aspx 87389


A-2. msdn.microsoft.com/library/aa578028.aspx 207089
A-3. msdn.microsoft.com/library/jj155761.aspx 30870
A-4. msdn.microsoft.com/library/hh290140.aspx 119037
A-5. msdn.microsoft.com/library/hh524395.aspx 71260

#Starting group B.
#Task assigned for group B. Download tasks are active.

A-6. msdn.microsoft.com/library/ms404677.aspx 199186


A-7. msdn.microsoft.com 53078
A-8. msdn.microsoft.com/library/ff730837.aspx 148010

TOTAL bytes returned: 915919

B-1. msdn.microsoft.com/library/hh191443.aspx 87388


B-2. msdn.microsoft.com/library/aa578028.aspx 207089
B-3. msdn.microsoft.com/library/jj155761.aspx 30870

#Group A is complete.

B-4. msdn.microsoft.com/library/hh290140.aspx 119027


B-5. msdn.microsoft.com/library/hh524395.aspx 71260
B-6. msdn.microsoft.com/library/ms404677.aspx 199186
B-7. msdn.microsoft.com 53078
B-8. msdn.microsoft.com/library/ff730837.aspx 148010

TOTAL bytes returned: 915908

@No__t_0 görevi, yalnızca ilk başlatılan A grubu için FinishOneGroupAsync başlangıcında boştur. A grubu
FinishOneGroupAsync ulaştığında bir await ifadesi henüz tamamlanmadı. Bu nedenle, denetim
AccessTheWebAsync döndürülmemiştir ve pendingWork ilk atama gerçekleşmemiştir.

Aşağıdaki iki satır, her zaman çıktıda birlikte görüntülenir.Kod, StartButton_Click bir grubun işlemini
başlatma ve grup için bir görevin pendingWork atama arasında hiçbir şekilde kesintiye uğramaz.

#Starting group B.
#Task assigned for group B. Download tasks are active.

Bir grup StartButton_Click girdikten sonra, işlem FinishOneGroupAsync girene kadar bir await ifadesi
tamamlanmaz. Bu nedenle, başka hiçbir işlem bu kod segmenti sırasında denetim elde edebilir.

Örnek uygulamayı inceleme ve çalıştırma


Örnek uygulamayı daha iyi anlamak için indirebilir, kendiniz derleyebilir veya uygulamayı uygulamadan bu
konunun sonundaki kodu inceleyebilirsiniz.

NOTE
Örneği bir Windows Presentation Foundation (WPF) masaüstü uygulaması olarak çalıştırmak için, bilgisayarınızda Visual
Studio 2012 veya daha yeni bir sürümü ve .NET Framework 4,5 ya da daha yeni bir sürümü yüklü olmalıdır.

Uygulama indiriliyor
1. Zaman uyumsuz örneklerden sıkıştırılmış dosyayı indirin: .net masaüstü uygulamalarında yeniden giriş.
2. İndirdiğiniz dosyayı sıkıştırmasını açın ve ardından Visual Studio 'Yu başlatın.
3. Menü çubuğunda Dosya, Aç, Proje/çözüm' ü seçin.
4. Sıkıştırması açılmış örnek kodun bulunduğu klasöre gidin ve çözüm (. sln) dosyasını açın.
5. Çözüm Gezgini' de, çalıştırmak istediğiniz projenin kısayol menüsünü açın ve ardından StartupProject
olarak ayarla' yı seçin.
6. Projeyi derlemek ve çalıştırmak için CTRL + F5 tuşlarını seçin.
Uygulamayı oluşturma
Aşağıdaki bölümde, örneği WPF uygulaması olarak derlemek için kod sağlanmaktadır.
W P F u y g u l a m a sı d e r l e m e k i ç i n

1. Visual Studio 'Yu başlatın.


2. Menü çubuğunda Dosya, Yeni, Proje' yi seçin.
Yeni proje iletişim kutusu açılır.
3. Yüklü şablonlar bölmesinde, görsel C# ' i genişletin ve ardından Windows' u genişletin.
4. Proje türleri listesinde WPF uygulaması' nı seçin.
5. Projeyi WebsiteDownloadWPF olarak adlandırın, .NET Framework 4,6 veya üzeri bir sürüm seçin ve Tamam
düğmesine tıklayın.
Yeni proje Çözüm Gezginigörüntülenir.
6. Visual Studio Code düzenleyicisinde MainWindow. xaml sekmesini seçin.
Sekme görünür değilse, Çözüm Gezgini' de MainWindow. xaml için kısayol menüsünü açın ve kodu
görüntüle' yi seçin.
7. MainWindow. xaml ' nin xaml görünümünde, kodu aşağıdaki kodla değiştirin.

<Window x:Class="WebsiteDownloadWPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WebsiteDownloadWPF"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">

<Grid Width="517" Height="360">


<Button x:Name="StartButton" Content="Start" HorizontalAlignment="Left" Margin="-1,0,0,0"
VerticalAlignment="Top" Click="StartButton_Click" Height="53" Background="#FFA89B9B" FontSize="36"
Width="518" />
<TextBox x:Name="ResultsTextBox" HorizontalAlignment="Left" Margin="-1,53,0,-36"
TextWrapping="Wrap" VerticalAlignment="Top" Height="343" FontSize="10"
ScrollViewer.VerticalScrollBarVisibility="Visible" Width="518" FontFamily="Lucida Console" />
</Grid>
</Window>

Bir metin kutusu ve bir düğme içeren basit bir pencere, MainWindow. xaml Tasarım görünümünde
görünür.
8. Çözüm Gezgini, Başvurular ' a sağ tıklayın ve Başvuru Ekle' yi seçin.
Zaten seçili değilse System.Net.Http için bir başvuru ekleyin.
9. Çözüm Gezgini' de, MainWindow.xaml.cs için kısayol menüsünü açın ve kodu görüntüle' yi seçin.
10. MainWindow.xaml.cs ' de, kodu aşağıdaki kodla değiştirin.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

// Add the following using directives, and add a reference for System.Net.Http.
using System.Net.Http;
using System.Threading;

namespace WebsiteDownloadWPF
{
public partial class MainWindow : Window
{
public MainWindow()
{
System.Net.ServicePointManager.SecurityProtocol |= System.Net.SecurityProtocolType.Tls12;
InitializeComponent();
}

private async void StartButton_Click(object sender, RoutedEventArgs e)


{
// This line is commented out to make the results clearer in the output.
//ResultsTextBox.Text = "";

try
{
await AccessTheWebAsync();
}
catch (Exception)
{
ResultsTextBox.Text += "\r\nDownloads failed.";
}
}

private async Task AccessTheWebAsync()


{
// Declare an HttpClient object.
HttpClient client = new HttpClient();

// Make a list of web addresses.


List<string> urlList = SetUpURLList();

var total = 0;
var position = 0;

foreach (var url in urlList)


{
// GetByteArrayAsync returns a task. At completion, the task
// produces a byte array.
byte[] urlContents = await client.GetByteArrayAsync(url);

DisplayResults(url, urlContents, ++position);

// Update the total.


total += urlContents.Length;
}

// Display the total count for all of the websites.


ResultsTextBox.Text +=
$"\r\n\r\nTOTAL bytes returned: {total}\r\n";
}

private List<string> SetUpURLList()


{
List<string> urls = new List<string>
{
"https://msdn.microsoft.com/library/hh191443.aspx",
"https://msdn.microsoft.com/library/aa578028.aspx",
"https://msdn.microsoft.com/library/jj155761.aspx",
"https://msdn.microsoft.com/library/hh290140.aspx",
"https://msdn.microsoft.com/library/hh524395.aspx",
"https://msdn.microsoft.com/library/ms404677.aspx",
"https://msdn.microsoft.com",
"https://msdn.microsoft.com/library/ff730837.aspx"
};
return urls;
}

private void DisplayResults(string url, byte[] content, int pos)


{
// Display the length of each website. The string format is designed
// to be used with a monospaced font, such as Lucida Console or
// Global Monospace.

// Strip off the "https://".


var displayURL = url.Replace("https://", "");
// Display position in the URL list, the URL, and the number of bytes.
ResultsTextBox.Text += $"\n{pos}. {displayURL,-58} {content.Length,8}";
}
}
}

11. Programı çalıştırmak için CTRL + F5 tuşlarını seçin ve sonra Başlat düğmesini birkaç kez seçin.
12. Başlat düğmesini devre dışı bırak' dan değişiklikleri yapın, işlemi Iptal edin ve yeniden başlatınya da birden
çok işlem çalıştırın ve çıktıyı kuyruğa alarak yeniden giriş işlemini idare edin.

Ayrıca bkz.
İzlenecek yol: Async ve await (C#) kullanarak Web 'e erişme
Async ve await (C#) ile zaman uyumsuz programlama
Dosya erişimi için Async Kullanma (C#)
23.10.2019 • 8 minutes to read • Edit Online

Dosyalara erişmek için zaman uyumsuz özelliği kullanabilirsiniz. Async özelliğini kullanarak, geri çağırmaları
kullanmadan veya kodunuzu birden çok yöntemde veya Lambda ifadelerinde bölmeden zaman uyumsuz
yöntemlere çağrı yapabilirsiniz. Zaman uyumlu kodu zaman uyumsuz yapmak için, zaman uyumlu bir yöntem
yerine zaman uyumsuz bir yöntem çağırır ve koda birkaç anahtar sözcük eklemeniz yeterlidir.
Dosya erişim çağrılarına zaman uyumsuzluğu eklemek için aşağıdaki nedenleri göz önünde bulundurmanız
gerekebilir:
İşlemi başlatan kullanıcı arabirimi iş parçacığı başka bir iş gerçekleştirebildiğinden, asynchrony UI
uygulamalarını daha hızlı hale getirir. UI iş parçacığının uzun zaman alan kodu yürütmesi gerekiyorsa
(örneğin, 50 milisaniyeden fazla), g/ç tamamlanana kadar UI dondurabilir ve Kullanıcı arabirimi iş parçacığı
klavye ve fare girişini ve diğer olayları yeniden işleyebilir.
Asynchrony, iş parçacıkları gereksinimini azaltarak ASP.NET ve diğer sunucu tabanlı uygulamaların
ölçeklenebilirliğini geliştirir. Uygulama yanıt başına adanmış bir iş parçacığı kullanıyorsa ve bin istek aynı
anda işleneiyorsa, bin iş parçacığı gerekir. Zaman uyumsuz işlemlerin genellikle bekleme sırasında bir iş
parçacığı kullanması gerekmez. Mevcut g/ç Tamamlama iş parçacığını kısa bir süre içinde kullanırlar.
Bir dosya erişim işleminin gecikmesi geçerli koşullar altında çok düşük olabilir, ancak gecikme gelecekte
büyük ölçüde artabilir. Örneğin, bir dosya dünya genelinde bir sunucuya taşınabilir.
Zaman uyumsuz özelliği kullanmanın ek yükü küçüktür.
Zaman uyumsuz görevler, paralel olarak kolayca çalıştırılabilir.

Örnekleri çalıştırma
Bu konudaki örnekleri çalıştırmak için bir WPF uygulaması veya Windows Forms uygulaması oluşturabilir ve
sonra bir düğmeekleyebilirsiniz. Düğmenin Click olayında, her örnekteki ilk yönteme bir çağrı ekleyin.
Aşağıdaki örneklerde aşağıdaki using deyimlerini ekleyin.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading.Tasks;

FILESTREAM sınıfının kullanımı


Bu konudaki örneklerde, zaman uyumsuz g FileStream /ç 'nin işletim sistemi düzeyinde oluşmasına neden olan bir
seçeneğe sahip olan sınıfını kullanın. Bu seçeneği kullanarak, birçok durumda bir ThreadPool iş parçacığını
engellemeyi önleyebilirsiniz. Bu seçeneği etkinleştirmek için, Oluşturucu çağrısında useAsync=true veya
options=FileOptions.Asynchronous bağımsız değişkenini belirtirsiniz.

Bu seçeneği StreamReader , ve StreamWriter doğrudan bir dosya yolu belirterek açarsanız kullanabilirsiniz. Ancak,
bu seçeneği, Stream FileStream sınıfının açık olduğunu bir şekilde sağlarsanız kullanabilirsiniz. Bekleme sırasında
UI iş parçacığı engellenmediğinden, zaman uyumsuz çağrıların Kullanıcı arabirimi uygulamalarında daha hızlı
olduğunu unutmayın.

Metin yazma
Aşağıdaki örnek bir dosyaya metin yazar. Her await ifadesinde, yöntemi hemen çıkar. G/ç dosyası
tamamlandığında, yöntemi await ifadesini izleyen deyimde devam eder. Zaman uyumsuz değiştiricinin await
ifadesini kullanan yöntemlerin tanımında olduğunu unutmayın.

public async Task ProcessWriteAsync()


{
string filePath = @"temp2.txt";
string text = "Hello World\r\n";

await WriteTextAsync(filePath, text);


}

private async Task WriteTextAsync(string filePath, string text)


{
byte[] encodedText = Encoding.Unicode.GetBytes(text);

using (FileStream sourceStream = new FileStream(filePath,


FileMode.Append, FileAccess.Write, FileShare.None,
bufferSize: 4096, useAsync: true))
{
await sourceStream.WriteAsync(encodedText, 0, encodedText.Length);
};
}

Özgün örnek, aşağıdaki iki deyimin await sourceStream.WriteAsync(encodedText, 0, encodedText.Length); bir örneği
olan ifadesine sahiptir:

Task theTask = sourceStream.WriteAsync(encodedText, 0, encodedText.Length);


await theTask;

İlk ifade bir görev döndürür ve dosya işlemenin başlatılmasına neden olur. Await ile ikinci ifade, yönteminin hemen
çıkmasına ve farklı bir görev döndürmesine neden olur. Dosya işleme daha sonra tamamlandığında, yürütme, await
' ı izleyen ifadeye geri döner. Daha fazla bilgi için bkz. zaman uyumsuz programlarda denetim akışıC#().

Metin okuma
Aşağıdaki örnek bir dosyadaki metni okur. Metin, arabelleğe alınmış ve bu durumda bir StringBuilderöğesine
yerleştirildi. Önceki örnekte aksine, await 'ın değerlendirmesi bir değer oluşturur. YöntemibirTask numRead
>döndürür Int32 , bu nedenle await 'ın değerlendirmesi işlem tamamlandıktan sonra bir değer () oluşturur. <
ReadAsync Int32 Daha fazla bilgi için bkz. Async Return TypesC#().
public async Task ProcessReadAsync()
{
string filePath = @"temp2.txt";

if (File.Exists(filePath) == false)
{
Debug.WriteLine("file not found: " + filePath);
}
else
{
try
{
string text = await ReadTextAsync(filePath);
Debug.WriteLine(text);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
}

private async Task<string> ReadTextAsync(string filePath)


{
using (FileStream sourceStream = new FileStream(filePath,
FileMode.Open, FileAccess.Read, FileShare.Read,
bufferSize: 4096, useAsync: true))
{
StringBuilder sb = new StringBuilder();

byte[] buffer = new byte[0x1000];


int numRead;
while ((numRead = await sourceStream.ReadAsync(buffer, 0, buffer.Length)) != 0)
{
string text = Encoding.Unicode.GetString(buffer, 0, numRead);
sb.Append(text);
}

return sb.ToString();
}
}

Paralel zaman uyumsuz g/ç


Aşağıdaki örnek, 10 metin dosyası yazarak paralel işlemeyi gösterir. Her dosya için, WriteAsync yöntemi bir görev
listesine eklenen bir görevi döndürür. await Task.WhenAll(tasks); Deyimden çıkılıyor ve tüm görevler için dosya
işleme tamamlandığında yöntemi içinde devam eder.
Örnek, görevler tamamlandıktan FileStream sonra bir finally bloktaki tüm örnekleri kapatır. Her biri FileStream
bir using bildiriminde oluşturulduysa, görev tamamlanmadan önce ' FileStream nin atımı bırakılmış olabilir.
Herhangi bir performans artışının, zaman uyumsuz işlemden değil, paralel işlemden neredeyse tamamen
olduğunu unutmayın. Zaman uyumsuzluğu 'nin avantajları birden çok iş parçacığını bağlamaktır ve Kullanıcı
arabirimi iş parçacığını bağlamaktır.
public async Task ProcessWriteMultAsync()
{
string folder = @"tempfolder\";
List<Task> tasks = new List<Task>();
List<FileStream> sourceStreams = new List<FileStream>();

try
{
for (int index = 1; index <= 10; index++)
{
string text = "In file " + index.ToString() + "\r\n";

string fileName = "thefile" + index.ToString("00") + ".txt";


string filePath = folder + fileName;

byte[] encodedText = Encoding.Unicode.GetBytes(text);

FileStream sourceStream = new FileStream(filePath,


FileMode.Append, FileAccess.Write, FileShare.None,
bufferSize: 4096, useAsync: true);

Task theTask = sourceStream.WriteAsync(encodedText, 0, encodedText.Length);


sourceStreams.Add(sourceStream);

tasks.Add(theTask);
}

await Task.WhenAll(tasks);
}

finally
{
foreach (FileStream sourceStream in sourceStreams)
{
sourceStream.Close();
}
}
}

WriteAsync CancellationTokenVe yöntemlerinikullanırken,işlemorta-


akışişleminiiptaletmekiçinkullanabileceğinizbirbelirtebilirsiniz.ReadAsync Daha fazla bilgi için bkz. yönetilen iş
parçacıklarında zaman uyumsuzC#uygulamanızı () ve iptali hassas ayarlama .

Ayrıca bkz.
Async ve await (C#) ile zaman uyumsuz programlama
Zaman uyumsuz dönüş türleriC#()
Zaman uyumsuz programlarda denetim akışı (C#)
Öznitelikler (C#)
25.11.2019 • 8 minutes to read • Edit Online

Öznitelikler, meta verileri veya bildirime dayalı bilgilerin kod (derlemeler, türler, Yöntemler, özellikler, vb.) ile
ilişkilendirilmesi için güçlü bir yöntem sağlar. Bir öznitelik bir program varlığıyla ilişkilendirildikten sonra, çalışma
zamanında, yansımaadlı bir teknik kullanarak öznitelik sorgulanabilir. Daha fazla bilgi için bkz. yansımaC#().
Öznitelikler aşağıdaki özelliklere sahiptir:
Öznitelikler, programınıza meta veri ekler. Meta veriler , bir programda tanımlanan türlerle ilgili bilgiler. Tüm
.NET derlemeleri, derlemede tanımlanan türleri ve tür üyelerini açıklayan, belirtilen meta veri kümesini içerir.
Gerekli ek bilgileri belirtmek için özel öznitelikler ekleyebilirsiniz. Daha fazla bilgi için bkz. özel öznitelikler
(C#) oluşturma.
Tüm derlemeler, modüller veya sınıflar ve özellikler gibi daha küçük program öğelerine bir veya daha fazla
öznitelik uygulayabilirsiniz.
Öznitelikler bağımsız değişkenleri Yöntemler ve özelliklerle aynı şekilde kabul edebilir.
Programınız, yansıma kullanarak kendi meta verilerini veya diğer programlardaki meta verileri inceleyebilir.
Daha fazla bilgi için bkz. Reflection (C#) kullanarak özniteliklere erişme.

Öznitelikleri kullanma
Öznitelikler, her bir bildirime yerleştirilebilecek, ancak belirli bir öznitelik, geçerli olduğu bildirimlerin türlerini
kısıtlayabilir. ' C#De, geçerli olduğu varlık bildiriminin üzerine köşeli ayraç ([]) içine alınmış özniteliğin adını
yerleştirerek bir özniteliği belirtirsiniz.
Bu örnekte, bir sınıfa belirli bir özelliği uygulamak için SerializableAttribute özniteliği kullanılır:

[Serializable]
public class SampleClass
{
// Objects of this type can be serialized.
}

DllImportAttribute özniteliğine sahip bir yöntem aşağıdaki örnekte olduğu gibi bildirilmiştir:

[System.Runtime.InteropServices.DllImport("user32.dll")]
extern static void SampleMethod();

Aşağıdaki örnekte gösterildiği gibi, bir bildirime birden fazla öznitelik yerleştirilebilecek:

using System.Runtime.InteropServices;

void MethodA([In][Out] ref double x) { }


void MethodB([Out][In] ref double x) { }
void MethodC([In, Out] ref double x) { }

Bazı öznitelikler, belirli bir varlık için birden çok kez belirtilebilir. Bu tür bir çok kullanım özniteliğine örnek
ConditionalAttribute:
[Conditional("DEBUG"), Conditional("TEST1")]
void TraceMethod()
{
// ...
}

NOTE
Kurala göre, tüm öznitelik adları, bunları .NET kitaplıklarında diğer öğelerden ayırt etmek için "Attribute" kelimesiyle biter.
Ancak, koddaki öznitelikleri kullanırken öznitelik sonekini belirtmeniz gerekmez. Örneğin, [DllImport]
[DllImportAttribute] eşdeğerdir, ancak DllImportAttribute özniteliğin .NET Framework sınıf kitaplığındaki gerçek
adıdır.

Öznitelik parametreleri
Birçok özniteliğin, konumsal, adlandırılmamış veya adlandırılmış olabilecek parametreleri vardır. Herhangi bir
Konumsal parametre belirli bir sırada belirtilmelidir ve atlanamaz. Adlandırılmış parametreler isteğe bağlıdır ve
herhangi bir sırada belirtilebilir. Konumsal parametreler önce belirtilmiştir. Örneğin, bu üç öznitelik eşdeğerdir:

[DllImport("user32.dll")]
[DllImport("user32.dll", SetLastError=false, ExactSpelling=false)]
[DllImport("user32.dll", ExactSpelling=false, SetLastError=false)]

İlk parametre olan DLL adı, konumsal ve her zaman ilk olarak gelir; diğerleri olarak adlandırılır. Bu durumda, her
ikisi de varsayılan olarak false değerine sahiptir, bu nedenle bu parametreler atlanabilir. Konumsal parametreler
öznitelik oluşturucusunun parametrelerine karşılık gelir. Adlandırılmış ya da isteğe bağlı parametreler, özelliğin
özelliklerine veya alanlarına karşılık gelir. Varsayılan parametre değerleri hakkında bilgi için bağımsız özniteliğin
belgelerine bakın.
Öznitelik hedefleri
Bir özniteliğin hedefi , özniteliğin uygulandığı varlıktır. Örneğin, bir öznitelik bir sınıfa, belirli bir yönteme veya bir
derlemenin tamamına uygulanabilir. Varsayılan olarak, bir öznitelik, onu izleyen öğesi için geçerlidir. Ancak, bir
özniteliğin bir yönteme mi, yoksa parametresine mi, yoksa dönüş değerine mi uygulanacağını de açıkça
belirleyebilirsiniz.
Bir öznitelik hedefini açıkça tanımlamak için aşağıdaki sözdizimini kullanın:

[target : attribute-list]

Olası target değerleri listesi aşağıdaki tabloda gösterilmiştir.

HEDEF DEĞER UYGULANDIĞI ÖĞE:

assembly Tüm derleme

module Geçerli derleme modülü

field Bir sınıf veya yapı içindeki alan

event Olay

method Yöntem veya get ve set Özellik erişimcileri


HEDEF DEĞER UYGULANDIĞI ÖĞE:

param Yöntem parametreleri veya set özellik erişimcisi


parametreleri

property Özellik

return Metodun, özellik dizin oluşturucusunun veya get Özellik


erişimcisinin dönüş değeri

type Struct, Class, Interface, Enum veya Delegate

Otomatik uygulanan bir özellikiçin oluşturulan yedekleme alanına bir öznitelik uygulamak üzere field Target
değerini belirtirsiniz.
Aşağıdaki örnek, derlemeler ve modüllere özniteliklerin nasıl uygulanacağını gösterir. Daha fazla bilgi için bkz.
ortak özniteliklerC#() .

using System;
using System.Reflection;
[assembly: AssemblyTitleAttribute("Production assembly 4")]
[module: CLSCompliant(true)]

Aşağıdaki örnek, içindeki C#yöntemlere, yöntem parametrelerine ve yöntem dönüş değerlerine özniteliklerin
nasıl uygulanacağını gösterir.

// default: applies to method


[ValidatedContract]
int Method1() { return 0; }

// applies to method
[method: ValidatedContract]
int Method2() { return 0; }

// applies to return value


[return: ValidatedContract]
int Method3() { return 0; }

NOTE
ValidatedContract tanımlanan hedeflerden bağımsız olarak, ValidatedContract yalnızca dönüş değerleri uygulamak
üzere tanımlansa bile return hedefi belirtilmelidir. Diğer bir deyişle, derleyici belirsiz öznitelik hedeflerini çözümlemek için
AttributeUsage bilgilerini kullanmaz. Daha fazla bilgi için bkz. AttributeUsageC#().

Öznitelikler için ortak kullanımlar


Aşağıdaki listede, kod içindeki özniteliklerin yaygın kullanımları yer almaktadır:
Metodun SOAP protokolü üzerinden çağrılabilir olması gerektiğini göstermek için Web hizmetlerindeki
WebMethod özniteliğini kullanarak yöntemleri işaretleme. Daha fazla bilgi için bkz. WebMethodAttribute.
Yerel kodla birlikte çalışırken yöntem parametrelerinin nasıl hazırlanacağını açıklama. Daha fazla bilgi için bkz.
MarshalAsAttribute.
Sınıflar, Yöntemler ve arabirimler için COM özelliklerini açıklama.
Yönetilmeyen kod DllImportAttribute sınıfını kullanarak çağrılıyor.
Derlemenizi başlık, sürüm, açıklama veya ticari marka açısından açıklama.
Bir sınıfın kalıcılığı için hangi üyelerin serileştirmek gerektiğini açıklama.
XML ile serileştirme için sınıf üyeleri ve XML düğümleri arasında nasıl eşleme yapılacağı açıklanır.
Yöntemler için güvenlik gereksinimlerini açıklama.
Güvenliği zorlamak için kullanılan özellikleri belirtme.
Tam zamanında (JıT) derleyicisine yönelik iyileştirmeler denetleniyor, böylece kod hata ayıklama için kolay
kalır.
Bir yönteme arayan hakkında bilgi alma.

İlgili bölümler
Daha fazla bilgi için bkz.:
Özel öznitelikler (C#) oluşturma
Yansıma (C#) kullanarak özniteliklere erişme
Öznitelikleri kullanarak C/C++ Union oluşturma ()C#
Ortak öznitelikler (C#)
Arayan bilgileri (C#)

Ayrıca bkz.
C# Programlama Kılavuzu
Yansıma (C#)
Öznitelikler
İçindeki öznitelikleri kullanmaC#
Özel öznitelikler (C#) oluşturma
23.10.2019 • 2 minutes to read • Edit Online

Doğrudan veya dolaylı Attributeolarak sınıfından türetilmiş bir sınıf olan öznitelik sınıfını tanımlayarak kendi özel
öznitelerinizi oluşturabilirsiniz. Bu, meta verilerde hızlı ve kolay bir şekilde öznitelik tanımları tanımlamayı sağlar.
Türleri, türünü yazan programcının adıyla etiketlemek istediğinizi varsayalım. Özel Author bir öznitelik sınıfı
tanımlayabilirsiniz:

[System.AttributeUsage(System.AttributeTargets.Class |
System.AttributeTargets.Struct)
]
public class Author : System.Attribute
{
private string name;
public double version;

public Author(string name)


{
this.name = name;
version = 1.0;
}
}

Sınıf adı özniteliğin adıdır, Author . Öğesinden System.Attribute türetilir, bu nedenle özel bir öznitelik sınıfıdır.
Oluşturucunun parametreleri özel özniteliğin konumsal parametreleridir. Bu örnekte, name bir Konumsal
parametredir. Tüm genel okuma/yazma alanları veya özellikleri parametreler olarak adlandırılır. Bu durumda,
version tek adlandırılmış parametredir. Özniteliği yalnızca sınıf ve AttributeUsage struct bildirimlerde geçerli
Author hale getirmek için özniteliğinin kullanımını unutmayın.

Bu yeni özniteliği şu şekilde kullanabilirsiniz:

[Author("P. Ackerman", version = 1.1)]


class SampleClass
{
// P. Ackerman's code goes here...
}

AttributeUsage , özel bir özniteliği tek AllowMultiple kullanımı veya çok kullanımı yapabileceğiniz adlandırılmış
bir parametreye sahiptir. Aşağıdaki kod örneğinde, Multiuse özniteliği oluşturulur.

[System.AttributeUsage(System.AttributeTargets.Class |
System.AttributeTargets.Struct,
AllowMultiple = true) // multiuse attribute
]
public class Author : System.Attribute

Aşağıdaki kod örneğinde, aynı türde birden çok öznitelik bir sınıfa uygulanır.
[Author("P. Ackerman", version = 1.1)]
[Author("R. Koch", version = 1.2)]
class SampleClass
{
// P. Ackerman's code goes here...
// R. Koch's code goes here...
}

Ayrıca bkz.
System.Reflection
C# Programlama Kılavuzu
Özel Öznitelikler Yazma
Yansıma (C#)
Öznitelikler (C#)
Yansıma (C#) kullanarak özniteliklere erişme
AttributeUsage (C#)
AttributeUsage (C#)
23.10.2019 • 4 minutes to read • Edit Online

Özel bir öznitelik sınıfı nasıl kullanılabileceğini belirler. AttributeUsageAttribute özel öznitelik tanımları için geçerli
bir özniteliktir. AttributeUsage Özniteliği denetimi sağlar:
Hangi program öğeleri özniteliği uygulanabilir. Kullanımını kısıtlamak sürece aşağıdaki program öğelerin
herhangi bir öznitelik uygulanabilir:
derleme
modül
alan
olay
yöntemi
param
özellik
return
türü
Olup öznitelik birden çok kez tek bir program öğesine uygulanabilir.
Olup öznitelikleri türetilmiş sınıflar tarafından devralınır.
Varsayılan ayarları açıkça uygulandığında aşağıdaki örnekteki gibi görünür:

[System.AttributeUsage(System.AttributeTargets.All,
AllowMultiple = false,
Inherited = true)]
class NewAttribute : System.Attribute { }

Bu örnekte, NewAttribute sınıfı için herhangi bir desteklenen bir program öğesine uygulanabilir. Ancak, her varlık
için yalnızca bir kez uygulanabilir. Öznitelik, bir temel sınıfa uygulandığında türetilmiş sınıflar tarafından devralınır.
AllowMultiple Ve Inherited aşağıdaki kodu aynı etkiye sahiptir. Bu nedenle bağımsız değişken isteğe bağlıdır:

[System.AttributeUsage(System.AttributeTargets.All)]
class NewAttribute : System.Attribute { }

İlk AttributeUsageAttribute bağımsız değişkeni olmalıdır bir veya daha fazla öğeleri AttributeTargets sabit listesi.
Birden çok hedef türü OR işlecini aşağıdaki örnekte gösterildiği gibi birlikte bağlanabilir:

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
class NewPropertyOrFieldAttribute : Attribute { }

C# 7.3 başlayarak, özellik ya da yedekleme alanını otomatik olarak uygulanan bir özellik için öznitelikleri
uygulanabilir. Siz belirtmediğiniz sürece özniteliği özelliğine uygulanır field öznitelikte tanımlayıcısı. Her ikisi de,
aşağıdaki örnekte gösterilmiştir:
class MyClass
{
// Attribute attached to property:
[NewPropertyOrField]
public string Name { get; set; }

// Attribute attached to backing field:


[field:NewPropertyOrField]
public string Description { get; set; }
}

Varsa AllowMultiple bağımsız değişkeni true , sonra elde edilen özniteliği birden çok kez tek bir varlık için
aşağıdaki örnekte gösterildiği gibi uygulanabilir:

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]


class MultiUse : Attribute { }

[MultiUse]
[MultiUse]
class Class1 { }

[MultiUse, MultiUse]
class Class2 { }

Bu durumda, MultiUseAttribute art arda çünkü uygulanabilir AllowMultiple ayarlanır true . Birden çok öznitelik
uygulamak için gösterilen iki biçimi geçerli değil.
Varsa Inherited olduğu false , öznitelik, öznitelik atanmış bir sınıftan türetilmiş sınıflar tarafından devralınan değil
sonra. Örneğin:

[AttributeUsage(AttributeTargets.Class, Inherited = false)]


class NonInheritedAttribute : Attribute { }

[NonInherited]
class BClass { }

class DClass : BClass { }

Bu durumda NonInheritedAttribute için uygulanmaz DClass devralma aracılığıyla.

Açıklamalar
AttributeUsage Özniteliği, bir tek kullanımlık özniteliğin birden çok kez aynı sınıfa uygulanamaz. AttributeUsage
için bir diğer addır AttributeUsageAttribute.
Daha fazla bilgi için yansıma (C#) kullanarak erişen özniteliklerle.

Örnek
Aşağıdaki örnek, etkisini gösterir Inherited ve AllowMultiple bağımsız değişkenleri AttributeUsageAttribute
özniteliği ve nasıl bir sınıfa uygulanan özel öznitelikler listelenebilir.
using System;

// Create some custom attributes:


[AttributeUsage(AttributeTargets.Class, Inherited = false)]
class FirstAttribute : Attribute { }

[AttributeUsage(AttributeTargets.Class)]
class SecondAttribute : Attribute { }

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]


class ThirdAttribute : Attribute { }

// Apply custom attributes to classes:


[First, Second]
class BaseClass { }

[Third, Third]
class DerivedClass : BaseClass { }

public class TestAttributeUsage


{
static void Main()
{
BaseClass b = new BaseClass();
DerivedClass d = new DerivedClass();

// Display custom attributes for each class.


Console.WriteLine("Attributes on Base Class:");
object[] attrs = b.GetType().GetCustomAttributes(true);
foreach (Attribute attr in attrs)
{
Console.WriteLine(attr);
}

Console.WriteLine("Attributes on Derived Class:");


attrs = d.GetType().GetCustomAttributes(true);
foreach (Attribute attr in attrs)
{
Console.WriteLine(attr);
}
}
}

Örnek Çıktı
Attributes on Base Class:
FirstAttribute
SecondAttribute
Attributes on Derived Class:
ThirdAttribute
ThirdAttribute
SecondAttribute

Ayrıca bkz.
Attribute
System.Reflection
C# Programlama Kılavuzu
Öznitelikler
Yansıma (C#)
Öznitelikler
Özel öznitelikler (C#) oluşturma
Yansıma (C#) kullanarak özniteliklere erişme
Yansıma (C#) kullanarak özniteliklere erişme
23.10.2019 • 2 minutes to read • Edit Online

Özel öznitelikleri tanımlayabilir ve bunları kaynak kodunuza yerleştirebilirsiniz. Bu bilgiler, bu bilgileri alma ve
üzerinde işlem yapmaya gerek kalmadan çok az değer elde edebilir. Yansıma kullanarak özel özniteliklerle
tanımlanan bilgileri alabilirsiniz. Anahtar yöntemi, kaynak GetCustomAttributes kodu özniteliklerinin çalışma
zamanı eşdeğerleri olan bir nesne dizisi döndüren ' dir. Bu yöntemin birkaç aşırı yüklü sürümü vardır. Daha fazla
bilgi için bkz. Attribute.
Şöyle bir öznitelik belirtimi:

[Author("P. Ackerman", version = 1.1)]


class SampleClass

kavramsal olarak eşdeğerdir:

Author anonymousAuthorObject = new Author("P. Ackerman");


anonymousAuthorObject.version = 1.1;

Ancak, kod öznitelikleri için sorgulanana kadar SampleClass yürütülmez. Author ' GetCustomAttributes
Inçağrılması,birnesneninyukarıyaoluşturulmasınıvebaşlatılmasınısağlar. SampleClass Sınıfın başka öznitelikleri
varsa, diğer öznitelik nesneleri benzer şekilde oluşturulur. GetCustomAttributes sonra Author nesneyi ve dizideki
diğer öznitelik nesnelerini döndürür. Daha sonra bu dizinin üzerinde yineleyebilir, her bir dizi öğesinin türüne
göre hangi özniteliklerin uygulandığını belirleyebilir ve öznitelik nesnelerinden bilgi ayıklayabilirsiniz.

Örnek
Aşağıda bir örnek verilmiştir. Özel bir öznitelik tanımlanır, birkaç varlığa uygulanır ve yansıma aracılığıyla alınır.

// Multiuse attribute.
[System.AttributeUsage(System.AttributeTargets.Class |
System.AttributeTargets.Struct,
AllowMultiple = true) // Multiuse attribute.
]
public class Author : System.Attribute
{
string name;
public double version;

public Author(string name)


{
this.name = name;

// Default value.
version = 1.0;
}

public string GetName()


{
return name;
}
}

// Class with the Author attribute.


[Author("P. Ackerman")]
[Author("P. Ackerman")]
public class FirstClass
{
// ...
}

// Class without the Author attribute.


public class SecondClass
{
// ...
}

// Class with multiple Author attributes.


[Author("P. Ackerman"), Author("R. Koch", version = 2.0)]
public class ThirdClass
{
// ...
}

class TestAuthorAttribute
{
static void Test()
{
PrintAuthorInfo(typeof(FirstClass));
PrintAuthorInfo(typeof(SecondClass));
PrintAuthorInfo(typeof(ThirdClass));
}

private static void PrintAuthorInfo(System.Type t)


{
System.Console.WriteLine("Author information for {0}", t);

// Using reflection.
System.Attribute[] attrs = System.Attribute.GetCustomAttributes(t); // Reflection.

// Displaying output.
foreach (System.Attribute attr in attrs)
{
if (attr is Author)
{
Author a = (Author)attr;
System.Console.WriteLine(" {0}, version {1:f}", a.GetName(), a.version);
}
}
}
}
/* Output:
Author information for FirstClass
P. Ackerman, version 1.00
Author information for SecondClass
Author information for ThirdClass
R. Koch, version 2.00
P. Ackerman, version 1.00
*/

Ayrıca bkz.
System.Reflection
Attribute
C# Programlama Kılavuzu
Özniteliklerde Depolanan Bilgileri Alma
Yansıma (C#)
Öznitelikler (C#)
Özel öznitelikler (C#) oluşturma
Öznitelikleri kullanarak C/C++ Union oluşturma ()C#
25.11.2019 • 2 minutes to read • Edit Online

Öznitelikleri kullanarak, yapıların bellekte nasıl düzenlendiğini özelleştirebilirsiniz. Örneğin,


StructLayout(LayoutKind.Explicit) ve FieldOffset özniteliklerini kullanarak C/C++ içinde birleşim olarak bilinen
öğeleri oluşturabilirsiniz.

Örnek
Bu kod kesiminde, tüm TestUnion alanları bellekte aynı konumda başlar.

// Add a using directive for System.Runtime.InteropServices.

[System.Runtime.InteropServices.StructLayout(LayoutKind.Explicit)]
struct TestUnion
{
[System.Runtime.InteropServices.FieldOffset(0)]
public int i;

[System.Runtime.InteropServices.FieldOffset(0)]
public double d;

[System.Runtime.InteropServices.FieldOffset(0)]
public char c;

[System.Runtime.InteropServices.FieldOffset(0)]
public byte b;
}

Örnek
Aşağıda, alanların farklı bir açık küme konumlarında başlayacağı başka bir örnek verilmiştir.

// Add a using directive for System.Runtime.InteropServices.

[System.Runtime.InteropServices.StructLayout(LayoutKind.Explicit)]
struct TestExplicit
{
[System.Runtime.InteropServices.FieldOffset(0)]
public long lg;

[System.Runtime.InteropServices.FieldOffset(0)]
public int i1;

[System.Runtime.InteropServices.FieldOffset(4)]
public int i2;

[System.Runtime.InteropServices.FieldOffset(8)]
public double d;

[System.Runtime.InteropServices.FieldOffset(12)]
public char c;

[System.Runtime.InteropServices.FieldOffset(14)]
public byte b;
}
İki tamsayı alanı i1 ve i2 , lg ile aynı bellek konumlarını paylaşır. Yapı düzeni üzerinde bu denetim sıralaması,
platform çağırma kullanılırken kullanışlıdır.

Ayrıca bkz.
System.Reflection
Attribute
C# Programlama Kılavuzu
Öznitelikler
Yansıma (C#)
Öznitelikler (C#)
Özel öznitelikler (C#) oluşturma
Yansıma (C#) kullanarak özniteliklere erişme
Ortak öznitelikler (C#)
23.10.2019 • 11 minutes to read • Edit Online

Bu konuda, C# programlarda en yaygın olarak kullanılan öznitelikler açıklanmaktadır.


Genel öznitelikler
Kullanımdan kaldırılmış öznitelik
Koşullu öznitelik
Arayan bilgileri öznitelikleri

Genel öznitelikler
Çoğu öznitelik sınıflar veya yöntemler gibi belirli dil öğelerine uygulanır; Ancak, bazı öznitelikler geneldir, tüm
derleme veya modül için geçerlidir. Örneğin, AssemblyVersionAttribute özniteliği aşağıdaki gibi bir derlemeye
sürüm bilgisi eklemek için kullanılabilir:

[assembly: AssemblyVersion("1.0.0.0")]

Genel öznitelikler, herhangi bir üst düzey using yönergelerden sonra ve herhangi bir tür, modül veya ad alanı
bildirimlerinden sonra kaynak kodunda görünür. Genel öznitelikler birden çok kaynak dosyasında görünebilir,
ancak dosyaların tek bir derleme geçişinde derlenmesi gerekir. C# Projelerde, genel öznitelikler AssemblyInfo.cs
dosyasına konur.
Derleme öznitelikleri, bir derleme hakkında bilgi sağlayan değerlerdir. Bunlar aşağıdaki kategorilere ayrılır:
Bütünleştirilmiş kod kimliği öznitelikleri
Bilgilendirici öznitelikler
Bütünleştirilmiş kod bildirim öznitelikleri
Bütünleştirilmiş kod kimliği öznitelikleri
Üç öznitelik (varsa, güçlü bir ad varsa) bir derlemenin kimliğini belirleme: ad, sürüm ve kültür. Bu öznitelikler,
derlemenin tam adını oluşturur ve kodda başvuru yaptığınızda gereklidir. Öznitelikleri kullanarak bir derlemenin
sürümünü ve kültürünü ayarlayabilirsiniz. Bununla birlikte, ad değeri derleyici tarafından, derleme bilgileri Iletişim
kutusundaVISUAL Studio IDE veya derleme oluşturulduğunda derleme Bağlayıcısı (al. exe) tarafından ayarlanır.
AssemblyFlagsAttribute Özniteliği, derlemenin birden çok kopyasının birlikte kullanılıp kullanılamayacağını
belirtir.
Aşağıdaki tabloda kimlik öznitelikleri gösterilmektedir.

ÖZNITELIK AMAÇ

AssemblyName Bir derlemenin kimliğini tam olarak açıklar.

AssemblyVersionAttribute Bir derlemenin sürümünü belirtir.

AssemblyCultureAttribute Derlemenin desteklediği kültürü belirtir.


ÖZNITELIK AMAÇ

AssemblyFlagsAttribute Bir derlemenin aynı bilgisayarda, aynı işlemde veya aynı


uygulama etki alanında yan yana yürütmeyi destekleyip
desteklemediğini belirtir.

Bilgilendirici öznitelikler
Bir derlemeye ek şirket veya ürün bilgileri sağlamak için bilgilendirici öznitelikleri kullanabilirsiniz. Aşağıdaki
tabloda, System.Reflection ad alanında tanımlanan bilgilendirici öznitelikler gösterilmektedir.

ÖZNITELIK AMAÇ

AssemblyProductAttribute Bir derleme bildirimi için bir ürün adı belirten özel bir özniteliği
tanımlar.

AssemblyTrademarkAttribute Bir derleme bildirimi için ticari marka belirten özel bir özniteliği
tanımlar.

AssemblyInformationalVersionAttribute Bir derleme bildirimi için bilgilendirici bir sürüm belirten özel
bir özniteliği tanımlar.

AssemblyCompanyAttribute Bir derleme bildirimi için bir şirket adı belirten özel bir
özniteliği tanımlar.

AssemblyCopyrightAttribute Bir derleme bildirimi için bir telif hakkı belirten özel bir
özniteliği tanımlar.

AssemblyFileVersionAttribute Derleyiciye Win32 dosya sürümü kaynağı için belirli bir sürüm
numarası kullanmasını söyler.

CLSCompliantAttribute Derlemenin ortak dil belirtimi (CLS) ile uyumlu olup olmadığını
gösterir.

Bütünleştirilmiş kod bildirim öznitelikleri


Derleme bildiriminde bilgi sağlamak için bütünleştirilmiş kod bildirim özniteliklerini kullanabilirsiniz. Buna Başlık,
açıklama, varsayılan diğer ad ve yapılandırma dahildir. Aşağıdaki tabloda, System.Reflection ad alanında
tanımlanan derleme bildirimi öznitelikleri gösterilmektedir.

ÖZNITELIK AMAÇ

AssemblyTitleAttribute Bir derleme bildirimi için derleme başlığını belirten özel bir
özniteliği tanımlar.

AssemblyDescriptionAttribute Bir derleme bildirimi için derleme açıklamasını belirten özel bir
özniteliği tanımlar.

AssemblyConfigurationAttribute Derleme bildirimi için bir derleme yapılandırması (perakende


veya hata ayıklama) belirten özel bir öznitelik tanımlar.

AssemblyDefaultAliasAttribute Bir derleme bildirimi için kolay bir varsayılan diğer ad tanımlar

Kullanımdan kaldırılmış öznitelik


Özniteliği Obsolete , bir program varlığını artık kullanım için önerilmeyen bir şekilde işaretler. Kullanımdan kalktı
olarak işaretlenen bir varlığın her kullanımı, özniteliğin nasıl yapılandırıldığına bağlı olarak bir uyarı veya hata
oluşturur. Örneğin:

[System.Obsolete("use class B")]


class A
{
public void Method() { }
}
class B
{
[System.Obsolete("use NewMethod", true)]
public void OldMethod() { }
public void NewMethod() { }
}

Bu örnekte, Obsolete özniteliği sınıfa A ve yöntemine B.OldMethod uygulanır. Öğesine B.OldMethod uygulanan
öznitelik oluşturucusunun ikinci bağımsız değişkeni olarak true ayarlandığından, bu yöntem bir derleyici hatasına
neden olur, ancak sınıf A kullanımı yalnızca bir uyarı oluşturur. Ancak B.NewMethod çağırma, hiçbir uyarı veya hata
üretir.
Öznitelik oluşturucusuna ilk bağımsız değişken olarak girilen dize, uyarının veya hatanın bir parçası olarak
görüntülenir. Örneğin, önceki tanımlarla birlikte kullandığınızda, aşağıdaki kod iki uyarı ve bir hata oluşturur:

// Generates 2 warnings:
// A a = new A();

// Generate no errors or warnings:


B b = new B();
b.NewMethod();

// Generates an error, terminating compilation:


// b.OldMethod();

Sınıf A için iki uyarı oluşturulur: biri sınıf başvurusunun bildirimi ve diğeri sınıf oluşturucusu içindir.
Obsolete Öznitelik bağımsız değişkenler olmadan kullanılabilir, ancak öğenin neden kullanımdan kalkdığına ve
bunun yerine ne tür bir açıklama dahil edilmesi önerilir.
Obsolete Özniteliği tek kullanım özniteliğidir ve özniteliklere izin veren herhangi bir varlığa uygulanabilir.
Obsolete , için ObsoleteAttributebir diğer addır.

Koşullu öznitelik
Conditional Özniteliği bir işlem ön işleme tanımlayıcısına bağımlı bir yöntemin yürütülmesini sağlar.
Conditional Özniteliği içinConditionalAttributebir diğer addır ve bir yönteme veya öznitelik sınıfına uygulanabilir.
Bu örnekte, Conditional programa özgü tanılama bilgilerinin görüntülenmesini etkinleştirmek veya devre dışı
bırakmak için bir yönteme uygulanır:
#define TRACE_ON
using System;
using System.Diagnostics;

public class Trace


{
[Conditional("TRACE_ON")]
public static void Msg(string msg)
{
Console.WriteLine(msg);
}
}

public class ProgramClass


{
static void Main()
{
Trace.Msg("Now in Main...");
Console.WriteLine("Done.");
}
}

TRACE_ON Tanımlayıcı tanımlanmamışsa, hiçbir izleme çıkışı gösterilmez.


Öznitelik, genellikle hata ayıklama derlemeleri için DEBUG izleme ve günlüğe kaydetme özelliklerini etkinleştirmek
için tanımlayıcı ile birlikte kullanılır, ancak bunun gibi sürüm yapılarında desteklenmez: Conditional

[Conditional("DEBUG")]
static void DebugMethod()
{
}

Koşullu olarak işaretlenen bir yöntem çağrıldığında, belirtilen ön işleme simgesinin varlığı veya yokluğu, çağrının
eklenip eklenmeyeceğini veya atlanmadığını belirler. Sembol tanımlanmışsa, çağrı dahil edilir; Aksi takdirde, çağrı
atlanır. Kullanılarak Conditional , blokların içindeki yöntemlerin içine yerleştirilmesi #if…#endif için aşağıdaki
gibi bir temizleyici, daha zarif ve daha az hataya açık bir alternatiftir:

#if DEBUG
void ConditionalMethod()
{
}
#endif

Koşullu Yöntem bir sınıf veya yapı bildiriminde bir yöntem olmalıdır ve dönüş değeri içermemelidir.
Birden çok tanımlayıcı kullanma
Bir yöntemin birden çok Conditional özniteliği varsa, koşullu simgelerden en az biri tanımlanmışsa yöntemine bir
çağrı dahil edilir (başka bir deyişle, semboller or işleci kullanılarak mantıksal olarak birbirlerine bağlanır). Bu
örnekte, ya da A B birinin varlığı bir yöntem çağrısına neden olur:

[Conditional("A"), Conditional("B")]
static void DoIfAorB()
{
// ...
}

VE işlecini kullanarak sembolleri mantıksal olarak bağlama etkisini elde etmek için, seri koşullu yöntemleri
tanımlayabilirsiniz. Örneğin, aşağıdaki ikinci yöntem yalnızca A ve B tanımlanırsa yürütülür:
[Conditional("A")]
static void DoIfA()
{
DoIfAandB();
}

[Conditional("B")]
static void DoIfAandB()
{
// Code to execute when both A and B are defined...
}

Öznitelik sınıfları ile koşullu kullanma


Öznitelik Conditional , öznitelik sınıfı tanımına da uygulanabilir. Bu örnekte, özel öznitelik Documentation yalnızca
hata ayıklama tanımlanmışsa meta verilere bilgi ekler.

[Conditional("DEBUG")]
public class Documentation : System.Attribute
{
string text;

public Documentation(string text)


{
this.text = text;
}
}

class SampleClass
{
// This attribute will only be included if DEBUG is defined.
[Documentation("This method displays an integer.")]
static void DoWork(int i)
{
System.Console.WriteLine(i.ToString());
}
}

Arayan bilgileri öznitelikleri


Arayan Bilgisi özniteliklerini kullanarak bir yöntemin arayanı hakkında bilgi edinebilirsiniz. Kaynak kodun dosya
yolunu, kaynak kodundaki satır numarasını ve arayanın üye adını elde edebilirsiniz.
Üye çağıran bilgilerini almak için, isteğe bağlı parametrelere uygulanan öznitelikleri kullanırsınız. Her isteğe bağlı
parametre varsayılan bir değer belirtir. Aşağıdaki tabloda, System.Runtime.CompilerServices ad alanında
tanımlanan arayan bilgileri öznitelikleri listelenmektedir:

ÖZNITELIK AÇIKLAMA TÜR

CallerFilePathAttribute Kaynak dosyasının arayanı içeren tam String


yolu. Bu, derleme zamanının yoludur.

CallerLineNumberAttribute Yöntemin çağrıldığı kaynak dosyadaki Integer


satır numarası.

CallerMemberNameAttribute Çağıranın Yöntem adı veya özellik adı. String


Daha fazla bilgi için bkz. arayan
bilgileriC#().

Arayan bilgileri öznitelikleri hakkında daha fazla bilgi için bkz. arayan bilgileri (C#).
Ayrıca bkz.
System.Reflection
Attribute
C# Programlama Kılavuzu
Öznitelikler
Yansıma (C#)
Yansıma (C#) kullanarak özniteliklere erişme
Arayan bilgileri (C#)
23.10.2019 • 4 minutes to read • Edit Online

Arayan Bilgisi özniteliklerini kullanarak bir yöntemin arayanı hakkında bilgi edinebilirsiniz. Kaynak kodunun
dosya yolunu, kaynak kodundaki satır numarasını ve arayanın üye adını alabilirsiniz. Bu bilgiler, tanılama
araçlarının izlenmesine, oluşturulmasına ve bu araçlarda hata ayıklanmasına yardımcı olur.
Bu bilgileri elde etmek için her biri varsayılan değere sahip isteğe bağlı parametrelere uygulanan öznitelikler
kullanabilirsiniz. Aşağıdaki tabloda, System.Runtime.CompilerServices ad alanında tanımlanan arayan bilgileri
öznitelikleri listelenmektedir:

ÖZNITELIK AÇIKLAMA TÜR

CallerFilePathAttribute Kaynak dosyasının arayanı içeren tam String


yolu. Bu, derleme zamanındaki dosya
yoludur.

CallerLineNumberAttribute Yöntemin çağrıldığı kaynak dosyadaki Integer


satır numarası.

CallerMemberNameAttribute Arayanın yöntemi veya özellik adı. Bu String


konunun devamındaki üye adları
bölümüne bakın.

Örnek
Aşağıdaki örnekte, Arayanın Bilgisi özniteliklerinin nasıl kullanılacağı gösterilmiştir. TraceMessage Yöntemine
yapılan her çağrıda, çağıran bilgileri isteğe bağlı parametrelere bağımsız değişkenler olarak değiştirilir.

public void DoProcessing()


{
TraceMessage("Something happened.");
}

public void TraceMessage(string message,


[System.Runtime.CompilerServices.CallerMemberName] string memberName = "",
[System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "",
[System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
{
System.Diagnostics.Trace.WriteLine("message: " + message);
System.Diagnostics.Trace.WriteLine("member name: " + memberName);
System.Diagnostics.Trace.WriteLine("source file path: " + sourceFilePath);
System.Diagnostics.Trace.WriteLine("source line number: " + sourceLineNumber);
}

// Sample Output:
// message: Something happened.
// member name: DoProcessing
// source file path: c:\Visual Studio Projects\CallerInfoCS\CallerInfoCS\Form1.cs
// source line number: 31

Açıklamalar
Her isteğe bağlı parametre için açık bir varsayılan değer belirtmeniz gerekir. İsteğe bağlı olarak belirtilmeyen
parametrelere Arayan Bilgisi özniteliklerini uygulayamazsınız.
Arayan Bilgisi öznitelikleri, bir parametreyi isteğe bağlı hale getirmez. Bunun yerine, bağımsız değişken
atlandığında geçirilen varsayılan değeri etkilerler.
Arayan Bilgisi değerleri, derleme zamanında Ara Dile (IL ) değişmez değerler olarak verilir. Özel durumlar için
StackTrace Özellik sonuçlarının aksine, sonuçlar gizleme tarafından etkilenmez.
Arayan bilgisini denetlemek veya gizlemek için isteğe bağlı bağımsız değişkenleri açıkça sağlayabilirsiniz.
Üye adları
CallerMemberName Özniteliği, çağrılan yönteme bir String bağımsız değişken olarak üye adını belirtmekten
kaçınmak için kullanabilirsiniz. Bu tekniği kullanarak yeniden düzenlemeyi yeniden adlandırma sorunu,
String değerleri değiştirmez. Bu, özellikle aşağıdaki görevler için yararlı olur:

İzleme ve tanılama yordamlarını kullanma.


Verileri bağlarken INotifyPropertyChanged arabirimi uygulama. Bu arabirim, bir nesnenin özelliğinin
bağlama denetimine özelliğin değiştirildiğini bildirmesini ve böylece denetimin güncelleştirilmiş bilgileri
görüntüleyebilmesini sağlar. CallerMemberName Özniteliği olmadan, özellik adını bir sabit değer olarak
belirtmeniz gerekir.
Aşağıdaki grafikte, CallerMemberName özniteliğini kullandığınızda döndürülen üye adları gösterilmektedir.

ÇAĞRININ OLUŞTUĞU YER ÜYE ADI SONUCU

Yöntem, özellik veya olay Yöntemin, özelliğin veya aramanın kaynaklandığı olayın adı.

Oluşturucu ".ctor" dizesi

Statik oluşturucu ".cctor" dizesi

Yok edici "Finalize" dizesi

Kullanıcı tanımlı işleçler veya dönüştürmeler Üye için oluşturulan "op_Addition" gibi bir ad.

Öznitelik oluşturucu Özniteliğin uygulandığı yöntemin veya özelliğin adı. Öznitelik


bir üye içerisindeki herhangi bir öğeyse (parametre, dönüş
değeri veya genel tür parametresi gibi), bu sonuç bu öğeyle
ilişkili öğenin adıdır.

İçeren üye yok (örneğin, derleme düzeyi veya türlere İsteğe bağlı parametrenin varsayılan değeri.
uygulanan öznitelikler)

Ayrıca bkz.
Öznitelikler (C#)
Ortak öznitelikler (C#)
Adlandırılmış ve İsteğe Bağlı Bağımsız Değişkenler
Programlama kavramları (C#)
Koleksiyonlar (C#)
4.11.2019 • 19 minutes to read • Edit Online

Birçok uygulama için ilgili nesne grupları oluşturmak ve yönetmek istersiniz. Nesneleri gruplandırmanın iki yolu
vardır: nesne dizileri oluşturarak ve nesne koleksiyonları oluşturarak.
Diziler, kesin olarak belirlenmiş sabit sayıda nesne oluşturmak ve bunlarla çalışmak için en yararlı seçenektir.
Diziler hakkında daha fazla bilgi için bkz. diziler.
Koleksiyonlar, nesne gruplarıyla çalışmak için daha esnek bir yol sağlar. Dizilerden farklı olarak, çalıştığınız nesne
grubu, uygulama değişikliğinin ihtiyaçlarına göre dinamik olarak büyüyebilir ve küçülebilir. Bazı koleksiyonlar için,
anahtarı kullanarak nesneyi hızlı bir şekilde alabilmeniz için koleksiyona yerleştirdiğiniz herhangi bir nesneye bir
anahtar atayabilirsiniz.
Koleksiyon bir sınıftır, bu nedenle bu koleksiyona öğe ekleyebilmeniz için önce sınıfın bir örneğini bildirmeniz
gerekir.
Koleksiyonunuz yalnızca bir veri türünün öğelerini içeriyorsa, System.Collections.Generic ad alanındaki sınıflardan
birini kullanabilirsiniz. Genel bir koleksiyon, tür güvenliğini, başka bir veri türü eklenememesi için uygular. Genel
koleksiyondan bir öğe aldığınızda, veri türünü belirlememek veya dönüştürmek zorunda değilsiniz.

NOTE
Bu konudaki örnekler için System.Collections.Generic ve System.Linq ad alanları için using yönergelerini içerir.

Bu konuda
Basit bir koleksiyon kullanma
Koleksiyon türleri
System. Collections. Generic sınıfları
System. Collections. eşzamanlı sınıflar
System. Collections sınıfları
Anahtar/değer çiftleri koleksiyonu uygulama
Koleksiyona erişmek için LINQ kullanma
Bir koleksiyonu sıralama
Özel bir koleksiyon tanımlama
Yineleyiciler

Basit bir koleksiyon kullanma


Bu bölümdeki örneklerde, türü kesin belirlenmiş bir nesne listesiyle çalışmanıza olanak sağlayan genel List<T>
sınıfını kullanın.
Aşağıdaki örnek, bir dizi dizenin bir listesini oluşturur ve sonra, bir foreach ifadesi kullanarak dizeler arasında
yinelenir.
// Create a list of strings.
var salmons = new List<string>();
salmons.Add("chinook");
salmons.Add("coho");
salmons.Add("pink");
salmons.Add("sockeye");

// Iterate through the list.


foreach (var salmon in salmons)
{
Console.Write(salmon + " ");
}
// Output: chinook coho pink sockeye

Bir koleksiyonun içeriği önceden biliniyorsa, koleksiyonu başlatmak için bir koleksiyon başlatıcısı kullanabilirsiniz.
Daha fazla bilgi için bkz. nesne ve koleksiyon başlatıcıları.
Aşağıdaki örnek, koleksiyona öğe eklemek için bir koleksiyon başlatıcısı kullanılması dışında, önceki örnekle
aynıdır.

// Create a list of strings by using a


// collection initializer.
var salmons = new List<string> { "chinook", "coho", "pink", "sockeye" };

// Iterate through the list.


foreach (var salmon in salmons)
{
Console.Write(salmon + " ");
}
// Output: chinook coho pink sockeye

Bir koleksiyon üzerinden yinelemek için bir foreach deyimin yerine for deyiminizi kullanabilirsiniz. Bunu,
koleksiyon öğelerine dizin konumuna erişerek gerçekleştirirsiniz. Öğelerin dizini 0 ' dan başlar ve öğe sayısı eksi 1
' den sona erer.
Aşağıdaki örnek, foreach yerine for kullanarak bir koleksiyonun öğeleri boyunca yinelenir.

// Create a list of strings by using a


// collection initializer.
var salmons = new List<string> { "chinook", "coho", "pink", "sockeye" };

for (var index = 0; index < salmons.Count; index++)


{
Console.Write(salmons[index] + " ");
}
// Output: chinook coho pink sockeye

Aşağıdaki örnek, kaldırılacak nesneyi belirterek koleksiyondan bir öğeyi kaldırır.


// Create a list of strings by using a
// collection initializer.
var salmons = new List<string> { "chinook", "coho", "pink", "sockeye" };

// Remove an element from the list by specifying


// the object.
salmons.Remove("coho");

// Iterate through the list.


foreach (var salmon in salmons)
{
Console.Write(salmon + " ");
}
// Output: chinook pink sockeye

Aşağıdaki örnek, genel bir listeden öğeleri kaldırır. Bir foreach deyimleri yerine, azalan düzende yinelenen bir for
deyimleri kullanılır. Bunun nedeni RemoveAt yöntemi kaldırılan bir öğeden sonra öğelerin daha düşük bir dizin
değerine sahip olmasına neden olur.

var numbers = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

// Remove odd numbers.


for (var index = numbers.Count - 1; index >= 0; index--)
{
if (numbers[index] % 2 == 1)
{
// Remove the element by specifying
// the zero-based index in the list.
numbers.RemoveAt(index);
}
}

// Iterate through the list.


// A lambda expression is placed in the ForEach method
// of the List(T) object.
numbers.ForEach(
number => Console.Write(number + " "));
// Output: 0 2 4 6 8

List<T>öğe türü için kendi sınıfınızı de tanımlayabilirsiniz. Aşağıdaki örnekte, List<T> tarafından kullanılan
Galaxy sınıfı kodda tanımlanmıştır.
private static void IterateThroughList()
{
var theGalaxies = new List<Galaxy>
{
new Galaxy() { Name="Tadpole", MegaLightYears=400},
new Galaxy() { Name="Pinwheel", MegaLightYears=25},
new Galaxy() { Name="Milky Way", MegaLightYears=0},
new Galaxy() { Name="Andromeda", MegaLightYears=3}
};

foreach (Galaxy theGalaxy in theGalaxies)


{
Console.WriteLine(theGalaxy.Name + " " + theGalaxy.MegaLightYears);
}

// Output:
// Tadpole 400
// Pinwheel 25
// Milky Way 0
// Andromeda 3
}

public class Galaxy


{
public string Name { get; set; }
public int MegaLightYears { get; set; }
}

Koleksiyon türleri
Birçok ortak koleksiyon .NET Framework tarafından sağlanır. Her koleksiyon türü belirli bir amaç için
tasarlanmıştır.
Ortak koleksiyon sınıflarından bazıları bu bölümde açıklanmıştır:
System.Collections.Generic sınıflar
System.Collections.Concurrent sınıflar
System.Collections sınıflar
System. Collections. Generic sınıfları
System.Collections.Generic ad alanındaki sınıflardan birini kullanarak genel bir koleksiyon oluşturabilirsiniz. Genel
bir koleksiyon, koleksiyondaki her öğe aynı veri türüne sahip olduğunda faydalıdır. Genel bir koleksiyon, yalnızca
istenen veri türünün eklenmesine izin vererek güçlü yazma uygular.
Aşağıdaki tabloda System.Collections.Generic ad alanının sık kullanılan sınıflarının bazıları listelenmektedir:

ÖRNEĞI AÇIKLAMA

Dictionary<TKey,TValue> Anahtara göre düzenlenen anahtar/değer çiftleri


koleksiyonunu temsil eder.

List<T> Dizin tarafından erişilebilen nesnelerin listesini temsil eder.


Listeleri aramak, sıralamak ve değiştirmek için yöntemler
sağlar.

Queue<T> Nesnelerin ilk, ilk çıkar (FıFO) koleksiyonunu temsil eder.


ÖRNEĞI AÇIKLAMA

SortedList<TKey,TValue> İlişkili IComparer<T> uygulamasına göre anahtara göre


sıralanan anahtar/değer çiftleri koleksiyonunu temsil eder.

Stack<T> Nesnelerin son, ilk çıkar (LıFO) koleksiyonunu temsil eder.

Daha fazla bilgi için bkz. yaygın olarak kullanılan koleksiyon türleri, bir koleksiyon sınıfı seçmeve
System.Collections.Generic.
System. Collections. eşzamanlı sınıflar
.NET Framework 4 veya daha yeni bir sürümde, System.Collections.Concurrent ad alanındaki koleksiyonlar,
koleksiyon öğelerine birden çok iş parçacığından erişmek için verimli iş parçacığı güvenli işlemleri sağlar.
System.Collections.Concurrent ad alanındaki sınıflar, koleksiyona aynı anda birden çok iş parçacığı eriştiği zaman,
System.Collections.Generic ve System.Collections ad alanlarında karşılık gelen türler yerine kullanılmalıdır. Daha
fazla bilgi için bkz. Iş parçacığı güvenli koleksiyonlar ve System.Collections.Concurrent.
System.Collections.Concurrent ad alanına eklenen bazı sınıflar BlockingCollection<T>,
ConcurrentDictionary<TKey,TValue>, ConcurrentQueue<T>ve ConcurrentStack<T>.
System. Collections sınıfları
System.Collections ad alanındaki sınıflar öğeleri özel olarak yazılmış nesneler olarak depolamaz, ancak Object
türündeki nesneler.
Mümkün olduğunda, System.Collections.Generic ad alanındaki genel koleksiyonları veya System.Collections ad
alanındaki eski türler yerine System.Collections.Concurrent ad alanını kullanmanız gerekir.
Aşağıdaki tabloda System.Collections ad alanında sık kullanılan sınıfların bazıları listelenmektedir:

ÖRNEĞI AÇIKLAMA

ArrayList Boyutu dinamik olarak gerektiği şekilde arttığı bir nesne


dizisini temsil eder.

Hashtable Anahtarın karma koduna göre düzenlenmiş anahtar/değer


çiftleri koleksiyonunu temsil eder.

Queue Nesnelerin ilk, ilk çıkar (FıFO) koleksiyonunu temsil eder.

Stack Nesnelerin son, ilk çıkar (LıFO) koleksiyonunu temsil eder.

System.Collections.Specialized ad alanı, yalnızca dize toplamaları ve bağlantılı liste ve karma sözlük gibi
özelleştirilmiş ve kesin tür belirtilmiş koleksiyon sınıfları sağlar.

Anahtar/değer çiftleri koleksiyonu uygulama


Dictionary<TKey,TValue> genel koleksiyonu, her bir öğenin anahtarını kullanarak bir koleksiyondaki öğelere
erişmenizi sağlar. Sözlüğe eklenen her ekleme bir değerden ve ilişkili anahtarından oluşur. Dictionary sınıfı bir
karma tablo olarak uygulandığından, anahtarını kullanarak bir değerin alınması hızlıdır.
Aşağıdaki örnek bir Dictionary koleksiyonu oluşturur ve bir foreach ifadesini kullanarak sözlükten yinelenir.
private static void IterateThruDictionary()
{
Dictionary<string, Element> elements = BuildDictionary();

foreach (KeyValuePair<string, Element> kvp in elements)


{
Element theElement = kvp.Value;

Console.WriteLine("key: " + kvp.Key);


Console.WriteLine("values: " + theElement.Symbol + " " +
theElement.Name + " " + theElement.AtomicNumber);
}
}

private static Dictionary<string, Element> BuildDictionary()


{
var elements = new Dictionary<string, Element>();

AddToDictionary(elements, "K", "Potassium", 19);


AddToDictionary(elements, "Ca", "Calcium", 20);
AddToDictionary(elements, "Sc", "Scandium", 21);
AddToDictionary(elements, "Ti", "Titanium", 22);

return elements;
}

private static void AddToDictionary(Dictionary<string, Element> elements,


string symbol, string name, int atomicNumber)
{
Element theElement = new Element();

theElement.Symbol = symbol;
theElement.Name = name;
theElement.AtomicNumber = atomicNumber;

elements.Add(key: theElement.Symbol, value: theElement);


}

public class Element


{
public string Symbol { get; set; }
public string Name { get; set; }
public int AtomicNumber { get; set; }
}

Bunun yerine, Dictionary koleksiyonunu oluşturmak için bir koleksiyon başlatıcısı kullanmak için,
BuildDictionary ve AddToDictionary yöntemlerini aşağıdaki yöntemle değiştirebilirsiniz.

private static Dictionary<string, Element> BuildDictionary2()


{
return new Dictionary<string, Element>
{
{"K",
new Element() { Symbol="K", Name="Potassium", AtomicNumber=19}},
{"Ca",
new Element() { Symbol="Ca", Name="Calcium", AtomicNumber=20}},
{"Sc",
new Element() { Symbol="Sc", Name="Scandium", AtomicNumber=21}},
{"Ti",
new Element() { Symbol="Ti", Name="Titanium", AtomicNumber=22}}
};
}

Aşağıdaki örnek, bir öğeyi anahtara göre hızlı bir şekilde bulmak için Dictionary ContainsKey yöntemini ve
Item[TKey] özelliğini kullanır. Item özelliği, içindeki C# elements[symbol] kullanarak elements koleksiyonundaki
bir öğeye erişmenizi sağlar.

private static void FindInDictionary(string symbol)


{
Dictionary<string, Element> elements = BuildDictionary();

if (elements.ContainsKey(symbol) == false)
{
Console.WriteLine(symbol + " not found");
}
else
{
Element theElement = elements[symbol];
Console.WriteLine("found: " + theElement.Name);
}
}

Aşağıdaki örnek bunun yerine, bir öğeyi anahtara göre hızlı bir şekilde bulmak TryGetValue yöntemini kullanır.

private static void FindInDictionary2(string symbol)


{
Dictionary<string, Element> elements = BuildDictionary();

Element theElement = null;


if (elements.TryGetValue(symbol, out theElement) == false)
Console.WriteLine(symbol + " not found");
else
Console.WriteLine("found: " + theElement.Name);
}

Koleksiyona erişmek için LINQ kullanma


LINQ (dil ile tümleşik sorgu), koleksiyonlara erişmek için kullanılabilir. LINQ sorguları filtreleme, sıralama ve
gruplama özellikleri sağlar. Daha fazla bilgi için bkz. C#LINQ ile çalışmaya başlama.
Aşağıdaki örnek, bir genel List karşı bir LINQ sorgusu çalıştırır. LINQ sorgusu, sonuçları içeren farklı bir
koleksiyon döndürür.
private static void ShowLINQ()
{
List<Element> elements = BuildList();

// LINQ Query.
var subset = from theElement in elements
where theElement.AtomicNumber < 22
orderby theElement.Name
select theElement;

foreach (Element theElement in subset)


{
Console.WriteLine(theElement.Name + " " + theElement.AtomicNumber);
}

// Output:
// Calcium 20
// Potassium 19
// Scandium 21
}

private static List<Element> BuildList()


{
return new List<Element>
{
{ new Element() { Symbol="K", Name="Potassium", AtomicNumber=19}},
{ new Element() { Symbol="Ca", Name="Calcium", AtomicNumber=20}},
{ new Element() { Symbol="Sc", Name="Scandium", AtomicNumber=21}},
{ new Element() { Symbol="Ti", Name="Titanium", AtomicNumber=22}}
};
}

public class Element


{
public string Symbol { get; set; }
public string Name { get; set; }
public int AtomicNumber { get; set; }
}

Bir koleksiyonu sıralama


Aşağıdaki örnek bir koleksiyonu sıralamak için bir yordam gösterir. Örnek, bir List<T>depolanan Car sınıfının
örneklerini sıralar. Car sınıfı, CompareTo yönteminin uygulanması için IComparable<T> arabirimini uygular.
CompareTo yöntemine yapılan her çağrı, sıralama için kullanılan tek bir karşılaştırma yapar. CompareTo
yönteminde Kullanıcı tarafından yazılan kod, geçerli nesnenin her karşılaştırması için başka bir nesneyle ilgili bir
değer döndürür. Geçerli nesne diğer nesneden daha küçükse döndürülen değer sıfırdan küçük, geçerli nesne diğer
nesneden büyükse sıfırdan büyük ve eşitse sıfır. Bu, büyük, küçüktür ve eşittir ölçütlerine göre kod içinde
tanımlamanızı sağlar.
ListCars yönteminde, cars.Sort() ifade listeyi sıralar. List<T> Sort yöntemine yapılan bu çağrı, CompareTo
yönteminin List``Car nesneler için otomatik olarak çağrılmasına neden olur.

private static void ListCars()


{
var cars = new List<Car>
{
{ new Car() { Name = "car1", Color = "blue", Speed = 20}},
{ new Car() { Name = "car2", Color = "red", Speed = 50}},
{ new Car() { Name = "car3", Color = "green", Speed = 10}},
{ new Car() { Name = "car4", Color = "blue", Speed = 50}},
{ new Car() { Name = "car5", Color = "blue", Speed = 30}},
{ new Car() { Name = "car6", Color = "red", Speed = 60}},
{ new Car() { Name = "car6", Color = "red", Speed = 60}},
{ new Car() { Name = "car7", Color = "green", Speed = 50}}
};

// Sort the cars by color alphabetically, and then by speed


// in descending order.
cars.Sort();

// View all of the cars.


foreach (Car thisCar in cars)
{
Console.Write(thisCar.Color.PadRight(5) + " ");
Console.Write(thisCar.Speed.ToString() + " ");
Console.Write(thisCar.Name);
Console.WriteLine();
}

// Output:
// blue 50 car4
// blue 30 car5
// blue 20 car1
// green 50 car7
// green 10 car3
// red 60 car6
// red 50 car2
}

public class Car : IComparable<Car>


{
public string Name { get; set; }
public int Speed { get; set; }
public string Color { get; set; }

public int CompareTo(Car other)


{
// A call to this method makes a single comparison that is
// used for sorting.

// Determine the relative order of the objects being compared.


// Sort by color alphabetically, and then by speed in
// descending order.

// Compare the colors.


int compare;
compare = String.Compare(this.Color, other.Color, true);

// If the colors are the same, compare the speeds.


if (compare == 0)
{
compare = this.Speed.CompareTo(other.Speed);

// Use descending order for speed.


compare = -compare;
}

return compare;
}
}

Özel bir koleksiyon tanımlama


IEnumerable<T> veya IEnumerable arabirimini uygulayarak bir koleksiyon tanımlayabilirsiniz.
Özel bir koleksiyon tanımlamanızı mümkün olsa da, bu konunun önceki kısımlarında yer alan koleksiyonlar
türlerinde açıklanan .NET Framework dahil edilen koleksiyonları kullanmak genellikle daha iyidir.
Aşağıdaki örnek, AllColors adlı bir özel koleksiyon sınıfını tanımlar. Bu sınıf, GetEnumerator yönteminin
uygulanması için IEnumerable arabirimini uygular.
GetEnumeratoryöntemi ColorEnumerator sınıfının bir örneğini döndürür. ColorEnumerator , Current özelliğinin,
MoveNext yönteminin ve Reset yönteminin uygulanması için IEnumerator arabirimini uygular.

private static void ListColors()


{
var colors = new AllColors();

foreach (Color theColor in colors)


{
Console.Write(theColor.Name + " ");
}
Console.WriteLine();
// Output: red blue green
}

// Collection class.
public class AllColors : System.Collections.IEnumerable
{
Color[] _colors =
{
new Color() { Name = "red" },
new Color() { Name = "blue" },
new Color() { Name = "green" }
};

public System.Collections.IEnumerator GetEnumerator()


{
return new ColorEnumerator(_colors);

// Instead of creating a custom enumerator, you could


// use the GetEnumerator of the array.
//return _colors.GetEnumerator();
}

// Custom enumerator.
private class ColorEnumerator : System.Collections.IEnumerator
{
private Color[] _colors;
private int _position = -1;

public ColorEnumerator(Color[] colors)


{
_colors = colors;
}

object System.Collections.IEnumerator.Current
{
get
{
return _colors[_position];
}
}

bool System.Collections.IEnumerator.MoveNext()
{
_position++;
return (_position < _colors.Length);
}

void System.Collections.IEnumerator.Reset()
{
_position = -1;
}
}
}
// Element class.
public class Color
{
public string Name { get; set; }
}

Yineleyiciler
Bir Yineleyici , bir koleksiyon üzerinde özel bir yineleme gerçekleştirmek için kullanılır. Yineleyici bir yöntem veya
get erişimcisi olabilir. Bir yineleyici, tek seferde koleksiyonun her bir öğesini döndürmek için bir yield return
ifadesini kullanır.
Bir foreach ifadesi kullanarak bir yineleyici çağırın. foreach döngüsünün her yinelemesi yineleyiciyi çağırır.
Yineleyiciden bir yield return deyimine ulaşıldığında, bir ifade döndürülür ve koddaki geçerli konum korunur. Bu
konumdan, yineleyici bir sonraki sefer çağrıldığında yürütme yeniden başlatılır.
Daha fazla bilgi için bkz. yineleyicilerC#().
Aşağıdaki örnek bir yineleyici yöntemi kullanır. Yineleyici yöntemi bir for döngüsü içinde olan bir yield return
ifadesine sahiptir. ListEvenNumbers yönteminde, foreach deyimin gövdesinin her yinelemesi, bir sonraki
yield return ifadesine devam eden Yineleyici yöntemine bir çağrı oluşturur.

private static void ListEvenNumbers()


{
foreach (int number in EvenSequence(5, 18))
{
Console.Write(number.ToString() + " ");
}
Console.WriteLine();
// Output: 6 8 10 12 14 16 18
}

private static IEnumerable<int> EvenSequence(


int firstNumber, int lastNumber)
{
// Yield even numbers in the range.
for (var number = firstNumber; number <= lastNumber; number++)
{
if (number % 2 == 0)
{
yield return number;
}
}
}

Ayrıca bkz.
Nesne ve Koleksiyon Başlatıcıları
Programlama kavramları (C#)
Option Strict Deyimi
LINQ to Objects (C#)
Paralel LINQ (PLINQ )
Koleksiyonlar ve Veri Yapıları
Koleksiyon Sınıfı Seçme
Koleksiyonlardaki Karşılaştırmalar ve Sıralamalar
Genel Koleksiyonlar Ne Zaman Kullanılır?
Kovaryans ve değişken varyans (C#)
23.10.2019 • 4 minutes to read • Edit Online

' C#De, Kovaryans ve değişken varyans dizi türleri, temsilci türleri ve genel tür bağımsız değişkenleri için örtük
başvuru dönüştürmeyi etkinleştirir. Kovaryans, atama uyumluluğunu korur ve değişken varyans onu tersine
çevirir.
Aşağıdaki kod, atama uyumluluğu, Kovaryans ve değişken varyans arasındaki farkı gösterir.

// Assignment compatibility.
string str = "test";
// An object of a more derived type is assigned to an object of a less derived type.
object obj = str;

// Covariance.
IEnumerable<string> strings = new List<string>();
// An object that is instantiated with a more derived type argument
// is assigned to an object instantiated with a less derived type argument.
// Assignment compatibility is preserved.
IEnumerable<object> objects = strings;

// Contravariance.
// Assume that the following method is in the class:
// static void SetObject(object o) { }
Action<object> actObject = SetObject;
// An object that is instantiated with a less derived type argument
// is assigned to an object instantiated with a more derived type argument.
// Assignment compatibility is reversed.
Action<string> actString = actObject;

Diziler için Kovaryans, daha önce türetilmiş bir türün dizisinin daha az türetilmiş bir tür dizisine örtük olarak
dönüştürülmesini sağlar. Ancak, aşağıdaki kod örneğinde gösterildiği gibi bu işlem tür kullanımı güvenli değildir.

object[] array = new String[10];


// The following statement produces a run-time exception.
// array[0] = 10;

Yöntem grupları için Kovaryans ve değişken varyans desteği, temsilci türleriyle eşleşen Yöntem imzalarına izin
verir. Bu, yalnızca eşleşen imzalara sahip yöntemlerin değil, aynı zamanda daha fazla türetilmiş tür (Kovaryans)
döndüren veya temsilci türü tarafından belirtilenden daha az türetilmiş türler (değişken varyans) döndüren
parametreleri kabul eden yöntemlere atama yapmanızı sağlar. Daha fazla bilgi için bkz. Temsilcilerde varyansC#()
ve Temsilciler (C#) içinde varyans kullanımı.
Aşağıdaki kod örneği, yöntem grupları için Kovaryans ve değişken varyans desteğini gösterir.
static object GetObject() { return null; }
static void SetObject(object obj) { }

static string GetString() { return ""; }


static void SetString(string str) { }

static void Test()


{
// Covariance. A delegate specifies a return type as object,
// but you can assign a method that returns a string.
Func<object> del = GetString;

// Contravariance. A delegate specifies a parameter type as string,


// but you can assign a method that takes an object.
Action<string> del2 = SetObject;
}

.NET Framework 4 veya sonraki C# sürümlerde Genel arabirimlerde ve temsilcilerde kovaryans ve değişken
varyans desteklenir ve genel tür parametrelerinin örtük dönüştürülmesine izin verir. Daha fazla bilgi için bkz.
Genel Arabirimlerde Varyans (C#) ve Temsilcilerde varyans (C#) .
Aşağıdaki kod örneğinde genel arabirimler için örtük başvuru dönüştürmesi gösterilmektedir.

IEnumerable<String> strings = new List<String>();


IEnumerable<Object> objects = strings;

Genel bir arabirim veya temsilci, genel parametreleri birlikte değişken veya değişken karşıtı olarak bildirilirse
değişken olarak adlandırılır. C#kendi değişken arabirimlerinizi ve temsilcilerinizi oluşturmanızı sağlar. Daha fazla
bilgi için bkz. TemsilcilerC#() içinde VARIANT genelC#arabirimleri () ve varyansı oluşturma.

İlgili Konular
BAŞLIK AÇIKLAMA

Genel Arabirimlerde Varyans (C#) Genel arabirimlerde Kovaryans ve değişken varyansı açıklar ve
.NET Framework değişken genel arabirimlerin bir listesini
sağlar.

Değişken genel arabirimler (C#) oluşturma Özel değişken arabirimlerinin nasıl oluşturulacağını gösterir.

Genel Koleksiyonlar için Arabirimlerde Varyans kullanma (C#) IEnumerable<T> VeIComparable<T> arabirimlerinde
Kovaryans ve değişken varyans desteğinin kodu yeniden
kullanmanıza nasıl yardımcı olduğunu gösterir.

Temsilcilerde varyans (C#) Genel ve genel olmayan temsilcilerde kovaryans ve değişken


varyansı açıklar ve .NET Framework değişken genel
temsilcilerin bir listesini sağlar.

Temsilcilerde (C#) varyans kullanma Temsilci türleriyle Yöntem imzalarını eşleştirmek için genel
olmayan temsilcilerde kovaryans ve değişken varyans
desteğinin nasıl kullanılacağını gösterir.

Func ve eylem genel temsilcileri için varyans kullanma (C#) Func Ve Action temsilcilerde kovaryans ve değişken
varyans desteğinin kodu yeniden kullanmanıza nasıl yardımcı
olduğunu gösterir.
Genel Arabirimlerde Varyans (C#)
23.10.2019 • 4 minutes to read • Edit Online

.NET Framework 4, mevcut birçok genel arabirim için varyans desteği getirmiştir. Varyans desteği, bu arabirimleri
uygulayan sınıfların örtük dönüştürülmesini mümkün.
.NET Framework 4 ' te başlayarak, aşağıdaki arabirimler değişkendir:
IEnumerable<T> (T değişkenle birlikte)
IEnumerator<T> (T değişkenle birlikte)
IQueryable<T> (T değişkenle birlikte)
IGrouping<TKey,TElement> ( TKey ve TElement değişkenle birlikte)
IComparer<T> (T değişken karşıtı)
IEqualityComparer<T> (T değişken karşıtı)
IComparable<T> (T değişken karşıtı)
.NET Framework 4,5 ' den başlayarak, aşağıdaki arabirimler değişkendir:
IReadOnlyList<T> (T değişkenle birlikte)
IReadOnlyCollection<T> (T değişkenle birlikte)
Kovaryans, bir metodun, arabirimin genel tür parametresiyle tanımlananla daha türetilmiş bir dönüş türüne sahip
olmasını sağlar. Kovaryans özelliğini göstermek için şu genel arabirimleri göz önünde bulundurun:
IEnumerable<Object> ve IEnumerable<String> . @No__t-0 arabirimi IEnumerable<Object> arabirimini almıyor.
Ancak String türü Object türünü devralınır ve bazı durumlarda bu arabirimlerin nesnelerini birbirlerine atamak
isteyebilirsiniz. Bu, aşağıdaki kod örneğinde gösterilmiştir.

IEnumerable<String> strings = new List<String>();


IEnumerable<Object> objects = strings;

.NET Framework önceki sürümlerinde, bu kod, ' de Option Strict varsa, C# Visual Basic içinde derleme hatasına
neden olur. Ancak artık, IEnumerable<T> arabirimi birlikte değişken olduğu için, önceki örnekte gösterildiği gibi
objects yerine strings kullanabilirsiniz.

Değişken Varyans, bir metodun, arabirimin genel parametresiyle belirtilenden daha az türetilmiş bağımsız
değişken türlerine sahip olmasını sağlar. Değişken varyansı göstermek için, BaseClass sınıfının örneklerini
karşılaştırmak üzere bir BaseComparer sınıfı oluşturduğunuzu varsayalım. BaseComparer sınıfı,
IEqualityComparer<BaseClass> arabirimini uygular. @No__t-0 arabirimi artık değişken karşıtı olduğundan,
BaseClass sınıfını devraldığı sınıfların örneklerini karşılaştırmak için BaseComparer kullanabilirsiniz. Bu, aşağıdaki
kod örneğinde gösterilmiştir.
// Simple hierarchy of classes.
class BaseClass { }
class DerivedClass : BaseClass { }

// Comparer class.
class BaseComparer : IEqualityComparer<BaseClass>
{
public int GetHashCode(BaseClass baseInstance)
{
return baseInstance.GetHashCode();
}
public bool Equals(BaseClass x, BaseClass y)
{
return x == y;
}
}
class Program
{
static void Test()
{
IEqualityComparer<BaseClass> baseComparer = new BaseComparer();

// Implicit conversion of IEqualityComparer<BaseClass> to


// IEqualityComparer<DerivedClass>.
IEqualityComparer<DerivedClass> childComparer = baseComparer;
}
}

Daha fazla örnek için bkz. Genel Koleksiyonlar Için Arabirimlerde Varyans kullanma (C#).
Genel Arabirimlerde Varyans yalnızca başvuru türleri için desteklenir. Değer türleri varyansı desteklemez.
Örneğin, IEnumerable<int> örtük olarak IEnumerable<object> ' e dönüştürülemez, çünkü tamsayılar bir değer
türü ile temsil edilir.

IEnumerable<int> integers = new List<int>();


// The following statement generates a compiler error,
// because int is a value type.
// IEnumerable<Object> objects = integers;

Ayrıca, VARIANT arabirimlerini uygulayan sınıfların hala sabit olduğunu unutmamak önemlidir. Örneğin, List<T>
covaryant arabirimini IEnumerable<T> ' i uygularsa, List<String> ' yi List<Object> ' e örtülü olarak
dönüştüremezsiniz. Bu, aşağıdaki kod örneğinde gösterilmiştir.

// The following line generates a compiler error


// because classes are invariant.
// List<Object> list = new List<String>();

// You can use the interface object instead.


IEnumerable<Object> listObjects = new List<String>();

Ayrıca bkz.
Genel Koleksiyonlar için Arabirimlerde Varyans kullanma (C#)
Değişken genel arabirimler (C#) oluşturma
Genel arabirimler
Temsilcilerde varyans (C#)
Değişken genel arabirimler (C#) oluşturma
23.10.2019 • 7 minutes to read • Edit Online

Arabirimlerdeki genel tür parametrelerini birlikte değişken veya değişken karşıtı olarak bildirebilirsiniz. Kovaryans
, Arabirim yöntemlerinin genel tür parametreleri tarafından tanımlananla daha fazla türetilmiş dönüş türüne sahip
olmasına izin verir. Değişken varyans , Arabirim yöntemlerinin genel parametreler tarafından belirtilenden daha az
türetilmiş bağımsız değişken türlerine sahip olmasına olanak sağlar. Değişkenle birlikte değişken veya değişken
karşıtı genel tür parametrelerine sahip genel bir arabirim değişkenolarak adlandırılır.

NOTE
.NET Framework 4, mevcut birçok genel arabirim için varyans desteği getirmiştir. .NET Framework değişken arabirimlerinin
listesi için bkz. Genel Arabirimlerde VaryansC#().

VARIANT genel arabirimlerini bildirme


Genel tür parametreleri için in ve out anahtar sözcüklerini kullanarak VARIANT genel arabirimleri
bildirebilirsiniz.

IMPORTANT
ref , in ve out içindeki C# parametreleri varyant olamaz. Değer türleri de varyansı desteklemez.

out Anahtar sözcüğünü kullanarak genel tür parametresi ortak değişkeni bildirebilirsiniz. Covaryant türü şu
koşulları karşılamalıdır:
Tür, yalnızca Arabirim yöntemlerinin dönüş türü olarak kullanılır ve Yöntem bağımsız değişkenlerinin türü
olarak kullanılmaz. Bu, türünün R birlikte değişken olarak bildirildiği aşağıdaki örnekte gösterilmiştir.

interface ICovariant<out R>


{
R GetSomething();
// The following statement generates a compiler error.
// void SetSomething(R sampleArg);

Bu kural için bir özel durum var. Bir yöntem parametresi olarak bir değişken karşıtı genel temsilciniz varsa,
türü temsilci için genel bir tür parametresi olarak kullanabilirsiniz. Bu, aşağıdaki örnekteki tür R tarafından
gösterilmiştir. Daha fazla bilgi için bkz. temsilcilerin içindeki varyansC#() ve Func ve ACTION Genel
Temsilciler (C#) için varyans kullanma.

interface ICovariant<out R>


{
void DoSomething(Action<R> callback);
}

Tür, arabirim yöntemleri için genel bir kısıtlama olarak kullanılmaz. Bu, aşağıdaki kodda gösterilmiştir.
interface ICovariant<out R>
{
// The following statement generates a compiler error
// because you can use only contravariant or invariant types
// in generic constraints.
// void DoSomething<T>() where T : R;
}

in Anahtar sözcüğünü kullanarak genel tür parametresi değişken karşıtı bildirebilirsiniz. Değişken karşıtı türü,
Arabirim yöntemlerinin dönüş türü olarak değil, yalnızca Yöntem bağımsız değişkenlerinin türü olarak
kullanılabilir. Değişken karşıtı türü, genel kısıtlamalar için de kullanılabilir. Aşağıdaki kod, bir değişken karşıtı
arabirimin nasıl bildirilemeyeceğini ve yöntemlerinden biri için genel bir kısıtlama nasıl kullanıldığını gösterir.

interface IContravariant<in A>


{
void SetSomething(A sampleArg);
void DoSomething<T>() where T : A;
// The following statement generates a compiler error.
// A GetSomething();
}

Ayrıca, aşağıdaki kod örneğinde gösterildiği gibi farklı tür parametreleri için aynı arabirimdeki kovaryansı ve
değişken varyansı desteklemek de mümkündür.

interface IVariant<out R, in A>


{
R GetSomething();
void SetSomething(A sampleArg);
R GetSetSomethings(A sampleArg);
}

VARIANT genel arabirimlerini uygulama


Sabit arabirimler için kullanılan söz dizimini kullanarak sınıflarda VARIANT genel arabirimler uygulayabilirsiniz.
Aşağıdaki kod örneği, bir genel sınıfta birlikte değişken arabiriminin nasıl uygulanacağını gösterir.

interface ICovariant<out R>


{
R GetSomething();
}
class SampleImplementation<R> : ICovariant<R>
{
public R GetSomething()
{
// Some code.
return default(R);
}
}

Varyant arabirimlerini uygulayan sınıflar sabit. Örneğin, aşağıdaki kodu göz önünde bulundurun.
// The interface is covariant.
ICovariant<Button> ibutton = new SampleImplementation<Button>();
ICovariant<Object> iobj = ibutton;

// The class is invariant.


SampleImplementation<Button> button = new SampleImplementation<Button>();
// The following statement generates a compiler error
// because classes are invariant.
// SampleImplementation<Object> obj = button;

VARIANT genel arabirimlerini genişletme


Bir varyant genel arabirimini genişlettiğinizde, türetilmiş arabirimin varyansı destekleyip desteklemediğini açıkça
belirtmek in için out ve anahtar sözcüklerini kullanmanız gerekir. Derleyici, genişletilmekte olan arabirimden
varyansı çıkarmıyor. Örneğin, aşağıdaki arabirimleri göz önünde bulundurun.

interface ICovariant<out T> { }


interface IInvariant<T> : ICovariant<T> { }
interface IExtCovariant<out T> : ICovariant<T> { }

Arabirimde, genel tür parametresi T değişmez, IExtCovariant<out T> ancak her iki arabirim de aynı arabirimi
genişletse de, tür parametresinde birlikte değişken olur. IInvariant<T> Aynı kural, değişken karşıtı genel tür
parametrelerine uygulanır.
Hem genel tür parametresinin T birlikte değişken olduğu arabirimi hem de genişletme arabiriminde genel tür
parametresi T sabit ise değişken karşıtı olan arabirimi genişleten bir arabirim oluşturabilirsiniz. Bu, aşağıdaki kod
örneğinde gösterilmiştir.

interface ICovariant<out T> { }


interface IContravariant<in T> { }
interface IInvariant<T> : ICovariant<T>, IContravariant<T> { }

Ancak, bir genel tür parametresi T bir arabirimde birlikte değişken olarak bildirilirse, genişletme arabiriminde bu
değişken karşıtı olarak bildiremezsiniz veya tam tersi de geçerlidir. Bu, aşağıdaki kod örneğinde gösterilmiştir.

interface ICovariant<out T> { }


// The following statement generates a compiler error.
// interface ICoContraVariant<in T> : ICovariant<T> { }

Belirsizlik önleme
VARIANT genel arabirimleri uyguladığınızda, fark bazen belirsizliğe neden olabilir. Bunun kaçınılması gerekir.
Örneğin, tek bir sınıfta farklı genel tür parametreleriyle aynı Varyant genel arabirimini açıkça uygularsanız,
belirsizlik oluşturabilir. Derleyici bu durumda bir hata oluşturmaz, ancak çalışma zamanında hangi arabirim
uygulamasının seçilme belirtilecektir. Bu, kodunuzda hafif hatalara neden olabilir. Aşağıdaki kod örneğini göz
önünde bulundurun.
// Simple class hierarchy.
class Animal { }
class Cat : Animal { }
class Dog : Animal { }

// This class introduces ambiguity


// because IEnumerable<out T> is covariant.
class Pets : IEnumerable<Cat>, IEnumerable<Dog>
{
IEnumerator<Cat> IEnumerable<Cat>.GetEnumerator()
{
Console.WriteLine("Cat");
// Some code.
return null;
}

IEnumerator IEnumerable.GetEnumerator()
{
// Some code.
return null;
}

IEnumerator<Dog> IEnumerable<Dog>.GetEnumerator()
{
Console.WriteLine("Dog");
// Some code.
return null;
}
}
class Program
{
public static void Test()
{
IEnumerable<Animal> pets = new Pets();
pets.GetEnumerator();
}
}

Bu örnekte, pets.GetEnumerator yönteminin ve Dog arasında Cat nasıl seçtiği belirtilmemiş. Bu, kodunuzda
sorun oluşmasına neden olabilir.

Ayrıca bkz.
Genel Arabirimlerde Varyans (C#)
Func ve eylem genel temsilcileri için varyans kullanma (C#)
Genel Koleksiyonlar için Arabirimlerde Varyans
kullanma (C#)
23.10.2019 • 2 minutes to read • Edit Online

Birlikte değişken arabirimi, yöntemlerinin arabirimde belirtilenden daha fazla türetilmiş tür döndürmesini sağlar.
Değişken karşıtı bir arabirim, yöntemlerinin, arabirimde belirtilenden daha az türetilmiş türdeki parametreleri
kabul etmesine olanak sağlar.
.NET Framework 4 ' te, bazı mevcut arabirimler birlikte değişken ve değişken karşıtı hale gelmiştir. Bunlar ve
IEnumerable<T> IComparable<T>içerir. Bu, türetilmiş türlerin koleksiyonları için genel temel tür koleksiyonlarıyla
çalışan yöntemleri yeniden kullanmanıza olanak sağlar.
.NET Framework değişken arabirimlerin listesi için bkz. Genel Arabirimlerde VaryansC#().

Genel koleksiyonları dönüştürme


Aşağıdaki örnekte, IEnumerable<T> arabirimindeki Kovaryans desteğinin avantajları gösterilmektedir. Yöntemi
PrintFullName , IEnumerable<Person> türü bir koleksiyonu bir parametre olarak kabul eder. Ancak, devraldığından
IEnumerable<Employee> Employee Person bir tür koleksiyonu için onu yeniden kullanabilirsiniz.

// Simple hierarchy of classes.


public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}

public class Employee : Person { }

class Program
{
// The method has a parameter of the IEnumerable<Person> type.
public static void PrintFullName(IEnumerable<Person> persons)
{
foreach (Person person in persons)
{
Console.WriteLine("Name: {0} {1}",
person.FirstName, person.LastName);
}
}

public static void Test()


{
IEnumerable<Employee> employees = new List<Employee>();

// You can pass IEnumerable<Employee>,


// although the method expects IEnumerable<Person>.

PrintFullName(employees);

}
}

Genel koleksiyonları karşılaştırma


Aşağıdaki örnek, IComparer<T> arabirimindeki fark desteğinin avantajlarından yararlanır. PersonComparer Sınıfı ,
IComparer<Person> arabirimini uygular. Ancak, devraldığından Employee Employee Person tür bir nesne dizisini
karşılaştırmak için bu sınıfı yeniden kullanabilirsiniz.

// Simple hierarchy of classes.


public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}

public class Employee : Person { }

// The custom comparer for the Person type


// with standard implementations of Equals()
// and GetHashCode() methods.
class PersonComparer : IEqualityComparer<Person>
{
public bool Equals(Person x, Person y)
{
if (Object.ReferenceEquals(x, y)) return true;
if (Object.ReferenceEquals(x, null) ||
Object.ReferenceEquals(y, null))
return false;
return x.FirstName == y.FirstName && x.LastName == y.LastName;
}
public int GetHashCode(Person person)
{
if (Object.ReferenceEquals(person, null)) return 0;
int hashFirstName = person.FirstName == null
? 0 : person.FirstName.GetHashCode();
int hashLastName = person.LastName.GetHashCode();
return hashFirstName ^ hashLastName;
}
}

class Program
{

public static void Test()


{
List<Employee> employees = new List<Employee> {
new Employee() {FirstName = "Michael", LastName = "Alexander"},
new Employee() {FirstName = "Jeff", LastName = "Price"}
};

// You can pass PersonComparer,


// which implements IEqualityComparer<Person>,
// although the method expects IEqualityComparer<Employee>.

IEnumerable<Employee> noduplicates =
employees.Distinct<Employee>(new PersonComparer());

foreach (var employee in noduplicates)


Console.WriteLine(employee.FirstName + " " + employee.LastName);
}
}

Ayrıca bkz.
Genel Arabirimlerde Varyans (C#)
Temsilcilerde varyans (C#)
24.10.2019 • 8 minutes to read • Edit Online

.NET Framework 3,5, içindeki C#tüm Temsilcilerde temsilci türleriyle eşleşen yöntem imzaları için varyans
desteği getirmiştir. Bu, yalnızca eşleşen imzalara sahip yöntemlerin değil, aynı zamanda daha fazla türetilmiş tür
(Kovaryans) döndüren veya temsilci türü tarafından belirtilenden daha az türetilmiş türler (değişken varyans)
döndüren parametreleri kabul eden yöntemlere atayabileceğiniz anlamına gelir. . Bu hem genel hem de genel
olmayan temsilcileri içerir.
Örneğin, iki sınıfı ve iki temsilciyi olan aşağıdaki kodu düşünün: genel ve genel olmayan.

public class First { }


public class Second : First { }
public delegate First SampleDelegate(Second a);
public delegate R SampleGenericDelegate<A, R>(A a);

@No__t_0 veya SampleGenericDelegate<A, R> türlerinin temsilcilerini oluşturduğunuzda, aşağıdaki


yöntemlerden herhangi birini bu temsilcilere atayabilirsiniz.

// Matching signature.
public static First ASecondRFirst(Second second)
{ return new First(); }

// The return type is more derived.


public static Second ASecondRSecond(Second second)
{ return new Second(); }

// The argument type is less derived.


public static First AFirstRFirst(First first)
{ return new First(); }

// The return type is more derived


// and the argument type is less derived.
public static Second AFirstRSecond(First first)
{ return new Second(); }

Aşağıdaki kod örneği, yöntem imzası ve temsilci türü arasındaki örtük dönüştürmeyi gösterir.

// Assigning a method with a matching signature


// to a non-generic delegate. No conversion is necessary.
SampleDelegate dNonGeneric = ASecondRFirst;
// Assigning a method with a more derived return type
// and less derived argument type to a non-generic delegate.
// The implicit conversion is used.
SampleDelegate dNonGenericConversion = AFirstRSecond;

// Assigning a method with a matching signature to a generic delegate.


// No conversion is necessary.
SampleGenericDelegate<Second, First> dGeneric = ASecondRFirst;
// Assigning a method with a more derived return type
// and less derived argument type to a generic delegate.
// The implicit conversion is used.
SampleGenericDelegate<Second, First> dGenericConversion = AFirstRSecond;

Daha fazla örnek için bkz. Temsilcilerde varyans kullanmaC#() ve Func ve ACTION Genel Temsilciler (C#) için
varyans kullanma.

Genel tür parametrelerindeki varyans


.NET Framework 4 veya sonraki sürümlerde temsilciler arasında örtük dönüştürmeyi etkinleştirebilirsiniz. bu
sayede, türler her biri için gerekli olduğu gibi, genel tür parametreleri tarafından belirtilen farklı türlere sahip
genel temsilcilerin birbirlerine atanabilmesini sağlar. denetlemesini.
Örtük dönüştürmeyi etkinleştirmek için, in veya out anahtar sözcüğünü kullanarak bir temsilcinin genel
parametrelerini ortak değişken veya değişken karşıtı olarak açıkça bildirmeniz gerekir.
Aşağıdaki kod örneği, birlikte değişken genel tür parametresine sahip olan bir temsilciyi nasıl
oluşturabileceğiniz gösterilmektedir.

// Type T is declared covariant by using the out keyword.


public delegate T SampleGenericDelegate <out T>();

public static void Test()


{
SampleGenericDelegate <String> dString = () => " ";

// You can assign delegates to each other,


// because the type T is declared covariant.
SampleGenericDelegate <Object> dObject = dString;
}

Yöntem imzalarını temsilci türleriyle eşleştirmek için yalnızca varyans desteğini kullanırsanız ve in ve out
anahtar sözcüklerini kullanmıyorsanız, bazen özdeş lambda ifadeleri veya yöntemlerine sahip temsilciler
örnekleyebilirsiniz, ancak bir tane atayamazsınız başka bir temsilci.
Aşağıdaki kod örneğinde, String Objectdevramla birlikte SampleGenericDelegate<String> açıkça
SampleGenericDelegate<Object> dönüştürülemiyor. Genel parametre T out anahtar sözcüğüyle işaretleyerek
bu sorunu çözebilirsiniz.

public delegate T SampleGenericDelegate<T>();

public static void Test()


{
SampleGenericDelegate<String> dString = () => " ";

// You can assign the dObject delegate


// to the same lambda expression as dString delegate
// because of the variance support for
// matching method signatures with delegate types.
SampleGenericDelegate<Object> dObject = () => " ";

// The following statement generates a compiler error


// because the generic type T is not marked as covariant.
// SampleGenericDelegate <Object> dObject = dString;

.NET Framework değişken tür parametrelerine sahip genel Temsilciler


.NET Framework 4, çeşitli genel temsilcilerde genel tür parametrelerine yönelik varyans desteği getirmiştir:
System ad alanından temsilciler Action , örneğin Action<T> ve Action<T1,T2>
System ad alanından temsilciler Func , örneğin Func<TResult> ve Func<T,TResult>
@No__t_0 temsilcisi
@No__t_0 temsilcisi
@No__t_0 temsilcisi
Daha fazla bilgi ve örnek için bkz. Func ve eylem genel temsilcileri Için varyans kullanmaC#() .
Genel Temsilcilerde değişken tür parametreleri bildirme
Genel bir temsilcinin birlikte değişken veya değişken karşıtı genel tür parametreleri varsa, bu, VARIANT genel
temsilcisiolarak adlandırılır.
@No__t_0 anahtar sözcüğünü kullanarak genel bir temsilci içinde genel bir tür parametresi ortak değişkeni
bildirebilirsiniz. Covaryant türü, yöntem bağımsız değişkenlerinin türü olarak değil, yalnızca bir yöntem dönüş
türü olarak kullanılabilir. Aşağıdaki kod örneği, bir covaryant genel temsilcisinin nasıl bildirilemeyeceğini
gösterir.

public delegate R DCovariant<out R>();

@No__t_0 anahtar sözcüğünü kullanarak genel bir temsilci içinde genel bir tür parametresi değişken değişkeni
bildirebilirsiniz. Değişken karşıtı türü, yöntem dönüş türü olarak değil, yalnızca Yöntem bağımsız değişkenlerinin
türü olarak kullanılabilir. Aşağıdaki kod örneği, bir değişken karşıtı genel temsilcinin nasıl bildirilemeyeceğini
gösterir.

public delegate void DContravariant<in A>(A a);

IMPORTANT
içindeki C# ref , in ve out parametreleri değişken olarak işaretlenemez.

Aynı temsilci, ancak farklı tür parametreleri için hem varyansı hem de kovaryansı desteklemek de mümkündür.
Bu, aşağıdaki örnekte gösterilir.

public delegate R DVariant<in A, out R>(A a);

VARIANT genel temsilcileri örnekleme ve çağırma


Sabit temsilcileri örneklediğinizde ve çağırdığınızda değişken temsilcileri örnek oluşturabilir ve çağırabilirsiniz.
Aşağıdaki örnekte, temsilci bir lambda ifadesi tarafından oluşturulur.

DVariant<String, String> dvariant = (String str) => str + " ";


dvariant("test");

Değişken genel temsilcileri birleştirme


Değişken temsilcileri birleştirmemelisiniz. @No__t_0 yöntemi, VARIANT temsilci dönüştürmeyi desteklemez ve
temsilcilerin tamamen aynı türde olmasını bekler. Bu, aşağıdaki kod örneğinde gösterildiği gibi Combine
yöntemi kullanılarak veya + işlecini kullanarak temsilcileri birleştirdiğinizde çalışma zamanı özel durumuna yol
açabilir.
Action<object> actObj = x => Console.WriteLine("object: {0}", x);
Action<string> actStr = x => Console.WriteLine("string: {0}", x);
// All of the following statements throw exceptions at run time.
// Action<string> actCombine = actStr + actObj;
// actStr += actObj;
// Delegate.Combine(actStr, actObj);

Değer ve başvuru türleri için genel tür parametrelerinin varyansı


Genel tür parametrelerinin varyansı yalnızca başvuru türleri için desteklenir. Örneğin, DVariant<int> örtük
olarak DVariant<Object> veya DVariant<long> dönüştürülemez, çünkü tamsayı bir değer türüdür.
Aşağıdaki örnek, genel tür parametrelerinin farkının değer türleri için desteklenmediğini gösterir.

// The type T is covariant.


public delegate T DVariant<out T>();

// The type T is invariant.


public delegate T DInvariant<T>();

public static void Test()


{
int i = 0;
DInvariant<int> dInt = () => i;
DVariant<int> dVariantInt = () => i;

// All of the following statements generate a compiler error


// because type variance in generic parameters is not supported
// for value types, even if generic type parameters are declared variant.
// DInvariant<Object> dObject = dInt;
// DInvariant<long> dLong = dInt;
// DVariant<Object> dVariantObject = dVariantInt;
// DVariant<long> dVariantLong = dVariantInt;
}

Ayrıca bkz.
Genel Türler
Func ve eylem genel temsilcileri için varyans kullanma (C#)
Nasıl yapılır: temsilcileri birleştirme (çok noktaya yayın temsilcileri)
Temsilcilerde (C#) varyans kullanma
23.10.2019 • 2 minutes to read • Edit Online

Bir temsilciye bir yöntem atadığınızda, Kovaryans ve değişken varyans , bir temsilci türünü Yöntem imzasıyla
eşleştirmek için esneklik sağlar. Kovaryans, bir metodun, temsilde tanımlı olandan daha fazla türetilmiş dönüş
türüne sahip olmasını sağlar. Değişken Varyans, temsilci türünden daha az türetilmiş parametre türlerine sahip
bir yönteme izin verir.

Örnek 1: Ko
Açıklama
Bu örnek, temsilci imzasında dönüş türünden türetilmiş dönüş türleri olan yöntemlerle temsilcilerin nasıl
kullanılabileceğini gösterir. Tarafından DogsHandler döndürülen veri Dogs türü Mammals , temsilde tanımlanan
türden türetilen türüdür.
Kod

class Mammals {}
class Dogs : Mammals {}

class Program
{
// Define the delegate.
public delegate Mammals HandlerMethod();

public static Mammals MammalsHandler()


{
return null;
}

public static Dogs DogsHandler()


{
return null;
}

static void Test()


{
HandlerMethod handlerMammals = MammalsHandler;

// Covariance enables this assignment.


HandlerMethod handlerDogs = DogsHandler;
}
}

Örnek 2: Kontravaryans
Açıklama
Bu örnek, temsilci imza parametre türünün temel türleri olan parametrelere sahip Yöntemler ile temsilcilerin nasıl
kullanılabileceğini gösterir. Değişken varyans ile ayrı işleyiciler yerine bir olay işleyicisi kullanabilirsiniz. Aşağıdaki
örnek iki temsilcinin kullanımını sağlar:
KeyEventHandler Button. KeyDown olayının imzasını tanımlayan bir temsilci. İmzası:
public delegate void KeyEventHandler(object sender, KeyEventArgs e)

MouseEventHandler Button. MouseClick olayının imzasını tanımlayan bir temsilci. İmzası:

public delegate void MouseEventHandler(object sender, MouseEventArgs e)

Örnek, EventArgs parametresiyle bir olay işleyicisini tanımlar ve Button.KeyDown hem hem de Button.MouseClick
olaylarını işlemek için onu kullanır. Bu EventArgs KeyEventArgs ,MouseEventArgshem hem de temel türü
olduğundan bunu yapabilir.
Kod

// Event handler that accepts a parameter of the EventArgs type.


private void MultiHandler(object sender, System.EventArgs e)
{
label1.Text = System.DateTime.Now.ToString();
}

public Form1()
{
InitializeComponent();

// You can use a method that has an EventArgs parameter,


// although the event expects the KeyEventArgs parameter.
this.button1.KeyDown += this.MultiHandler;

// You can use the same method


// for an event that expects the MouseEventArgs parameter.
this.button1.MouseClick += this.MultiHandler;

Ayrıca bkz.
Temsilcilerde varyans (C#)
Func ve eylem genel temsilcileri için varyans kullanma (C#)
Func ve eylem genel temsilcileri için varyans
kullanma (C#)
23.10.2019 • 2 minutes to read • Edit Online

Bu örnekler, Func ve ' de yöntemlerin yeniden kullanımını etkinleştirmek ve kodunuzda daha Action fazla
esneklik sağlamak için ve genel temsilcilerde kovaryans ve değişken varyans kullanımını gösterir.
Kovaryans ve değişken varyans hakkında daha fazla bilgi için bkz. temsilcilerin varyansı (C#) .

Birlikte değişken tür parametrelerine sahip temsilciler kullanma


Aşağıdaki örnekte, genel Func temsilcilerde kovaryans desteğinin avantajları gösterilmektedir. Yöntemi, String
türünün bir parametresini alır ve Employee türünün bir nesnesini döndürür. FindByTitle Ancak, devraldığından
Func<String, Person> Employee Person bu yöntemi temsilciye atayabilirsiniz.

// Simple hierarchy of classes.


public class Person { }
public class Employee : Person { }
class Program
{
static Employee FindByTitle(String title)
{
// This is a stub for a method that returns
// an employee that has the specified title.
return new Employee();
}

static void Test()


{
// Create an instance of the delegate without using variance.
Func<String, Employee> findEmployee = FindByTitle;

// The delegate expects a method to return Person,


// but you can assign it a method that returns Employee.
Func<String, Person> findPerson = FindByTitle;

// You can also assign a delegate


// that returns a more derived type
// to a delegate that returns a less derived type.
findPerson = findEmployee;

}
}

Değişken karşıtı tür parametreleriyle temsilciler kullanma


Aşağıdaki örnekte, genel Action Temsilcilerde değişken varyans desteğinin avantajları gösterilmektedir.
Yöntemi, Person türünün bir parametresini alır. AddToContacts Ancak, devraldığından Action<Employee>
Employee Person bu yöntemi temsilciye atayabilirsiniz.
public class Person { }
public class Employee : Person { }
class Program
{
static void AddToContacts(Person person)
{
// This method adds a Person object
// to a contact list.
}

static void Test()


{
// Create an instance of the delegate without using variance.
Action<Person> addPersonToContacts = AddToContacts;

// The Action delegate expects


// a method that has an Employee parameter,
// but you can assign it a method that has a Person parameter
// because Employee derives from Person.
Action<Employee> addEmployeeToContacts = AddToContacts;

// You can also assign a delegate


// that accepts a less derived parameter to a delegate
// that accepts a more derived parameter.
addEmployeeToContacts = addPersonToContacts;
}
}

Ayrıca bkz.
Kovaryans ve değişken varyans (C#)
Genel Türler
İfade ağaçları (C#)
25.11.2019 • 7 minutes to read • Edit Online

İfade ağaçları, her düğümün bir ifade olduğu, örneğin bir yöntem çağrısı veya x < y gibi bir ikili işlem olduğu
ağaç benzeri bir veri yapısında kodu temsil eder.
İfade ağaçları ile temsil edilen kodu derleyebilir ve çalıştırabilirsiniz. Bu, yürütülebilir kodun dinamik olarak
değiştirilmesini, çeşitli veritabanlarındaki LINQ sorgularının yürütülmesini ve dinamik sorguların
oluşturulmasını mümkün bir şekilde sunar. LINQ içindeki ifade ağaçları hakkında daha fazla bilgi için bkz.
dinamik sorgular oluşturmak için ifade ağaçları kullanma (C#).
İfade ağaçları ayrıca dinamik diller ve .NET Framework arasında birlikte çalışabilirlik sağlamak ve derleyici
yazıcılarının Microsoft ara dili (MSIL ) yerine ifade ağaçları sunmak için dinamik dil çalışma zamanı (DLR ) içinde
de kullanılır. DLR hakkında daha fazla bilgi için bkz. dinamik dil çalışma zamanına genel bakış.
C# Veya Visual Basic derleyicisinin anonim lambda ifadesine göre sizin için bir ifade ağacı oluşturmasını
sağlayabilir veya System.Linq.Expressions ad alanını kullanarak el ile ifade ağaçları oluşturabilirsiniz.

Lambda Ifadelerinden Ifade ağaçları oluşturma


Lambda ifadesi Expression<TDelegate>türünde bir değişkene atandığında, derleyici lambda ifadesini temsil
eden bir ifade ağacı oluşturmak için kodu yayar.
C# Derleyici yalnızca ifade lambdaları (veya tek satırlık Lambdalar) için ifade ağaçları oluşturabilir. İfade
lambdaları (veya çok satırlı Lambdalar) ayrıştırılamaz. İçindeki C#lambda ifadeleri hakkında daha fazla bilgi için
bkz. lambda ifadeleri.
Aşağıdaki kod örnekleri, C# derleyicinin num => num < 5 lambda ifadesini temsil eden bir ifade ağacının nasıl
oluşturulduğunu gösterir.

Expression<Func<int, bool>> lambda = num => num < 5;

API kullanarak Ifade ağaçları oluşturma


API kullanarak ifade ağaçları oluşturmak için Expression sınıfını kullanın. Bu sınıf, bir değişken veya parametre
temsil eden ParameterExpression, ya da bir yöntem çağrısını temsil eden MethodCallExpressiongibi belirli
türlerin ifade ağacı düğümlerini oluşturan statik fabrika yöntemleri içerir. ParameterExpression,
MethodCallExpressionve diğer ifadeye özgü türler System.Linq.Expressions ad alanında da tanımlanmıştır. Bu
türler Expressionsoyut türünden türetilir.
Aşağıdaki kod örneği, API kullanarak num => num < 5 lambda ifadesini temsil eden bir ifade ağacının nasıl
oluşturulacağını göstermektedir.
// Add the following using directive to your code file:
// using System.Linq.Expressions;

// Manually build the expression tree for


// the lambda expression num => num < 5.
ParameterExpression numParam = Expression.Parameter(typeof(int), "num");
ConstantExpression five = Expression.Constant(5, typeof(int));
BinaryExpression numLessThanFive = Expression.LessThan(numParam, five);
Expression<Func<int, bool>> lambda1 =
Expression.Lambda<Func<int, bool>>(
numLessThanFive,
new ParameterExpression[] { numParam });

.NET Framework 4 veya sonraki sürümlerde, ifade ağaçları API 'SI, döngüleri, koşullu blokları ve try-catch
blokları gibi atamaları ve denetim akışı ifadelerini de destekler. API 'yi kullanarak, C# derleyici tarafından
lambda ifadelerinden oluşturulanlardan daha karmaşık ifade ağaçları oluşturabilirsiniz. Aşağıdaki örnek, bir
sayının faktöriyelini hesaplayan bir ifade ağacının nasıl oluşturulacağını göstermektedir.

// Creating a parameter expression.


ParameterExpression value = Expression.Parameter(typeof(int), "value");

// Creating an expression to hold a local variable.


ParameterExpression result = Expression.Parameter(typeof(int), "result");

// Creating a label to jump to from a loop.


LabelTarget label = Expression.Label(typeof(int));

// Creating a method body.


BlockExpression block = Expression.Block(
// Adding a local variable.
new[] { result },
// Assigning a constant to a local variable: result = 1
Expression.Assign(result, Expression.Constant(1)),
// Adding a loop.
Expression.Loop(
// Adding a conditional block into the loop.
Expression.IfThenElse(
// Condition: value > 1
Expression.GreaterThan(value, Expression.Constant(1)),
// If true: result *= value --
Expression.MultiplyAssign(result,
Expression.PostDecrementAssign(value)),
// If false, exit the loop and go to the label.
Expression.Break(label, result)
),
// Label to jump to.
label
)
);

// Compile and execute an expression tree.


int factorial = Expression.Lambda<Func<int, int>>(block, value).Compile()(5);

Console.WriteLine(factorial);
// Prints 120.

Daha fazla bilgi için bkz. Visual Studio 'nun sonraki sürümleri için de geçerli olan Visual studio 2010 ' de Ifade
ağaçları Ile dinamik yöntemler üretme.

Ifade ağaçlarını ayrıştırma


Aşağıdaki kod örneği, num => num < 5 lambda ifadesini temsil eden ifade ağacının bölümlerine nasıl
parçalanacağını göstermektedir.

// Add the following using directive to your code file:


// using System.Linq.Expressions;

// Create an expression tree.


Expression<Func<int, bool>> exprTree = num => num < 5;

// Decompose the expression tree.


ParameterExpression param = (ParameterExpression)exprTree.Parameters[0];
BinaryExpression operation = (BinaryExpression)exprTree.Body;
ParameterExpression left = (ParameterExpression)operation.Left;
ConstantExpression right = (ConstantExpression)operation.Right;

Console.WriteLine("Decomposed expression: {0} => {1} {2} {3}",


param.Name, left.Name, operation.NodeType, right.Value);

// This code produces the following output:

// Decomposed expression: num => num LessThan 5

Ifade ağaçlarının dengeszlik düzeyini bilme


İfade ağaçları sabit olmalıdır. Yani, bir ifade ağacını değiştirmek istiyorsanız, var olan birini kopyalayarak ve
içindeki düğümleri değiştirerek yeni bir ifade ağacı oluşturmanız gerekir. Varolan ifade ağacında çapraz geçiş
yapmak için bir ifade ağacı Visitor kullanabilirsiniz. Daha fazla bilgi için bkz. ifade ağaçlarını değiştirmeC#().

Ifade ağaçlarını derleme


Expression<TDelegate> türü, bir ifade ağacının temsil ettiği kodu yürütülebilir bir temsilciye derleyen Compile
yöntemini sağlar.
Aşağıdaki kod örneği, bir ifade ağacının nasıl derlendiğini ve sonuçta elde edilen kodu nasıl çalıştıracağınızı
gösterir.

// Creating an expression tree.


Expression<Func<int, bool>> expr = num => num < 5;

// Compiling the expression tree into a delegate.


Func<int, bool> result = expr.Compile();

// Invoking the delegate and writing the result to the console.


Console.WriteLine(result(4));

// Prints True.

// You can also use simplified syntax


// to compile and run an expression tree.
// The following line can replace two previous statements.
Console.WriteLine(expr.Compile()(4));

// Also prints True.

Daha fazla bilgi için bkz. ifade ağaçlarını yürütmeC#().

Ayrıca bkz.
System.Linq.Expressions
İfade ağaçlarını yürütme (C#)
İfade ağaçlarını değiştirme (C#)
Lambda İfadeleri
Dinamik Dil Çalışma Zamanına Genel Bakış
Programlama kavramları (C#)
İfade ağaçlarını yürütme (C#)
25.11.2019 • 2 minutes to read • Edit Online

Bu konu başlığı altında, bir ifade ağacının nasıl yürütüleceği gösterilmektedir. Bir ifade ağacının yürütülmesi bir
değer döndürebilir veya bir yöntemi çağırmak gibi yalnızca bir eylem gerçekleştirebilir.
Yalnızca Lambda ifadelerini temsil eden ifade ağaçları yürütülebilir. Lambda ifadelerini temsil eden ifade ağaçları
LambdaExpression veya Expression<TDelegate>türündedir. Bu ifade ağaçlarını yürütmek için Compile yöntemini
çağırarak yürütülebilir bir temsilci oluşturun ve ardından temsilciyi çağırın.

NOTE
Temsilcinin türü bilinmiyorsa, diğer bir deyişle, lambda ifadesi LambdaExpression türüdür ve Expression<TDelegate>değil,
temsilci üzerinde DynamicInvoke yöntemini çağırmanız gerekir.

Bir ifade ağacı bir lambda ifadesini temsil etmez, Lambda<TDelegate>(Expression,


IEnumerable<ParameterExpression>) yöntemini çağırarak, gövdesi olarak özgün ifade ağacını içeren yeni bir
lambda ifadesi oluşturabilirsiniz. Ardından, bu bölümde daha önce anlatıldığı gibi lambda ifadesini
çalıştırabilirsiniz.

Örnek
Aşağıdaki kod örneği, bir lambda ifadesi oluşturarak ve yürüterek bir sayıyı bir üsle yükseltmeyi temsil eden bir
ifade ağacının nasıl yürütüleceğini göstermektedir. Bu, kuvvet olarak oluşturulan sayıyı temsil eden sonuç
görüntülenir.

// The expression tree to execute.


BinaryExpression be = Expression.Power(Expression.Constant(2D), Expression.Constant(3D));

// Create a lambda expression.


Expression<Func<double>> le = Expression.Lambda<Func<double>>(be);

// Compile the lambda expression.


Func<double> compiledExpression = le.Compile();

// Execute the lambda expression.


double result = compiledExpression();

// Display the result.


Console.WriteLine(result);

// This code produces the following output:


// 8

Kod Derleniyor
System. Linq. Ifadeler ad alanını ekleyin.

Ayrıca bkz.
İfade ağaçları (C#)
İfade ağaçlarını değiştirme (C#)
İfade ağaçlarını değiştirme (C#)
25.11.2019 • 3 minutes to read • Edit Online

Bu konu başlığı altında, bir ifade ağacının nasıl değiştirileceği gösterilmektedir. İfade ağaçları sabittir ve bu,
doğrudan değiştirilemediği anlamına gelir. Bir ifade ağacını değiştirmek için, var olan bir ifade ağacının bir
kopyasını oluşturmanız ve kopyayı oluşturduğunuzda gerekli değişiklikleri yapmanız gerekir. ExpressionVisitor
sınıfını, var olan bir ifade ağacında çapraz geçiş yapmak ve bulduğu her düğümü kopyalamak için kullanabilirsiniz.
Bir ifade ağacını değiştirmek için
1. Yeni bir konsol uygulaması projesi oluşturun.
2. System.Linq.Expressions ad alanı için dosyaya bir using yönergesi ekleyin.
3. AndAlsoModifier sınıfını projenize ekleyin.

public class AndAlsoModifier : ExpressionVisitor


{
public Expression Modify(Expression expression)
{
return Visit(expression);
}

protected override Expression VisitBinary(BinaryExpression b)


{
if (b.NodeType == ExpressionType.AndAlso)
{
Expression left = this.Visit(b.Left);
Expression right = this.Visit(b.Right);

// Make this binary expression an OrElse operation instead of an AndAlso operation.


return Expression.MakeBinary(ExpressionType.OrElse, left, right, b.IsLiftedToNull,
b.Method);
}

return base.VisitBinary(b);
}
}

Bu sınıf ExpressionVisitor sınıfını devralır ve koşullu AND işlemlerini temsil eden ifadeleri değiştirmek için
özelleştirilmiştir. Bu işlemleri koşullu bir AND koşullu OR olarak değiştirir. Bunu yapmak için, koşullu AND
ifadeler ikili ifadeler olarak temsil edildiği için sınıf temel türün VisitBinary yöntemini geçersiz kılar.
VisitBinary yönteminde, kendisine geçirilen ifade koşullu bir AND işlemini gösteriyorsa, kod koşullu AND
işleci yerine koşullu OR işlecini içeren yeni bir ifade oluşturur. VisitBinary geçirilen ifade koşullu AND
işlemini temsil ediyorsa, yöntemi temel sınıf uygulamasına erteler. Temel sınıf yöntemleri, geçirilen ifade
ağaçları gibi düğümleri oluşturur, ancak düğümlerin alt ağaçları, ziyaretçi tarafından yinelemeli olarak
üretilen ifade ağaçları ile değiştirilmiştir.
4. System.Linq.Expressions ad alanı için dosyaya bir using yönergesi ekleyin.
5. Bir ifade ağacı oluşturmak ve bunu değiştirecek yönteme geçirmek için Program.cs dosyasındaki Main
yöntemine kod ekleyin.
Expression<Func<string, bool>> expr = name => name.Length > 10 && name.StartsWith("G");
Console.WriteLine(expr);

AndAlsoModifier treeModifier = new AndAlsoModifier();


Expression modifiedExpr = treeModifier.Modify((Expression) expr);

Console.WriteLine(modifiedExpr);

/* This code produces the following output:

name => ((name.Length > 10) && name.StartsWith("G"))


name => ((name.Length > 10) || name.StartsWith("G"))
*/

Kod, koşullu AND işlemi içeren bir ifade oluşturur. Daha sonra, AndAlsoModifier sınıfının bir örneğini
oluşturur ve bu sınıfın Modify yöntemine ifadeyi geçirir. Hem özgün hem de değiştirilen ifade ağaçları
değişikliği göstermek için çıktılardır.
6. Uygulamayı derleyin ve çalıştırın.

Ayrıca bkz.
İfade ağaçlarını yürütme (C#)
İfade ağaçları (C#)
Dinamik sorgular oluşturmak için ifade ağaçları
kullanma (C#)
25.11.2019 • 4 minutes to read • Edit Online

LINQ içinde, ifade ağaçları, IQueryable<T>uygulayan veri kaynaklarını hedefleyen yapısal sorguları temsil etmek
için kullanılır. Örneğin, LINQ sağlayıcısı ilişkisel veri depolarını sorgulamak için IQueryable<T> arabirimini
uygular. Derleyici C# , bu tür veri kaynaklarını hedefleyen sorguları, çalışma zamanında bir ifade ağacı oluşturan
koda derler. Sorgu sağlayıcısı daha sonra ifade ağacı veri yapısına çapraz geçiş yapabilir ve veri kaynağı için uygun
bir sorgu diline çevirebilir.
İfade ağaçları Ayrıca LINQ içinde Expression<TDelegate>tür değişkenlerine atanan Lambda ifadelerini temsil
etmek için de kullanılır.
Bu konu başlığı altında, dinamik LINQ sorguları oluşturmak için ifade ağaçlarının nasıl kullanılacağı
açıklanmaktadır. Dinamik sorgular, bir sorgunun özelliklerinin derleme zamanında bilinmediği durumlarda
faydalıdır. Örneğin, bir uygulama, son kullanıcının verileri filtrelemek için bir veya daha fazla koşul belirtmesini
sağlayan bir kullanıcı arabirimi sağlayabilir. Bu tür bir uygulamanın, sorgulama için LINQ kullanabilmesi amacıyla,
çalışma zamanında LINQ sorgusu oluşturmak için ifade ağaçları kullanması gerekir.

Örnek
Aşağıdaki örnek, IQueryable veri kaynağında bir sorgu oluşturmak ve sonra çalıştırmak için ifade ağaçlarının nasıl
kullanılacağını gösterir. Kod, aşağıdaki sorguyu temsil etmek için bir ifade ağacı oluşturur:

companies.Where(company => (company.ToLower() == "coho winery" || company.Length > 16))


.OrderBy(company => company)

System.Linq.Expressions ad alanındaki Fabrika yöntemleri, genel sorguyu oluşturan ifadeleri temsil eden ifade
ağaçları oluşturmak için kullanılır. Standart sorgu operatörü yöntemlerine yapılan çağrıları temsil eden ifadeler, bu
yöntemlerin Queryable uygulamalarına başvurur. Son ifade ağacı, IQueryable türünde yürütülebilir bir sorgu
oluşturmak için IQueryable veri kaynağı sağlayıcısının CreateQuery<TElement>(Expression) uygulamasına
geçirilir. Sonuçlar, bu sorgu değişkeni numaralandırıldığı için alınır.

// Add a using directive for System.Linq.Expressions.

string[] companies = { "Consolidated Messenger", "Alpine Ski House", "Southridge Video", "City Power & Light",
"Coho Winery", "Wide World Importers", "Graphic Design Institute", "Adventure Works",
"Humongous Insurance", "Woodgrove Bank", "Margie's Travel", "Northwind Traders",
"Blue Yonder Airlines", "Trey Research", "The Phone Company",
"Wingtip Toys", "Lucerne Publishing", "Fourth Coffee" };

// The IQueryable data to query.


IQueryable<String> queryableData = companies.AsQueryable<string>();

// Compose the expression tree that represents the parameter to the predicate.
ParameterExpression pe = Expression.Parameter(typeof(string), "company");

// ***** Where(company => (company.ToLower() == "coho winery" || company.Length > 16)) *****
// Create an expression tree that represents the expression 'company.ToLower() == "coho winery"'.
Expression left = Expression.Call(pe, typeof(string).GetMethod("ToLower", System.Type.EmptyTypes));
Expression right = Expression.Constant("coho winery");
Expression e1 = Expression.Equal(left, right);

// Create an expression tree that represents the expression 'company.Length > 16'.
// Create an expression tree that represents the expression 'company.Length > 16'.
left = Expression.Property(pe, typeof(string).GetProperty("Length"));
right = Expression.Constant(16, typeof(int));
Expression e2 = Expression.GreaterThan(left, right);

// Combine the expression trees to create an expression tree that represents the
// expression '(company.ToLower() == "coho winery" || company.Length > 16)'.
Expression predicateBody = Expression.OrElse(e1, e2);

// Create an expression tree that represents the expression


// 'queryableData.Where(company => (company.ToLower() == "coho winery" || company.Length > 16))'
MethodCallExpression whereCallExpression = Expression.Call(
typeof(Queryable),
"Where",
new Type[] { queryableData.ElementType },
queryableData.Expression,
Expression.Lambda<Func<string, bool>>(predicateBody, new ParameterExpression[] { pe }));
// ***** End Where *****

// ***** OrderBy(company => company) *****


// Create an expression tree that represents the expression
// 'whereCallExpression.OrderBy(company => company)'
MethodCallExpression orderByCallExpression = Expression.Call(
typeof(Queryable),
"OrderBy",
new Type[] { queryableData.ElementType, queryableData.ElementType },
whereCallExpression,
Expression.Lambda<Func<string, string>>(pe, new ParameterExpression[] { pe }));
// ***** End OrderBy *****

// Create an executable query from the expression tree.


IQueryable<string> results = queryableData.Provider.CreateQuery<string>(orderByCallExpression);

// Enumerate the results.


foreach (string company in results)
Console.WriteLine(company);

/* This code produces the following output:

Blue Yonder Airlines


City Power & Light
Coho Winery
Consolidated Messenger
Graphic Design Institute
Humongous Insurance
Lucerne Publishing
Northwind Traders
The Phone Company
Wide World Importers
*/

Bu kod, Queryable.Where metoduna geçirilen koşuldaki sabit sayıda ifadeyi kullanır. Ancak, kullanıcı girişine bağlı
bir değişken sayıda koşul ifadesini birleştiren bir uygulama yazabilirsiniz. Ayrıca, kullanıcının girişine bağlı olarak
sorguda çağrılan standart sorgu işleçlerini da değiştirebilirsiniz.

Kod Derleniyor
System. Linq. Ifadeler ad alanını ekleyin.

Ayrıca bkz.
İfade ağaçları (C#)
İfade ağaçlarını yürütme (C#)
Nasıl yapılır: çalışma zamanında koşul filtrelerini dinamik olarak belirtme
Visual Studio 'da Ifade ağaçlarında hata ayıklamaC#()
31.10.2019 • 2 minutes to read • Edit Online

Uygulamalarınızda hata ayıklarken ifade ağaçlarının yapısını ve içeriğini çözümleyebilirsiniz. İfade ağacı yapısına
hızlı bir genel bakış almak için, özel bir sözdizimi kullanarakifade ağaçlarını temsil eden DebugView özelliğini
kullanabilirsiniz. ( DebugView yalnızca hata ayıklama modunda kullanılabilir olduğunu unutmayın.)

DebugView bir dize olduğundan, DebugView etiketinin yanındaki büyüteç simgesinden metin görselleştiricisi ' i
seçerek birden çok satırda görüntülemek Için yerleşik metin Görselleştirici ' u kullanabilirsiniz.

Alternatif olarak, şu gibi bir ifade ağaçları için özel Görselleştirici yükleyebilir ve kullanabilirsiniz:
Okunabilir ifadeler ( Visual Studio Marketsağlanan C# MIT Lisansı), ifade ağacını kod olarak işler:

Ifade ağacı görselleştiricisi (MIT Lisansı), ifade ağacının, özelliklerinin ve ilgili nesnelerin grafik görünümünü
sağlar:

Bir ifade ağacı için Görselleştirici açmak için


1. DataTips, bir Gözcü penceresinde, oto penceresinde veya Locals penceresinde ifade ağacının yanında
görünen büyüteç simgesine tıklayın.
Kullanılabilir görselleştiricilerin listesi görüntülenir.:
2. Kullanmak istediğiniz Görselleştirici tıklayın.

Ayrıca bkz.
İfade ağaçları (C#)
Visual Studio’da hata ayıklama
Özel Görselleştirici Oluşturma
DebugView sözdizimi
DebugView Söz dizimi
23.10.2019 • 3 minutes to read • Edit Online

DebugView Özelliği (yalnızca hata ayıklama sırasında kullanılabilir) ifade ağaçları dize işlenmesini sağlar. Çoğu söz
dizimini anlamak oldukça açıktır; özel durumlar aşağıdaki bölümlerde açıklanmıştır.
Her örneğin bir blok açıklama tarafından izlenir içeren DebugView .

ParameterExpression
System.Linq.Expressions.ParameterExpression değişken adları ile görüntülenir bir $ simge başlangıcındaki.
Parametre bir adı yoksa, otomatik olarak oluşturulmuş bir adı gibi atandıktan $var1 veya $var2 .
Örnekler

ParameterExpression numParam = Expression.Parameter(typeof(int), "num");


/*
$num
*/

ParameterExpression numParam = Expression.Parameter(typeof(int));


/*
$var1
*/

SabitDeyim'in
İçin System.Linq.Expressions.ConstantExpression dize, tamsayı değerlerini temsil eden nesneleri ve null , sabit
değeri görüntülenir.
C# sabit değer olarak standart sonekleri olan sayısal türleri için sonek değerine eklenir. Aşağıdaki tabloda, çeşitli
sayısal türler ile ilişkili soneklerini gösterir.

TÜR ANAHTAR SÖZCÜĞÜ SON EKI

System.UInt32 uint U

System.Int64 long L

System.UInt64 ulong UL

System.Double double D

System.Single float F

System.Decimal decimal M

Örnekler
int num = 10;
ConstantExpression expr = Expression.Constant(num);
/*
10
*/

double num = 10;


ConstantExpression expr = Expression.Constant(num);
/*
10D
*/

BlockExpression
Varsa türünü bir System.Linq.Expressions.BlockExpression bloğundaki son ifadenin türü nesne farklıdır, açılı
ayraçlar içinde türü görüntülenir ( < ve > ). Aksi halde, türünü BlockExpression nesne görüntülenmez.
Örnekler

BlockExpression block = Expression.Block(Expression.Constant("test"));


/*
.Block() {
"test"
}
*/

BlockExpression block = Expression.Block(typeof(Object), Expression.Constant("test"));


/*
.Block<System.Object>() {
"test"
}
*/

LambdaExpression
System.Linq.Expressions.LambdaExpression nesneler, temsilci türleri ile birlikte görüntülenir.
Bir lambda ifadesi bir adı yoksa, otomatik olarak oluşturulmuş bir adı gibi atandıktan #Lambda1 veya #Lambda2 .
Örnekler

LambdaExpression lambda = Expression.Lambda<Func<int>>(Expression.Constant(1));


/*
.Lambda #Lambda1<System.Func'1[System.Int32]>() {
1
}
*/

LambdaExpression lambda = Expression.Lambda<Func<int>>(Expression.Constant(1), "SampleLambda", null);


/*
.Lambda #SampleLambda<System.Func'1[System.Int32]>() {
1
}
*/

LabelExpression
İçin varsayılan bir değer belirtirseniz System.Linq.Expressions.LabelExpression nesnesi, bu değer, önce
görüntülenir System.Linq.Expressions.LabelTarget nesne.
.Label Belirteci etiketi başlangıcını gösterir. .LabelTarget Belirteci atlamak için hedef hedefinin gösterir.
Bir etiket bir ad yoksa otomatik olarak oluşturulmuş bir adı gibi atandıktan #Label1 veya #Label2 .
Örnekler

LabelTarget target = Expression.Label(typeof(int), "SampleLabel");


BlockExpression block = Expression.Block(
Expression.Goto(target, Expression.Constant(0)),
Expression.Label(target, Expression.Constant(-1))
);
/*
.Block() {
.Goto SampleLabel { 0 };
.Label
-1
.LabelTarget SampleLabel:
}
*/

LabelTarget target = Expression.Label();


BlockExpression block = Expression.Block(
Expression.Goto(target),
Expression.Label(target)
);
/*
.Block() {
.Goto #Label1 { };
.Label
.LabelTarget #Label1:
}
*/

İşaretli işleçleri
İşaretli işleçleri ile görüntülenir # işleci önünde simge. Örneğin, işaretli Toplama işleci olarak görüntülenir #+ .
Örnekler

Expression expr = Expression.AddChecked( Expression.Constant(1), Expression.Constant(2));


/*
1 #+ 2
*/

Expression expr = Expression.ConvertChecked( Expression.Constant(10.0), typeof(int));


/*
#(System.Int32)10D
*/
Yineleyiciler (C#)
23.10.2019 • 10 minutes to read • Edit Online

Bir Yineleyici , listeler ve diziler gibi koleksiyonlardan dolaşmak için kullanılabilir.


Yineleyici yöntemi veya get erişimcisi bir koleksiyon üzerinde özel bir yineleme gerçekleştirir. Yineleyici
yöntemi, her öğeyi birer birer döndürmek için yield return ifadesini kullanır. Bir yield return ifadeye
ulaşıldığında, koddaki geçerli konum hatırlanır. Bu konumdan, Yineleyici işlevinin bir sonraki çağrılışında
yürütme yeniden başlatılır.
Bir foreach ifadesi veya bir LINQ sorgusu kullanarak istemci kodundan bir yineleyici tüketin.
Aşağıdaki örnekte, foreach döngünün ilk yinelemesi yürütmenin ilk yield return ifadeye ulaşılana kadar
SomeNumbers yineleyici yönteminde devam etmesine neden olur. Bu yineleme 3 değerini döndürür ve yineleyici
yöntemindeki geçerli konum korunur. Döngünün bir sonraki yinelemesinde, yineleyici yönteminde yürütme
kaldığınız yerden devam eder, bir yield return ifadeye ulaştığında yeniden durdurulur. Bu yineleme 5 değerini
döndürür ve yineleyici yöntemindeki geçerli konum yeniden korunur. Yineleyici yönteminin sonuna ulaşıldığında
döngü tamamlanır.

static void Main()


{
foreach (int number in SomeNumbers())
{
Console.Write(number.ToString() + " ");
}
// Output: 3 5 8
Console.ReadKey();
}

public static System.Collections.IEnumerable SomeNumbers()


{
yield return 3;
yield return 5;
yield return 8;
}

Bir yineleyici yönteminin veya get erişimcisinin dönüş türü, IEnumerable IEnumerable<T> IEnumerator,, veya
IEnumerator<T>olabilir.
Yinelemeyi sonlandırmak için bir yield break ifade kullanabilirsiniz.

NOTE
Bu konudaki basit Yineleyici örneği hariç tüm örneklerde, System.Collections ve System.Collections.Generic ad
alanları için using yönergelerini dahil edin.

Basit Yineleyici
Aşağıdaki örnek, for döngüsü içindeki yield return tek bir ifadeye sahiptir. ' Main De, foreach ifade gövdesinin
her yinelemesi bir sonraki yield return ifadeye devam eden Yineleyici işlevine bir çağrı oluşturur.
static void Main()
{
foreach (int number in EvenSequence(5, 18))
{
Console.Write(number.ToString() + " ");
}
// Output: 6 8 10 12 14 16 18
Console.ReadKey();
}

public static System.Collections.Generic.IEnumerable<int>


EvenSequence(int firstNumber, int lastNumber)
{
// Yield even numbers in the range.
for (int number = firstNumber; number <= lastNumber; number++)
{
if (number % 2 == 0)
{
yield return number;
}
}
}

Koleksiyon sınıfı oluşturma


Aşağıdaki örnekte, DaysOfTheWeek sınıfı bir GetEnumerator yöntemi gerektiren IEnumerable arabirimini uygular.
Derleyici, bir GetEnumerator IEnumeratordöndüren yöntemini dolaylı olarak çağırır.
Yöntemi, yöntemini yield return kullanarak her bir dizeyi bir kez döndürür. GetEnumerator

static void Main()


{
DaysOfTheWeek days = new DaysOfTheWeek();

foreach (string day in days)


{
Console.Write(day + " ");
}
// Output: Sun Mon Tue Wed Thu Fri Sat
Console.ReadKey();
}

public class DaysOfTheWeek : IEnumerable


{
private string[] days = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };

public IEnumerator GetEnumerator()


{
for (int index = 0; index < days.Length; index++)
{
// Yield each day of the week.
yield return days[index];
}
}
}

Aşağıdaki örnek, hayvanlar koleksiyonunu Zoo içeren bir sınıf oluşturur.


Sınıf örneğine ( theZoo ) başvuran GetEnumerator ifade,yöntemiörtükolarakçağırır. foreach Birds
AnimalsForType Ve özelliklerine Mammals başvuran deyimler foreach adlandırılmış yineleyici yöntemini kullanır.

static void Main()


{
Zoo theZoo = new Zoo();

theZoo.AddMammal("Whale");
theZoo.AddMammal("Rhinoceros");
theZoo.AddBird("Penguin");
theZoo.AddBird("Warbler");

foreach (string name in theZoo)


{
Console.Write(name + " ");
}
Console.WriteLine();
// Output: Whale Rhinoceros Penguin Warbler

foreach (string name in theZoo.Birds)


{
Console.Write(name + " ");
}
Console.WriteLine();
// Output: Penguin Warbler

foreach (string name in theZoo.Mammals)


{
Console.Write(name + " ");
}
Console.WriteLine();
// Output: Whale Rhinoceros

Console.ReadKey();
}

public class Zoo : IEnumerable


{
// Private members.
private List<Animal> animals = new List<Animal>();

// Public methods.
public void AddMammal(string name)
{
animals.Add(new Animal { Name = name, Type = Animal.TypeEnum.Mammal });
}

public void AddBird(string name)


{
animals.Add(new Animal { Name = name, Type = Animal.TypeEnum.Bird });
}

public IEnumerator GetEnumerator()


{
foreach (Animal theAnimal in animals)
{
yield return theAnimal.Name;
}
}

// Public members.
public IEnumerable Mammals
{
get { return AnimalsForType(Animal.TypeEnum.Mammal); }
}

public IEnumerable Birds


{
get { return AnimalsForType(Animal.TypeEnum.Bird); }
}

// Private methods.
private IEnumerable AnimalsForType(Animal.TypeEnum type)
{
foreach (Animal theAnimal in animals)
{
if (theAnimal.Type == type)
{
yield return theAnimal.Name;
}
}
}

// Private class.
private class Animal
{
public enum TypeEnum { Bird, Mammal }

public string Name { get; set; }


public TypeEnum Type { get; set; }
}
}

Bir genel liste ile yineleyiciler kullanma


Aşağıdaki örnekte, Stack<T> genel sınıf IEnumerable<T> genel arabirimini uygular. Yöntemi Push , türü T bir
diziye değerler atar. Yöntemi, yield return ifadesini kullanarak dizi değerlerini döndürür. GetEnumerator
Genel GetEnumerator yöntemin yanı sıra genel GetEnumerator olmayan yöntemin de uygulanması gerekir.
Bunun nedeni IEnumerable<T> , öğesinden IEnumerabledevralmasıdır. Genel olmayan uygulama genel
uygulamaya erteler.
Örnek, aynı veri topluluğunda tekrarların çeşitli yollarını desteklemek için adlandırılmış yineleyiciler kullanır. Bu
adlandırılmış yineleyiciler TopToBottom , ve BottomToTop özellikleridir TopN ve yöntemidir.
Özelliği BottomToTop , bir get erişimcide yineleyici kullanır.

static void Main()


{
Stack<int> theStack = new Stack<int>();

// Add items to the stack.


for (int number = 0; number <= 9; number++)
{
theStack.Push(number);
}

// Retrieve items from the stack.


// foreach is allowed because theStack implements IEnumerable<int>.
foreach (int number in theStack)
{
Console.Write("{0} ", number);
}
Console.WriteLine();
// Output: 9 8 7 6 5 4 3 2 1 0

// foreach is allowed, because theStack.TopToBottom returns IEnumerable(Of Integer).


foreach (int number in theStack.TopToBottom)
{
Console.Write("{0} ", number);
}
Console.WriteLine();
// Output: 9 8 7 6 5 4 3 2 1 0

foreach (int number in theStack.BottomToTop)


{
Console.Write("{0} ", number);
}
}
Console.WriteLine();
// Output: 0 1 2 3 4 5 6 7 8 9

foreach (int number in theStack.TopN(7))


{
Console.Write("{0} ", number);
}
Console.WriteLine();
// Output: 9 8 7 6 5 4 3

Console.ReadKey();
}

public class Stack<T> : IEnumerable<T>


{
private T[] values = new T[100];
private int top = 0;

public void Push(T t)


{
values[top] = t;
top++;
}
public T Pop()
{
top--;
return values[top];
}

// This method implements the GetEnumerator method. It allows


// an instance of the class to be used in a foreach statement.
public IEnumerator<T> GetEnumerator()
{
for (int index = top - 1; index >= 0; index--)
{
yield return values[index];
}
}

IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}

public IEnumerable<T> TopToBottom


{
get { return this; }
}

public IEnumerable<T> BottomToTop


{
get
{
for (int index = 0; index <= top - 1; index++)
{
yield return values[index];
}
}
}

public IEnumerable<T> TopN(int itemsFromTop)


{
// Return less than itemsFromTop if necessary.
int startIndex = itemsFromTop >= top ? 0 : top - itemsFromTop;

for (int index = top - 1; index >= startIndex; index--)


{
yield return values[index];
}
}
}

Sözdizimi bilgileri
Yineleyici bir yöntem veya get erişimci olarak gerçekleşebilir. Bir olay, örnek Oluşturucu, statik oluşturucu veya
statik sonlandırıcının içinde bir yineleyici gerçekleşemez.
yield return Deyimdeki ifade türünden, Yineleyici tarafından döndürülen IEnumerable<T > bağımsız
değişkenine örtük bir dönüştürme bulunmalıdır.
' C#De, yineleyici yönteminde herhangi in bir, ref veya out parametresi olamaz.
' C#De, "yield" ayrılmış bir sözcük değildir ve yalnızca bir return veya break anahtar sözcüğünden önce
kullanıldığında özel anlamı vardır.

Teknik Uygulama
Bir yineleyici Yöntem olarak yazdığınızda, derleyici onu bir durum makinesi olan bir iç içe geçmiş sınıfa çevirir. Bu
sınıf, istemci kodundaki foreach döngü devam ettiğinde yineleyicinin konumunu izler.
Derleyicinin ne yaptığını görmek için, bir yineleyici yöntemi için oluşturulan Microsoft ara dil kodunu
görüntülemek için ıldadsm. exe aracını kullanabilirsiniz.
Bir sınıf veya Yapıiçin Yineleyici oluşturduğunuzda, tüm IEnumerator arabirimini uygulamanız gerekmez.
Derleyici Current yineleyiciyi algıladığında, IEnumerator veya MoveNext Dispose arabiriminin,,
veyöntemleriniotomatikolarakoluştururIEnumerator<T> .
foreach Döngünün art arda her tekrarında (veya doğrudan IEnumerator.MoveNext çağrısının), sonraki Yineleyici
kod gövdesi önceki yield return deyimden sonra devam eder. Daha sonra Yineleyici gövdesinin sonuna
ulaşılana kadar veya bir yield return yield break deyime ulaşılana kadar sonraki ifadeye devam eder.
Yineleyiciler IEnumerator.Reset yöntemi desteklemiyor. Başlangıçtan itibaren yeniden yinelemek için yeni bir
yineleyici edinmeniz gerekir. Yineleyici Reset yöntemi tarafından döndürülen yineleyicinin çağrılması bir
NotSupportedExceptionoluşturur.
Daha fazla bilgi için bkz. C# dil belirtimi.

Yineleyicilerin kullanımı
Yineleyiciler, bir liste dizisini doldurmak için karmaşık kod foreach kullanmanız gerektiğinde bir döngünün
basitliğini korumanıza olanak sağlar. Bu, aşağıdakileri yapmak istediğinizde yararlı olabilir:
İlk foreach döngü yinelemeden sonra liste sırasını değiştirin.
Bir foreach döngünün ilk yinelemesinden önce büyük bir listenin tam olarak yüklenmesini önleyin. Tablo
satırlarını toplu olarak yüklemek için disk belleğine alınmış bir getirme örneği. Diğer bir örnek
EnumerateFiles , .NET Framework içinde yineleyiciler uygulayan yöntemidir.
Yineleyici içinde listenin oluşturulmasını yalıt. Yineleyici yönteminde, listeyi derleyip her sonucu bir
döngüde sağlayabilirsiniz.

Ayrıca bkz.
System.Collections.Generic
IEnumerable<T>
foreach, in
yield
Dizilerle foreach kullanma
Genel Türler
Dil ile Tümleşik Sorgu (LINQ)
4.11.2019 • 6 minutes to read • Edit Online

Dil ile tümleşik sorgu (LINQ ), sorgu yeteneklerinin doğrudan C# dile tümleştirilmesine dayalı bir teknoloji
kümesinin adıdır. Geleneksel olarak, verilere karşı sorgular derleme zamanında veya IntelliSense desteğiyle
tür denetlemesi olmadan basit dizeler olarak ifade edilir. Ayrıca, her veri kaynağı türü için farklı bir sorgu dili
öğrenirsiniz: SQL veritabanları, XML belgeleri, çeşitli Web Hizmetleri ve benzeri. LINQ ile sorgu, sınıflar,
Yöntemler ve olaylar gibi birinci sınıf bir dil yapısıdır. Dil anahtar sözcükleri ve tanıdık işleçleri kullanarak, türü
kesin belirlenmiş nesne koleksiyonlara karşı sorgular yazarsınız. LINQ teknolojileri, nesneler (LINQ to
Objects), ilişkisel veritabanları (LINQ to SQL ) ve XML (LINQ to XML ) için tutarlı bir sorgu deneyimi sağlar.
Sorgu yazan bir geliştirici için, LINQ 'nin en görünür "dil ile tümleşik" bir kısmı sorgu ifadesidir. Sorgu
ifadeleri bildirime dayalı bir sorgu söz dizimineyazılır. Sorgu söz dizimini kullanarak veri kaynaklarında en az
kodla filtreleme, sıralama ve gruplama işlemlerini gerçekleştirebilirsiniz. SQL veritabanlarındaki verileri
sorgulamak ve dönüştürmek için aynı temel sorgu ifadesi desenlerini, ADO .NET veri kümelerini, XML
belgelerini ve akışlarını ve .NET koleksiyonlarını kullanırsınız.
SQL Server veritabanları, XML belgeleri, C# ADO.NET veri kümeleri ve IEnumerable ya da genel
IEnumerable<T> arabirimini destekleyen herhangi bir nesne KOLEKSIYONU için LINQ sorguları
yazabilirsiniz. Ayrıca, LINQ desteği birçok Web hizmeti ve diğer veritabanı uygulamaları için üçüncü taraflar
tarafından da sağlanır.
Aşağıdaki örnek, tüm sorgu işlemini gösterir. Tamamlanmış işlem, bir veri kaynağı oluşturmayı, sorgu ifadesini
tanımlamayı ve sorguyu foreach deyiminde yürütmeyi içerir.

class LINQQueryExpressions
{
static void Main()
{

// Specify the data source.


int[] scores = new int[] { 97, 92, 81, 60 };

// Define the query expression.


IEnumerable<int> scoreQuery =
from score in scores
where score > 80
select score;

// Execute the query.


foreach (int i in scoreQuery)
{
Console.Write(i + " ");
}
}
}
// Output: 97 92 81

Visual Studio 'dan aşağıdaki çizimde, hem SQL Server hem C# de tam tür denetimi ve ıntellisense desteğiyle
Visual Basic bir veritabanına karşı kısmen tamamlanmış bir LINQ sorgusu gösterilmektedir:
Sorgu ifadesine genel bakış
Sorgu ifadeleri, LINQ özellikli herhangi bir veri kaynağından verileri sorgulamak ve dönüştürmek için
kullanılabilir. Örneğin, tek bir sorgu bir SQL veritabanından veri alabilir ve çıkış olarak bir XML akışı
üretebilir.
Sorgu ifadeleri çok tanıdık C# dil yapıları kullandıkları için kolayca ana öğe kullanmaktır.
Bir sorgu ifadesindeki değişkenlerin hepsi kesin olarak türlidir, ancak çoğu durumda derleyici onu çıkardığı
için türü açıkça sağlamak zorunda değilsiniz. Daha fazla bilgi için bkz. LINQ sorgu Işlemlerinde tür ilişkileri.
Sorgu değişkeni üzerinde yineleme yapana kadar sorgu yürütülmez, örneğin, bir foreach bildiriminde.
Daha fazla bilgi için bkz. LINQ Sorgularına Giriş.
Derleme zamanında sorgu ifadeleri, C# belirtimde belirtilen kurallara göre standart sorgu operatörü
yöntemi çağrılarına dönüştürülür. Sorgu söz dizimi kullanılarak ifade edilebilir herhangi bir sorgu, yöntem
sözdizimi kullanılarak da ifade edilebilir. Ancak çoğu durumda sorgu sözdizimi daha okunabilir ve kısadır.
Daha fazla bilgi için bkz C# . dil belirtimi ve Standart sorgu işleçlerine genel bakış.
LINQ sorguları yazdığınızda bir kural olarak, gerektiğinde sorgu söz dizimini ve Yöntem sözdizimini
kullanmanızı öneririz. İki farklı form arasında anlam veya performans farkı yoktur. Sorgu ifadeleri genellikle
yöntem sözdiziminde yazılan denk ifadelerden daha okunabilir.
Count veya Maxgibi bazı sorgu işlemlerinde denk bir sorgu ifadesi yan tümcesi yoktur ve bu nedenle bir
yöntem çağrısı olarak ifade edilmesi gerekir. Yöntem sözdizimi, sorgu söz dizimi ile çeşitli şekillerde
birleştirilebilir. Daha fazla bilgi için bkz. LINQ 'Te sorgu sözdizimi ve Yöntem sözdizimi.
Sorgu ifadeleri, sorgu uygulanmış türe bağlı olarak ifade ağaçlarına veya temsilcilere derlenebilir.
IEnumerable<T> sorguları temsilcilere derlenir. IQueryable ve IQueryable<T> sorguları, ifade ağaçlarına
derlenir. Daha fazla bilgi için bkz. ifade ağaçları.

Sonraki adımlar
LINQ hakkında daha fazla bilgi edinmek için sorgu ifadesi temelkavramları konusundaki bazı temel
kavramları öğrenerek başlayın ve ardından ilgilendiğiniz LINQ teknolojisinin belgelerini okuyun:
XML belgeleri: LINQ to XML
ADO.NET Entity Framework: LINQ to Entities
.NET koleksiyonları, dosyalar, dizeler ve benzeri: LINQ to Objects
Genel olarak LINQ hakkında daha ayrıntılı bilgi edinmek için bkz. LINQ ın C# .
LINQ C#ile çalışmaya başlamak için bkz. LINQ ile çalışmaöğreticisi.
LINQ Sorgularına Giriş (C#)
4.11.2019 • 10 minutes to read • Edit Online

Sorgu , veri kaynağından veri alan bir ifadedir. Sorgular genellikle özelleştirilmiş bir sorgu dilinde ifade edilir.
Çeşitli veri kaynağı türleri için zaman içinde geliştirilmiş farklı diller, örneğin SQL ilişkisel veritabanları için SQL
ve XML için XQuery. Bu nedenle, geliştiricilerin desteklemesi gereken her veri kaynağı türü veya veri biçimi için
yeni bir sorgu dili öğrenmeleri gerekiyordu. LINQ, çeşitli veri kaynakları ve biçimlerdeki verilerle çalışmaya
yönelik tutarlı bir model sunarak bu durumu basitleştirir. LINQ sorgusunda, her zaman nesneleriyle birlikte
çalışmanız gerekir. XML belgeleri, SQL veritabanları, ADO.NET veri kümeleri, .NET koleksiyonları ve LINQ
sağlayıcı kullanılabilir olan diğer herhangi bir biçimde sorgulamak ve dönüştürmek için aynı temel kodlama
düzenlerini kullanırsınız.

Bir Sorgu İşleminin Üç Bölümü


Tüm LINQ sorgu işlemleri üç farklı eylemden oluşur:
1. Veri kaynağını edinin.
2. Sorguyu oluşturun.
3. Sorguyu yürütün.
Aşağıdaki örnek, bir sorgu işleminin üç bölümünün kaynak kodda nasıl ifade edildiği gösterilmektedir. Örnek,
bir tamsayı dizisini kolaylık sağlaması için bir veri kaynağı olarak kullanır; Ancak, aynı kavramlar diğer veri
kaynakları için de geçerlidir. Bu örnek, bu konunun geri kalanı boyunca ifade edilir.

class IntroToLINQ
{
static void Main()
{
// The Three Parts of a LINQ Query:
// 1. Data source.
int[] numbers = new int[7] { 0, 1, 2, 3, 4, 5, 6 };

// 2. Query creation.
// numQuery is an IEnumerable<int>
var numQuery =
from num in numbers
where (num % 2) == 0
select num;

// 3. Query execution.
foreach (int num in numQuery)
{
Console.Write("{0,1} ", num);
}
}
}

Aşağıdaki çizimde sorgu işleminin tamamı gösterilmektedir. LINQ, sorgunun yürütülmesi sorgunun kendisinden
farklıdır; diğer bir deyişle, yalnızca bir sorgu değişkeni oluşturarak herhangi bir veri alınamadınız.
Veri Kaynağı
Önceki örnekte, veri kaynağı bir dizi olduğundan, genel IEnumerable<T> arabirimini örtülü olarak destekler. Bu
olgu, LINQile sorgulanabilecek anlamına gelir. Bir sorgu foreach ifadesinde yürütülür ve foreach IEnumerable
veya IEnumerable<T>gerekir. IEnumerable<T> destekleyen türler veya genel IQueryable<T> gibi türetilmiş bir
arabirim sorgulanabilir türlerolarak adlandırılır.
Sorgulanabilir bir tür, LINQ veri kaynağı olarak kullanılmak üzere değişiklik veya özel bir işleme gerektirmez.
Kaynak veriler, sorgulanabilir bir tür olarak zaten bellekte değilse, LINQ sağlayıcı tarafından temsil etmelidir.
Örneğin, LINQ - XML bir XML belgesini sorgulanabilir XElement türüne yükler:

// Create a data source from an XML document.


// using System.Xml.Linq;
XElement contacts = XElement.Load(@"c:\myContactList.xml");

LINQ - SQL, ilk olarak tasarım zamanında ya da Visual Studio 'daki Visual Studio 'daki LINQ to SQL araçlarını
kullanarak bir nesne ilişkisel eşleme oluşturursunuz. Sorgular nesnelere karşı yazılır ve çalışma zamanında
LINQ - SQL veritabanıyla iletişimi işler. Aşağıdaki örnekte, Customers veritabanındaki belirli bir tabloyu temsil
eder ve sorgu sonucunun türü IQueryable<T>IEnumerable<T>türetilir.

Northwnd db = new Northwnd(@"c:\northwnd.mdf");

// Query for customers in London.


IQueryable<Customer> custQuery =
from cust in db.Customers
where cust.City == "London"
select cust;

Belirli veri kaynağı türlerinin nasıl oluşturulacağı hakkında daha fazla bilgi için çeşitli LINQ sağlayıcılarına
yönelik belgelere bakın. Ancak, temel kural çok basittir: LINQ veri kaynağı, genel IEnumerable<T> arabirimini
veya bundan devralan bir arabirimi destekleyen herhangi bir nesnedir.

NOTE
Genel olmayan IEnumerable arabirimini destekleyen ArrayList gibi türler, LINQ veri kaynağı olarak da kullanılabilir. Daha
fazla bilgi için bkz. nasıl yapılır: bir ArrayList 'ı LINQ (C#) ile sorgulama.
Sorgu
Sorgu, veri kaynağından veya kaynaklardan alınacak bilgileri belirtir. İsteğe bağlı olarak, bir sorgu
döndürülmeden önce bu bilgilerin nasıl sıralanması, gruplandırılacağı ve şekillendirilmiş olması gerektiğini de
belirtir. Sorgu bir sorgu değişkeninde depolanır ve sorgu ifadesiyle başlatılır. Sorguları C# yazmayı
kolaylaştırmak için yeni sorgu söz dizimini sunmuştur.
Önceki örnekteki sorgu, tamsayı dizisindeki tüm çift sayıları döndürür. Sorgu ifadesi üç yan tümce içerir: from ,
where ve select . ( SQL hakkında bilginiz varsa, yan tümcelerinin sıralamasını SQL 'deki siparişten tersine
çevrilmiş olduğunu fark etmiş olursunuz.) from yan tümcesi veri kaynağını belirtir, where yan tümcesi filtreyi
uygular ve select yan tümcesi döndürülen öğelerin türünü belirtir. Bunlar ve diğer sorgu yan tümceleri, LINQ
sorgu ifadeleri bölümünde ayrıntılı olarak ele alınmıştır. Şimdilik, önemli nokta LINQ, sorgu değişkeninin kendisi
hiçbir eylemde bulunmaz ve veri döndürmez. Yalnızca sorgu daha sonraki bir noktada yürütüldüğünde sonuçları
üretmek için gereken bilgileri depolar. Sorguların arka planda nasıl oluşturulduğu hakkında daha fazla bilgi için
bkz. Standart sorgu Işleçlerine genel bakışC#().

NOTE
Sorgular, yöntem sözdizimi kullanılarak da ifade edilebilir. Daha fazla bilgi için bkz. LINQ 'Te sorgu sözdizimi ve Yöntem
sözdizimi.

Sorgu Yürütme
Ertelenmiş Yürütme
Daha önce belirtildiği gibi, sorgu değişkeni yalnızca sorgu komutlarını depolar. Sorgunun gerçek yürütmesi, bir
foreach deyimindeki sorgu değişkeni üzerinde yineleme yapana kadar ertelenir. Bu kavram ertelenmiş yürütme
olarak adlandırılır ve aşağıdaki örnekte gösterilmiştir:

// Query execution.
foreach (int num in numQuery)
{
Console.Write("{0,1} ", num);
}

foreach deyimde sorgu sonuçlarının alındığı yerdir. Örneğin, önceki sorguda, yineleme num değişkeni,
döndürülen dizideki her bir değeri (bir kez) barındırır.
Sorgu değişkeni hiçbir zaman sorgu sonuçlarını içermediğinden, onu istediğiniz sıklıkta yürütebilirsiniz.
Örneğin, ayrı bir uygulama tarafından sürekli olarak güncelleştirilmekte olan bir veritabanınız olabilir.
Uygulamanızda, en son verileri alan bir sorgu oluşturabilir ve her seferinde farklı sonuçlar almak için bir aralıkta
tekrar tekrar çalıştırabilirsiniz.
Hemen Yürütmeyi Zorlama
Bir kaynak öğe aralığı üzerinde toplama işlevleri gerçekleştiren sorgular önce bu öğeler üzerinde yineleme
olmalıdır. Bu tür sorgulara örnek olarak Count , Max , Average ve First verilebilir. Bu, sorgunun kendisi bir
sonuç döndürmek için foreach kullanması gerektiğinden açık bir foreach deyimleri olmadan yürütülür. Ayrıca,
bu sorgu türlerinin IEnumerable bir koleksiyon değil tek bir değer döndürdüğüne de göz önünde. Aşağıdaki
sorgu, kaynak dizideki Çift sayıların sayısını döndürür:
var evenNumQuery =
from num in numbers
where (num % 2) == 0
select num;

int evenNumCount = evenNumQuery.Count();

Herhangi bir sorgunun hemen yürütülmesini zorlamak ve sonuçlarını önbelleğe almak için ToList veya ToArray
yöntemlerini çağırabilirsiniz.

List<int> numQuery2 =
(from num in numbers
where (num % 2) == 0
select num).ToList();

// or like this:
// numQuery3 is still an int[]

var numQuery3 =
(from num in numbers
where (num % 2) == 0
select num).ToArray();

Ayrıca, foreachdöngüsünü sorgu ifadesinden hemen sonra yerleştirerek yürütmeye zorlayabilirsiniz. Ancak,
ToList veya ToArray çağırarak, tüm verileri tek bir koleksiyon nesnesi içinde de önbelleğe alabilirsiniz.

Ayrıca bkz.
C#'de LINQ Kullanmaya Başlama
İzlenecek yol: sorguları yazmaC#
LINQ sorgu Ifadeleri
foreach, in
Sorgu anahtar sözcükleri (LINQ )
LINQ ve Genel Türler (C#)
23.10.2019 • 3 minutes to read • Edit Online

LINQsorgular, .NET Framework sürüm 2,0 ' de tanıtılan genel türleri temel alır.Sorgu yazmaya başlayabilmeniz
için önce genel türler hakkında ayrıntılı bilgi sahibi olmanız gerekmez. Ancak, iki temel kavramı anlamak
isteyebilirsiniz:
1. Gibi bir genel koleksiyon sınıfının List<T>bir örneğini oluşturduğunuzda, "T" öğesini listenin tutacaksınız
nesne türüyle değiştirirsiniz. Örneğin, dizelerin bir listesi olarak List<string> ifade edilir ve Customer nesne
listesi olarak List<Customer> ifade edilir. Genel liste kesin bir şekilde yazılır ve öğelerini olarak
Objectdepolayan koleksiyonlar üzerinde birçok avantaj sağlar. Bir ' a Customer List<string> eklemeye
çalışırsanız, derleme zamanında bir hata alırsınız. Çalışma zamanı türü atama gerçekleştirmeniz zorunda
olmadığınızdan genel koleksiyonları kullanmak kolaydır.
2. IEnumerable<T>, genel koleksiyon sınıflarının foreach ifadesini kullanarak numaralandırılacağını sağlayan
arabirimdir. Genel koleksiyon sınıfları, IEnumerable<T> destek IEnumerablegibi ArrayList genel olmayan
koleksiyon sınıfları gibi desteklenir.
Genel türler hakkında daha fazla bilgi için bkz. Genel türler.

LINQ sorgularında IEnumerable> < T değişkenleri


LINQsorgu değişkenleri, gibi bir IEnumerable<T> türetilmiş tür IQueryable<T>veya olarak yazılır. Olarak
IEnumerable<Customer> yazılmış bir sorgu değişkeni gördüğünüzde, yalnızca sorgunun çalıştırıldığı zaman, sıfır veya
daha fazla Customer nesne dizisi üreten anlamına gelir.

IEnumerable<Customer> customerQuery =
from cust in customers
where cust.City == "London"
select cust;

foreach (Customer customer in customerQuery)


{
Console.WriteLine(customer.LastName + ", " + customer.FirstName);
}

Daha fazla bilgi için bkz. LINQ sorgu Işlemlerinde tür ilişkileri.

Derleyicinin genel tür bildirimleri tanıtıcısına izin verme


Tercih ederseniz, var anahtar sözcüğünü kullanarak genel sözdiziminden kaçınabilirsiniz. Anahtar sözcüğü,
derleyiciye, from yan tümcesinde belirtilen veri kaynağına bakarak bir sorgu değişkeninin türünü çıkarmasını
söyler. var Aşağıdaki örnek, önceki örnekle aynı derlenmiş kodu üretir:
var customerQuery2 =
from cust in customers
where cust.City == "London"
select cust;

foreach(var customer in customerQuery2)


{
Console.WriteLine(customer.LastName + ", " + customer.FirstName);
}

var Anahtar sözcüğü, değişkenin türü belirgin olduğunda veya grup sorguları tarafından üretilenler gibi iç içe
geçmiş genel türleri açıkça belirtmek önemli olmadığında yararlıdır. Genel olarak, kullanmanız var durumunda
kodunuzun başkalarının okuması için daha zor hale yapabileceğini fark ederiz. Daha fazla bilgi için bkz. örtülü
olarak yazılan yerel değişkenler.

Ayrıca bkz.
Genel Türler
Temel LINQ Sorgu İşlemleri (C#)
4.11.2019 • 8 minutes to read • Edit Online

Bu konu, sorgu ifadelerine LINQ için kısa bir giriş ve bir sorguda gerçekleştirdiğiniz bazı tipik işlem türlerinden
bazılarını vermektedir. Daha ayrıntılı bilgi aşağıdaki konularda yer verilmiştir:
LINQ sorgu Ifadeleri
Standart sorgu Işleçlerine genelC#bakış ()
İzlenecek yol: sorguları yazmaC#

NOTE
SQL veya XQuery gibi bir sorgu dili zaten hakkında bilginiz varsa, bu konunun çoğunu atlayabilirsiniz. LINQ sorgu ifadelerinde
yan tümceler sırası hakkında bilgi edinmek için sonraki bölümde " from yan tümcesi" konusunu okuyun.

Bir Veri Kaynağı Elde Etme


LINQ sorgusunda ilk adım veri kaynağını belirtmektir. Çoğu C# programlama dilinde olduğu gibi, kullanılmadan
önce bir değişken bildirilmelidir. LINQ sorgusunda, veri kaynağını ( customers ) ve Aralık değişkenini ( cust )
tanıtmak için ilk olarak from yan tümcesi gelir.

//queryAllCustomers is an IEnumerable<Customer>
var queryAllCustomers = from cust in customers
select cust;

Aralık değişkeni, bir sorgu ifadesinde hiçbir gerçek yineleme gerçekleşmedikçe, bir foreach döngüsünde yineleme
değişkeni gibidir. Sorgu yürütüldüğünde, Aralık değişkeni customers art arda her bir öğeye başvuru olarak görev
yapar. Derleyici cust türünü çıkarsanbildiğinden, açıkça belirtmeniz gerekmez. Ek Aralık değişkenleri, bir let yan
tümcesi tarafından tanıtılamaz. Daha fazla bilgi için bkz. Let yan tümcesi.

NOTE
ArrayListgibi genel olmayan veri kaynakları için, Aralık değişkeni açıkça yazılmalıdır. Daha fazla bilgi için bkz. nasıl yapılır: bir
ArrayList 'i LINQ (C#) ve from yan tümcesiile sorgulama.

Filtreleme
Büyük olasılıkla en yaygın sorgu işlemi, bir filtrenin Boole ifadesi biçiminde uygulanmasından kaynaklanıyor
olabilir. Filtre sorgunun yalnızca ifadenin true olduğu öğeleri döndürmesine neden olur. Sonuç, where yan tümcesi
kullanılarak oluşturulur. Etkin filtre, kaynak sırasından hangi öğelerin dışlanacağını belirtir. Aşağıdaki örnekte,
yalnızca Londra 'da bir adrese sahip olan customers döndürülür.

var queryLondonCustomers = from cust in customers


where cust.City == "London"
select cust;

Tanıdık C# mantıksal AND ve OR işleçlerini where yan tümcesinde gereken sayıda filtre ifadesi uygulamak için
kullanabilirsiniz. Örneğin, yalnızca "Istanbul" AND , adı "Devon" olan müşterileri döndürmek için aşağıdaki kodu
yazarsınız:

where cust.City=="London" && cust.Name == "Devon"

Londra veya Paris 'ten müşterileri döndürmek için aşağıdaki kodu yazarsınız:

where cust.City == "London" || cust.City == "Paris"

Daha fazla bilgi için bkz. WHERE yan tümcesi.

Sıralama
Genellikle döndürülen verileri sıralamak uygundur. orderby yan tümcesi, döndürülen dizideki öğelerin
sıralanmakta olan türün varsayılan karşılaştırmasına göre sıralanmasına neden olur. Örneğin, aşağıdaki sorgu,
Name özelliğine göre sonuçları sıralamak için genişletilebilir. Name bir dize olduğundan, varsayılan karşılaştırıcı, A
'dan Z 'ye alfabetik bir sıralama gerçekleştirir.

var queryLondonCustomers3 =
from cust in customers
where cust.City == "London"
orderby cust.Name ascending
select cust;

Sonuçları Z 'den A 'ya doğru sırada sıralamak için orderby…descending yan tümcesini kullanın.
Daha fazla bilgi için bkz. OrderBy tümcesi.

Gruplandırma
group yan tümcesi, sonuçlarınızı belirttiğiniz bir anahtara göre gruplandırmanızı sağlar. Örneğin, Londra veya
Paris 'teki tüm müşterilerin ayrı gruplar halinde olması için sonuçların City göre gruplanmasını belirtebilirsiniz.
Bu durumda, cust.City anahtardır.

// queryCustomersByCity is an IEnumerable<IGrouping<string, Customer>>


var queryCustomersByCity =
from cust in customers
group cust by cust.City;

// customerGroup is an IGrouping<string, Customer>


foreach (var customerGroup in queryCustomersByCity)
{
Console.WriteLine(customerGroup.Key);
foreach (Customer customer in customerGroup)
{
Console.WriteLine(" {0}", customer.Name);
}
}

Bir group yan tümcesiyle bir sorgu sonlandırdığınızda, sonuçlarınız bir liste listesi biçimini alır. Listedeki her öğe,
bir Key üyesine ve bu anahtar altında gruplanmış öğelerin listesine sahip olan bir nesnedir. Bir grup dizisi üreten
bir sorgu üzerinde yineleme yaparken, iç içe geçmiş bir foreach döngüsü kullanmanız gerekir. Dış döngü her grup
üzerinde yinelenir ve iç döngü her bir grubun üyesi üzerinde yinelenir.
Bir grup işleminin sonuçlarına başvurmanız gerekirse, daha fazla sorgulanabilecek bir tanımlayıcı oluşturmak için
into anahtar sözcüğünü kullanabilirsiniz. Aşağıdaki sorgu yalnızca ikiden fazla müşteri içeren grupları döndürür:

// custQuery is an IEnumerable<IGrouping<string, Customer>>


var custQuery =
from cust in customers
group cust by cust.City into custGroup
where custGroup.Count() > 2
orderby custGroup.Key
select custGroup;

Daha fazla bilgi için bkz. Group yan tümcesi.

Katılma
JOIN işlemleri, veri kaynaklarında açıkça Modellenmemiş diziler arasında ilişkiler oluşturur. Örneğin, aynı konuma
sahip tüm müşterileri ve dağıtımcıları bulmak için bir JOIN işlemi gerçekleştirebilirsiniz. LINQ join yan tümcesi
her zaman doğrudan veritabanı tabloları yerine nesne koleksiyonlarına göre geçerlidir.

var innerJoinQuery =
from cust in customers
join dist in distributors on cust.City equals dist.City
select new { CustomerName = cust.Name, DistributorName = dist.Name };

LINQ, LINQ yabancı anahtarları nesne modelinde bir öğe koleksiyonu tutan özellikler olarak temsil ettiğinden,
SQL 'de yaptığınız gibi join kullanmak zorunda değilsiniz. Örneğin, bir Customer nesnesi bir Order nesneleri
koleksiyonu içerir. Bir JOIN gerçekleştirmek yerine, siparişe nokta gösterimini kullanarak erişirsiniz:

from order in Customer.Orders...

Daha fazla bilgi için bkz. JOIN yan tümcesi.

Seçme (Tahminler)
select yan tümcesi sorgunun sonuçlarını üretir ve döndürülen her öğenin "şeklini" veya türünü belirtir. Örneğin,
sonuçlarınızın tam Customer nesneleri, yalnızca bir üye, bir üye alt kümesi veya bir hesaplama ya da yeni nesne
oluşturmaya göre tamamen farklı sonuç türü olacağını belirtebilirsiniz. select yan tümcesi kaynak öğenin bir
kopyası dışında bir şey üretirse, işleme bir projeksiyonolarak adlandırılır. Verileri dönüştürmek için projeksiyonun
kullanımı, LINQ sorgu ifadelerinin güçlü bir özelliğidir. Daha fazla bilgi için bkz. LINQ (C#) ve Select yan
tümcesiyleveri dönüştürmeleri.

Ayrıca bkz.
LINQ sorgu Ifadeleri
İzlenecek yol: sorguları yazmaC#
Sorgu anahtar sözcükleri (LINQ )
Anonim Tipler
LINQ ile Veri Dönüştürmeler (C#)
4.11.2019 • 7 minutes to read • Edit Online

Dil ile Tümleşik Sorgu (LINQ ) yalnızca verileri alma hakkında değildir. Ayrıca, verileri dönüştürmek için güçlü bir
araçtır. Bir LINQ sorgusu kullanarak, giriş olarak bir kaynak sırası kullanabilir ve yeni bir çıkış sırası oluşturmak
için bunu birçok şekilde değiştirebilirsiniz. Sıralamayı sıralama ve gruplama yoluyla öğeleri değiştirmeden
değiştirebilirsiniz. Ancak, LINQ sorgularının en güçlü özelliği yeni türler oluşturma olanağıdır. Bu, Select yan
tümcesinde gerçekleştirilir. Örneğin, aşağıdaki görevleri gerçekleştirebilirsiniz:
Birden çok giriş dizisini yeni bir türe sahip tek bir çıkış dizisinde birleştirin.
Öğeleri, kaynak dizideki her öğenin yalnızca bir veya birkaç özelliklerinden oluşan çıkış dizileri oluşturun.
Öğeleri, kaynak verilerde gerçekleştirilen işlemlerin sonuçlarından oluşan çıkış dizileri oluşturun.
Çıkış dizilerini farklı biçimde oluşturun. Örneğin, verileri SQL satırlarından veya metin dosyalarından XML
'e dönüştürebilirsiniz.
Bunlar yalnızca birkaç örnektir. Tabii ki, bu dönüşümler aynı sorgudaki çeşitli şekillerde birleştirilebilir. Ayrıca, bir
sorgunun çıkış sırası yeni bir sorgu için giriş sırası olarak kullanılabilir.

Birden Çok Girdiyi Bir Çıkış Sırasına Katma


Birden fazla giriş dizisinin öğelerini içeren bir çıkış sırası oluşturmak için LINQ bir sorgu kullanabilirsiniz.
Aşağıdaki örnek, iki bellek içi veri yapısının nasıl birleştirileceğini gösterir, ancak aynı ilkeler XML veya SQL veya
veri kümesi kaynaklarından verileri birleştirmek için uygulanabilir. Aşağıdaki iki sınıf türünü varsayın:

class Student
{
public string First { get; set; }
public string Last {get; set;}
public int ID { get; set; }
public string Street { get; set; }
public string City { get; set; }
public List<int> Scores;
}

class Teacher
{
public string First { get; set; }
public string Last { get; set; }
public int ID { get; set; }
public string City { get; set; }
}

Aşağıdaki örnekte sorgu gösterilmektedir:


class DataTransformations
{
static void Main()
{
// Create the first data source.
List<Student> students = new List<Student>()
{
new Student { First="Svetlana",
Last="Omelchenko",
ID=111,
Street="123 Main Street",
City="Seattle",
Scores= new List<int> { 97, 92, 81, 60 } },
new Student { First="Claire",
Last="O’Donnell",
ID=112,
Street="124 Main Street",
City="Redmond",
Scores= new List<int> { 75, 84, 91, 39 } },
new Student { First="Sven",
Last="Mortensen",
ID=113,
Street="125 Main Street",
City="Lake City",
Scores= new List<int> { 88, 94, 65, 91 } },
};

// Create the second data source.


List<Teacher> teachers = new List<Teacher>()
{
new Teacher { First="Ann", Last="Beebe", ID=945, City="Seattle" },
new Teacher { First="Alex", Last="Robinson", ID=956, City="Redmond" },
new Teacher { First="Michiyo", Last="Sato", ID=972, City="Tacoma" }
};

// Create the query.


var peopleInSeattle = (from student in students
where student.City == "Seattle"
select student.Last)
.Concat(from teacher in teachers
where teacher.City == "Seattle"
select teacher.Last);

Console.WriteLine("The following students and teachers live in Seattle:");


// Execute the query.
foreach (var person in peopleInSeattle)
{
Console.WriteLine(person);
}

Console.WriteLine("Press any key to exit.");


Console.ReadKey();
}
}
/* Output:
The following students and teachers live in Seattle:
Omelchenko
Beebe
*/

Daha fazla bilgi için bkz. JOIN yan tümcesi ve Select yan tümcesi.

Her Kaynak Öğesinin alt kümesini seçme


Kaynak dizideki her bir öğenin alt kümesini seçmek için iki temel yol vardır:
1. Kaynak öğenin yalnızca bir üyesini seçmek için, nokta işlemini kullanın. Aşağıdaki örnekte, bir Customer
nesnesinin City adlı bir dize de dahil olmak üzere birkaç ortak özellik içerdiğini varsayın. Yürütüldüğünde,
bu sorgu dizelerin çıkış dizisini üretir.

var query = from cust in Customers


select cust.City;

2. Kaynak öğeden birden fazla özellik içeren öğeler oluşturmak için, bir nesne başlatıcısını adlandırılmış bir
nesne veya anonim bir türle birlikte kullanabilirsiniz. Aşağıdaki örnek, her bir Customer öğesinden iki
özelliği kapsüllemek için anonim bir türün kullanımını gösterir:

var query = from cust in Customer


select new {Name = cust.Name, City = cust.City};

Daha fazla bilgi için bkz. nesne ve koleksiyon başlatıcıları ve anonim türler.

Bellek İçi Nesneleri XML'e dönüştürme


LINQ sorguları, bellek içi veri yapıları, SQL veritabanları, ADO.NET veri kümeleri ve XML akışları veya belgeler
arasında veri dönüştürmeyi kolaylaştırır. Aşağıdaki örnek, bellek içi veri yapısındaki nesneleri XML öğelerine
dönüştürür.

class XMLTransform
{
static void Main()
{
// Create the data source by using a collection initializer.
// The Student class was defined previously in this topic.
List<Student> students = new List<Student>()
{
new Student {First="Svetlana", Last="Omelchenko", ID=111, Scores = new List<int>{97, 92, 81,
60}},
new Student {First="Claire", Last="O’Donnell", ID=112, Scores = new List<int>{75, 84, 91, 39}},
new Student {First="Sven", Last="Mortensen", ID=113, Scores = new List<int>{88, 94, 65, 91}},
};

// Create the query.


var studentsToXML = new XElement("Root",
from student in students
let scores = string.Join(",", student.Scores)
select new XElement("student",
new XElement("First", student.First),
new XElement("Last", student.Last),
new XElement("Scores", scores)
) // end "student"
); // end "Root"

// Execute the query.


Console.WriteLine(studentsToXML);

// Keep the console open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}

Kod aşağıdaki XML çıktısını üretir:


<Root>
<student>
<First>Svetlana</First>
<Last>Omelchenko</Last>
<Scores>97,92,81,60</Scores>
</student>
<student>
<First>Claire</First>
<Last>O'Donnell</Last>
<Scores>75,84,91,39</Scores>
</student>
<student>
<First>Sven</First>
<Last>Mortensen</Last>
<Scores>88,94,65,91</Scores>
</student>
</Root>

Daha fazla bilgi için bkz. XML ağaçlarını oluşturma C# (LINQ to XML ).

Kaynak Öğeler Üzerinde İşlemler Gerçekleştirme


Çıkış sırası, kaynak dizisinden herhangi bir öğe veya öğe özelliği içermeyebilir. Çıktı bunun yerine, kaynak öğeleri
giriş bağımsız değişkenleri olarak kullanılarak hesaplanan bir değer dizisi olabilir. Aşağıdaki basit sorgu
yürütüldüğünde, değerleri, double türündeki öğelerin kaynak dizisine göre hesaplamayı temsil eden bir dize dizisi
çıkarır.

NOTE
Sorgu başka bir etki alanına çevrilecektir sorgu ifadelerinde çağırma yöntemi desteklenmez. Örneğin, SQL Server hiçbir
bağlamı olmadığından LINQ - SQL sıradan C# bir yöntem çağrılamaz. Ancak, saklı yordamları yöntemlere eşleyebilir ve
bunları çağırabilirsiniz. Daha fazla bilgi için bkz. saklı yordamlar.

class FormatQuery
{
static void Main()
{
// Data source.
double[] radii = { 1, 2, 3 };

// Query.
IEnumerable<string> query =
from rad in radii
select $"Area = {rad * rad * Math.PI:F2}";

// Query execution.
foreach (string s in query)
Console.WriteLine(s);

// Keep the console open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* Output:
Area = 3.14
Area = 12.57
Area = 28.27
*/
Ayrıca bkz.
Dil ile tümleşik sorgu (LINQ ) (C#)
LINQ to SQL
LINQ to DataSet
LINQ to XML (C#)
LINQ sorgu Ifadeleri
select yan tümcesi
LINQ Sorgu İşlemlerinde Tür İlişkileri (C#)
23.10.2019 • 4 minutes to read • Edit Online

Sorguları etkili bir şekilde yazmak için, bir bütün sorgu işlemindeki değişkenlerin türlerinin birbirleriyle ilişkisini
anlamalısınız. Bu ilişkileri anladıysanız, belgelerde LINQ örnekleri ve kod örneklerini daha kolay anlarsınız.
Ayrıca, değişkenler, kullanılarak var örtük olarak yazıldığında ne olduğunu anlamış olursunuz.
LINQsorgu işlemleri veri kaynağında, sorgunun kendisinde ve sorgu yürütmesinde kesin olarak türdedir.
Sorgudaki değişkenlerin türü, veri kaynağındaki öğelerin türüyle ve foreach deyimdeki yineleme değişkeni
türüyle uyumlu olmalıdır). Bu güçlü yazma, tür hatalarının Kullanıcı tarafından karşılaşmadan önce
düzeltilebilecekleri derleme zamanında yakalanmasını güvence altına alır.
Bu tür ilişkilerini göstermek için, aşağıdaki örneklerin çoğu tüm değişkenler için açık yazma kullanır. Son örnek,
varkullanarak örtük yazma kullandığınızda bile aynı ilkelerin nasıl uygulanacağını gösterir.

Kaynak verileri dönüştürmeksizin sorgular


Aşağıdaki çizimde, verilerde dönüştürme LINQ gerçekleştirmeyen bir nesneler sorgu işlemi gösterilmektedir.
Kaynak bir dize dizisi içerir ve sorgu çıktısı da dizeler dizisidir.

1. Veri kaynağının tür bağımsız değişkeni, Aralık değişkeninin türünü belirler.


2. Seçilen nesnenin türü, sorgu değişkeninin türünü belirler. İşte name bir dize. Bu nedenle, sorgu değişkeni
bir IEnumerable<string> .
3. Sorgu değişkeni, foreach ifadesinde tekrarlanıyor. Sorgu değişkeni bir dizeler dizisi olduğundan,
yineleme değişkeni de bir dizedir.

Kaynak verileri dönüştüren sorgular


Aşağıdaki çizimde, verilerde basit LINQ - SQL bir dönüşüm gerçekleştiren bir sorgu işlemi gösterilmektedir.
Sorgu, giriş olarak bir dizi Customer nesne alır ve Name yalnızca sonuç içindeki özelliği seçer. Name Bir dize
olduğundan, sorgu çıktı olarak bir dize dizisi üretir.
1. Veri kaynağının tür bağımsız değişkeni, Aralık değişkeninin türünü belirler.
2. İfade, tüm Customer nesne yerine özelliği döndürür.
Name select Bir dize olduğundan, custNameQuery
Customer öğesinin tür bağımsız değişkeni değildir. string Name

3. Bir dize dizisi olduğundan foreach , döngünün yineleme değişkeni de bir string olmalıdır.
custNameQuery

Aşağıdaki çizimde biraz daha karmaşık bir dönüştürme gösterilmektedir. İfade, özgün Customer nesnenin
yalnızca iki üyesini yakalayan bir anonim tür döndürür. select

1. Veri kaynağının tür bağımsız değişkeni her zaman sorgudaki aralık değişkeninin türüdür.
2. İfade anonim bir tür oluşturduğundan, sorgu değişkeninin kullanılarak var örtük olarak yazılması
gerekir. select
3. Sorgu değişkeninin türü örtük olduğundan, foreach döngüdeki yineleme değişkeni de örtük olmalıdır.

Derleyicinin tür bilgilerini çıkarmalarına izin verme


Bir sorgu işlemindeki tür ilişkilerini anlamanız gerekse de, derleyicinin tüm işleri gerçekleştirmesini sağlamak
için seçeneğiniz vardır. Var anahtar sözcüğü, bir sorgu işlemindeki herhangi bir yerel değişken için kullanılabilir.
Aşağıdaki çizim, daha önce açıklanan örnek numarası 2 ' ye benzer. Ancak, derleyici sorgu işlemindeki her
değişken için güçlü tür sağlar.
Hakkında var daha fazla bilgi için bkz. örtülü olarak yazılan yerel değişkenler.
LINQ'te Sorgu Sözdizimi ve Yöntem Sözdizimi (C#)
23.10.2019 • 7 minutes to read • Edit Online

Giriş dili tümleşik sorgu (LINQ ) belgelerindeki çoğu sorgu LINQ bildirime dayalı sorgu söz dizimi kullanılarak
yazılır. Ancak, kod derlendiğinde, sorgu söz dizimi .NET ortak dil çalışma zamanı (CLR ) için yöntem çağrılarına
çevrilmelidir. Bu Where Yöntem Select , ,, Join ,, ve Average gibi adlara sahip standart sorgu işleçlerini çağırır.
GroupBy Max Sorgu söz dizimi yerine yöntemi sözdizimi kullanarak doğrudan çağırabilirsiniz.

Sorgu sözdizimi ve Yöntem sözdizimi anlam açısından aynıdır, ancak birçok kişi sorgu söz dizimini daha basit ve
okunması daha kolay bir şekilde bulur. Bazı sorgular Yöntem çağrıları olarak ifade etmelidir. Örneğin, belirli bir
koşulla eşleşen öğe sayısını alan bir sorgu ifade etmek için bir yöntem çağrısı kullanmanız gerekir. Ayrıca, bir
kaynak dizisinde en büyük değere sahip öğeyi alan bir sorgu için bir yöntem çağrısı kullanmanız gerekir.
System.Linq Ad alanındaki standart sorgu işleçleri için başvuru belgeleri genellikle Yöntem sözdizimini kullanır.
Bu nedenle, sorgu yazmaya LINQ Başlarken bile, sorgularda ve sorgu ifadelerinde Yöntem sözdiziminin nasıl
kullanılacağına ilişkin bilgi sahibi olmak yararlı olacaktır.

Standart Sorgu İşleci Genişletme Yöntemleri


Aşağıdaki örnek, basit bir sorgu ifadesini ve Yöntem tabanlı sorguolarak yazılmış anlamsal olarak denk sorguyu
gösterir.
class QueryVMethodSyntax
{
static void Main()
{
int[] numbers = { 5, 10, 8, 3, 6, 12};

//Query syntax:
IEnumerable<int> numQuery1 =
from num in numbers
where num % 2 == 0
orderby num
select num;

//Method syntax:
IEnumerable<int> numQuery2 = numbers.Where(num => num % 2 == 0).OrderBy(n => n);

foreach (int i in numQuery1)


{
Console.Write(i + " ");
}
Console.WriteLine(System.Environment.NewLine);
foreach (int i in numQuery2)
{
Console.Write(i + " ");
}

// Keep the console open in debug mode.


Console.WriteLine(System.Environment.NewLine);
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
}
/*
Output:
6 8 10 12
6 8 10 12
*/

İki örnekten alınan çıkış aynı. Sorgu değişkeninin türünün her iki formlarda de aynı olduğunu görebilirsiniz:
IEnumerable<T>.
Yöntem tabanlı sorguyu anlamak için daha yakından inceleyelim. İfadenin sağ tarafında, where yan tümcesinin
artık numbers nesne üzerinde bir örnek yöntemi olarak ifade ettiğini unutmayın IEnumerable<int> . Bu, geri
çekmenin bir türü olur. Genel IEnumerable<T> arabirime alışkın değilseniz, bir Where yöntemi olmadığını
bilirsiniz. Ancak, Visual Studio IDE 'de IntelliSense tamamlanma listesini çağırdığınızda yalnızca Where bir
yöntem değil,, ve Orderby gibi birçok başka yöntem Select SelectMany Join de görüntülenir. Bunlar standart
sorgu işleçleridir.

Bu ek yöntemleri dahil etmek IEnumerable<T> için yeniden tanımlanmış gibi görünse de, aslında bu durum
değildir. Standart sorgu işleçleri, genişletme yöntemleriolarak adlandırılan yeni bir yöntem türü olarak uygulanır.
Uzantı yöntemleri "genişletme" varolan bir tür; Bunlar, tür üzerinde örnek yöntemmiş gibi çağrılabilir. Standart
sorgu işleçleri genişletilir IEnumerable<T> ve bu, neden yazılabilir. numbers.Where(...)

Kullanmaya LINQbaşlamak için, aslında uzantı yöntemleri hakkında bilmeniz gereken her şey, doğru using
yönergeleri kullanarak bunları uygulamanızdaki kapsama getirme yöntemleridir. Uygulamanızın görünüm
noktasından, bir genişletme yöntemi ve normal bir örnek yöntemi aynıdır.
Uzantı yöntemleri hakkında daha fazla bilgi için bkz. Uzantı yöntemleri. Standart sorgu işleçleri hakkında daha
fazla bilgi için bkz. Standart sorgu IşleçlerineC#genel bakış (). LINQ - SQL Ve LINQ IEnumerable<T>gibi bazı
sağlayıcılar, kendi standart sorgu işleçlerini ve diğer türler için ek genişletme yöntemlerini uygular. LINQ - XML

Lambda İfadeleri
Önceki örnekte, koşullu ifadenin ( num % 2 == 0 ) Where yönteme bir satır içi bağımsız değişken olarak geçtiğini
unutmayın: Where(num => num % 2 == 0). Bu satır içi ifadeye lambda ifadesi denir. Başka türlü bir anonim
yöntem veya bir genel temsilci ya da bir ifade ağacı olarak daha az sayıda biçimde yazılması gereken kodu
yazmak için kullanışlı bir yoldur. ' C# => De, "gider" olarak okunan lambda işleçtir. İşlecinin sol tarafındaki giriş
değişkeni sorgu ifadesinde öğesine num karşılık gelir. num Derleyici, genel num numbers
birtürolduğunubildiğindenIEnumerable<T> , türünü çıkarabilir. Lambda gövdesi sorgu söz dizimi ya da başka
C# bir ifade ya da deyimde yalnızca ifadesiyle aynıdır; Bu, Yöntem çağrılarını ve diğer karmaşık mantığı
içerebilir. "Dönüş değeri" yalnızca ifade sonucudur.
Kullanmaya LINQbaşlamak için lambdaları yoğun bir şekilde kullanmanız gerekmez. Ancak bazı sorgular
yalnızca Yöntem söz dizimine ve bu öğelerden bazıları lambda ifadeleri gerektirir. Lambdalar hakkında daha
tanıdık olduktan sonra, LINQ araç kutusu 'nda güçlü ve esnek bir araç olduğunu fark edersiniz. Daha fazla bilgi
için bkz. lambda ifadeleri.

Sorgu Oluşturabilirliği
Önceki kod örneğinde, OrderBy yönteminin, Where çağrısı üzerindeki nokta operatörü kullanılarak çağrılacağını
unutmayın. Where filtrelenmiş bir sıra üretir ve sonra Orderby bu dizi üzerinde sıralama yaparak çalışır.
Sorgular bir IEnumerable döndürdüğü için, Yöntem çağrılarını birlikte zincirleyerek yöntem sözdiziminde
oluşturursunuz. Sorgu söz dizimini kullanarak sorgular yazdığınızda derleyicinin arka planda yaptığı şeydir. Bir
sorgu değişkeni sorgunun sonuçlarını depolamadığından, bunu değiştirebilir veya herhangi bir zamanda yeni
bir sorgu için temel olarak kullanabilirsiniz.
LINQ'i Destekleyen C# Özellikleri
4.11.2019 • 6 minutes to read • Edit Online

Aşağıdaki bölümde 3,0 sürümünde C# tanıtılan yeni dil yapıları tanıtılmaktadır. Bu yeni özelliklerin tümü LINQ
sorgularıyla bir dereceye kadar kullanılsa da, LINQ bunlarla sınırlı değildir ve yararlı bulduğunuz herhangi bir
bağlamda kullanılabilir.

Sorgu İfadeleri
Sorgu ifadeleri, IEnumerable koleksiyonlarını sorgulamak için SQL veya XQuery ile benzer bir bildirime dayalı
sözdizimi kullanır. Derleme zamanı sorgu söz dizimi, bir LINQ sağlayıcının standart sorgu işleci genişletme
yöntemlerinin uygulamasına olan yöntem çağrılarına dönüştürülür. Uygulamalar, using yönergesi ile uygun ad
alanını belirterek kapsamdaki standart sorgu işleçlerini denetler. Aşağıdaki sorgu ifadesi bir dize dizisi alır, bunları
dizedeki ilk karaktere göre gruplandırır ve grupları sıralar.

var query = from str in stringArray


group str by str[0] into stringGroup
orderby stringGroup.Key
select stringGroup;

Daha fazla bilgi için bkz. LINQ sorgu ifadeleri.

Örtük olarak yazılan değişkenler (var)


Bir değişkeni bildirdiğinizde ve başlattığınızda açıkça bir tür belirtmek yerine, derleyicinin türü çıkarması ve
atamasını bildirmek için, burada gösterildiği gibi var değiştiricisini kullanabilirsiniz:

var number = 5;
var name = "Virginia";
var query = from str in stringArray
where str[0] == 'm'
select str;

var olarak belirtilen değişkenler, türü açıkça belirttiğiniz değişkenler olarak kesin olarak türdedir. var kullanımı
anonim türler oluşturmayı mümkün kılar, ancak yalnızca yerel değişkenler için kullanılabilir. Diziler, örtük yazma ile
de bildirilemez.
Daha fazla bilgi için bkz. örtülü olarak yazılan yerel değişkenler.

Nesne ve Koleksiyon Başlatıcıları


Nesne ve koleksiyon başlatıcıları nesne için bir oluşturucu açıkça çağrılmadan nesneleri başlatmayı mümkün hale
getirir. Başlatıcılar, genellikle, kaynak verileri yeni bir veri türüne proje yaparken sorgu ifadelerinde kullanılır. Ortak
Name ve Phone özellikleriyle Customer adlı bir sınıf kabul edildiğinde, nesne Başlatıcısı aşağıdaki kodda olduğu
gibi kullanılabilir:

var cust = new Customer { Name = "Mike", Phone = "555-1212" };

Customer sınıfınız ile devam ederek, IncomingOrders adlı bir veri kaynağı olduğunu ve her bir sipariş için büyük bir
OrderSize olan her sıra için bu siparişi temel alan yeni bir Customer oluşturmak istediğinizi varsayalım. Bir LINQ
sorgusu bu veri kaynağında yürütülebilir ve bir koleksiyonu doldurarak nesne başlatma işlemi kullanılabilir:

var newLargeOrderCustomers = from o in IncomingOrders


where o.OrderSize > 5
select new Customer { Name = o.Name, Phone = o.Phone };

Veri kaynağı, OrderSize gibi Customer sınıftan çok daha fazla özelliğe sahip olabilir, ancak nesne başlatma ile,
sorgudan döndürülen veriler istenen veri türüne kopyalanır; sınıfımızla ilgili verileri seçtik. Sonuç olarak, şimdi
yaptığımız yeni Customer s IEnumerable . Yukarıdaki, LINQ yöntem sözdiziminde de yazılabilir:

var newLargeOrderCustomers = IncomingOrders.Where(x => x.OrderSize > 5).Select(y => new Customer { Name =
y.Name, Phone = y.Phone });

Daha fazla bilgi için bkz.:


Nesne ve Koleksiyon Başlatıcıları
Standart Sorgu İşleçleri için Sorgu İfade Sözdizimi

Anonim Türler
Anonim bir tür derleyici tarafından oluşturulur ve tür adı yalnızca derleyici tarafından kullanılabilir. Anonim türler,
farklı bir adlandırılmış tür tanımlamak zorunda kalmadan bir özellik kümesini geçici olarak bir sorgu sonucuyla
gruplamak için kullanışlı bir yol sağlar. Anonim türler aşağıda gösterildiği gibi yeni bir ifadeyle ve bir nesne
başlatıcısıyla başlatılır:

select new {name = cust.Name, phone = cust.Phone};

Daha fazla bilgi için bkz. anonim türler.

Genişletme Yöntemleri
Uzantı yöntemi, bir tür ile ilişkilendirilebilen statik bir yöntemdir ve bu sayede tür üzerinde bir örnek yöntemi gibi
çağrılabilir. Bu özellik, etkin bir şekilde, var olan türlere "Ekle" gibi yeni yöntemler eklemenizi sağlar. Standart sorgu
işleçleri, IEnumerable<T>uygulayan her tür için LINQ sorgu işlevselliği sağlayan bir genişletme yöntemleri
kümesidir.
Daha fazla bilgi için bkz. Uzantı yöntemleri.

Lambda İfadeleri
Lambda ifadesi, işlev gövdesinden giriş parametrelerini ayırmak için = > işlecini kullanan ve derleme zamanında
bir temsilciye veya bir ifade ağacına dönüştürülebilen bir satır içi işlevdir. LINQ programlamada, standart sorgu
işleçleri için doğrudan Yöntem çağrıları yaptığınızda lambda ifadeleriyle karşılaşacaksınız.
Daha fazla bilgi için bkz.:
Anonim İşlevler
Lambda İfadeleri
İfade ağaçları (C#)

Ayrıca bkz.
Dil ile tümleşik sorgu (LINQ ) (C#)
İzlenecek yol: C#'de Sorgu Yazma (LINQ)
4.11.2019 • 15 minutes to read • Edit Online

Bu izlenecek yol, C# LINQ sorgu ifadeleri yazmak için kullanılan dil özelliklerini gösterir.

Bir C# Projesi Oluşturma


NOTE
Aşağıdaki yönergeler Visual Studio içindir. Farklı bir geliştirme ortamı kullanıyorsanız, System. Core. dll başvurusu ve
System.Linq ad alanı için bir using yönergesine sahip bir konsol projesi oluşturun.

Visual Studio 'da bir proje oluşturmak için


1. Visual Studio 'Yu başlatın.
2. Menü çubuğunda Dosya, Yeni, Proje' yi seçin.
Yeni proje iletişim kutusu açılır.
3. Yüklü' i genişletin, Şablonlar' ı genişletin, C#görsel' i genişletin ve konsol uygulaması' nı
4. Ad metin kutusuna, farklı bir ad girin veya varsayılan adı kabul edin ve Tamam düğmesini seçin.
Yeni proje Çözüm Gezginigörüntülenir.
5. Projenizin System. Core. dll dosyasına ve System.Linq ad alanı için bir using yönergesine başvurduğuna
dikkat edin.

Bellek İçi Veri Kaynağı Oluşturma


Sorgular için veri kaynağı Student nesnelerinin basit bir listesidir. Her Student kaydı, sınıf içindeki test puanlarını
temsil eden bir ad, soyadı ve bir tamsayılar dizisi içerir. Bu kodu projenize kopyalayın. Aşağıdaki özelliklere göz
önünde edin:
Student sınıfı otomatik uygulanan özelliklerden oluşur.
Listedeki her öğrenci bir nesne başlatıcısı ile başlatılır.
Listenin kendisi bir koleksiyon başlatıcısı ile başlatılır.
Bu bütün veri yapısı, herhangi bir oluşturucuya veya açık üye erişimine açık çağrılar olmadan başlatılır ve
oluşturulur. Bu yeni özellikler hakkında daha fazla bilgi için bkz. Otomatik uygulanan özellikler ve nesne ve
koleksiyon başlatıcıları.
Veri kaynağını eklemek için
Student sınıfını ve başlatılan öğrenciler listesini projenizdeki Program sınıfına ekleyin.
public class Student
{
public string First { get; set; }
public string Last { get; set; }
public int ID { get; set; }
public List<int> Scores;
}

// Create a data source by using a collection initializer.


static List<Student> students = new List<Student>
{
new Student {First="Svetlana", Last="Omelchenko", ID=111, Scores= new List<int> {97, 92, 81, 60}},
new Student {First="Claire", Last="O'Donnell", ID=112, Scores= new List<int> {75, 84, 91, 39}},
new Student {First="Sven", Last="Mortensen", ID=113, Scores= new List<int> {88, 94, 65, 91}},
new Student {First="Cesar", Last="Garcia", ID=114, Scores= new List<int> {97, 89, 85, 82}},
new Student {First="Debra", Last="Garcia", ID=115, Scores= new List<int> {35, 72, 91, 70}},
new Student {First="Fadi", Last="Fakhouri", ID=116, Scores= new List<int> {99, 86, 90, 94}},
new Student {First="Hanying", Last="Feng", ID=117, Scores= new List<int> {93, 92, 80, 87}},
new Student {First="Hugo", Last="Garcia", ID=118, Scores= new List<int> {92, 90, 83, 78}},
new Student {First="Lance", Last="Tucker", ID=119, Scores= new List<int> {68, 79, 88, 92}},
new Student {First="Terry", Last="Adams", ID=120, Scores= new List<int> {99, 82, 81, 79}},
new Student {First="Eugene", Last="Zabokritski", ID=121, Scores= new List<int> {96, 85, 91, 60}},
new Student {First="Michael", Last="Tucker", ID=122, Scores= new List<int> {94, 92, 91, 91}}
};

Öğrenciler listesine yeni bir Öğrenci eklemek için


1. Students listesine yeni bir Student ekleyin ve tercih ettiğiniz bir ad ve test puanlarını kullanın. Nesne
başlatıcısının sözdizimini daha iyi öğrenmek için tüm yeni öğrenci bilgilerini yazmayı deneyin.

Sorgu Oluşturma
Basit bir sorgu oluşturmak için
Uygulamanın Main yönteminde, ilk testteki puanı 90 'den büyük olan tüm öğrencilerin bir listesini
üretecek basit bir sorgu oluşturun. Student nesnesinin tamamı seçili olduğundan, sorgunun türü
IEnumerable<Student> . Kod aynı zamanda var anahtar sözcüğünü kullanarak örtük yazma da kullanabilir,
ancak sonuçları açıkça göstermek için açık yazma kullanılır. ( var hakkında daha fazla bilgi için bkz. örtülü
olarak yazılan yerel değişkenler.)
Ayrıca, sorgunun Aralık değişkeni student , kaynaktaki her bir Student başvuru işlevi görür ve her nesne
için üye erişimi sağlar.

// Create the query.


// The first line could also be written as "var studentQuery ="
IEnumerable<Student> studentQuery =
from student in students
where student.Scores[0] > 90
select student;

Sorguyu Yürütme
Sorguyu yürütmek için
1. Şimdi sorgunun yürütülmesine neden olacak foreach döngüsünü yazın. Kod hakkında aşağıdakilere göz
önünde edin:
Döndürülen dizideki her öğeye, foreach döngüsünde yineleme değişkeni üzerinden erişilir.
Bu değişkenin türü Student ve sorgu değişkeninin türü uyumlu, IEnumerable<Student> .
2. Bu kodu ekledikten sonra, sonuçları konsol penceresinde görmek için uygulamayı derleyin ve çalıştırın.
// Execute the query.
// var could be used here also.
foreach (Student student in studentQuery)
{
Console.WriteLine("{0}, {1}", student.Last, student.First);
}

// Output:
// Omelchenko, Svetlana
// Garcia, Cesar
// Fakhouri, Fadi
// Feng, Hanying
// Garcia, Hugo
// Adams, Terry
// Zabokritski, Eugene
// Tucker, Michael

Başka bir filtre koşulu eklemek için


1. Bir sorguyu daha da belirginleştirmek için where yan tümcesinde birden çok Boolean koşulu
birleştirebilirsiniz. Aşağıdaki kod, sorgunun ilk puanı 90 üzerinde olan ve son puanı 80 ' den az olan bu
öğrencileri döndüren bir koşul ekler. where yan tümcesi aşağıdaki koda benzemelidir.

where student.Scores[0] > 90 && student.Scores[3] < 80

Daha fazla bilgi için bkz. WHERE yan tümcesi.

Sorguyu Değiştirme
Sonuçları sıralamak için
1. Belirli bir sıra türünde olmaları durumunda sonuçların taranması daha kolay olacaktır. Döndürülen sırayı,
kaynak öğelerde erişilebilir olan herhangi bir alana göre sıraya alabilirsiniz. Örneğin, aşağıdaki orderby
yan tümcesi sonuçları alfabetik sırada her öğrencinin son adına göre bir ile Z 'ye sıralar. Sorgunuz için
aşağıdaki orderby yan tümcesini, where deyiminize ve select deyimden önce ekleyin:

orderby student.Last ascending

2. Şimdi orderby yan tümcesini, en yüksek puanın en düşük puanına kadar ilk testteki puana göre ters sırada
sipariş verecek şekilde değiştirin.

orderby student.Scores[0] descending

3. Puanları görebilmeniz için WriteLine biçim dizesini değiştirin:

Console.WriteLine("{0}, {1} {2}", student.Last, student.First, student.Scores[0]);

Daha fazla bilgi için bkz. OrderBy tümcesi.


Sonuçları gruplandırmak için
1. Gruplandırma, sorgu ifadelerinde güçlü bir özelliktir. Group yan tümcesi içeren bir sorgu bir grup sırası
üretir ve her bir grubun kendisi bir Key ve bu grubun tüm üyelerinden oluşan bir dizi içerir. Aşağıdaki yeni
sorgu, en son adının ilk harfini anahtar olarak kullanarak öğrencileri gruplandırır.
// studentQuery2 is an IEnumerable<IGrouping<char, Student>>
var studentQuery2 =
from student in students
group student by student.Last[0];

2. Sorgu türünün artık değiştiğini unutmayın. Artık anahtar olarak char türüne ve Student nesne dizisine
sahip bir grup sırası oluşturur. Sorgunun türü değiştiği için aşağıdaki kod foreach yürütme döngüsünü de
değiştirir:

// studentGroup is a IGrouping<char, Student>


foreach (var studentGroup in studentQuery2)
{
Console.WriteLine(studentGroup.Key);
foreach (Student student in studentGroup)
{
Console.WriteLine(" {0}, {1}",
student.Last, student.First);
}
}

// Output:
// O
// Omelchenko, Svetlana
// O'Donnell, Claire
// M
// Mortensen, Sven
// G
// Garcia, Cesar
// Garcia, Debra
// Garcia, Hugo
// F
// Fakhouri, Fadi
// Feng, Hanying
// T
// Tucker, Lance
// Tucker, Michael
// A
// Adams, Terry
// Z
// Zabokritski, Eugene

3. Uygulamayı çalıştırın ve sonuçları konsol penceresinde görüntüleyin.


Daha fazla bilgi için bkz. Group yan tümcesi.
Değişkenlerin dolaylı olarak yazılmasını sağlamak için
1. IGroupings IEnumerables açıkça kodlanması hızla sıkıcı hale gelebilir. var kullanarak aynı sorgu ve
foreach döngüsünü çok daha kolay bir şekilde yazabilirsiniz. var anahtar sözcüğü, nesnelerinizin türlerini
değiştirmez; yalnızca derleyiciye tür çıkarması talimatını verir. studentQuery türünü ve group yineleme
değişkenini var olarak değiştirin ve sorguyu yeniden çalıştırın. Inner foreach döngüsünde, yineleme
değişkeninin hala Student olarak yazıldığı ve sorgunun daha önce olduğu gibi çalıştığından emin olmanız
gerektiğini unutmayın. s yineleme değişkenini var olarak değiştirip sorguyu yeniden çalıştırın. Tam
olarak aynı sonuçları elde edersiniz.
var studentQuery3 =
from student in students
group student by student.Last[0];

foreach (var groupOfStudents in studentQuery3)


{
Console.WriteLine(groupOfStudents.Key);
foreach (var student in groupOfStudents)
{
Console.WriteLine(" {0}, {1}",
student.Last, student.First);
}
}

// Output:
// O
// Omelchenko, Svetlana
// O'Donnell, Claire
// M
// Mortensen, Sven
// G
// Garcia, Cesar
// Garcia, Debra
// Garcia, Hugo
// F
// Fakhouri, Fadi
// Feng, Hanying
// T
// Tucker, Lance
// Tucker, Michael
// A
// Adams, Terry
// Z
// Zabokritski, Eugene

Varhakkında daha fazla bilgi için bkz. örtülü olarak yazılan yerel değişkenler.
Grupları anahtar değerlerine göre sıralamak için
1. Önceki sorguyu çalıştırdığınızda grupların alfabetik sırada olmadığına dikkat edin. Bunu değiştirmek için,
group yan tümcesinden sonra bir orderby yan tümcesi sağlamanız gerekir. Ancak, bir orderby yan
tümcesi kullanmak için, önce group yan tümcesi tarafından oluşturulan gruplara başvuru olarak hizmet
veren bir tanımlayıcıya ihtiyacınız vardır. Tanımlayıcıyı, aşağıdaki gibi into anahtar sözcüğünü kullanarak
sağlarsınız:
var studentQuery4 =
from student in students
group student by student.Last[0] into studentGroup
orderby studentGroup.Key
select studentGroup;

foreach (var groupOfStudents in studentQuery4)


{
Console.WriteLine(groupOfStudents.Key);
foreach (var student in groupOfStudents)
{
Console.WriteLine(" {0}, {1}",
student.Last, student.First);
}
}

// Output:
//A
// Adams, Terry
//F
// Fakhouri, Fadi
// Feng, Hanying
//G
// Garcia, Cesar
// Garcia, Debra
// Garcia, Hugo
//M
// Mortensen, Sven
//O
// Omelchenko, Svetlana
// O'Donnell, Claire
//T
// Tucker, Lance
// Tucker, Michael
//Z
// Zabokritski, Eugene

Bu sorguyu çalıştırdığınızda, grupların artık alfabetik sırada sıralanacağını görürsünüz.


Bir tanımlayıcıyı let kullanarak tanıtmak için
1. Sorgu ifadesindeki herhangi bir ifade sonucu için bir tanımlayıcı tanıtmak üzere let anahtar sözcüğünü
kullanabilirsiniz. Bu tanımlayıcı, aşağıdaki örnekte olduğu gibi kolaylık olabilir veya bir ifadenin sonuçlarını
birden çok kez hesaplanmak zorunda kalmayacak şekilde depolayarak performansı geliştirebilir.
// studentQuery5 is an IEnumerable<string>
// This query returns those students whose
// first test score was higher than their
// average score.
var studentQuery5 =
from student in students
let totalScore = student.Scores[0] + student.Scores[1] +
student.Scores[2] + student.Scores[3]
where totalScore / 4 < student.Scores[0]
select student.Last + " " + student.First;

foreach (string s in studentQuery5)


{
Console.WriteLine(s);
}

// Output:
// Omelchenko Svetlana
// O'Donnell Claire
// Mortensen Sven
// Garcia Cesar
// Fakhouri Fadi
// Feng Hanying
// Garcia Hugo
// Adams Terry
// Zabokritski Eugene
// Tucker Michael

Daha fazla bilgi için bkz. Let yan tümcesi.


Bir sorgu ifadesinde yöntem sözdizimini kullanmak için
1. Sorgu söz dizimi ve LINQ 'Teki yöntem sözdizimindeaçıklandığı gibi, bazı sorgu işlemleri yalnızca Yöntem
sözdizimi kullanılarak ifade edilebilir. Aşağıdaki kod, kaynak dizideki her bir Student için toplam puanı
hesaplar ve sonra sınıfın ortalama Puanını hesaplamak için bu sorgunun sonuçlarında Average()
yöntemini çağırır.

var studentQuery6 =
from student in students
let totalScore = student.Scores[0] + student.Scores[1] +
student.Scores[2] + student.Scores[3]
select totalScore;

double averageScore = studentQuery6.Average();


Console.WriteLine("Class average score = {0}", averageScore);

// Output:
// Class average score = 334.166666666667

Select yan tümcesinde dönüştürmek ya da planlamak için


1. Bir sorgu için, öğeleri kaynak dizideki öğelerden farklı olan bir sıra üretmek çok yaygındır. Önceki
sorgunuzu ve yürütme döngünüzü silin veya bir yorum yapın ve aşağıdaki kodla değiştirin. Sorgunun bir
dizi dizeyi ( Students değil) döndürdüğünü ve bu olguyu foreach döngüsünde yansıtıldığını unutmayın.
IEnumerable<string> studentQuery7 =
from student in students
where student.Last == "Garcia"
select student.First;

Console.WriteLine("The Garcias in the class are:");


foreach (string s in studentQuery7)
{
Console.WriteLine(s);
}

// Output:
// The Garcias in the class are:
// Cesar
// Debra
// Hugo

2. Bu kılavuzda daha önce bahsedilen kod, Ortalama sınıf puanının yaklaşık 334 olduğunu gösterdi. Toplam
puanı, Student ID olan ve ortalamasının Students bir dizisini oluşturmak için select deyimindeki anonim
bir tür kullanabilirsiniz:

var studentQuery8 =
from student in students
let x = student.Scores[0] + student.Scores[1] +
student.Scores[2] + student.Scores[3]
where x > averageScore
select new { id = student.ID, score = x };

foreach (var item in studentQuery8)


{
Console.WriteLine("Student ID: {0}, Score: {1}", item.id, item.score);
}

// Output:
// Student ID: 113, Score: 338
// Student ID: 114, Score: 353
// Student ID: 116, Score: 369
// Student ID: 117, Score: 352
// Student ID: 118, Score: 343
// Student ID: 120, Score: 341
// Student ID: 122, Score: 368

Sonraki Adımlar
İçindeki C#sorgularla çalışmanın temel yönleri hakkında bilgi sahibi olduktan sonra, ilgilendiğiniz LINQ sağlayıcısı
türü için belge ve örnekleri okumaya hazırsınızdır:
LINQ to SQL
LINQ to DataSet
LINQ to XML (C#)
LINQ to Objects (C#)

Ayrıca bkz.
Dil ile tümleşik sorgu (LINQ ) (C#)
LINQ sorgu Ifadeleri
Standart sorgu Işleçlerine genelC#bakış ()
23.10.2019 • 5 minutes to read • Edit Online

Standart sorgu IŞLEÇLERI LINQ deseninin bulunduğu yöntemlerdir. Bu yöntemlerin çoğu diziler üzerinde
çalışır, burada bir sıra, türü IEnumerable<T> arabirimini IQueryable<T> veya arabirimi uygulayan bir
nesnedir. Standart sorgu işleçleri filtreleme, yansıtma, toplama, sıralama ve daha fazlasını içeren sorgu
özellikleri sağlar.
Türü IEnumerable<T> nesneler üzerinde çalışan diğeri türü IQueryable<T>nesneler üzerinde çalışan iki
LINQ standart sorgu işleci kümesi vardır. Her kümeyi oluşturan Yöntemler sırasıyla Enumerable ve
Queryable sınıflarının statik üyeleridir. Bunlar üzerinde çalıştıkları türün Uzantı yöntemleri olarak
tanımlanmıştır. Bu, statik yöntem sözdizimi veya örnek yöntemi sözdizimi kullanılarak çağrılabilecek
anlamına gelir.
Ayrıca, birkaç standart sorgu işleci yöntemi, IEnumerable<T> veya IQueryable<T>tabanlı olanlar dışındaki
türler üzerinde çalışır. Türü Enumerable , her ikisi de türündeki IEnumerablenesneler üzerinde çalışan iki
yöntemi tanımlar. Bu yöntemler Cast<TResult>(IEnumerable) ve OfType<TResult>(IEnumerable),
parametreli olmayan veya genel olmayan bir koleksiyonun LINQ düzeninde sorgulanmasını etkinleştirmenizi
sağlar. Bu, nesne türü kesin belirlenmiş bir koleksiyon oluşturarak bunu yapabilirler. Sınıfı, Cast<TResult>
(IQueryable) veOfType<TResult>(IQueryable)türündeki nesnelerQueryableüzerinde çalışan iki benzer
yöntemi tanımlar. Queryable
Standart sorgu işleçleri, tek bir değer veya bir dizi değer döndürmediğine bağlı olarak yürütmesinin
zamanlamalarına göre farklılık gösterir. Tek bir değer döndüren Yöntemler (örneğin, Average ve Sum) hemen
yürütülür. Bir dizi döndüren yöntemler sorgu yürütmesini erteler ve Numaralandırılabilir bir nesne
döndürüyor.
Bellek içi koleksiyonlar üzerinde çalışan yöntemler söz konusu olduğunda, diğer bir deyişle IEnumerable<T>,
döndürülen sıralanabilir nesne, metoduna geçirilen bağımsız değişkenleri yakalar. Bu nesne
numaralandırıldıktan sonra, sorgu işlecinin mantığı işe alınır ve sorgu sonuçları döndürülür.
Buna karşılık, genişleyen IQueryable<T> Yöntemler herhangi bir sorgulama davranışı uygulamaz, ancak
gerçekleştirilecek sorguyu temsil eden bir ifade ağacı oluşturur. Sorgu işleme, kaynak IQueryable<T> nesne
tarafından işlenir.
Sorgu yöntemlerine yapılan çağrılar tek bir sorgu içinde birbirine zincirlenebilir ve bu da sorguların rastgele
karmaşık olmasını sağlar.
Aşağıdaki kod örneği, bir dizi hakkında bilgi edinmek için standart sorgu işleçlerinin nasıl kullanılabileceğini
gösterir.
string sentence = "the quick brown fox jumps over the lazy dog";
// Split the string into individual words to create a collection.
string[] words = sentence.Split(' ');

// Using query expression syntax.


var query = from word in words
group word.ToUpper() by word.Length into gr
orderby gr.Key
select new { Length = gr.Key, Words = gr };

// Using method-based query syntax.


var query2 = words.
GroupBy(w => w.Length, w => w.ToUpper()).
Select(g => new { Length = g.Key, Words = g }).
OrderBy(o => o.Length);

foreach (var obj in query)


{
Console.WriteLine("Words of length {0}:", obj.Length);
foreach (string word in obj.Words)
Console.WriteLine(word);
}

// This code example produces the following output:


//
// Words of length 3:
// THE
// FOX
// THE
// DOG
// Words of length 4:
// OVER
// LAZY
// Words of length 5:
// QUICK
// BROWN
// JUMPS

Sorgu Ifadesi söz dizimi


Daha sık kullanılan standart sorgu işleçlerinden bazılarının, bir C# sorgu ifadesininparçası olarak
çağrılmasına olanak tanıyan adanmış ve Visual Basic Language anahtar sözcüğü sözdizimi vardır. Adanmış
anahtar sözcüklere ve bunlara karşılık gelen sözdizimleri içeren standart sorgu işleçleri hakkında daha fazla
bilgi için bkz. Standart sorgu işleçleri Için sorgu IfadesiC#sözdizimi ().

Standart sorgu Işleçlerini genişletme


Hedef etki alanınız veya teknolojiniz için uygun olan alana özgü Yöntemler oluşturarak standart sorgu
işleçleri kümesini daha da getirebilirsiniz. Standart sorgu işleçlerini, uzaktan değerlendirme, sorgu çevirisi ve
iyileştirme gibi ek hizmetler sağlayan kendi uygulamalarınız ile de değiştirebilirsiniz. Bir AsEnumerable örnek
için bkz.

İlgili Bölümler
Aşağıdaki bağlantılar, işlevleri temel alan çeşitli standart sorgu işleçleri hakkında ek bilgiler sağlayan konulara
götürür.
Verileri sıralama (C#)
Işlemleri ayarla (C#)
Verileri filtreleme (C#)
Nicelik belirteci IşlemleriC#()
Projeksiyon Işlemleri (C#)
Verileri bölümleme (C#)
JOIN Işlemleri (C#)
Verileri gruplandırma (C#)
Oluşturma Işlemleri (C#)
Eşitlik Işlemleri (C#)
Öğe Işlemleri (C#)
Veri türlerini dönüştürme (C#)
Birleştirme Işlemleri (C#)
Toplama Işlemleri (C#)

Ayrıca bkz.
Enumerable
Queryable
LINQ Sorgularına Giriş (C#)
Standart sorgu Işleçleri için sorgu Ifadesi sözdizimi (C#)
Standart sorgu Işleçleri yürütme (C#) yöntemine göre sınıflandırması
Genişletme Yöntemleri
Standart sorgu Işleçleri için sorgu Ifadesi sözdizimi
(C#)
23.10.2019 • 2 minutes to read • Edit Online

Daha sık kullanılan standart sorgu işleçlerinden bazılarının, bir C# sorgu ifadesininparçası olarak çağrılmasına
olanak tanıyan adanmış dil anahtar sözcüğü sözdizimi vardır. Sorgu ifadesi, sorgu yöntemi tabanlı eşinden farklı
bir sorgu ifade eden farklı, daha okunabilir bir formdur. Sorgu ifadesi yan tümceleri, derleme zamanında sorgu
yöntemlerine yapılan çağrılara çevrilir.

Sorgu Ifadesi söz dizimi tablosu


Aşağıdaki tabloda denk sorgu ifadesi yan tümceleri olan standart sorgu işleçleri listelenmektedir.

YÖNTEM C#SORGU IFADESI SÖZ DIZIMI

Cast Açıkça yazılmış bir Aralık değişkeni kullanın, örneğin:

from int i in numbers

(Daha fazla bilgi için bkz. from tümcesi.)

GroupBy group … by

-veya-

group … by … into …

(Daha fazla bilgi için bkz. Grup tümcesi.)

GroupJoin<TOuter,TInner,TKey,TResult> join … in … on … equals … into …


(IEnumerable<TOuter>, IEnumerable<TInner>,
Func<TOuter,TKey>, Func<TInner,TKey>, (Daha fazla bilgi için bkz. JOIN yan tümcesi.)
Func<TOuter,IEnumerable<TInner>,TResult>)

Join<TOuter,TInner,TKey,TResult>(IEnumerable<TOuter>, join … in … on … equals …


IEnumerable<TInner>, Func<TOuter,TKey>,
Func<TInner,TKey>, Func<TOuter,TInner,TResult>) (Daha fazla bilgi için bkz. JOIN yan tümcesi.)

OrderBy<TSource,TKey>(IEnumerable<TSource>, orderby
Func<TSource,TKey>)
(Daha fazla bilgi için bkz. OrderBy tümcesi.)

OrderByDescending<TSource,TKey>(IEnumerable<TSource>, orderby … descending


Func<TSource,TKey>)
(Daha fazla bilgi için bkz. OrderBy tümcesi.)

Select select

(Daha fazla bilgi için bkz. Select yan tümcesi.)


YÖNTEM C#SORGU IFADESI SÖZ DIZIMI

SelectMany Birden from çok yan tümce.

(Daha fazla bilgi için bkz. from tümcesi.)

ThenBy<TSource,TKey>(IOrderedEnumerable<TSource>, orderby …, …
Func<TSource,TKey>)
(Daha fazla bilgi için bkz. OrderBy tümcesi.)

ThenByDescending<TSource,TKey> orderby …, … descending


(IOrderedEnumerable<TSource>, Func<TSource,TKey>)
(Daha fazla bilgi için bkz. OrderBy tümcesi.)

Where where

(Daha fazla bilgi için bkz. WHERE tümcesi.)

Ayrıca bkz.
Enumerable
Queryable
Standart sorgu Işleçlerine genelC#bakış ()
Standart sorgu Işleçleri yürütme (C#) yöntemine göre sınıflandırması
Standart sorgu Işleçleri yürütme (C#) yöntemine göre
sınıflandırması
23.10.2019 • 4 minutes to read • Edit Online

Standart sorgu işleci yöntemlerinin LINQ to Objects uygulamaları iki ana yöntemden biriyle yürütülür: ımımor
ertelenmiş. Ertelenmiş yürütmeyi kullanan sorgu işleçleri Ayrıca iki kategoriye ayrılabilir: akış ve akış olmayan.
Farklı sorgu işleçlerinin nasıl yürütüleceğini biliyorsanız, belirli bir sorgudan aldığınız sonuçları anlamanıza
yardımcı olabilir. Bu, veri kaynağı değiştirilirken veya başka bir sorgunun üstünde bir sorgu oluşturuyorsanız
özellikle doğrudur. Bu konu, standart sorgu işleçlerini yürütme tarzlarına göre sınıflandırır.

Yürütme mananlar
Hemen
Anında yürütme, veri kaynağının okunduğu ve işlemin sorgunun bildirildiği noktada gerçekleştirildiği anlamına
gelir. Tek, Numaralandırılmamış bir sonuç döndüren tüm standart sorgu işleçleri hemen yürütülür.
Ertelenmiş
Ertelenmiş yürütme, işlemin sorgunun bildirildiği noktada gerçekleştirilmediği anlamına gelir. İşlem yalnızca sorgu
değişkeni numaralandırıldıktan sonra, örneğin bir foreach ifade kullanılarak yapılır. Bu, sorguyu yürütmenin
sonuçlarının sorgu tanımlandığında değil, sorgu yürütüldüğünde veri kaynağının içeriğine bağlı olduğunu gösterir.
Sorgu değişkeni birden çok kez numaralandırıldıktan sonra sonuçlar her seferinde farklılık gösterebilir. Dönüş türü
IEnumerable<T> veya IOrderedEnumerable<TElement> ertelenmiş bir şekilde yürütülen tüm standart sorgu
işleçleri neredeyse hepsi.
Ertelenmiş yürütmeyi kullanan sorgu işleçleri ayrıca akış veya akış olmayan olarak sınıflandırılabilirler.
Akış
Akış işleçleri, öğeleri almadan önce tüm kaynak verileri okumak zorunda değildir. Yürütme sırasında, bir akış işleci
her kaynak öğe okunışında işlemini gerçekleştirir ve uygunsa öğeyi verir. Bir akış işleci, bir sonuç öğesi üretilene
kadar kaynak öğeleri okumaya devam eder. Bu, bir sonuç öğesi oluşturmak için birden fazla kaynak öğesinin
okunabileceğini gösterir.
Akış olmayan
Akış olmayan operatörler, bir sonuç öğesi elde etmeden önce tüm kaynak verileri okummalıdır.Sıralama veya
gruplama gibi işlemler bu kategoriye girer. Yürütme sırasında akış olmayan sorgu işleçleri tüm kaynak verileri okur,
veri yapısına koyar, işlemi gerçekleştirir ve sonuçta elde edilen öğeleri verir.

Sınıflandırma tablosu
Aşağıdaki tabloda, her standart sorgu operatörü yöntemi yürütme yöntemine göre sınıflandırılırdı.

NOTE
Bir işleç iki sütunda işaretlenmişse, işleme iki giriş dizisi dahil edilir ve her sıra farklı şekilde değerlendirilir. Bu durumlarda,
parametre listesindeki her zaman, ertelenmiş, akış halinde değerlendirilen ilk dizidir.
STANDART SORGU ERTELENMIŞ AKIŞ ERTELENMIŞ AKIŞ
IŞLECI DÖNÜŞ TÜRÜ HEMEN YÜRÜTME YÜRÜTME OLMAYAN YÜRÜTME

Aggregate TSource X

All Boolean X

Any Boolean X

AsEnumerable IEnumerable<T> X

Average Tek sayısal değer X

Cast IEnumerable<T> X

Concat IEnumerable<T> X

Contains Boolean X

Count Int32 X

DefaultIfEmpty IEnumerable<T> X

Distinct IEnumerable<T> X

ElementAt TSource X

ElementAtOrDefault TSource X

Empty IEnumerable<T> X

Except IEnumerable<T> X X

First TSource X

FirstOrDefault TSource X

GroupBy IEnumerable<T> X

GroupJoin IEnumerable<T> X X

Intersect IEnumerable<T> X X

Join IEnumerable<T> X X

Last TSource X

LastOrDefault TSource X

LongCount Int64 X

Max Tek sayısal değer, X


TSource veya TResult
STANDART SORGU ERTELENMIŞ AKIŞ ERTELENMIŞ AKIŞ
IŞLECI DÖNÜŞ TÜRÜ HEMEN YÜRÜTME YÜRÜTME OLMAYAN YÜRÜTME

Min Tek sayısal değer, X


TSource veya TResult

OfType IEnumerable<T> X

OrderBy IOrderedEnumerable X
<TElement>

OrderByDescending IOrderedEnumerable X
<TElement>

Range IEnumerable<T> X

Repeat IEnumerable<T> X

Reverse IEnumerable<T> X

Select IEnumerable<T> X

SelectMany IEnumerable<T> X

SequenceEqual Boolean X

Single TSource X

SingleOrDefault TSource X

Skip IEnumerable<T> X

SkipWhile IEnumerable<T> X

Sum Tek sayısal değer X

Take IEnumerable<T> X

TakeWhile IEnumerable<T> X

ThenBy IOrderedEnumerable X
<TElement>

ThenByDescending IOrderedEnumerable X
<TElement>

ToArray TSource dizisi X

ToDictionary Dictionary<TKey,TVal X
ue>

ToList IList<T> X
STANDART SORGU ERTELENMIŞ AKIŞ ERTELENMIŞ AKIŞ
IŞLECI DÖNÜŞ TÜRÜ HEMEN YÜRÜTME YÜRÜTME OLMAYAN YÜRÜTME

ToLookup ILookup<TKey,TEleme X
nt>

Union IEnumerable<T> X

Where IEnumerable<T> X

Ayrıca bkz.
Enumerable
Standart sorgu Işleçlerine genelC#bakış ()
Standart sorgu Işleçleri için sorgu Ifadesi sözdizimi (C#)
LINQ to Objects (C#)
Verileri sıralama (C#)
4.11.2019 • 3 minutes to read • Edit Online

Sıralama işlemi bir veya daha fazla özniteliğe göre bir sıranın öğelerini sıralar. İlk sıralama ölçütü öğeler üzerinde
birincil bir sıralama gerçekleştirir. İkinci bir sıralama ölçütü belirterek, her birincil sıralama grubu içindeki öğeleri
sıralayabilirsiniz.
Aşağıdaki çizimde, bir karakter dizisi üzerinde alfabetik bir sıralama işleminin sonuçları gösterilmektedir:

Verileri sıralayan standart sorgu işleci yöntemleri aşağıdaki bölümde listelenmiştir.

Yöntemler
YÖNTEM ADI AÇIKLAMA C#SORGU IFADESI SÖZ DIZIMI DAHA FAZLA BILGI

OrderBy Değerleri artan düzende orderby Enumerable.OrderBy


sıralar.
Queryable.OrderBy

OrderByDescending Değerleri azalan düzende orderby … descending Enumerable.OrderByDescen


sıralar. ding

Queryable.OrderByDescendi
ng

ThenBy Artan sırada ikincil bir orderby …, … Enumerable.ThenBy


sıralama gerçekleştirir.
Queryable.ThenBy

ThenByDescending Azalan sırada ikincil bir orderby …, … descending Enumerable.ThenByDescendi


sıralama gerçekleştirir. ng

Queryable.ThenByDescendin
g

Tersini Bir koleksiyondaki öğelerin Yok. Enumerable.Reverse


sırasını tersine çevirir.
Queryable.Reverse

Sorgu Ifadesi söz dizimi örnekleri


Birincil sıralama örnekleri
Birincil artan sıralama
Aşağıdaki örnek, bir dizideki dizeleri dize uzunluğuna göre artan sırada sıralamak için bir LINQ sorgusunda
orderby yan tümcesinin nasıl kullanılacağını gösterir.
string[] words = { "the", "quick", "brown", "fox", "jumps" };

IEnumerable<string> query = from word in words


orderby word.Length
select word;

foreach (string str in query)


Console.WriteLine(str);

/* This code produces the following output:

the
fox
quick
brown
jumps
*/

Birincil azalan sıralama


Sonraki örnekte, dizeleri ilk harfine göre azalan sırada sıralamak için bir LINQ sorgusunda orderby descending
yan tümcesinin nasıl kullanılacağı gösterilmektedir.

string[] words = { "the", "quick", "brown", "fox", "jumps" };

IEnumerable<string> query = from word in words


orderby word.Substring(0, 1) descending
select word;

foreach (string str in query)


Console.WriteLine(str);

/* This code produces the following output:

the
quick
jumps
fox
brown
*/

İkincil sıralama örnekleri


İkincil artan sıralama
Aşağıdaki örnek, bir dizideki dizelerin birincil ve ikincil sıralamasını gerçekleştirmek için bir LINQ sorgusunda
orderby yan tümcesinin nasıl kullanılacağını gösterir. Dizeler birincil olarak length ve secondarily ile dizenin ilk
harfine göre, her ikisi de artan düzende sıralanır.
string[] words = { "the", "quick", "brown", "fox", "jumps" };

IEnumerable<string> query = from word in words


orderby word.Length, word.Substring(0, 1)
select word;

foreach (string str in query)


Console.WriteLine(str);

/* This code produces the following output:

fox
the
brown
jumps
quick
*/

İkincil azalan sıralama


Sonraki örnekte, bir LINQ sorgusunda orderby descending yan tümcesinin nasıl kullanılacağı gösterilmektedir ve
bu bir birincil sıralama, artan düzende, ikincil bir sıralama ise azalan düzende yapılır. Dizeler öncelikle dizenin ilk
harfine göre uzunluğa ve secondarily göre sıralanır.

string[] words = { "the", "quick", "brown", "fox", "jumps" };

IEnumerable<string> query = from word in words


orderby word.Length, word.Substring(0, 1) descending
select word;

foreach (string str in query)


Console.WriteLine(str);

/* This code produces the following output:

the
fox
quick
jumps
brown
*/

Ayrıca bkz.
System.Linq
Standart sorgu Işleçlerine genelC#bakış ()
orderby yan tümcesi
Nasıl yapılır: JOIN yan tümcesinin sonuçlarını sıralama
Nasıl yapılır: herhangi bir sözcük veya alana göre metin verilerini sıralama veya filtreleme (LINQ )C#()
Işlemleri ayarla (C#)
4.12.2019 • 3 minutes to read • Edit Online

LINQ 'teki işlemleri, aynı veya ayrı Koleksiyonlar (veya kümeler) içindeki eşdeğer öğelerin varlığına veya
yokluğuna dayalı bir sonuç kümesi üreten sorgu işlemlerine yönelik olarak ayarlayın.
Ayarlanan işlemleri gerçekleştiren standart sorgu işleci yöntemleri aşağıdaki bölümde listelenmiştir.

Yöntemler
YÖNTEM ADI AÇIKLAMA C#SORGU IFADESI SÖZ DIZIMI DAHA FAZLA BILGI

Distinct Yinelenen değerleri bir Yok. Enumerable.Distinct


koleksiyondan kaldırır.
Queryable.Distinct

Dışlama İkinci bir koleksiyonda Yok. Enumerable.Except


görünmeyen bir
koleksiyonun öğelerinin Queryable.Except
anlamı olan küme farkını
döndürür.

Kesiştir Küme kesişimini döndürür, Yok. Enumerable.Intersect


bu iki koleksiyonun her
birinde görüntülenen öğeleri Queryable.Intersect
gösterir.

UNION İki koleksiyonda de görünen Yok. Enumerable.Union


benzersiz öğeler anlamına
gelen set birleşimini Queryable.Union
döndürür.

Ayarlama Işlemlerinin karşılaştırması


Distinct
Aşağıdaki örnek, Enumerable.Distinct yönteminin bir karakter dizisinde davranışını gösterir. Döndürülen dizi, Giriş
dizisinden benzersiz öğeleri içerir.
string[] planets = { "Mercury", "Venus", "Venus", "Earth", "Mars", "Earth" };

IEnumerable<string> query = from planet in planets.Distinct()


select planet;

foreach (var str in query)


{
Console.WriteLine(str);
}

/* This code produces the following output:


*
* Mercury
* Venus
* Earth
* Mars
*/

Dışlama
Aşağıdaki örnek Enumerable.Exceptdavranışını gösterir. Döndürülen dizi yalnızca ilk giriş dizisinin ikinci giriş
dizisinde olmayan öğelerini içerir.

string[] planets1 = { "Mercury", "Venus", "Earth", "Jupiter" };


string[] planets2 = { "Mercury", "Earth", "Mars", "Jupiter" };

IEnumerable<string> query = from planet in planets1.Except(planets2)


select planet;

foreach (var str in query)


{
Console.WriteLine(str);
}

/* This code produces the following output:


*
* Venus
*/

Kesiştir
Aşağıdaki örnek Enumerable.Intersectdavranışını gösterir. Döndürülen dizi, her iki giriş dizisinde da ortak olan
öğeleri içerir.
string[] planets1 = { "Mercury", "Venus", "Earth", "Jupiter" };
string[] planets2 = { "Mercury", "Earth", "Mars", "Jupiter" };

IEnumerable<string> query = from planet in planets1.Intersect(planets2)


select planet;

foreach (var str in query)


{
Console.WriteLine(str);
}

/* This code produces the following output:


*
* Mercury
* Earth
* Jupiter
*/

UNION
Aşağıdaki örnek iki karakter dizisi üzerinde bir bileşim işlemini gösterir. Döndürülen dizi, her iki giriş dizisinden
benzersiz öğeleri içerir.

string[] planets1 = { "Mercury", "Venus", "Earth", "Jupiter" };


string[] planets2 = { "Mercury", "Earth", "Mars", "Jupiter" };

IEnumerable<string> query = from planet in planets1.Union(planets2)


select planet;

foreach (var str in query)


{
Console.WriteLine(str);
}

/* This code produces the following output:


*
* Mercury
* Venus
* Earth
* Jupiter
* Mars
*/

Ayrıca bkz.
System.Linq
Standart sorgu Işleçlerine genelC#bakış ()
Dize koleksiyonlarını birleştirme ve karşılaştırma (LINQ ) (C#)
Nasıl yapılır: Iki liste arasında küme farkını bulma (LINQ ) (C#)
Verileri filtreleme (C#)
4.11.2019 • 2 minutes to read • Edit Online

Filtreleme, sonuç kümesini yalnızca belirtilen bir koşulu karşılayan öğeleri içerecek şekilde kısıtlama işlemini ifade
eder. Seçim olarak da bilinir.
Aşağıdaki çizimde, bir karakter dizisinin filtrelenmesi sonuçları gösterilmektedir. Filtreleme işleminin koşulu,
karakterin ' A ' olması gerektiğini belirtir.

Seçimi gerçekleştiren standart sorgu işleci yöntemleri aşağıdaki bölümde listelenmiştir.

Yöntemler
YÖNTEM ADI AÇIKLAMA C#SORGU IFADESI SÖZ DIZIMI DAHA FAZLA BILGI

OfType Belirtilen türe atama Yok. Enumerable.OfType


becerisine bağlı olarak
değerleri seçer. Queryable.OfType

Where Bir koşul işlevini temel alan where Enumerable.Where


değerleri seçer.
Queryable.Where

Sorgu Ifadesi söz dizimi örneği


Aşağıdaki örnek, belirli bir uzunluğa sahip dizelerin bu dizilerle filtreleneceği where yan tümcesini kullanır.

string[] words = { "the", "quick", "brown", "fox", "jumps" };

IEnumerable<string> query = from word in words


where word.Length == 3
select word;

foreach (string str in query)


Console.WriteLine(str);

/* This code produces the following output:

the
fox
*/

Ayrıca bkz.
System.Linq
Standart sorgu Işleçlerine genelC#bakış ()
where yan tümcesi
Nasıl yapılır: çalışma zamanında koşul filtrelerini dinamik olarak belirtme
Nasıl yapılır: bir derlemenin meta verilerini yansıma ile sorgulama (LINQ ) (C#)
Nasıl yapılır: belirtilen bir özniteliğe veya ada (C#) sahip dosyaları sorgulama
Nasıl yapılır: herhangi bir sözcük veya alana göre metin verilerini sıralama veya filtreleme (LINQ )C#()
Nicelik belirteci IşlemleriC#()
4.11.2019 • 2 minutes to read • Edit Online

Nicelik belirteci işlemleri bir dizideki öğelerin bazılarının veya tümünün bir koşulu karşılayıp karşılamadığını
belirten Boolean bir değer döndürür.
Aşağıdaki çizimde iki farklı kaynak dizisi üzerinde iki farklı belirleyici işlem gösterilmektedir. İlk işlem, bir veya daha
fazla öğenin ' A ' karakteri olup olmadığını sorar ve sonuç true . İkinci işlem, tüm öğelerin ' A ' karakteri olup
olmadığını sorar ve sonuç true .

Belirleyici işlemler gerçekleştiren standart sorgu işleci yöntemleri aşağıdaki bölümde listelenmiştir.

Yöntemler
YÖNTEM ADI AÇIKLAMA C#SORGU IFADESI SÖZ DIZIMI DAHA FAZLA BILGI

Tümü Bir dizideki tüm öğelerin bir Yok. Enumerable.All


koşulu karşılayıp
karşılamadığını belirler. Queryable.All

Kaydedilmemiş Bir dizideki herhangi bir Yok. Enumerable.Any


öğenin bir koşulu karşılayıp
karşılamadığını belirler. Queryable.Any

İçerir Bir sıranın belirtilen bir öğeyi Yok. Enumerable.Contains


içerip içermediğini belirler.
Queryable.Contains

Ayrıca bkz.
System.Linq
Standart sorgu Işleçlerine genelC#bakış ()
Nasıl yapılır: çalışma zamanında koşul filtrelerini dinamik olarak belirtme
Nasıl yapılır: belirli bir sözcükler kümesini içeren cümleleri sorgulama (LINQ ) (C#)
Projeksiyon Işlemleri (C#)
23.10.2019 • 5 minutes to read • Edit Online

Projeksiyon, bir nesneyi genellikle daha sonra kullanılacak olan özelliklerden oluşan yeni bir forma dönüştürme
işlemine başvurur. Projeksiyonu kullanarak her nesneden oluşturulan yeni bir tür oluşturabilirsiniz. Bir özelliği
proje üzerinde bir matematik işlevi de gerçekleştirebilirsiniz. Özgün nesneyi değiştirmeden de proje
oluşturabilirsiniz.
Yansıtmayı gerçekleştiren standart sorgu işleci yöntemleri aşağıdaki bölümde listelenmiştir.

Yöntemler
YÖNTEM ADI AÇIKLAMA C#SORGU IFADESI SÖZ DIZIMI DAHA FAZLA BILGI

Seçim Bir dönüşüm işlevine dayalı select Enumerable.Select


projeler değerleri.
Queryable.Select

SelectMany Bir dönüşüm işlevine dayalı Birden çok from yan tümce Enumerable.SelectMany
ve sonra bunları tek bir kullanma
sırayla düzleştirir. Queryable.SelectMany

Sorgu Ifadesi söz dizimi örnekleri


Seçim
Aşağıdaki örnek, select bir dize listesindeki her bir dizeden ilk harfi proje için yan tümcesini kullanır.

List<string> words = new List<string>() { "an", "apple", "a", "day" };

var query = from word in words


select word.Substring(0, 1);

foreach (string s in query)


Console.WriteLine(s);

/* This code produces the following output:

a
a
a
d
*/

SelectMany
Aşağıdaki örnek, her bir from sözcüğü bir dize listesindeki her bir dizeden proje için birden çok yan tümce
kullanır.
List<string> phrases = new List<string>() { "an apple a day", "the quick brown fox" };

var query = from phrase in phrases


from word in phrase.Split(' ')
select word;

foreach (string s in query)


Console.WriteLine(s);

/* This code produces the following output:

an
apple
a
day
the
quick
brown
fox
*/

Select SelectMany
Her ikisinin de Select() SelectMany() işi, kaynak değerlerinden bir sonuç değeri (veya değerler) üretmeniz.
Select() Her kaynak değer için bir sonuç değeri üretir. Bu nedenle, genel sonuç, kaynak koleksiyonuyla aynı
sayıda öğeye sahip olan bir koleksiyondur. Buna karşılık, SelectMany() her kaynak değerden birleştirilmiş alt
koleksiyonlar içeren tek bir genel sonuç üretir. Bağımsız değişken SelectMany() olarak geçirilen dönüştürme
işlevinin her kaynak değer için sıralanabilir bir değer dizisi döndürmesi gerekir. Bu sıralanabilir sıralar daha sonra
bir büyük SelectMany() sıra oluşturmak için ile birleştirilir.
Aşağıdaki iki çizimde, bu iki yöntemin eylemleri arasındaki kavramsal fark gösterilmektedir. Her durumda, seçici
(dönüşüm) işlevinin her kaynak değerden çiçekler dizisini seçtiği varsayılır.
Bu çizimde, kaynak Select() koleksiyonuyla aynı sayıda öğeye sahip bir koleksiyonun nasıl döndürdüğü
gösterilmektedir.

Bu çizimde, dizi SelectMany() dizilerinin her bir ara dizideki her bir değeri içeren bir son sonuç değerine nasıl
sıralanacağı gösterilmektedir.
Kod Örneği
Aşağıdaki örnek, Select() ve SelectMany() davranışlarını karşılaştırır. Kod, kaynak koleksiyondaki her bir çiçek adı
listesinden ilk iki öğeyi alarak çiçekler ' ın bir "Buquet" oluşturur. Bu örnekte, Transform işlevinin
Select<TSource,TResult>(IEnumerable<TSource>, Func<TSource,TResult>) kullandığı "tek değer" değeri bir
değer koleksiyonudur. Bu, her bir foreach alt dizideki her bir dizeyi numaralandırmak için ek döngü gerektirir.

class Bouquet
{
public List<string> Flowers { get; set; }
}

static void SelectVsSelectMany()


{
List<Bouquet> bouquets = new List<Bouquet>() {
new Bouquet { Flowers = new List<string> { "sunflower", "daisy", "daffodil", "larkspur" }},
new Bouquet{ Flowers = new List<string> { "tulip", "rose", "orchid" }},
new Bouquet{ Flowers = new List<string> { "gladiolis", "lily", "snapdragon", "aster", "protea" }},
new Bouquet{ Flowers = new List<string> { "larkspur", "lilac", "iris", "dahlia" }}
};

// *********** Select ***********


IEnumerable<List<string>> query1 = bouquets.Select(bq => bq.Flowers);

// ********* SelectMany *********


IEnumerable<string> query2 = bouquets.SelectMany(bq => bq.Flowers);

Console.WriteLine("Results by using Select():");


// Note the extra foreach loop here.
foreach (IEnumerable<String> collection in query1)
foreach (string item in collection)
Console.WriteLine(item);

Console.WriteLine("\nResults by using SelectMany():");


foreach (string item in query2)
Console.WriteLine(item);

/* This code produces the following output:

Results by using Select():


sunflower
daisy
daffodil
larkspur
tulip
rose
orchid
gladiolis
lily
snapdragon
aster
aster
protea
larkspur
lilac
iris
dahlia

Results by using SelectMany():


sunflower
daisy
daffodil
larkspur
tulip
rose
orchid
gladiolis
lily
snapdragon
aster
protea
larkspur
lilac
iris
dahlia
*/

Ayrıca bkz.
System.Linq
Standart sorgu Işleçlerine genelC#bakış ()
select yan tümcesi
Nasıl yapılır: Birden çok kaynaktan nesne koleksiyonları doldurma (LINQ ) (C#)
Nasıl yapılır: Grupları (LINQ ) kullanarak bir dosyayı çok sayıda dosyaya bölme (LINQC#) ()
Verileri bölümleme (C#)
23.10.2019 • 2 minutes to read • Edit Online

LINQ içinde bölümlendirme, bir giriş dizisini, öğeleri yeniden düzenleme ve sonra bölümlerden birini
döndürmeden iki bölüme bölme işlemine başvurur.
Aşağıdaki çizimde, bir karakter dizisi üzerinde üç farklı bölümlendirme işlemi sonuçları gösterilmektedir. İlk işlem
dizideki ilk üç öğeyi döndürür. İkinci işlem ilk üç öğeyi atlar ve kalan öğeleri döndürür. Üçüncü işlem dizideki ilk iki
öğeyi atlar ve sonraki üç öğeyi döndürür.

Bölüm dizilerinin aşağıdaki bölümde listelendiği standart sorgu işleci yöntemleri.

İşleçler
İŞLEÇ ADI AÇIKLAMA C#SORGU IFADESI SÖZ DIZIMI DAHA FAZLA BILGI

Atla Bir dizide belirtilen konuma Geçerli değildir. Enumerable.Skip


kadar olan öğeleri atlar.
Queryable.Skip

SkipWhile Bir öğe koşulu Geçerli değildir. Enumerable.SkipWhile


sağlamadığında bir koşul
işlevine göre öğeleri atlar. Queryable.SkipWhile

Take Öğeleri bir dizide belirtilen Geçerli değildir. Enumerable.Take


konuma kadar alır.
Queryable.Take

TakeWhile Öğe koşulu sağlamadığında Geçerli değildir. Enumerable.TakeWhile


bir koşul işlevine göre öğeleri
alır. Queryable.TakeWhile

Ayrıca bkz.
System.Linq
Standart sorgu Işleçlerine genelC#bakış ()
JOIN Işlemleri (C#)
4.11.2019 • 3 minutes to read • Edit Online

İki veri kaynağının birleşimi , bir veri kaynağındaki nesnelerin, başka bir veri kaynağında ortak bir özniteliği
paylaşan nesnelerle ilişkilendirilmesi.
Birleştirme, birbirleriyle ilişkilerini hedefleyen veri kaynaklarını hedef alan sorgularda önemli bir işlemdir. Nesne
odaklı programlamada bu, tek yönlü bir ilişkinin geriye doğru yönü gibi Modellenmemiş nesneler arasındaki bir
bağıntı anlamına gelebilir. Tek yönlü ilişki örneği, şehir türünde bir özelliği olan bir müşteri sınıfıdır, ancak City
sınıfı, müşteri nesnelerinin bir koleksiyonu olan bir özelliğine sahip değildir. Bir şehir nesneleri listeniz varsa ve her
bir şehirde tüm müşterileri bulmak istiyorsanız, bunları bulmak için bir JOIN işlemi kullanabilirsiniz.
LINQ çerçevesinde sunulan JOIN yöntemleri Join ve GroupJoin. Bu yöntemler, anahtarlarının eşitliğine göre iki
veri kaynağıyla eşleşen eş birleştirmeleri veya birleştirmeleri gerçekleştirir. (Karşılaştırma için Transact-SQL '
Equals ' dışındaki bir JOIN işleçlerini destekler, örneğin ' küçüktür ' işleci.) İlişkisel veritabanı koşullarında Join,
yalnızca diğer veri kümesinde eşleşme olan nesnelerin döndürüldüğü bir birleşim türü olan bir iç birleşim uygular.
GroupJoin yönteminin ilişkisel veritabanı terimlerinde doğrudan eşdeğeri yoktur, ancak iç birleştirmeler ve sol dış
birleşimlerin bir üst kümesini uygular. Sol dış birleşim, diğer veri kaynağında bağıntılı bir öğesi olmasa bile, ilk
(soldaki) veri kaynağının her bir öğesini döndüren birleşimdir.
Aşağıdaki çizimde, iki kümenin kavramsal görünümü ve bu kümeler içindeki öğelerin bir iç birleşime veya bir sol
dış birleşime dahil olduğu gösterilmektedir.

Yöntemler
YÖNTEM ADI AÇIKLAMA C#SORGU IFADESI SÖZ DIZIMI DAHA FAZLA BILGI

Birleştirme Anahtar Seçici işlevlerine join … in … on … equals Enumerable.Join


göre iki diziyi birleştirir ve …
değer çiftlerini ayıklar. Queryable.Join

GroupJoin Anahtar Seçici işlevlerine join … in … on … equals Enumerable.GroupJoin


göre iki diziyi birleştirir ve … into …
her öğe için elde edilen Queryable.GroupJoin
eşleşmeleri gruplandırır.

Ayrıca bkz.
System.Linq
Standart sorgu Işleçlerine genelC#bakış ()
Anonim Tipler
Birleşimler ve Çapraz Ürün Sorguları Düzenleme
join yan tümcesi
Nasıl yapılır: bileşik anahtarlar kullanarak ekleme
Nasıl yapılır: farklı dosyalardan Içerik ekleme (LINQ ) (C#)
Nasıl yapılır: JOIN yan tümcesinin sonuçlarını sıralama
Nasıl yapılır: özel JOIN Işlemleri gerçekleştirme
Nasıl yapılır: Gruplandırılmış Birleştirmeler Gerçekleştirme
Nasıl yapılır: Iç birleştirmeler gerçekleştirme
Nasıl yapılır: sol dış birleştirmeler gerçekleştirme
Nasıl yapılır: birden çok kaynaktan nesne koleksiyonları doldurma (LINQ ) (C#)
Verileri gruplandırma (C#)
4.11.2019 • 2 minutes to read • Edit Online

Gruplandırma, her bir gruptaki öğelerin ortak bir özniteliği paylaşması için verileri gruplara yerleştirme işlemini
ifade eder.
Aşağıdaki çizimde, bir karakter dizisini gruplandırmanın sonuçları gösterilmektedir. Her grup için anahtar
karakterdir.

Veri öğelerini gruplamak için kullanılan standart sorgu işleci yöntemleri aşağıdaki bölümde listelenmiştir.

Yöntemler
YÖNTEM ADI AÇIKLAMA C#SORGU IFADESI SÖZ DIZIMI DAHA FAZLA BILGI

Ölçütü Ortak bir özniteliği paylaşan group … by Enumerable.GroupBy


öğeleri gruplandırır. Her grup
IGrouping<TKey,TElement> veya Queryable.GroupBy
nesne tarafından temsil edilir.
group … by … into …

ToLookup Bir anahtar Seçici işlevine Yok. Enumerable.ToLookup


dayalı olarak bir
Lookup<TKey,TElement>
(bire çok sözlüğüne) öğe
ekler.

Sorgu Ifadesi söz dizimi örneği


Aşağıdaki kod örneği, bir listedeki tamsayıları, hatta veya tek olup olmadığına göre gruplamak için group by yan
tümcesini kullanır.
List<int> numbers = new List<int>() { 35, 44, 200, 84, 3987, 4, 199, 329, 446, 208 };

IEnumerable<IGrouping<int, int>> query = from number in numbers


group number by number % 2;

foreach (var group in query)


{
Console.WriteLine(group.Key == 0 ? "\nEven numbers:" : "\nOdd numbers:");
foreach (int i in group)
Console.WriteLine(i);
}

/* This code produces the following output:

Odd numbers:
35
3987
199
329

Even numbers:
44
200
84
4
446
208
*/

Ayrıca bkz.
System.Linq
Standart sorgu Işleçlerine genelC#bakış ()
group yan tümcesi
Nasıl yapılır: Iç Içe geçmiş grup oluşturma
Nasıl yapılır: dosyaları uzantıya göre gruplama (LINQ ) (C#)
Nasıl yapılır: sorgu sonuçlarını gruplandırma
Nasıl yapılır: gruplandırma Işleminde alt sorgu gerçekleştirme
Nasıl yapılır: grupları (LINQ ) kullanarak bir dosyayı birçok dosyaya bölme (LINQ )C#()
Oluşturma Işlemleri (C#)
23.10.2019 • 2 minutes to read • Edit Online

Oluşturma, yeni bir değer dizisi oluşturma anlamına gelir.


Oluşturma işlemini gerçekleştiren standart sorgu işleci yöntemleri aşağıdaki bölümde listelenmiştir.

Yöntemler
YÖNTEM ADI AÇIKLAMA C#SORGU IFADESI SÖZ DIZIMI DAHA FAZLA BILGI

Defaultıempty Boş bir koleksiyonu Geçerli değildir. Enumerable.DefaultIfEmpty


varsayılan değerli Singleton
koleksiyonuyla değiştirir. Queryable.DefaultIfEmpty

Olmamalıdır Boş bir koleksiyon döndürür. Geçerli değildir. Enumerable.Empty

Aralık Sayı dizisi içeren bir Geçerli değildir. Enumerable.Range


koleksiyon oluşturur.

Yinele Yinelenen bir değer içeren Geçerli değildir. Enumerable.Repeat


bir koleksiyon oluşturur.

Ayrıca bkz.
System.Linq
Standart sorgu Işleçlerine genelC#bakış ()
Eşitlik Işlemleri (C#)
25.11.2019 • 2 minutes to read • Edit Online

Karşılık gelen öğeleri eşit ve aynı sayıda öğeye sahip olan iki dizi eşit kabul edilir.

Yöntemler
YÖNTEM ADI AÇIKLAMA C#SORGU IFADESI SÖZ DIZIMI DAHA FAZLA BILGI

Sequenceeşittir Öğelerin çift yönlü olarak Yok. Enumerable.SequenceEqual


karşılaştırılmasıyla iki sıranın
eşit olup olmadığını belirler. Queryable.SequenceEqual

Ayrıca bkz.
System.Linq
Standart sorgu Işleçlerine genelC#bakış ()
İki klasörün içeriğini karşılaştırma (LINQ ) (C#)
Öğe Işlemleri (C#)
23.10.2019 • 2 minutes to read • Edit Online

Öğe işlemleri bir dizideki tek ve belirli bir öğeyi döndürür.


Öğe işlemlerini gerçekleştiren standart sorgu işleci yöntemleri aşağıdaki bölümde listelenmiştir.

Yöntemler
YÖNTEM ADI AÇIKLAMA C#SORGU IFADESI SÖZ DIZIMI DAHA FAZLA BILGI

ElementAt Koleksiyonda belirtilen Geçerli değildir. Enumerable.ElementAt


dizindeki öğeyi döndürür.
Queryable.ElementAt

ElementAtOrDefault Dizin aralık dışında Geçerli değildir. Enumerable.ElementAtOrDef


olduğunda, bir ault
koleksiyondaki belirtilen
dizindeki öğeyi veya Queryable.ElementAtOrDefa
varsayılan değeri döndürür. ult

Adı Bir koleksiyonun ilk öğesini Geçerli değildir. Enumerable.First


veya bir koşulu karşılayan ilk
öğeyi döndürür. Queryable.First

FirstOrDefault Bir koleksiyonun ilk öğesini Geçerli değildir. Enumerable.FirstOrDefault


veya bir koşulu karşılayan ilk
öğeyi döndürür. Böyle bir Queryable.FirstOrDefault
öğe yoksa, varsayılan bir
değer döndürür. Queryable.FirstOrDefault<TS
ource>
(IQueryable<TSource>)

Son Bir koleksiyonun son öğesini Geçerli değildir. Enumerable.Last


veya bir koşulu karşılayan
son öğeyi döndürür. Queryable.Last

LastOrDefault Bir koleksiyonun son öğesini Geçerli değildir. Enumerable.LastOrDefault


veya bir koşulu karşılayan
son öğeyi döndürür. Böyle Queryable.LastOrDefault
bir öğe yoksa, varsayılan bir
değer döndürür.

Tek Bir koleksiyonun tek bir Geçerli değildir. Enumerable.Single


öğesini veya bir koşulu
karşılayan tek öğeyi Queryable.Single
döndürür. Döndürülecek bir
InvalidOperationException
öğe yoksa veya birden fazla
öğe yoksa bir öğesi
oluşturur.
YÖNTEM ADI AÇIKLAMA C#SORGU IFADESI SÖZ DIZIMI DAHA FAZLA BILGI

SingleOrDefault Bir koleksiyonun tek bir Geçerli değildir. Enumerable.SingleOrDefault


öğesini veya bir koşulu
karşılayan tek öğeyi Queryable.SingleOrDefault
döndürür. Döndürülecek öğe
yoksa, varsayılan bir değer
döndürür. Döndürülecek
birden
InvalidOperationException
fazla öğe varsa, bir oluşturur.

Ayrıca bkz.
System.Linq
Standart sorgu Işleçlerine genelC#bakış ()
Nasıl yapılır: Bir dizin ağacındaki en büyük dosya veya dosyalar için sorgu (LINQ ) (C#)
Veri türlerini dönüştürme (C#)
4.11.2019 • 3 minutes to read • Edit Online

Dönüştürme yöntemleri giriş nesnelerinin türünü değiştirir.


LINQ sorgularındaki dönüştürme işlemleri çeşitli uygulamalarda yararlıdır. Aşağıda bazı örnekler verilmiştir:
Enumerable.AsEnumerable yöntemi, bir türün standart sorgu işlecinin özel uygulamasını gizlemek için
kullanılabilir.
Enumerable.OfType yöntemi, LINQ sorgulaması için parametreli olmayan koleksiyonları etkinleştirmek
üzere kullanılabilir.
Enumerable.ToArray, Enumerable.ToDictionary, Enumerable.ToListve Enumerable.ToLookup yöntemleri,
sorgu numaralandırılana kadar, sorgu yürütmeye zorlamak yerine hemen bu işlemi yapmak için
kullanılabilir.

Yöntemler
Aşağıdaki tabloda, veri türü dönüştürmeleri gerçekleştiren standart sorgu işleci yöntemleri listelenmektedir.
Bu tablodaki, adları "as" ile başlayan dönüştürme yöntemleri, kaynak koleksiyonun statik türünü değiştirir ancak
onu numaralandırmaz. Adları "to" ile başlayan Yöntemler, kaynak koleksiyonu numaralandırır ve öğeleri karşılık
gelen koleksiyon türüne koyar.

YÖNTEM ADI AÇIKLAMA C#SORGU IFADESI SÖZ DIZIMI DAHA FAZLA BILGI

Asılabilir IEnumerable<T>olarak Yok. Enumerable.AsEnumerable


yazılan girişi döndürür.

AsQueryable Bir (genel) IEnumerable bir Yok. Queryable.AsQueryable


(genel) IQueryable
dönüştürür.

Cast Bir koleksiyonun öğelerini Açıkça yazılmış bir Aralık Enumerable.Cast


belirtilen bir türe yayınlar. değişkeni kullanın. Örneğin:
Queryable.Cast
from string str in
words

OfType Değerleri, belirli bir türe Yok. Enumerable.OfType


atama becerisine bağlı olarak
filtreler. Queryable.OfType

ToArray Bir koleksiyonu bir diziye Yok. Enumerable.ToArray


dönüştürür. Bu yöntem
sorgu yürütmeyi zorlar.

ToDictionary Öğeleri bir anahtar Seçici Yok. Enumerable.ToDictionary


işlevine göre
Dictionary<TKey,TValue>
koyar. Bu yöntem sorgu
yürütmeyi zorlar.
YÖNTEM ADI AÇIKLAMA C#SORGU IFADESI SÖZ DIZIMI DAHA FAZLA BILGI

ToList Bir koleksiyonu bir Yok. Enumerable.ToList


List<T>dönüştürür. Bu
yöntem sorgu yürütmeyi
zorlar.

ToLookup Öğeleri bir anahtar Seçici Yok. Enumerable.ToLookup


işlevine göre bir
Lookup<TKey,TElement>
(bire çok sözlüğüne) koyar.
Bu yöntem sorgu yürütmeyi
zorlar.

Sorgu Ifadesi söz dizimi örneği


Aşağıdaki kod örneği, yalnızca alt tür üzerinde kullanılabilir olan bir üyeye erişmeden önce bir türü bir alt türe
dönüştürmek için, açıkça yazılmış bir Aralık değişkeni kullanır.

class Plant
{
public string Name { get; set; }
}

class CarnivorousPlant : Plant


{
public string TrapType { get; set; }
}

static void Cast()


{
Plant[] plants = new Plant[] {
new CarnivorousPlant { Name = "Venus Fly Trap", TrapType = "Snap Trap" },
new CarnivorousPlant { Name = "Pitcher Plant", TrapType = "Pitfall Trap" },
new CarnivorousPlant { Name = "Sundew", TrapType = "Flypaper Trap" },
new CarnivorousPlant { Name = "Waterwheel Plant", TrapType = "Snap Trap" }
};

var query = from CarnivorousPlant cPlant in plants


where cPlant.TrapType == "Snap Trap"
select cPlant;

foreach (Plant plant in query)


Console.WriteLine(plant.Name);

/* This code produces the following output:

Venus Fly Trap


Waterwheel Plant
*/
}

Ayrıca bkz.
System.Linq
Standart sorgu Işleçlerine genelC#bakış ()
from yan tümcesi
LINQ sorgu Ifadeleri
Nasıl yapılır: LINQ (C#) ile ArrayList 'i sorgulama
Birleştirme Işlemleri (C#)
25.11.2019 • 2 minutes to read • Edit Online

Birleştirme, bir sırayı diğerine ekleme işlemini ifade eder.


Aşağıdaki çizimde iki karakter dizisi üzerinde birleştirme işlemi gösterilmektedir.

Birleştirme işlemini gerçekleştiren standart sorgu işleci yöntemleri aşağıdaki bölümde listelenmiştir.

Yöntemler
YÖNTEM ADI AÇIKLAMA C#SORGU IFADESI SÖZ DIZIMI DAHA FAZLA BILGI

Concat Tek bir sıra oluşturmak için Yok. Enumerable.Concat


iki diziyi birleştirir.
Queryable.Concat

Ayrıca bkz.
System.Linq
Standart sorgu Işleçlerine genelC#bakış ()
Dize koleksiyonlarını birleştirme ve karşılaştırma (LINQ ) (C#)
Toplama Işlemleri (C#)
25.11.2019 • 2 minutes to read • Edit Online

Toplama işlemi, bir değerler koleksiyonundan tek bir değeri hesaplar. Bir toplama işlemine bir örnek, bir aylık
günlük sıcaklık değerleri için günlük ortalama sıcaklığın hesaplanmasından oluşur.
Aşağıdaki çizimde, bir dizi sayı üzerinde iki farklı toplama işlemi sonuçları gösterilmektedir. İlk işlem, sayıları toplar.
İkinci işlem dizideki en büyük değeri döndürür.

Toplama işlemlerini gerçekleştiren standart sorgu işleci yöntemleri aşağıdaki bölümde listelenmiştir.

Yöntemler
YÖNTEM ADI AÇIKLAMA C#SORGU IFADESI SÖZ DIZIMI DAHA FAZLA BILGI

Toplama Bir koleksiyonun değerleri Yok. Enumerable.Aggregate


üzerinde özel toplama işlemi
gerçekleştirir. Queryable.Aggregate

Ortalama Bir değerler koleksiyonunun Yok. Enumerable.Average


ortalama değerini hesaplar.
Queryable.Average

Biriktirme Bir koleksiyondaki öğeleri, Yok. Enumerable.Count


isteğe bağlı olarak yalnızca
bir koşul işlevini karşılayan Queryable.Count
öğeleri sayar.

LongCount Büyük bir koleksiyondaki Yok. Enumerable.LongCount


öğeleri, isteğe bağlı olarak
yalnızca bir koşul işlevini Queryable.LongCount
karşılayan öğeleri sayar.

Maks. Bir koleksiyondaki Yok. Enumerable.Max


maksimum değeri belirler.
Queryable.Max

Min. Bir koleksiyondaki en küçük Yok. Enumerable.Min


değeri belirler.
Queryable.Min

Toplamlarını Bir koleksiyondaki değerlerin Yok. Enumerable.Sum


toplamını hesaplar.
Queryable.Sum
Ayrıca bkz.
System.Linq
Standart sorgu Işleçlerine genelC#bakış ()
CSV metin dosyasında (LINQ ) sütun değerlerini hesaplama (LINQ ) (C#)
Nasıl yapılır: bir dizin ağacındaki en büyük dosya veya dosyalar için sorgu (LINQ ) (C#)
Nasıl yapılır: bir klasör kümesindeki toplam bayt sayısını sorgulama (LINQ ) (C#)
LINQ to Objects (C#)
25.11.2019 • 3 minutes to read • Edit Online

"LINQ to Objects" terimi, bir ara LINQ sağlayıcısının veya LINQ to SQL veya LINQ to XMLgibi API
kullanılmadan doğrudan herhangi bir IEnumerable veya IEnumerable<T> koleksiyonuyla LINQ sorgularının
kullanımını ifade eder. List<T>, Arrayveya Dictionary<TKey,TValue>gibi herhangi bir sıralanabilir koleksiyonu
sorgulamak için LINQ 'i kullanabilirsiniz. Koleksiyon Kullanıcı tanımlı olabilir veya bir .NET Framework API 'SI
tarafından döndürülen olabilir.
Temel anlamda, LINQ to Objects koleksiyonlara yönelik yeni bir yaklaşımı temsil eder. Eski şekilde, bir
koleksiyondan verilerin nasıl alınacağını belirtilen karmaşık foreach döngüleri yazmanız gerekiyordu. LINQ
yaklaşımında, almak istediklerinizi açıklayan bildirim kodu yazarsınız.
Ayrıca, LINQ sorguları geleneksel foreach döngülerine göre üç temel avantaj sunar:
1. Özellikle birden fazla koşula filtre uygulanırken bunlar daha kısa ve okunabilir.
2. En az uygulama kodu ile güçlü filtreleme, sıralama ve gruplama özellikleri sağlar.
3. Bunlar, çok az değişiklik yapmadan diğer veri kaynaklarına da eklenebilir.
Genel olarak, veriler üzerinde gerçekleştirmek istediğiniz işlem daha karmaşıktır, geleneksel yineleme teknikleri
yerine LINQ kullanarak bunu daha fazla avantaj elde edersiniz.
Bu bölümün amacı, bazı Select örnekleri ile LINQ yaklaşımını göstermektir. Bu, kapsamlı olmak üzere
tasarlanmamıştır.

Bu Bölümde
LINQ ve dizeler (C#)
LINQ 'in dizeleri ve dize koleksiyonlarını sorgulamak ve dönüştürmek için nasıl kullanılabileceğini açıklar.
Ayrıca, bu ilkeleri gösteren konuların bağlantılarını içerir.
LINQ ve yansıma (C#)
LINQ 'in yansıma kullanımını gösteren bir örneğe bağlantılar.
LINQ ve dosya dizinleri (C#)
LINQ 'in dosya sistemleriyle etkileşime geçmek için nasıl kullanılabileceğini açıklar. Ayrıca, bu kavramları
gösteren konuların bağlantılarını içerir.
Nasıl yapılır: LINQ (C#) ile ArrayList 'i sorgulama
İçinde C#ArrayList 'in nasıl sorgulanacağını gösterir.
LINQ sorguları için özel yöntemler ekleme (C#)
IEnumerable<T> arabirimine uzantı yöntemleri ekleyerek, LINQ sorguları için kullanabileceğiniz yöntemlerin
kümesinin nasıl genişletileceğini açıklar.
Dil ile tümleşik sorgu (LINQ ) (C#)
LINQ ' i açıklayan ve sorguları gerçekleştiren koda örnek sağlayan konulara bağlantılar sağlar.
LINQ ve dizeler (C#)
25.11.2019 • 4 minutes to read • Edit Online

LINQ, dizeleri ve dize koleksiyonlarını sorgulamak ve dönüştürmek için kullanılabilir. Bu, özellikle metin
dosyalarındaki yarı yapılandırılmış verilerle yararlı olabilir. LINQ sorguları, geleneksel dize işlevleri ve normal
ifadelerle birleştirilebilir. Örneğin, LINQ kullanarak sorgulayabilmeniz veya değiştiremeyeceğiniz bir dize dizisi
oluşturmak için String.Split veya Regex.Split yöntemini kullanabilirsiniz. Bir LINQ sorgusunun where yan
tümcesinde Regex.IsMatch yöntemini kullanabilirsiniz. Aynı şekilde, bir normal ifade tarafından döndürülen
MatchCollection sonuçlarını sorgulamak veya değiştirmek için LINQ kullanabilirsiniz.
Yarı yapılandırılmış metin verilerini XML 'e dönüştürmek için bu bölümde açıklanan teknikleri de
kullanabilirsiniz. Daha fazla bilgi için bkz. nasıl yapılır: CSV DOSYALARıNDAN XML oluşturma.
Bu bölümdeki örnekler iki kategoriye ayrılır:

Metin bloğunu sorgulama


String.Split yöntemini veya Regex.Split yöntemini kullanarak bunları bir daha küçük dizeler dizisine bölerek
metin bloklarını sorgulayabilir, çözümleyebilir ve değiştirebilirsiniz. Kaynak metni sözcükler, cümleler, paragraflar,
sayfalar veya diğer ölçütlere bölebilir ve ardından sorgunuzda gerekliyse ek bölmeler gerçekleştirebilirsiniz.
Dizedeki bir sözcüğün tekrarlamalarını sayma (LINQ ) (C#)
Metin üzerinde basit sorgulama için LINQ 'ın nasıl kullanılacağını gösterir.
Nasıl yapılır: belirli bir sözcükler kümesini içeren cümleleri sorgulama (LINQ ) (C#)
Metin dosyalarının rastgele sınırlarda nasıl bölüneceği ve her parçaya yönelik sorguların nasıl
gerçekleştirileceğini gösterir.
Nasıl yapılır: bir dizedeki karakterleri sorgulama (LINQ ) (C#)
Bir dizenin sorgulanabilir bir tür olduğunu gösterir.
LINQ sorgularını normal ifadelerle birleştirme (C#)
Filtrelenmiş sorgu sonuçlarında karmaşık model eşleştirmesi için LINQ sorgularında normal ifadelerin
nasıl kullanılacağını gösterir.

Yarı yapılandırılmış verileri metin biçiminde sorgulama


Birçok farklı metin dosyası türü, genellikle sekme veya virgülle ayrılmış dosyalar ya da sabit uzunluklu çizgiler
gibi benzer biçimlendirmeler içeren bir dizi satırdan oluşur. Bu tür bir metin dosyasını belleğe okuduktan sonra,
satırları sorgulamak ve/veya değiştirmek için LINQ kullanabilirsiniz. LINQ sorguları Ayrıca birden çok kaynaktan
veri birleştirme görevini basitleştirir.
Nasıl yapılır: Iki liste arasında küme farkını bulma (LINQ ) (C#)
Bir listede bulunan ancak diğeri olmayan tüm dizelerin nasıl bulunacağını gösterir.
Nasıl yapılır: herhangi bir sözcük veya alana göre metin verilerini sıralama veya filtreleme (LINQ )C#()
Metin çizgilerinin herhangi bir sözcük veya alana göre nasıl sıralanacağını gösterir.
Nasıl yapılır: ayrılmış bir dosyanın alanlarını yeniden sıralama (LINQ ) (C#)
Bir. csv dosyasındaki bir satırdaki alanların nasıl yeniden oluşturulduğunu gösterir.
Nasıl yapılır: dize koleksiyonlarını birleştirme ve karşılaştırma (LINQ ) (C#)
Dize listelerinin çeşitli yollarla nasıl birleştirileceğini gösterir.
Nasıl yapılır: birden çok kaynaktan nesne koleksiyonları doldurma (LINQ ) (C#)
Birden çok metin dosyasını veri kaynağı olarak kullanarak nasıl nesne koleksiyonları oluşturulacağını
gösterir.
Nasıl yapılır: farklı dosyalardan Içerik ekleme (LINQ ) (C#)
İki listedeki dizelerin, eşleşen bir anahtar kullanılarak tek bir dize içinde nasıl birleştirileceğini gösterir.
Nasıl yapılır: grupları (LINQ ) kullanarak bir dosyayı birçok dosyaya bölme (LINQ )C#()
Veri kaynağı olarak tek bir dosya kullanarak yeni dosyaların nasıl oluşturulacağını gösterir.
CSV metin dosyasında (LINQ ) sütun değerlerini hesaplama (LINQ ) (C#)
. Csv dosyalarındaki metin verilerinde matematiksel hesaplamaların nasıl gerçekleştirileceğini gösterir.

Ayrıca bkz.
Dil ile tümleşik sorgu (LINQ ) (C#)
Nasıl yapılır: CSV Dosyalarından XML Oluşturma
Dizedeki bir sözcüğün tekrarlamalarını sayma (LINQ)
(C#)
25.11.2019 • 2 minutes to read • Edit Online

Bu örnek, bir dizedeki belirli bir sözcüğün tekrarlamalarını saymak için bir LINQ sorgusunun nasıl kullanılacağını
gösterir. Sayıyı tamamlamak için öncelikle Split yönteminin bir dizi sözcük oluşturmak için çağrıldığını unutmayın.
Split yönteminin performans maliyeti vardır. Dizedeki tek işlem kelimeleri saymaya ise bunun yerine Matches veya
IndexOf yöntemlerini kullanmayı düşünmelisiniz. Ancak, performans kritik bir sorun değilse veya tümceyi zaten
böldüğünüz takdirde, diğer sorgu türlerini kullanmak için tümceyi daha önce ayırdıysanız, LINQ 'ı kullanarak
sözcükleri veya tümceleri de saymanız mantıklıdır.

Örnek
class CountWords
{
static void Main()
{
string text = @"Historically, the world of data and the world of objects" +
@" have not been well integrated. Programmers work in C# or Visual Basic" +
@" and also in SQL or XQuery. On the one side are concepts such as classes," +
@" objects, fields, inheritance, and .NET Framework APIs. On the other side" +
@" are tables, columns, rows, nodes, and separate languages for dealing with" +
@" them. Data types often require translation between the two worlds; there are" +
@" different standard functions. Because the object world has no notion of query, a" +
@" query can only be represented as a string without compile-time type checking or" +
@" IntelliSense support in the IDE. Transferring data from SQL tables or XML trees to" +
@" objects in memory is often tedious and error-prone.";

string searchTerm = "data";

//Convert the string into an array of words


string[] source = text.Split(new char[] { '.', '?', '!', ' ', ';', ':', ',' },
StringSplitOptions.RemoveEmptyEntries);

// Create the query. Use ToLowerInvariant to match "data" and "Data"


var matchQuery = from word in source
where word.ToLowerInvariant() == searchTerm.ToLowerInvariant()
select word;

// Count the matches, which executes the query.


int wordCount = matchQuery.Count();
Console.WriteLine("{0} occurrences(s) of the search term \"{1}\" were found.", wordCount, searchTerm);

// Keep console window open in debug mode


Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
}
/* Output:
3 occurrences(s) of the search term "data" were found.
*/

Kod Derleniyor
System. C# lınq ve System.IO ad alanları için using yönergeler içeren bir konsol uygulaması projesi oluşturun.
Ayrıca bkz.
LINQ ve dizeler (C#)
Nasıl yapılır: Belirli bir sözcük kümesini (LINQ) içeren
cümleleri sorgulama (LINQ) (C#)
23.10.2019 • 3 minutes to read • Edit Online

Bu örnek, belirli bir sözcük kümesinin her biri için eşleşmeler içeren bir metin dosyasında Tümcelerin nasıl
bulunacağını gösterir. Bu örnekte, arama terimleri dizisi sabit kodlanmış olsa da, çalışma zamanında dinamik olarak
doldurulabilir. Bu örnekte sorgu, "tarihsel olarak", "Data" ve "Integrated" sözcüklerini içeren cümleleri döndürür.

Örnek
class FindSentences
{
static void Main()
{
string text = @"Historically, the world of data and the world of objects " +
@"have not been well integrated. Programmers work in C# or Visual Basic " +
@"and also in SQL or XQuery. On the one side are concepts such as classes, " +
@"objects, fields, inheritance, and .NET Framework APIs. On the other side " +
@"are tables, columns, rows, nodes, and separate languages for dealing with " +
@"them. Data types often require translation between the two worlds; there are " +
@"different standard functions. Because the object world has no notion of query, a " +
@"query can only be represented as a string without compile-time type checking or " +
@"IntelliSense support in the IDE. Transferring data from SQL tables or XML trees to " +
@"objects in memory is often tedious and error-prone.";

// Split the text block into an array of sentences.


string[] sentences = text.Split(new char[] { '.', '?', '!' });

// Define the search terms. This list could also be dynamically populated at runtime.
string[] wordsToMatch = { "Historically", "data", "integrated" };

// Find sentences that contain all the terms in the wordsToMatch array.
// Note that the number of terms to match is not specified at compile time.
var sentenceQuery = from sentence in sentences
let w = sentence.Split(new char[] { '.', '?', '!', ' ', ';', ':', ',' },
StringSplitOptions.RemoveEmptyEntries)
where w.Distinct().Intersect(wordsToMatch).Count() == wordsToMatch.Count()
select sentence;

// Execute the query. Note that you can explicitly type


// the iteration variable here even though sentenceQuery
// was implicitly typed.
foreach (string str in sentenceQuery)
{
Console.WriteLine(str);
}

// Keep the console window open in debug mode.


Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
}
/* Output:
Historically, the world of data and the world of objects have not been well integrated
*/

Sorgu önce metni cümlelere bölerek ve sonra cümleleri her bir sözcüğü tutan dizeler dizisine bölerek işe yarar. Bu
dizilerin Distinct her biri için yöntem, tüm yinelenen sözcükleri kaldırır ve sonra sorgu, Word dizisi ve
wordsToMatch dizi Intersect üzerinde bir işlem gerçekleştirir. Kesişimin sayısı wordsToMatch dizinin sayısıyla
aynıysa, sözcüklerde tüm sözcükler bulunur ve özgün tümce döndürülür.
Çağrısında Split, noktalama işaretleri dizeden kaldırmak için ayırıcılar olarak kullanılır. Bunu yapmadıysanız,
örneğin, wordsToMatch dizide "tarihsel" olarak eşleşmeyen "tarihsel" bir dizeye sahip olabilirsiniz. Kaynak metinde
bulunan noktalama türlerine bağlı olarak ek ayırıcılar kullanmanız gerekebilir.

Kod Derleniyor
System. C# LINQ ve System.IO ad alanları using için yönergeler içeren bir konsol uygulaması projesi oluşturun.

Ayrıca bkz.
LINQ ve dizeler (C#)
Nasıl yapılır: bir dizedeki karakterleri sorgulama
(LINQ) (C#)
25.11.2019 • 2 minutes to read • Edit Online

String sınıfı genel IEnumerable<T> arabirimini gerçekleştirdiğinden, herhangi bir dize bir karakter dizisi olarak
sorgulanabilir. Ancak bu, LINQ 'in yaygın bir kullanımı değildir. Karmaşık kalıp eşleştirme işlemleri için Regex
sınıfını kullanın.

Örnek
Aşağıdaki örnek, içerdiği sayısal basamak sayısını belirlemede bir dizeyi sorgular. Sorgunun ilk kez yürütüldükten
sonra "yeniden kullanılır" olduğunu unutmayın. Sorgunun kendisi gerçek sonuçları depolamadığından bu
mümkündür.

class QueryAString
{
static void Main()
{
string aString = "ABCDE99F-J74-12-89A";

// Select only those characters that are numbers


IEnumerable<char> stringQuery =
from ch in aString
where Char.IsDigit(ch)
select ch;

// Execute the query


foreach (char c in stringQuery)
Console.Write(c + " ");

// Call the Count method on the existing query.


int count = stringQuery.Count();
Console.WriteLine("Count = {0}", count);

// Select all characters before the first '-'


IEnumerable<char> stringQuery2 = aString.TakeWhile(c => c != '-');

// Execute the second query


foreach (char c in stringQuery2)
Console.Write(c);

Console.WriteLine(System.Environment.NewLine + "Press any key to exit");


Console.ReadKey();
}
}
/* Output:
Output: 9 9 7 4 1 2 8 9
Count = 8
ABCDE99F
*/

Kod Derleniyor
System. C# lınq ve System.IO ad alanları için using yönergeler içeren bir konsol uygulaması projesi oluşturun.
Ayrıca bkz.
LINQ ve dizeler (C#)
LINQ sorgularını normal ifadelerle birleştirme (C#)
LINQ sorgularını normal ifadelerle birleştirme (C#)
25.11.2019 • 2 minutes to read • Edit Online

Bu örnek, metin dizelerinde daha karmaşık eşleştirme için bir normal ifade oluşturmak üzere Regex sınıfını nasıl
kullanacağınızı gösterir. LINQ sorgusu, normal ifadeyle arama yapmak istediğiniz dosyaları tam olarak
filtrelemenizi ve sonuçları şekillendirmenizi kolaylaştırır.

Örnek
class QueryWithRegEx
{
public static void Main()
{
// Modify this path as necessary so that it accesses your version of Visual Studio.
string startFolder = @"C:\Program Files (x86)\Microsoft Visual Studio 14.0\";
// One of the following paths may be more appropriate on your computer.
//string startFolder = @"C:\Program Files (x86)\Microsoft Visual Studio\2017\";

// Take a snapshot of the file system.


IEnumerable<System.IO.FileInfo> fileList = GetFiles(startFolder);

// Create the regular expression to find all things "Visual".


System.Text.RegularExpressions.Regex searchTerm =
new System.Text.RegularExpressions.Regex(@"Visual (Basic|C#|C\+\+|Studio)");

// Search the contents of each .htm file.


// Remove the where clause to find even more matchedValues!
// This query produces a list of files where a match
// was found, and a list of the matchedValues in that file.
// Note: Explicit typing of "Match" in select clause.
// This is required because MatchCollection is not a
// generic IEnumerable collection.
var queryMatchingFiles =
from file in fileList
where file.Extension == ".htm"
let fileText = System.IO.File.ReadAllText(file.FullName)
let matches = searchTerm.Matches(fileText)
where matches.Count > 0
select new
{
name = file.FullName,
matchedValues = from System.Text.RegularExpressions.Match match in matches
select match.Value
};

// Execute the query.


Console.WriteLine("The term \"{0}\" was found in:", searchTerm.ToString());

foreach (var v in queryMatchingFiles)


{
// Trim the path a bit, then write
// the file name in which a match was found.
string s = v.name.Substring(startFolder.Length - 1);
Console.WriteLine(s);

// For this file, write out all the matching strings


foreach (var v2 in v.matchedValues)
{
Console.WriteLine(" " + v2);
}
}
}

// Keep the console window open in debug mode


Console.WriteLine("Press any key to exit");
Console.ReadKey();
}

// This method assumes that the application has discovery


// permissions for all folders under the specified path.
static IEnumerable<System.IO.FileInfo> GetFiles(string path)
{
if (!System.IO.Directory.Exists(path))
throw new System.IO.DirectoryNotFoundException();

string[] fileNames = null;


List<System.IO.FileInfo> files = new List<System.IO.FileInfo>();

fileNames = System.IO.Directory.GetFiles(path, "*.*", System.IO.SearchOption.AllDirectories);


foreach (string name in fileNames)
{
files.Add(new System.IO.FileInfo(name));
}
return files;
}
}

Ayrıca, bir RegEx arama tarafından döndürülen MatchCollection nesnesini sorgulayabileceğinizi unutmayın. Bu
örnekte, sonuçlarda yalnızca her bir eşleşmenin değeri üretilir. Ancak, bu koleksiyonda tüm filtreleme, sıralama ve
gruplama türlerini gerçekleştirmek için LINQ kullanmak da mümkündür. MatchCollection genel olmayan bir
IEnumerable koleksiyonu olduğundan, sorgudaki aralık değişkeninin türünü açıkça belirtmelisiniz.

Kod Derleniyor
System. C# lınq ve System.IO ad alanları için using yönergeleriyle bir konsol uygulaması projesi oluşturun.

Ayrıca bkz.
LINQ ve dizeler (C#)
LINQ ve dosya dizinleri (C#)
Nasıl yapılır: Iki liste arasında küme farkını bulma
(LINQ) (C#)
25.11.2019 • 2 minutes to read • Edit Online

Bu örnek, iki dize listesini karşılaştırmak ve names1. txt içinde olan ancak names2. txt içinde olmayan satırları
çıkarmak için LINQ 'ın nasıl kullanılacağını gösterir.
Veri dosyalarını oluşturmak için
1. Names1. txt ve names2. txt dosyasını, dize koleksiyonlarını birleştirme ve karşılaştırma (LINQ ) (C#)bölümünde
gösterildiği gibi çözüm klasörünüze kopyalayın.

Örnek
class CompareLists
{
static void Main()
{
// Create the IEnumerable data sources.
string[] names1 = System.IO.File.ReadAllLines(@"../../../names1.txt");
string[] names2 = System.IO.File.ReadAllLines(@"../../../names2.txt");

// Create the query. Note that method syntax must be used here.
IEnumerable<string> differenceQuery =
names1.Except(names2);

// Execute the query.


Console.WriteLine("The following lines are in names1.txt but not names2.txt");
foreach (string s in differenceQuery)
Console.WriteLine(s);

// Keep the console window open in debug mode.


Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
}
/* Output:
The following lines are in names1.txt but not names2.txt
Potra, Cristina
Noriega, Fabricio
Aw, Kam Foo
Toyoshima, Tim
Guy, Wey Yuan
Garcia, Debra
*/

Except, Distinct, Unionve C#Concatgibi bazı sorgu işlemleri türleri yalnızca Yöntem tabanlı sözdiziminde ifade
edilebilir.

Kod Derleniyor
System. C# lınq ve System.IO ad alanları için using yönergeler içeren bir konsol uygulaması projesi oluşturun.

Ayrıca bkz.
LINQ ve dizeler (C#)
Nasıl yapılır: Her kelime veya alana göre metin
verilerini sıralama veya filtreleme (LINQ) (C#)
23.10.2019 • 2 minutes to read • Edit Online

Aşağıdaki örnek, virgülle ayrılmış değerler gibi yapılandırılmış metnin çizgilerinin satırdaki herhangi bir alana göre
nasıl sıralanacağını gösterir. Alan, çalışma zamanında dinamik olarak belirtilmiş olabilir. Puanlar. csv içindeki
alanların, bir öğrencinin KIMLIK numarasını temsil ettiğini ve ardından bir dizi dört test puandığını varsayın.
Veri içeren bir dosya oluşturmak için
1. Bu konudaki puanlarını. csv verilerini şu konudan kopyalayın: Benzer olmayan dosyalardaki (LINQ ) (C#) içeriği
birleştirin ve çözüm klasörünüze kaydedin.

Örnek
public class SortLines
{
static void Main()
{
// Create an IEnumerable data source
string[] scores = System.IO.File.ReadAllLines(@"../../../scores.csv");

// Change this to any value from 0 to 4.


int sortField = 1;

Console.WriteLine("Sorted highest to lowest by field [{0}]:", sortField);

// Demonstrates how to return query from a method.


// The query is executed here.
foreach (string str in RunQuery(scores, sortField))
{
Console.WriteLine(str);
}

// Keep the console window open in debug mode.


Console.WriteLine("Press any key to exit");
Console.ReadKey();
}

// Returns the query variable, not query results!


static IEnumerable<string> RunQuery(IEnumerable<string> source, int num)
{
// Split the string and sort on field[num]
var scoreQuery = from line in source
let fields = line.Split(',')
orderby fields[num] descending
select line;

return scoreQuery;
}
}
/* Output (if sortField == 1):
Sorted highest to lowest by field [1]:
116, 99, 86, 90, 94
120, 99, 82, 81, 79
111, 97, 92, 81, 60
114, 97, 89, 85, 82
121, 96, 85, 91, 60
122, 94, 92, 91, 91
117, 93, 92, 80, 87
118, 92, 90, 83, 78
113, 88, 94, 65, 91
112, 75, 84, 91, 39
119, 68, 79, 88, 92
115, 35, 72, 91, 70
*/

Bu örnek ayrıca bir yöntemden nasıl sorgu değişkeni dönebileceğinizi gösterir.

Kod Derleniyor
System. C# LINQ ve System.IO ad alanları using için yönergeler içeren bir konsol uygulaması projesi oluşturun.

Ayrıca bkz.
LINQ ve dizeler (C#)
Nasıl yapılır: Ayrılmış bir dosyanın alanlarını yeniden
sıralama (LINQ) (C#)
23.10.2019 • 2 minutes to read • Edit Online

Virgülle ayrılmış değer (CSV ) dosyası, elektronik tablo verilerini veya satırlar ve sütunlar tarafından temsil edilen
diğer tablo verilerini depolamak için genellikle kullanılan bir metin dosyasıdır. Alanları ayırmak için Split yöntemini
kullanarak, LINQ kullanarak CSV dosyalarını sorgulamak ve işlemek çok kolaydır. Aslında, yapılandırılmış herhangi
bir metin satırının parçalarını yeniden sıralamak için aynı teknik de kullanılabilir; CSV dosyalarıyla sınırlı değildir.
Aşağıdaki örnekte, üç sütunun öğrencileri ' "soyadı," "First Name" ve "ID" temsil ettiğini varsayın. Alanlar,
öğrencilerin son adlarına göre alfabetik sıralardır. Sorgu önce KIMLIK sütununun ilk göründüğü yeni bir dizi
oluşturur, ardından öğrencinin adı ve soyadı birleştiren ikinci bir sütun gelir. Satırlar KIMLIK alanına göre yeniden
sıralanabilir. Sonuçlar yeni bir dosyaya kaydedilir ve özgün veriler değiştirilmez.
Veri dosyası oluşturmak için
1. Aşağıdaki satırları spreadsheet1. csv adlı bir düz metin dosyasına kopyalayın. Dosyayı proje klasörünüze
kaydedin.

Adams,Terry,120
Fakhouri,Fadi,116
Feng,Hanying,117
Garcia,Cesar,114
Garcia,Debra,115
Garcia,Hugo,118
Mortensen,Sven,113
O'Donnell,Claire,112
Omelchenko,Svetlana,111
Tucker,Lance,119
Tucker,Michael,122
Zabokritski,Eugene,121

Örnek
class CSVFiles
{
static void Main(string[] args)
{
// Create the IEnumerable data source
string[] lines = System.IO.File.ReadAllLines(@"../../../spreadsheet1.csv");

// Create the query. Put field 2 first, then


// reverse and combine fields 0 and 1 from the old field
IEnumerable<string> query =
from line in lines
let x = line.Split(',')
orderby x[2]
select x[2] + ", " + (x[1] + " " + x[0]);

// Execute the query and write out the new file. Note that WriteAllLines
// takes a string[], so ToArray is called on the query.
System.IO.File.WriteAllLines(@"../../../spreadsheet2.csv", query.ToArray());

Console.WriteLine("Spreadsheet2.csv written to disk. Press any key to exit");


Console.ReadKey();
}
}
/* Output to spreadsheet2.csv:
111, Svetlana Omelchenko
112, Claire O'Donnell
113, Sven Mortensen
114, Cesar Garcia
115, Debra Garcia
116, Fadi Fakhouri
117, Hanying Feng
118, Hugo Garcia
119, Lance Tucker
120, Terry Adams
121, Eugene Zabokritski
122, Michael Tucker
*/

Kod Derleniyor
System. C# LINQ ve System.IO ad alanları using için yönergeler içeren bir konsol uygulaması projesi oluşturun.

Ayrıca bkz.
LINQ ve dizeler (C#)
LINQ ve dosya dizinleri (C#)
Nasıl yapılır: CSV dosyalarından XML oluştur (C#)
Dize koleksiyonlarını birleştirme ve karşılaştırma
(LINQ) (C#)
25.11.2019 • 3 minutes to read • Edit Online

Bu örnekte, metin satırları içeren dosyaların nasıl birleştiriyapılacağı ve sonuçların nasıl sıralanacağını
gösterilmektedir. Özellikle, iki metin satırı kümesinde basit bir birleştirme, birleşim ve bir kesişimin nasıl
gerçekleştirileceğini gösterir.
Projeyi ve metin dosyalarını ayarlamak için
1. Bu adları names1. txt adlı bir metin dosyasına kopyalayın ve proje klasörünüze kaydedin:

Bankov, Peter
Holm, Michael
Garcia, Hugo
Potra, Cristina
Noriega, Fabricio
Aw, Kam Foo
Beebe, Ann
Toyoshima, Tim
Guy, Wey Yuan
Garcia, Debra

2. Bu adları names2. txt adlı bir metin dosyasına kopyalayın ve proje klasörünüze kaydedin. İki dosyanın bazı
adları yaygın olarak olduğunu unutmayın.

Liu, Jinghao
Bankov, Peter
Holm, Michael
Garcia, Hugo
Beebe, Ann
Gilchrist, Beth
Myrcha, Jacek
Giakoumakis, Leo
McLin, Nkenge
El Yassir, Mehdi

Örnek
class MergeStrings
{
static void Main(string[] args)
{
//Put text files in your solution folder
string[] fileA = System.IO.File.ReadAllLines(@"../../../names1.txt");
string[] fileB = System.IO.File.ReadAllLines(@"../../../names2.txt");

//Simple concatenation and sort. Duplicates are preserved.


IEnumerable<string> concatQuery =
fileA.Concat(fileB).OrderBy(s => s);

// Pass the query variable to another function for execution.


OutputQueryResults(concatQuery, "Simple concatenate and sort. Duplicates are preserved:");

// Concatenate and remove duplicate names based on


// default string comparer.
// default string comparer.
IEnumerable<string> uniqueNamesQuery =
fileA.Union(fileB).OrderBy(s => s);
OutputQueryResults(uniqueNamesQuery, "Union removes duplicate names:");

// Find the names that occur in both files (based on


// default string comparer).
IEnumerable<string> commonNamesQuery =
fileA.Intersect(fileB);
OutputQueryResults(commonNamesQuery, "Merge based on intersect:");

// Find the matching fields in each list. Merge the two


// results by using Concat, and then
// sort using the default string comparer.
string nameMatch = "Garcia";

IEnumerable<String> tempQuery1 =
from name in fileA
let n = name.Split(',')
where n[0] == nameMatch
select name;

IEnumerable<string> tempQuery2 =
from name2 in fileB
let n2 = name2.Split(',')
where n2[0] == nameMatch
select name2;

IEnumerable<string> nameMatchQuery =
tempQuery1.Concat(tempQuery2).OrderBy(s => s);
OutputQueryResults(nameMatchQuery, $"Concat based on partial name match \"{nameMatch}\":");

// Keep the console window open in debug mode.


Console.WriteLine("Press any key to exit");
Console.ReadKey();
}

static void OutputQueryResults(IEnumerable<string> query, string message)


{
Console.WriteLine(System.Environment.NewLine + message);
foreach (string item in query)
{
Console.WriteLine(item);
}
Console.WriteLine("{0} total names in list", query.Count());
}
}
/* Output:
Simple concatenate and sort. Duplicates are preserved:
Aw, Kam Foo
Bankov, Peter
Bankov, Peter
Beebe, Ann
Beebe, Ann
El Yassir, Mehdi
Garcia, Debra
Garcia, Hugo
Garcia, Hugo
Giakoumakis, Leo
Gilchrist, Beth
Guy, Wey Yuan
Holm, Michael
Holm, Michael
Liu, Jinghao
McLin, Nkenge
Myrcha, Jacek
Noriega, Fabricio
Potra, Cristina
Toyoshima, Tim
20 total names in list
20 total names in list

Union removes duplicate names:


Aw, Kam Foo
Bankov, Peter
Beebe, Ann
El Yassir, Mehdi
Garcia, Debra
Garcia, Hugo
Giakoumakis, Leo
Gilchrist, Beth
Guy, Wey Yuan
Holm, Michael
Liu, Jinghao
McLin, Nkenge
Myrcha, Jacek
Noriega, Fabricio
Potra, Cristina
Toyoshima, Tim
16 total names in list

Merge based on intersect:


Bankov, Peter
Holm, Michael
Garcia, Hugo
Beebe, Ann
4 total names in list

Concat based on partial name match "Garcia":


Garcia, Debra
Garcia, Hugo
Garcia, Hugo
3 total names in list
*/

Kod Derleniyor
System. C# lınq ve System.IO ad alanları için using yönergeler içeren bir konsol uygulaması projesi oluşturun.

Ayrıca bkz.
LINQ ve dizeler (C#)
LINQ ve dosya dizinleri (C#)
Nasıl yapılır: Birden çok kaynaktan nesne
koleksiyonları doldurma (LINQ) (C#)
23.10.2019 • 5 minutes to read • Edit Online

Bu örnekte, farklı kaynaklardaki verilerin yeni türler dizisine nasıl birleştiriyapılacağı gösterilmektedir.

NOTE
Dosya sistemindeki bellek içi verileri veya verileri, hala veritabanında bulunan verilerle birleştirmeyi denemeyin. Bu tür etki
alanları arası birleştirmeler, birleştirme işlemlerinin veritabanı sorguları ve diğer kaynak türleri için tanımlanabileceğinden farklı
yollarla tanımsız sonuçlar verebilir. Ayrıca, veritabanındaki veri miktarı yeterince büyükse, bu tür bir işlemin bellek dışı bir özel
duruma neden olabileceği bir risk vardır. Verileri bir veritabanından bellek içi verilere katmak için, önce veritabanı sorgusuna
çağrı ToList ToArray yapın ve ardından döndürülen koleksiyonda JOIN işlemini gerçekleştirin.

Veri dosyası oluşturmak için


Names. csv ve puanlarını. csv dosyalarını proje klasörünüze kopyalayın, örneğin : Benzer olmayan dosyalardaki
(LINQ ) (C#)içerik birleştirin.

Örnek
Aşağıdaki örnek,. csv biçiminde elektronik tablo verilerinin benzetimini Student yapan iki bellekteki iki bellek
koleksiyonundan birleştirilmiş verileri depolamak için adlandırılmış bir türün nasıl kullanılacağını gösterir. İlk dize
koleksiyonu, öğrenci adlarını ve kimliklerini temsil eder ve ikinci koleksiyon öğrenci KIMLIĞINI (ilk sütunda) ve
dört sınav puanlarını temsil eder. KIMLIK yabancı anahtar olarak kullanılır.

using System;
using System.Collections.Generic;
using System.Linq;

class Student
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int ID { get; set; }
public List<int> ExamScores { get; set; }
}

class PopulateCollection
{
static void Main()
{
// These data files are defined in How to: Join Content from
// Dissimilar Files (LINQ).

// Each line of names.csv consists of a last name, a first name, and an


// ID number, separated by commas. For example, Omelchenko,Svetlana,111
string[] names = System.IO.File.ReadAllLines(@"../../../names.csv");

// Each line of scores.csv consists of an ID number and four test


// scores, separated by commas. For example, 111, 97, 92, 81, 60
string[] scores = System.IO.File.ReadAllLines(@"../../../scores.csv");

// Merge the data sources using a named type.


// var could be used instead of an explicit type. Note the dynamic
// var could be used instead of an explicit type. Note the dynamic
// creation of a list of ints for the ExamScores member. The first item
// is skipped in the split string because it is the student ID,
// not an exam score.
IEnumerable<Student> queryNamesScores =
from nameLine in names
let splitName = nameLine.Split(',')
from scoreLine in scores
let splitScoreLine = scoreLine.Split(',')
where Convert.ToInt32(splitName[2]) == Convert.ToInt32(splitScoreLine[0])
select new Student()
{
FirstName = splitName[0],
LastName = splitName[1],
ID = Convert.ToInt32(splitName[2]),
ExamScores = (from scoreAsText in splitScoreLine.Skip(1)
select Convert.ToInt32(scoreAsText)).
ToList()
};

// Optional. Store the newly created student objects in memory


// for faster access in future queries. This could be useful with
// very large data files.
List<Student> students = queryNamesScores.ToList();

// Display each student's name and exam score average.


foreach (var student in students)
{
Console.WriteLine("The average score of {0} {1} is {2}.",
student.FirstName, student.LastName,
student.ExamScores.Average());
}

//Keep console window open in debug mode


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* Output:
The average score of Omelchenko Svetlana is 82.5.
The average score of O'Donnell Claire is 72.25.
The average score of Mortensen Sven is 84.5.
The average score of Garcia Cesar is 88.25.
The average score of Garcia Debra is 67.
The average score of Fakhouri Fadi is 92.25.
The average score of Feng Hanying is 88.
The average score of Garcia Hugo is 85.75.
The average score of Tucker Lance is 81.75.
The average score of Adams Terry is 85.25.
The average score of Zabokritski Eugene is 83.
The average score of Tucker Michael is 92.
*/

Select yan tümcesinde bir nesne Başlatıcısı, iki kaynaktaki verileri kullanarak her yeni Student nesnenin örneğini
oluşturmak için kullanılır.
Bir sorgunun sonuçlarını depolamanız gerekmiyorsa, anonim türler adlandırılmış türlerden daha kullanışlı olabilir.
Sorgu sonuçlarını sorgunun yürütüldüğü yöntemin dışına geçirirseniz adlandırılmış türler gereklidir. Aşağıdaki
örnek, önceki örnekle aynı görevi yürütür, ancak adlandırılmış türler yerine anonim türler kullanır:
// Merge the data sources by using an anonymous type.
// Note the dynamic creation of a list of ints for the
// ExamScores member. We skip 1 because the first string
// in the array is the student ID, not an exam score.
var queryNamesScores2 =
from nameLine in names
let splitName = nameLine.Split(',')
from scoreLine in scores
let splitScoreLine = scoreLine.Split(',')
where Convert.ToInt32(splitName[2]) == Convert.ToInt32(splitScoreLine[0])
select new
{
First = splitName[0],
Last = splitName[1],
ExamScores = (from scoreAsText in splitScoreLine.Skip(1)
select Convert.ToInt32(scoreAsText))
.ToList()
};

// Display each student's name and exam score average.


foreach (var student in queryNamesScores2)
{
Console.WriteLine("The average score of {0} {1} is {2}.",
student.First, student.Last, student.ExamScores.Average());
}

Ayrıca bkz.
LINQ ve dizeler (C#)
Nesne ve Koleksiyon Başlatıcıları
Anonim Tipler
Nasıl yapılır: Grupları (LINQ) kullanarak bir dosyayı
çok sayıda dosyaya bölme (LINQC#) ()
23.10.2019 • 2 minutes to read • Edit Online

Bu örnek, iki dosyanın içeriğini birleştirmenin bir yolunu gösterir ve ardından verileri yeni bir şekilde düzenleyen
yeni bir dosya kümesi oluşturur.
Veri dosyalarını oluşturmak için
1. Bu adları names1. txt adlı bir metin dosyasına kopyalayın ve proje klasörünüze kaydedin:

Bankov, Peter
Holm, Michael
Garcia, Hugo
Potra, Cristina
Noriega, Fabricio
Aw, Kam Foo
Beebe, Ann
Toyoshima, Tim
Guy, Wey Yuan
Garcia, Debra

2. Bu adları names2. txt adlı bir metin dosyasına kopyalayın ve proje klasörünüze kaydedin: İki dosyanın bazı
adları yaygın olarak olduğunu unutmayın.

Liu, Jinghao
Bankov, Peter
Holm, Michael
Garcia, Hugo
Beebe, Ann
Gilchrist, Beth
Myrcha, Jacek
Giakoumakis, Leo
McLin, Nkenge
El Yassir, Mehdi

Örnek
class SplitWithGroups
{
static void Main()
{
string[] fileA = System.IO.File.ReadAllLines(@"../../../names1.txt");
string[] fileB = System.IO.File.ReadAllLines(@"../../../names2.txt");

// Concatenate and remove duplicate names based on


// default string comparer
var mergeQuery = fileA.Union(fileB);

// Group the names by the first letter in the last name.


var groupQuery = from name in mergeQuery
let n = name.Split(',')
group name by n[0][0] into g
orderby g.Key
select g;
// Create a new file for each group that was created
// Note that nested foreach loops are required to access
// individual items with each group.
foreach (var g in groupQuery)
{
// Create the new file name.
string fileName = @"../../../testFile_" + g.Key + ".txt";

// Output to display.
Console.WriteLine(g.Key);

// Write file.
using (System.IO.StreamWriter sw = new System.IO.StreamWriter(fileName))
{
foreach (var item in g)
{
sw.WriteLine(item);
// Output to console for example purposes.
Console.WriteLine(" {0}", item);
}
}
}
// Keep console window open in debug mode.
Console.WriteLine("Files have been written. Press any key to exit");
Console.ReadKey();
}
}
/* Output:
A
Aw, Kam Foo
B
Bankov, Peter
Beebe, Ann
E
El Yassir, Mehdi
G
Garcia, Hugo
Guy, Wey Yuan
Garcia, Debra
Gilchrist, Beth
Giakoumakis, Leo
H
Holm, Michael
L
Liu, Jinghao
M
Myrcha, Jacek
McLin, Nkenge
N
Noriega, Fabricio
P
Potra, Cristina
T
Toyoshima, Tim
*/

Program, veri dosyalarıyla aynı klasöre her bir grup için ayrı bir dosya yazar.

Kod Derleniyor
System. C# LINQ ve System.IO ad alanları using için yönergeler içeren bir konsol uygulaması projesi oluşturun.

Ayrıca bkz.
LINQ ve dizeler (C#)
LINQ ve dosya dizinleri (C#)
Nasıl yapılır: Benzer olmayan dosyalardaki (LINQ)
(C#) içerik birleştirin
23.10.2019 • 3 minutes to read • Edit Online

Bu örnek, eşleşen anahtar olarak kullanılan ortak bir değeri paylaşan, virgülle ayrılmış iki dosyadan verilerin nasıl
birleştirileceğini gösterir. Bu teknik, iki elektronik tablodan veya bir elektronik tabloda ve başka bir biçime sahip
bir dosyadan yeni bir dosyaya veri birleştirmek istiyorsanız yararlı olabilir. Örneği herhangi bir tür yapılandırılmış
metinle çalışacak şekilde değiştirebilirsiniz.

Veri dosyalarını oluşturmak için


1. Aşağıdaki satırları puanlarını. csv adlı bir dosyaya kopyalayın ve proje klasörünüze kaydedin. Dosya,
elektronik tablo verilerini temsil eder. 1. sütun, öğrencinin KIMLIĞIDIR ve 2 ile 5 arasındaki sütunlar test
puanlarıdır.

111, 97, 92, 81, 60


112, 75, 84, 91, 39
113, 88, 94, 65, 91
114, 97, 89, 85, 82
115, 35, 72, 91, 70
116, 99, 86, 90, 94
117, 93, 92, 80, 87
118, 92, 90, 83, 78
119, 68, 79, 88, 92
120, 99, 82, 81, 79
121, 96, 85, 91, 60
122, 94, 92, 91, 91

2. Aşağıdaki satırları Names. csv adlı bir dosyaya kopyalayın ve proje klasörünüze kaydedin. Dosya,
öğrencinin Soyadı, adı ve öğrenci KIMLIĞINI içeren bir elektronik tabloyu temsil eder.

Omelchenko,Svetlana,111
O'Donnell,Claire,112
Mortensen,Sven,113
Garcia,Cesar,114
Garcia,Debra,115
Fakhouri,Fadi,116
Feng,Hanying,117
Garcia,Hugo,118
Tucker,Lance,119
Adams,Terry,120
Zabokritski,Eugene,121
Tucker,Michael,122

Örnek
using System;
using System.Collections.Generic;
using System.Linq;

class JoinStrings
{
static void Main()
{
{
// Join content from dissimilar files that contain
// related information. File names.csv contains the student
// name plus an ID number. File scores.csv contains the ID
// and a set of four test scores. The following query joins
// the scores to the student names by using ID as a
// matching key.

string[] names = System.IO.File.ReadAllLines(@"../../../names.csv");


string[] scores = System.IO.File.ReadAllLines(@"../../../scores.csv");

// Name: Last[0], First[1], ID[2]


// Omelchenko, Svetlana, 11
// Score: StudentID[0], Exam1[1] Exam2[2], Exam3[3], Exam4[4]
// 111, 97, 92, 81, 60

// This query joins two dissimilar spreadsheets based on common ID value.


// Multiple from clauses are used instead of a join clause
// in order to store results of id.Split.
IEnumerable<string> scoreQuery1 =
from name in names
let nameFields = name.Split(',')
from id in scores
let scoreFields = id.Split(',')
where Convert.ToInt32(nameFields[2]) == Convert.ToInt32(scoreFields[0])
select nameFields[0] + "," + scoreFields[1] + "," + scoreFields[2]
+ "," + scoreFields[3] + "," + scoreFields[4];

// Pass a query variable to a method and execute it


// in the method. The query itself is unchanged.
OutputQueryResults(scoreQuery1, "Merge two spreadsheets:");

// Keep console window open in debug mode.


Console.WriteLine("Press any key to exit");
Console.ReadKey();
}

static void OutputQueryResults(IEnumerable<string> query, string message)


{
Console.WriteLine(System.Environment.NewLine + message);
foreach (string item in query)
{
Console.WriteLine(item);
}
Console.WriteLine("{0} total names in list", query.Count());
}
}
/* Output:
Merge two spreadsheets:
Omelchenko, 97, 92, 81, 60
O'Donnell, 75, 84, 91, 39
Mortensen, 88, 94, 65, 91
Garcia, 97, 89, 85, 82
Garcia, 35, 72, 91, 70
Fakhouri, 99, 86, 90, 94
Feng, 93, 92, 80, 87
Garcia, 92, 90, 83, 78
Tucker, 68, 79, 88, 92
Adams, 99, 82, 81, 79
Zabokritski, 96, 85, 91, 60
Tucker, 94, 92, 91, 91
12 total names in list
*/

Ayrıca bkz.
LINQ ve dizeler (C#)
LINQ ve dosya dizinleri (C#)
CSV metin dosyasında (LINQ) sütun değerlerini
hesaplama (LINQ) (C#)
25.11.2019 • 4 minutes to read • Edit Online

Bu örnek, bir. csv dosyasının sütunlarında Sum, Average, min ve Max gibi toplam hesaplamaların nasıl
gerçekleştirileceğini gösterir. Burada gösterilen örnek ilkeler diğer yapılandırılmış metin türlerine uygulanabilir.

Kaynak dosyayı oluşturmak için


1. Aşağıdaki satırları puanlarını. csv adlı bir dosyaya kopyalayın ve proje klasörünüze kaydedin. İlk sütunun bir
öğrenci KIMLIĞINI temsil ettiğini ve sonraki sütunlarda dört sınavın puanlarını temsil ettiğini varsayın.

111, 97, 92, 81, 60


112, 75, 84, 91, 39
113, 88, 94, 65, 91
114, 97, 89, 85, 82
115, 35, 72, 91, 70
116, 99, 86, 90, 94
117, 93, 92, 80, 87
118, 92, 90, 83, 78
119, 68, 79, 88, 92
120, 99, 82, 81, 79
121, 96, 85, 91, 60
122, 94, 92, 91, 91

Örnek
class SumColumns
{
static void Main(string[] args)
{
string[] lines = System.IO.File.ReadAllLines(@"../../../scores.csv");

// Specifies the column to compute.


int exam = 3;

// Spreadsheet format:
// Student ID Exam#1 Exam#2 Exam#3 Exam#4
// 111, 97, 92, 81, 60

// Add one to exam to skip over the first column,


// which holds the student ID.
SingleColumn(lines, exam + 1);
Console.WriteLine();
MultiColumns(lines);

Console.WriteLine("Press any key to exit");


Console.ReadKey();
}

static void SingleColumn(IEnumerable<string> strs, int examNum)


{
Console.WriteLine("Single Column Query:");

// Parameter examNum specifies the column to


// run the calculations on. This value could be
// passed in dynamically at runtime.
// passed in dynamically at runtime.

// Variable columnQuery is an IEnumerable<int>.


// The following query performs two steps:
// 1) use Split to break each row (a string) into an array
// of strings,
// 2) convert the element at position examNum to an int
// and select it.
var columnQuery =
from line in strs
let elements = line.Split(',')
select Convert.ToInt32(elements[examNum]);

// Execute the query and cache the results to improve


// performance. This is helpful only with very large files.
var results = columnQuery.ToList();

// Perform aggregate calculations Average, Max, and


// Min on the column specified by examNum.
double average = results.Average();
int max = results.Max();
int min = results.Min();

Console.WriteLine("Exam #{0}: Average:{1:##.##} High Score:{2} Low Score:{3}",


examNum, average, max, min);
}

static void MultiColumns(IEnumerable<string> strs)


{
Console.WriteLine("Multi Column Query:");

// Create a query, multiColQuery. Explicit typing is used


// to make clear that, when executed, multiColQuery produces
// nested sequences. However, you get the same results by
// using 'var'.

// The multiColQuery query performs the following steps:


// 1) use Split to break each row (a string) into an array
// of strings,
// 2) use Skip to skip the "Student ID" column, and store the
// rest of the row in scores.
// 3) convert each score in the current row from a string to
// an int, and select that entire sequence as one row
// in the results.
IEnumerable<IEnumerable<int>> multiColQuery =
from line in strs
let elements = line.Split(',')
let scores = elements.Skip(1)
select (from str in scores
select Convert.ToInt32(str));

// Execute the query and cache the results to improve


// performance.
// ToArray could be used instead of ToList.
var results = multiColQuery.ToList();

// Find out how many columns you have in results.


int columnCount = results[0].Count();

// Perform aggregate calculations Average, Max, and


// Min on each column.
// Perform one iteration of the loop for each column
// of scores.
// You can use a for loop instead of a foreach loop
// because you already executed the multiColQuery
// query by calling ToList.
for (int column = 0; column < columnCount; column++)
{
var results2 = from row in results
select row.ElementAt(column);
select row.ElementAt(column);
double average = results2.Average();
int max = results2.Max();
int min = results2.Min();

// Add one to column because the first exam is Exam #1,


// not Exam #0.
Console.WriteLine("Exam #{0} Average: {1:##.##} High Score: {2} Low Score: {3}",
column + 1, average, max, min);
}
}
}
/* Output:
Single Column Query:
Exam #4: Average:76.92 High Score:94 Low Score:39

Multi Column Query:


Exam #1 Average: 86.08 High Score: 99 Low Score: 35
Exam #2 Average: 86.42 High Score: 94 Low Score: 72
Exam #3 Average: 84.75 High Score: 91 Low Score: 65
Exam #4 Average: 76.92 High Score: 94 Low Score: 39
*/

Sorgu, her metin satırını bir diziye dönüştürmek için Split yöntemi kullanılarak işe yarar. Her dizi öğesi bir sütunu
temsil eder. Son olarak, her sütundaki metin sayısal gösterimine dönüştürülür. Dosyanız sekmeyle ayrılmış bir
dosya ise, \t için Split yöntemindeki bağımsız değişkeni güncelleştirmeniz yeterlidir.

Kod Derleniyor
System. C# lınq ve System.IO ad alanları için using yönergeler içeren bir konsol uygulaması projesi oluşturun.

Ayrıca bkz.
LINQ ve dizeler (C#)
LINQ ve dosya dizinleri (C#)
2 minutes to read
Nasıl yapılır: Bir derlemenin meta verilerini yansıma
ile sorgulama (LINQ) (C#)
23.10.2019 • 2 minutes to read • Edit Online

.NET Framework sınıf kitaplığı yansıma API 'Leri, bir .NET derlemesinde meta verileri incelemek ve bu derlemede
bulunan tür koleksiyonları, tür üyelerini, parametreleri ve benzerlerini oluşturmak için kullanılabilir. Bu
koleksiyonlar genel IEnumerable<T> arabirimi desteklediklerinden, LINQ kullanılarak sorgulanırlar.
Aşağıdaki örnek, belirtilen bir arama ölçütüyle eşleşen yöntemler hakkında belirli meta verileri almak için, LINQ 'in
yansıma ile nasıl kullanılabileceğini gösterir. Bu durumda sorgu, derlemede diziler gibi sıralanabilir türler döndüren
tüm yöntemlerin adlarını bulur.

Örnek
using System;
using System.Linq;
using System.Reflection;

class ReflectionHowTO
{
static void Main()
{
Assembly assembly = Assembly.Load("System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=
b77a5c561934e089");
var pubTypesQuery = from type in assembly.GetTypes()
where type.IsPublic
from method in type.GetMethods()
where method.ReturnType.IsArray == true
|| ( method.ReturnType.GetInterface(
typeof(System.Collections.Generic.IEnumerable<>).FullName ) != null
&& method.ReturnType.FullName != "System.String" )
group method.ToString() by type.ToString();

foreach (var groupOfMethods in pubTypesQuery)


{
Console.WriteLine("Type: {0}", groupOfMethods.Key);
foreach (var method in groupOfMethods)
{
Console.WriteLine(" {0}", method);
}
}

Console.WriteLine("Press any key to exit... ");


Console.ReadKey();
}
}

Örnek, belirtilen derlemedeki Assembly.GetTypes türlerin bir dizisini döndürmek için yöntemini kullanır. Yalnızca
ortak türlerin döndürülmemesi için WHERE filtresi uygulanır. Her genel tür için, MethodInfo Type.GetMethods
çağrıdan döndürülen dizi kullanılarak bir alt sorgu oluşturulur. Bu sonuçlar yalnızca, dönüş türü bir dizi veya başka
bir türü IEnumerable<T>olan yöntemleri döndürecek şekilde filtrelenir. Son olarak, bu sonuçlar tür adı anahtar
olarak kullanılarak gruplandırılır.

Ayrıca bkz.
LINQ to Objects (C#)
LINQ ve dosya dizinleri (C#)
25.11.2019 • 4 minutes to read • Edit Online

Birçok dosya sistemi işlemi aslında sorgular ve bu nedenle LINQ yaklaşımına uygundur.
Bu bölümdeki sorguların bozucu olmadığına unutmayın. Özgün dosyaların veya klasörlerin içeriğini değiştirmek
için kullanılmaz. Bu, sorguların hiçbir yan etkiye neden olmaması gerektiğine yönelik kuralı izler. Genel olarak,
kaynak verileri değiştiren tüm kodlar (oluşturma/güncelleştirme/silme işleçleri de dahil olmak üzere) yalnızca
verileri sorgulayan koddan ayrı tutulmalıdır.
Bu bölüm aşağıdaki konular içerir:
Nasıl yapılır: belirtilen bir özniteliğe veya ada (C#) sahip dosyaları sorgulama
FileInfo nesnesinin bir veya daha fazla özelliğini inceleyerek dosyaların nasıl aranacağını gösterir.
Nasıl yapılır: dosyaları uzantıya göre gruplama (LINQ ) (C#)
FileInfo nesne gruplarının dosya adı uzantısına göre nasıl geri alınacağını gösterir.
Nasıl yapılır: bir klasör kümesindeki toplam bayt sayısını sorgulama (LINQ ) (C#)
Belirtilen bir dizin ağacındaki tüm dosyalardaki toplam bayt sayısının nasıl geri yükleneceğini gösterir.
İki klasörün içeriğini karşılaştırma (LINQ ) (C#)s
Belirtilen iki klasörde bulunan tüm dosyaları ve aynı zamanda bir klasörde bulunan ancak diğeri olmayan tüm
dosyaları döndürmeyi gösterir.
Nasıl yapılır: bir dizin ağacındaki en büyük dosya veya dosyalar için sorgu (LINQ ) (C#)
Bir dizin ağacında en büyük veya en küçük dosyanın veya belirli bir sayıdaki dosyanın nasıl döndürülmeli
olduğunu gösterir.
Nasıl yapılır: bir dizin ağacında (LINQ ) (C#) yinelenen dosyaları sorgulama
Belirtilen bir dizin ağacındaki birden fazla konumda gerçekleşen tüm dosya adlarının nasıl gruplandıralınacağını
gösterir. Ayrıca, özel bir karşılaştırıcıyı temel alan daha karmaşık karşılaştırmalar yapmayı gösterir.
Nasıl yapılır: bir klasördeki dosyaların Içeriğini sorgulama (LINQ ) (C#)
Bir ağaçtaki klasörlerin nasıl tekrarlanması, her dosyanın nasıl açılacağı ve dosyanın içeriğini sorgulama
işlemlerinin nasıl yapılacağını gösterir.

Açıklamalar
Dosya sisteminin içeriğini doğru bir şekilde temsil eden bir veri kaynağı oluşturma konusunda bazı
karmaşıklıklar vardır ve özel durumları düzgün bir şekilde işler. Bu bölümdeki örneklerde, belirtilen bir kök
klasörü ve tüm alt klasörleri altındaki tüm dosyaları temsil eden FileInfo nesnelerinin bir anlık görüntü
koleksiyonu oluşturulur. Her bir FileInfo gerçek durumu, bir sorgu yürütme ve sonlandırma arasındaki sürede
değişebilir. Örneğin, bir veri kaynağı olarak kullanmak üzere FileInfo nesnelerinin bir listesini oluşturabilirsiniz.
Bir sorgudaki Length özelliğine erişmeyi denerseniz, FileInfo nesnesi Length değerini güncelleştirmek için
dosya sistemine erişmeye çalışır. Dosya artık yoksa, dosya sistemini doğrudan sorguladığınız halde sorgunuzda
bir FileNotFoundException alırsınız. Bu bölümdeki bazı sorgular belirli durumlarda bu özel durumları tüketen
ayrı bir yöntem kullanır. Diğer bir seçenek de FileSystemWatcherkullanarak veri kaynağınızı dinamik olarak
güncel tutkullanmaktır.

Ayrıca bkz.
LINQ to Objects (C#)
Nasıl yapılır: Belirtilen bir özniteliğe veya ada (C#)
sahip dosyaları sorgula
23.10.2019 • 2 minutes to read • Edit Online

Bu örnek, belirtilen bir dizin ağacında belirtilen dosya adı uzantısına (örneğin ". txt") sahip tüm dosyaların nasıl
bulunacağını gösterir. Ayrıca, oluşturma zamanına göre ağaçta en yeni veya en eski dosyanın nasıl
dönegösterdiğini gösterir.

Örnek
class FindFileByExtension
{
// This query will produce the full path for all .txt files
// under the specified folder including subfolders.
// It orders the list according to the file name.
static void Main()
{
string startFolder = @"c:\program files\Microsoft Visual Studio 9.0\";

// Take a snapshot of the file system.


System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(startFolder);

// This method assumes that the application has discovery permissions


// for all folders under the specified path.
IEnumerable<System.IO.FileInfo> fileList = dir.GetFiles("*.*", System.IO.SearchOption.AllDirectories);

//Create the query


IEnumerable<System.IO.FileInfo> fileQuery =
from file in fileList
where file.Extension == ".txt"
orderby file.Name
select file;

//Execute the query. This might write out a lot of files!


foreach (System.IO.FileInfo fi in fileQuery)
{
Console.WriteLine(fi.FullName);
}

// Create and execute a new query by using the previous


// query as a starting point. fileQuery is not
// executed again until the call to Last()
var newestFile =
(from file in fileQuery
orderby file.CreationTime
select new { file.FullName, file.CreationTime })
.Last();

Console.WriteLine("\r\nThe newest .txt file is {0}. Creation time: {1}",


newestFile.FullName, newestFile.CreationTime);

// Keep the console window open in debug mode.


Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
}
Kod Derleniyor
System. C# LINQ ve System.IO ad alanları using için yönergeler içeren bir konsol uygulaması projesi oluşturun.

Ayrıca bkz.
LINQ to Objects (C#)
LINQ ve dosya dizinleri (C#)
Nasıl yapılır: Dosyaları uzantıya göre Gruplandır
(LINQ) (C#)
23.10.2019 • 3 minutes to read • Edit Online

Bu örnek, LINQ 'ın dosya veya klasör listelerinde gelişmiş gruplandırma ve sıralama işlemleri gerçekleştirmek için
nasıl kullanılabileceğini gösterir. Ayrıca, Skip ve Take yöntemlerini kullanarak konsol penceresinde çıkışın nasıl
yapılacağını gösterir.

Örnek
Aşağıdaki sorguda, belirtilen dizin ağacının içeriğini dosya adı uzantısı tarafından nasıl gruplandırmak
gösterilmektedir.

class GroupByExtension
{
// This query will sort all the files under the specified folder
// and subfolder into groups keyed by the file extension.
private static void Main()
{
// Take a snapshot of the file system.
string startFolder = @"c:\program files\Microsoft Visual Studio 9.0\Common7";

// Used in WriteLine to trim output lines.


int trimLength = startFolder.Length;

// Take a snapshot of the file system.


System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(startFolder);

// This method assumes that the application has discovery permissions


// for all folders under the specified path.
IEnumerable<System.IO.FileInfo> fileList = dir.GetFiles("*.*", System.IO.SearchOption.AllDirectories);

// Create the query.


var queryGroupByExt =
from file in fileList
group file by file.Extension.ToLower() into fileGroup
orderby fileGroup.Key
select fileGroup;

// Display one group at a time. If the number of


// entries is greater than the number of lines
// in the console window, then page the output.
PageOutput(trimLength, queryGroupByExt);
}

// This method specifically handles group queries of FileInfo objects with string keys.
// It can be modified to work for any long listings of data. Note that explicit typing
// must be used in method signatures. The groupbyExtList parameter is a query that produces
// groups of FileInfo objects with string keys.
private static void PageOutput(int rootLength,
IEnumerable<System.Linq.IGrouping<string, System.IO.FileInfo>>
groupByExtList)
{
// Flag to break out of paging loop.
bool goAgain = true;

// "3" = 1 line for extension + 1 for "Press any key" + 1 for input cursor.
int numLines = Console.WindowHeight - 3;
// Iterate through the outer collection of groups.
foreach (var filegroup in groupByExtList)
{
// Start a new extension at the top of a page.
int currentLine = 0;

// Output only as many lines of the current group as will fit in the window.
do
{
Console.Clear();
Console.WriteLine(filegroup.Key == String.Empty ? "[none]" : filegroup.Key);

// Get 'numLines' number of items starting at number 'currentLine'.


var resultPage = filegroup.Skip(currentLine).Take(numLines);

//Execute the resultPage query


foreach (var f in resultPage)
{
Console.WriteLine("\t{0}", f.FullName.Substring(rootLength));
}

// Increment the line counter.


currentLine += numLines;

// Give the user a chance to escape.


Console.WriteLine("Press any key to continue or the 'End' key to break...");
ConsoleKey key = Console.ReadKey().Key;
if (key == ConsoleKey.End)
{
goAgain = false;
break;
}
} while (currentLine < filegroup.Count());

if (goAgain == false)
break;
}
}
}

Bu programın çıktısı, yerel dosya sisteminin ayrıntılarına ve ' nin ne startFolder ayarlı olduğuna bağlı olarak uzun
olabilir. Tüm sonuçların görüntülenmesini sağlamak için bu örnek, sonuçların nasıl ekleneceğini gösterir. Windows
ve Web uygulamalarına aynı teknikler de uygulanabilir. Kod, bir gruptaki öğeler, iç içe geçmiş foreach bir döngü
gerekli olduğundan emin olun. Ayrıca, listedeki geçerli konumu hesaplamak için bazı ek Logic de vardır ve
kullanıcının sayfalamayı durdurmasına ve programdan çıkmasına olanak tanır. Bu durumda, disk belleği sorgusu
özgün sorgudaki önbelleğe alınmış sonuçlara karşı çalıştırılır. Diğer bağlamlarda, örneğin LINQ to SQL, önbelleğe
alma gerekli değildir.

Kod Derleniyor
System. C# LINQ ve System.IO ad alanları using için yönergeler içeren bir konsol uygulaması projesi oluşturun.

Ayrıca bkz.
LINQ to Objects (C#)
LINQ ve dosya dizinleri (C#)
Nasıl yapılır: Bir klasör kümesindeki toplam bayt
sayısını sorgulama (LINQ) (C#)
23.10.2019 • 3 minutes to read • Edit Online

Bu örnek, belirtilen bir klasör ve tüm alt klasörlerindeki tüm dosyalar tarafından kullanılan toplam bayt sayısının
nasıl alınacağını gösterir.

Örnek
Yöntemi, select yan tümcesinde seçili olan tüm öğelerin değerlerini ekler. Sum Yerine Min veyaMaxmetodunu
çağırarak, belirtilen dizin ağacındaki en büyük veya en küçük dosyayı almak için bu sorguyu kolayca
değiştirebilirsiniz. Sum
class QuerySize
{
public static void Main()
{
string startFolder = @"c:\program files\Microsoft Visual Studio 9.0\VC#";

// Take a snapshot of the file system.


// This method assumes that the application has discovery permissions
// for all folders under the specified path.
IEnumerable<string> fileList = System.IO.Directory.GetFiles(startFolder, "*.*",
System.IO.SearchOption.AllDirectories);

var fileQuery = from file in fileList


select GetFileLength(file);

// Cache the results to avoid multiple trips to the file system.


long[] fileLengths = fileQuery.ToArray();

// Return the size of the largest file


long largestFile = fileLengths.Max();

// Return the total number of bytes in all the files under the specified folder.
long totalBytes = fileLengths.Sum();

Console.WriteLine("There are {0} bytes in {1} files under {2}",


totalBytes, fileList.Count(), startFolder);
Console.WriteLine("The largest files is {0} bytes.", largestFile);

// Keep the console window open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}

// This method is used to swallow the possible exception


// that can be raised when accessing the System.IO.FileInfo.Length property.
static long GetFileLength(string filename)
{
long retval;
try
{
System.IO.FileInfo fi = new System.IO.FileInfo(filename);
retval = fi.Length;
}
catch (System.IO.FileNotFoundException)
{
// If a file is no longer present,
// just add zero bytes to the total.
retval = 0;
}
return retval;
}
}

Yalnızca belirtilen bir dizin ağacındaki bayt sayısını saymanız gerekiyorsa, bunu bir veri kaynağı olarak liste
koleksiyonu oluşturma ek yükünü bir LINQ sorgusu oluşturmadan daha verimli bir şekilde yapabilirsiniz. Sorgu
daha karmaşık hale geldiği veya aynı veri kaynağında birden çok sorgu çalıştırmanız gerektiğinde LINQ yaklaşımın
Yararlılığı artar.
Sorgu, dosya uzunluğunu elde etmek için ayrı bir yönteme çağrı yapılır. Bu, dosya, öğesine yapılan FileInfo
GetFiles çağrıda oluşturulduktan sonra başka bir iş parçacığında silinmişse, ortaya çıkan olası özel durumu
kullanmak için bunu yapar. Nesne zaten oluşturulmuş olsa da, bir FileInfo nesne, özelliği ilk kez erişildiği zaman en
güncel uzunlukla yenilemeyi Length deneyeceğinden, özel durum oluşabilir. FileInfo Bu işlemi sorgu dışında bir
try-catch bloğuna koyarak, kod, yan etkilere neden olabilecek sorgularda işlemleri önleme kuralına uyar. Genel
olarak, bir uygulamanın bilinmeyen bir durumda ayrılmadığından emin olmak için özel durumlar kullandığınızda
harika dikkatli olunmalıdır.

Kod Derleniyor
System. C# LINQ ve System.IO ad alanları using için yönergeler içeren bir konsol uygulaması projesi oluşturun.

Ayrıca bkz.
LINQ to Objects (C#)
LINQ ve dosya dizinleri (C#)
İki klasörün içeriğini karşılaştırma (LINQ) (C#)
25.11.2019 • 3 minutes to read • Edit Online

Bu örnekte iki dosya listesi karşılaştırmanın üç yolu gösterilmektedir:


İki dosya listelerinin aynı olup olmadığını belirten bir Boolean değeri sorgulayarak.
Her iki klasördeki dosyaları almak için kesişimini sorgulayarak.
Bir klasörde olan ancak diğeri olmayan dosyaları almak için ayarlanan farkı sorgulayarak.

NOTE
Burada gösterilen teknikler, herhangi bir türdeki nesne dizilerini karşılaştırmak için uyarlanmıştır.

Burada gösterilen FileComparer sınıfı, standart sorgu Işleçleri ile birlikte özel bir karşılaştırıcı sınıfının nasıl
kullanılacağını gösterir. Sınıfı, gerçek dünyada senaryolarda kullanılmak üzere tasarlanmamıştır. Her bir klasörün
içeriğinin aynı olup olmadığını anlamak için her bir dosyanın bayt cinsinden adını ve uzunluğunu kullanır. Gerçek
dünyada bir senaryoda, daha kapsamlı bir eşitlik denetimi gerçekleştirmek için bu karşılaştırıcıyı değiştirmelisiniz.

Örnek
namespace QueryCompareTwoDirs
{
class CompareDirs
{

static void Main(string[] args)


{

// Create two identical or different temporary folders


// on a local drive and change these file paths.
string pathA = @"C:\TestDir";
string pathB = @"C:\TestDir2";

System.IO.DirectoryInfo dir1 = new System.IO.DirectoryInfo(pathA);


System.IO.DirectoryInfo dir2 = new System.IO.DirectoryInfo(pathB);

// Take a snapshot of the file system.


IEnumerable<System.IO.FileInfo> list1 = dir1.GetFiles("*.*",
System.IO.SearchOption.AllDirectories);
IEnumerable<System.IO.FileInfo> list2 = dir2.GetFiles("*.*",
System.IO.SearchOption.AllDirectories);

//A custom file comparer defined below


FileCompare myFileCompare = new FileCompare();

// This query determines whether the two folders contain


// identical file lists, based on the custom file comparer
// that is defined in the FileCompare class.
// The query executes immediately because it returns a bool.
bool areIdentical = list1.SequenceEqual(list2, myFileCompare);

if (areIdentical == true)
{
Console.WriteLine("the two folders are the same");
}
else
{
Console.WriteLine("The two folders are not the same");
}

// Find the common files. It produces a sequence and doesn't


// execute until the foreach statement.
var queryCommonFiles = list1.Intersect(list2, myFileCompare);

if (queryCommonFiles.Count() > 0)
{
Console.WriteLine("The following files are in both folders:");
foreach (var v in queryCommonFiles)
{
Console.WriteLine(v.FullName); //shows which items end up in result list
}
}
else
{
Console.WriteLine("There are no common files in the two folders.");
}

// Find the set difference between the two folders.


// For this example we only check one way.
var queryList1Only = (from file in list1
select file).Except(list2, myFileCompare);

Console.WriteLine("The following files are in list1 but not list2:");


foreach (var v in queryList1Only)
{
Console.WriteLine(v.FullName);
}

// Keep the console window open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}

// This implementation defines a very simple comparison


// between two FileInfo objects. It only compares the name
// of the files being compared and their length in bytes.
class FileCompare : System.Collections.Generic.IEqualityComparer<System.IO.FileInfo>
{
public FileCompare() { }

public bool Equals(System.IO.FileInfo f1, System.IO.FileInfo f2)


{
return (f1.Name == f2.Name &&
f1.Length == f2.Length);
}

// Return a hash that reflects the comparison criteria. According to the


// rules for IEqualityComparer<T>, if Equals is true, then the hash codes must
// also be equal. Because equality as defined here is a simple value equality, not
// reference identity, it is possible that two or more objects will produce the same
// hash code.
public int GetHashCode(System.IO.FileInfo fi)
{
string s = $"{fi.Name}{fi.Length}";
return s.GetHashCode();
}
}
}

Kod Derleniyor
System. C# lınq ve System.IO ad alanları için using yönergeler içeren bir konsol uygulaması projesi oluşturun.

Ayrıca bkz.
LINQ to Objects (C#)
LINQ ve dosya dizinleri (C#)
Nasıl yapılır: Bir dizin ağacındaki en büyük dosya
veya dosyalar için sorgu (LINQ) (C#)
23.10.2019 • 5 minutes to read • Edit Online

Bu örnekte, bayt cinsinden dosya boyutuyla ilgili beş sorgu gösterilmektedir:


En büyük dosyanın bayt cinsinden boyutunu alma.
En küçük dosyanın bayt cinsinden boyutunu alma.
Belirtilen kök klasörü altındaki FileInfo bir veya daha fazla klasörden en büyük veya en küçük dosyayı alma.
10 en büyük dosya gibi bir sıra alma.
Dosyaları, belirli bir boyuttan daha az olan dosyaları yoksayarak, dosya boyutlarına göre gruplar halinde
sıralama.

Örnek
Aşağıdaki örnek, dosya boyutlarına bağlı olarak dosyaların nasıl sorgulandığına ve gruplandıralınacağını gösteren
beş ayrı sorgu içerir. Bu örnekleri, sorgunun diğer bir özelliğindeki FileInfo sorgu temel alınarak kolayca
değiştirebilirsiniz.

class QueryBySize
{
static void Main(string[] args)
{
QueryFilesBySize();
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}

private static void QueryFilesBySize()


{
string startFolder = @"c:\program files\Microsoft Visual Studio 9.0\";

// Take a snapshot of the file system.


System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(startFolder);

// This method assumes that the application has discovery permissions


// for all folders under the specified path.
IEnumerable<System.IO.FileInfo> fileList = dir.GetFiles("*.*", System.IO.SearchOption.AllDirectories);

//Return the size of the largest file


long maxSize =
(from file in fileList
let len = GetFileLength(file)
select len)
.Max();

Console.WriteLine("The length of the largest file under {0} is {1}",


startFolder, maxSize);

// Return the FileInfo object for the largest file


// by sorting and selecting from beginning of list
System.IO.FileInfo longestFile =
(from file in fileList
let len = GetFileLength(file)
where len > 0
where len > 0
orderby len descending
select file)
.First();

Console.WriteLine("The largest file under {0} is {1} with a length of {2} bytes",
startFolder, longestFile.FullName, longestFile.Length);

//Return the FileInfo of the smallest file


System.IO.FileInfo smallestFile =
(from file in fileList
let len = GetFileLength(file)
where len > 0
orderby len ascending
select file).First();

Console.WriteLine("The smallest file under {0} is {1} with a length of {2} bytes",
startFolder, smallestFile.FullName, smallestFile.Length);

//Return the FileInfos for the 10 largest files


// queryTenLargest is an IEnumerable<System.IO.FileInfo>
var queryTenLargest =
(from file in fileList
let len = GetFileLength(file)
orderby len descending
select file).Take(10);

Console.WriteLine("The 10 largest files under {0} are:", startFolder);

foreach (var v in queryTenLargest)


{
Console.WriteLine("{0}: {1} bytes", v.FullName, v.Length);
}

// Group the files according to their size, leaving out


// files that are less than 200000 bytes.
var querySizeGroups =
from file in fileList
let len = GetFileLength(file)
where len > 0
group file by (len / 100000) into fileGroup
where fileGroup.Key >= 2
orderby fileGroup.Key descending
select fileGroup;

foreach (var filegroup in querySizeGroups)


{
Console.WriteLine(filegroup.Key.ToString() + "00000");
foreach (var item in filegroup)
{
Console.WriteLine("\t{0}: {1}", item.Name, item.Length);
}
}
}

// This method is used to swallow the possible exception


// that can be raised when accessing the FileInfo.Length property.
// In this particular case, it is safe to swallow the exception.
static long GetFileLength(System.IO.FileInfo fi)
{
long retval;
try
{
retval = fi.Length;
}
catch (System.IO.FileNotFoundException)
{
// If a file is no longer present,
// just add zero bytes to the total.
retval = 0;
retval = 0;
}
return retval;
}

Bir veya daha fazla tamamlanmış FileInfo nesne döndürmek için, sorgunun her birini veri kaynağında incelemesi
gerekir ve sonra bunları length özelliğinin değerine göre sıralayın. Ardından, en büyük uzunluklara sahip tek bir
veya sırası döndürebilir. Bir First listedeki ilk öğeyi döndürmek için kullanın. İlk Take n öğe sayısını döndürmek için
kullanın. Listenin başlangıcında en küçük öğeleri yerleştirmek için azalan bir sıralama düzeni belirtin.
Burada bir dosya silindi başka bir iş parçacığında bu yana zaman dönemi içindeki durumda gerçekleştirilecektir
olası özel kullanmak bayt cinsinden boyutunu almak için ayrı bir yöntem için sorguyu çağırır FileInfo nesne
oluşturulduğu çağrısında GetFiles . Nesne zaten oluşturulsa da, bir FileInfo nesne, özelliğin ilk kez en güncel
boyutunu bayt olarak yenilemeyi Length deneyeceğinden, özel durum oluşabilir. FileInfo Bu işlemi sorgu dışında
bir try-catch bloğuna yerleştirerek, sorguların içindeki işlemleri, yan etkilere neden olabilecek şekilde önleme
kuralını izliyoruz. Genel olarak, bir uygulamanın bilinmeyen bir durumda ayrılmadığından emin olmak için özel
durumlar tüketirken harika bir dikkatli olunması gerekir.

Kod Derleniyor
System. C# LINQ ve System.IO ad alanları using için yönergeler içeren bir konsol uygulaması projesi oluşturun.

Ayrıca bkz.
LINQ to Objects (C#)
LINQ ve dosya dizinleri (C#)
Nasıl yapılır: Bir dizin ağacında (LINQ) (C#) yinelenen
dosyalar için sorgu
23.10.2019 • 4 minutes to read • Edit Online

Bazen aynı ada sahip dosyalar birden fazla klasörde bulunabilir. Örneğin, Visual Studio yükleme klasörü altında,
birkaç klasör Readme. htm dosyasına sahiptir. Bu örnek, belirtilen bir kök klasör altında bu tür yinelenen dosya
adlarının nasıl sorgulanalınacağını gösterir. İkinci örnek, boyutu ve LastWrite süreleri de aynı olan dosyaların nasıl
sorgulanacağı gösterilmektedir.

Örnek
class QueryDuplicateFileNames
{
static void Main(string[] args)
{
// Uncomment QueryDuplicates2 to run that query.
QueryDuplicates();
// QueryDuplicates2();

// Keep the console window open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}

static void QueryDuplicates()


{
// Change the root drive or folder if necessary
string startFolder = @"c:\program files\Microsoft Visual Studio 9.0\";

// Take a snapshot of the file system.


System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(startFolder);

// This method assumes that the application has discovery permissions


// for all folders under the specified path.
IEnumerable<System.IO.FileInfo> fileList = dir.GetFiles("*.*", System.IO.SearchOption.AllDirectories);

// used in WriteLine to keep the lines shorter


int charsToSkip = startFolder.Length;

// var can be used for convenience with groups.


var queryDupNames =
from file in fileList
group file.FullName.Substring(charsToSkip) by file.Name into fileGroup
where fileGroup.Count() > 1
select fileGroup;

// Pass the query to a method that will


// output one page at a time.
PageOutput<string, string>(queryDupNames);
}

// A Group key that can be passed to a separate method.


// Override Equals and GetHashCode to define equality for the key.
// Override ToString to provide a friendly name for Key.ToString()
class PortableKey
{
public string Name { get; set; }
public DateTime LastWriteTime { get; set; }
public long Length { get; set; }
public override bool Equals(object obj)
{
PortableKey other = (PortableKey)obj;
return other.LastWriteTime == this.LastWriteTime &&
other.Length == this.Length &&
other.Name == this.Name;
}

public override int GetHashCode()


{
string str = $"{this.LastWriteTime}{this.Length}{this.Name}";
return str.GetHashCode();
}
public override string ToString()
{
return $"{this.Name} {this.Length} {this.LastWriteTime}";
}
}
static void QueryDuplicates2()
{
// Change the root drive or folder if necessary.
string startFolder = @"c:\program files\Microsoft Visual Studio 9.0\Common7";

// Make the lines shorter for the console display


int charsToSkip = startFolder.Length;

// Take a snapshot of the file system.


System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(startFolder);
IEnumerable<System.IO.FileInfo> fileList = dir.GetFiles("*.*", System.IO.SearchOption.AllDirectories);

// Note the use of a compound key. Files that match


// all three properties belong to the same group.
// A named type is used to enable the query to be
// passed to another method. Anonymous types can also be used
// for composite keys but cannot be passed across method boundaries
//
var queryDupFiles =
from file in fileList
group file.FullName.Substring(charsToSkip) by
new PortableKey { Name = file.Name, LastWriteTime = file.LastWriteTime, Length = file.Length }
into fileGroup
where fileGroup.Count() > 1
select fileGroup;

var list = queryDupFiles.ToList();

int i = queryDupFiles.Count();

PageOutput<PortableKey, string>(queryDupFiles);
}

// A generic method to page the output of the QueryDuplications methods


// Here the type of the group must be specified explicitly. "var" cannot
// be used in method signatures. This method does not display more than one
// group per page.
private static void PageOutput<K, V>(IEnumerable<System.Linq.IGrouping<K, V>> groupByExtList)
{
// Flag to break out of paging loop.
bool goAgain = true;

// "3" = 1 line for extension + 1 for "Press any key" + 1 for input cursor.
int numLines = Console.WindowHeight - 3;

// Iterate through the outer collection of groups.


foreach (var filegroup in groupByExtList)
{
// Start a new extension at the top of a page.
int currentLine = 0;
int currentLine = 0;

// Output only as many lines of the current group as will fit in the window.
do
{
Console.Clear();
Console.WriteLine("Filename = {0}", filegroup.Key.ToString() == String.Empty ? "[none]" :
filegroup.Key.ToString());

// Get 'numLines' number of items starting at number 'currentLine'.


var resultPage = filegroup.Skip(currentLine).Take(numLines);

//Execute the resultPage query


foreach (var fileName in resultPage)
{
Console.WriteLine("\t{0}", fileName);
}

// Increment the line counter.


currentLine += numLines;

// Give the user a chance to escape.


Console.WriteLine("Press any key to continue or the 'End' key to break...");
ConsoleKey key = Console.ReadKey().Key;
if (key == ConsoleKey.End)
{
goAgain = false;
break;
}
} while (currentLine < filegroup.Count());

if (goAgain == false)
break;
}
}
}

İlk sorgu, bir eşleşmeyi tespit etmek için basit bir anahtar kullanır; Bu, aynı ada sahip ancak içeriği farklı olabilecek
olan dosyaları bulur. İkinci sorgu, FileInfo nesnenin üç özellikleriyle eşleşmesi için bir bileşik anahtar kullanır. Bu
sorgu, aynı ada ve benzer veya özdeş içeriğe sahip dosyaları bulmak çok daha olasıdır.

Kod Derleniyor
System. C# LINQ ve System.IO ad alanları using için yönergeler içeren bir konsol uygulaması projesi oluşturun.

Ayrıca bkz.
LINQ to Objects (C#)
LINQ ve dosya dizinleri (C#)
Nasıl yapılır: bir klasördeki metin dosyalarının Içeriğini
sorgulama (LINQ) (C#)
25.11.2019 • 2 minutes to read • Edit Online

Bu örnek, belirtilen bir dizin ağacındaki tüm dosyaların üzerinde nasıl sorgu yapılacağını, her bir dosyanın nasıl
açılacağını ve içeriğini incelemenizi gösterir. Bu tür bir teknik, dizin ağacı içeriğinin dizinlerini veya ters dizinlerini
oluşturmak için kullanılabilir. Bu örnekte basit bir dize araması gerçekleştirilir. Ancak, bir normal ifadeyle, daha
karmaşık bir tür model eşleşmesi gerçekleştirilebilir. Daha fazla bilgi için bkz. LINQ sorgularını normal ifadelerle
birleştirme (C#).

Örnek
class QueryContents
{
public static void Main()
{
// Modify this path as necessary.
string startFolder = @"c:\program files\Microsoft Visual Studio 9.0\";

// Take a snapshot of the file system.


System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(startFolder);

// This method assumes that the application has discovery permissions


// for all folders under the specified path.
IEnumerable<System.IO.FileInfo> fileList = dir.GetFiles("*.*", System.IO.SearchOption.AllDirectories);

string searchTerm = @"Visual Studio";

// Search the contents of each file.


// A regular expression created with the RegEx class
// could be used instead of the Contains method.
// queryMatchingFiles is an IEnumerable<string>.
var queryMatchingFiles =
from file in fileList
where file.Extension == ".htm"
let fileText = GetFileText(file.FullName)
where fileText.Contains(searchTerm)
select file.FullName;

// Execute the query.


Console.WriteLine("The term \"{0}\" was found in:", searchTerm);
foreach (string filename in queryMatchingFiles)
{
Console.WriteLine(filename);
}

// Keep the console window open in debug mode.


Console.WriteLine("Press any key to exit");
Console.ReadKey();
}

// Read the contents of the file.


static string GetFileText(string name)
{
string fileContents = String.Empty;

// If the file has been deleted since we took


// the snapshot, ignore it and return the empty string.
if (System.IO.File.Exists(name))
{
fileContents = System.IO.File.ReadAllText(name);
}
return fileContents;
}
}

Kod Derleniyor
System. C# lınq ve System.IO ad alanları için using yönergeler içeren bir konsol uygulaması projesi oluşturun.

Ayrıca bkz.
LINQ ve dosya dizinleri (C#)
LINQ to Objects (C#)
Nasıl yapılır: LINQ (C#) ile ArrayList 'i sorgulama
25.11.2019 • 2 minutes to read • Edit Online

LINQ to ArrayList gibi genel olmayan IEnumerable koleksiyonlarını sorgulamak için kullandığınızda,
koleksiyondaki nesne türlerini yansıtacak şekilde Aralık değişkeninin türünü açıkça bildirmeniz gerekir. Örneğin,
Student nesneleri ArrayList varsa, from yan tümcesinden aşağıdaki gibi görünmelidir:

var query = from Student s in arrList


//...

Aralık değişkeninin türünü belirterek, ArrayList ' daki her öğeyi bir Student ' e dönüştürmektir.
Bir sorgu ifadesinde açıkça yazılmış bir aralık değişkeninin kullanılması Cast yöntemini çağırmaya eşdeğerdir.
Belirtilen tür dönüştürme gerçekleştirilemiyorsa Cast bir özel durum oluşturur. Cast ve OfType, genel olmayan
IEnumerable türlerinde çalışan iki standart sorgu Işleci yöntemleridir. Daha fazla bilgi için bkz. LINQ sorgu
Işlemlerinde tür ilişkileri.

Örnek
Aşağıdaki örnek, ArrayList üzerinde basit bir sorgu gösterir. Bu örnek, kod Add yöntemini çağırdığında nesne
başlatıcıları kullanır, ancak bu bir gereklilik değildir.
using System;
using System.Collections;
using System.Linq;

namespace NonGenericLINQ
{
public class Student
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int[] Scores { get; set; }
}

class Program
{
static void Main(string[] args)
{
ArrayList arrList = new ArrayList();
arrList.Add(
new Student
{
FirstName = "Svetlana", LastName = "Omelchenko", Scores = new int[] { 98, 92, 81, 60
}
});
arrList.Add(
new Student
{
FirstName = "Claire", LastName = "O’Donnell", Scores = new int[] { 75, 84, 91, 39 }
});
arrList.Add(
new Student
{
FirstName = "Sven", LastName = "Mortensen", Scores = new int[] { 88, 94, 65, 91 }
});
arrList.Add(
new Student
{
FirstName = "Cesar", LastName = "Garcia", Scores = new int[] { 97, 89, 85, 82 }
});

var query = from Student student in arrList


where student.Scores[0] > 95
select student;

foreach (Student s in query)


Console.WriteLine(s.LastName + ": " + s.Scores[0]);

// Keep the console window open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
}
/* Output:
Omelchenko: 98
Garcia: 97
*/

Ayrıca bkz.
LINQ to Objects (C#)
LINQ sorguları için özel yöntemler ekleme (C#)
25.11.2019 • 7 minutes to read • Edit Online

IEnumerable<T> arabirimine uzantı yöntemleri ekleyerek, LINQ sorguları için kullanabileceğiniz yöntemlerin
kümesini genişletebilirsiniz. Örneğin, standart ortalama veya en yüksek işlemlere ek olarak, bir dizi değerden tek
bir değeri hesaplamak için özel bir toplama yöntemi oluşturabilirsiniz. Ayrıca, bir dizi değer için özel bir filtre veya
belirli bir veri dönüştürmesi olarak çalışacak bir yöntem oluşturabilirsiniz ve yeni bir dizi döndürür. Bu tür
yöntemlere örnek olarak Distinct, Skipve Reverseverilebilir.
IEnumerable<T> arabirimini genişlettiğinizde, özel yöntemlerinizi herhangi bir sıralanabilir koleksiyona
uygulayabilirsiniz. Daha fazla bilgi için bkz. Uzantı yöntemleri.

Toplama yöntemi ekleme


Toplama yöntemi bir değer kümesinden tek bir değeri hesaplar. LINQ, Average, Minve Maxdahil olmak üzere
birkaç toplama yöntemi sağlar. IEnumerable<T> arabirimine bir genişletme yöntemi ekleyerek kendi toplama
yönteminizi oluşturabilirsiniz.
Aşağıdaki kod örneği, double tür bir sayı dizisi için ortanca hesaplamak üzere Median adlı bir genişletme
yönteminin nasıl oluşturulacağını gösterir.

public static class LINQExtension


{
public static double Median(this IEnumerable<double> source)
{
if (source.Count() == 0)
{
throw new InvalidOperationException("Cannot compute median for an empty set.");
}

var sortedList = from number in source


orderby number
select number;

int itemIndex = (int)sortedList.Count() / 2;

if (sortedList.Count() % 2 == 0)
{
// Even number of items.
return (sortedList.ElementAt(itemIndex) + sortedList.ElementAt(itemIndex - 1)) / 2;
}
else
{
// Odd number of items.
return sortedList.ElementAt(itemIndex);
}
}
}

Bu genişletme yöntemini, her türlü sıralanabilir koleksiyon için IEnumerable<T> arabiriminden diğer toplama
yöntemlerini çağırdığınız şekilde çağırabilirsiniz.
Aşağıdaki kod örneği, double türünde bir dizi için Median yönteminin nasıl kullanılacağını gösterir.
double[] numbers1 = { 1.9, 2, 8, 4, 5.7, 6, 7.2, 0 };

var query1 = numbers1.Median();

Console.WriteLine("double: Median = " + query1);

/*
This code produces the following output:

Double: Median = 4.85


*/

Çeşitli türleri kabul etmek için bir toplama yöntemini aşırı yükleme
Toplama yönteminizi çeşitli türlerde dizileri kabul edecek şekilde aşırı yükleyebilirsiniz. Standart yaklaşım, her tür
için bir aşırı yükleme oluşturmaktır. Başka bir yaklaşım ise genel bir tür alacak ve bir temsilciyi kullanarak belirli bir
türe dönüştürecek bir aşırı yükleme oluşturmaktır. Her iki yaklaşımı de birleştirebilirsiniz.
Her tür için bir aşırı yükleme oluşturmak için
Desteklemek istediğiniz her tür için belirli bir aşırı yükleme oluşturabilirsiniz. Aşağıdaki kod örneğinde, integer
türü için Median yönteminin aşırı yüklemesi gösterilmektedir.

//int overload

public static double Median(this IEnumerable<int> source)


{
return (from num in source select (double)num).Median();
}

Artık aşağıdaki kodda gösterildiği gibi integer ve double türleri için Median aşırı yüklerini çağırabilirsiniz:

double[] numbers1 = { 1.9, 2, 8, 4, 5.7, 6, 7.2, 0 };

var query1 = numbers1.Median();

Console.WriteLine("double: Median = " + query1);

int[] numbers2 = { 1, 2, 3, 4, 5 };

var query2 = numbers2.Median();

Console.WriteLine("int: Median = " + query2);

/*
This code produces the following output:

Double: Median = 4.85


Integer: Median = 3
*/

Genel aşırı yükleme oluşturmak için


Ayrıca, genel nesne dizisini kabul eden bir aşırı yükleme de oluşturabilirsiniz. Bu aşırı yükleme bir temsilciyi
parametre olarak alır ve bir genel türdeki nesne dizisini belirli bir türe dönüştürmek için kullanır.
Aşağıdaki kod, Func<T,TResult> temsilcisini bir parametre olarak alan Median yönteminin aşırı yüklemesini
gösterir. Bu temsilci, T genel türünde bir nesne alır ve double türünde bir nesne döndürür.
// Generic overload.

public static double Median<T>(this IEnumerable<T> numbers,


Func<T, double> selector)
{
return (from num in numbers select selector(num)).Median();
}

Artık herhangi bir türdeki nesne dizisi için Median yöntemini çağırabilirsiniz. Türün kendi yöntem aşırı yüklemesi
yoksa, bir temsilci parametresi geçirmeniz gerekir. ' C#De, bu amaçla bir lambda ifadesi kullanabilirsiniz. Ayrıca,
yalnızca Visual Basic içinde yöntem çağrısı yerine Aggregate veya Group By yan tümcesini kullanırsanız, bu yan
tümce kapsamındaki herhangi bir değer veya ifade geçirebilirsiniz.
Aşağıdaki örnek kod, bir tamsayılar dizisi ve dizeler dizisi için Median yönteminin nasıl çağrılacağını gösterir.
Dizeler için, dizideki dizelerin uzunluklarının ortancası hesaplanır. Örnek, Func<T,TResult> temsilci parametresinin
her durum için Median yöntemine nasıl geçirileceğini gösterir.

int[] numbers3 = { 1, 2, 3, 4, 5 };

/*
You can use the num=>num lambda expression as a parameter for the Median method
so that the compiler will implicitly convert its value to double.
If there is no implicit conversion, the compiler will display an error message.
*/

var query3 = numbers3.Median(num => num);

Console.WriteLine("int: Median = " + query3);

string[] numbers4 = { "one", "two", "three", "four", "five" };

// With the generic overload, you can also use numeric properties of objects.

var query4 = numbers4.Median(str => str.Length);

Console.WriteLine("String: Median = " + query4);

/*
This code produces the following output:

Integer: Median = 3
String: Median = 4
*/

Koleksiyon döndüren bir yöntem ekleme


IEnumerable<T> arabirimini bir değer dizisi döndüren özel bir sorgu yöntemiyle genişletebilirsiniz. Bu durumda,
yöntemin IEnumerable<T>türünde bir koleksiyon döndürmesi gerekir. Bu tür yöntemler, bir değerler dizisine filtre
veya veri dönüştürmeleri uygulamak için kullanılabilir.
Aşağıdaki örnek, ilk öğeden başlayarak bir koleksiyondaki her öğeyi döndüren AlternateElements adlı bir
genişletme yönteminin nasıl oluşturulacağını gösterir.
// Extension method for the IEnumerable<T> interface.
// The method returns every other element of a sequence.

public static IEnumerable<T> AlternateElements<T>(this IEnumerable<T> source)


{
List<T> list = new List<T>();

int i = 0;

foreach (var element in source)


{
if (i % 2 == 0)
{
list.Add(element);
}

i++;
}

return list;
}

Aşağıdaki kodda gösterildiği gibi, diğer yöntemleri IEnumerable<T> arabiriminden çağırdığınız gibi, herhangi bir
sıralanabilir koleksiyon için bu genişletme yöntemini çağırabilirsiniz:

string[] strings = { "a", "b", "c", "d", "e" };

var query = strings.AlternateElements();

foreach (var element in query)


{
Console.WriteLine(element);
}
/*
This code produces the following output:

a
c
e
*/

Ayrıca bkz.
IEnumerable<T>
Genişletme Yöntemleri
LINQ to XML genel bakışC#()
23.10.2019 • 7 minutes to read • Edit Online

LINQ to XML, .NET dil ile tümleşik sorgu (LINQ ) çerçevesini kullanan bellek içi bir XML programlama
arabirimi sağlar. LINQ to XML, .NET yeteneklerini kullanır ve güncelleştirilmiş, yeniden tasarlanan Belge Nesne
Modeli (DOM ) XML programlama arabirimine benzer.
XML, çok sayıda bağlamdaki verileri biçimlendirmeye yönelik bir yöntem olarak çok daha benimsemiştir.
Örneğin, Web 'de, yapılandırma dosyalarında, Microsoft Office Word dosyalarında ve veritabanlarında XML
bulabilirsiniz.
LINQ - XML, XML ile programlamaya yönelik güncel ve yeniden tasarlanan bir yaklaşımdır. Belge nesne
modeli (DOM ) için bellek içi belge değiştirme yeteneklerini sağlar ve sorgu ifadelerini destekler LINQ . Bu
sorgu ifadeleri XPath 'ten farklı bir şekilde farklılık içerse de, benzer işlevler sağlarlar.

LINQ to XML geliştiriciler


LINQ - XMLçeşitli geliştiricileri hedefler. Yalnızca bir şey yapmak isteyen ortalama bir geliştirici için, LINQ -
XML SQL 'e benzer bir sorgu deneyimi sağlayarak xml 'i daha kolay hale getirir. Yalnızca bir çok çalışma
sayesinde programcılar, tercih ettiğiniz programlama dilinde kısa ve güçlü sorgular yazmayı öğreniyor.
Profesyonel geliştiriciler, üretkenliğini LINQ - XML önemli ölçüde artırmak için kullanabilir. İle LINQ - XML,
daha açıklayıcı, daha kompakt ve daha güçlü bir kod yazabilir. Aynı anda birden çok veri etki alanından sorgu
ifadeleri kullanabilirler.

LINQ to XML nedir?


LINQ - XML, .NET Framework programlama dilleri içinden XML ile çalışmanıza olanak sağlayan, LINQ
özellikli, bellek içi bir XML programlama arabirimidir.
LINQ - XML, XML belgesini belleğe getiren Belge Nesne Modeli (DOM ) gibidir. Belgeyi sorgulayabilir ve
değiştirebilir ve değişiklik yaptıktan sonra dosyayı bir dosyaya kaydedebilir veya seri hale getirebilirsiniz ve
Internet üzerinden gönderebilirsiniz. Ancak, LINQ - XML Dom 'dan farklıdır: Daha açık ağırlığı olan yeni bir
nesne modeli sağlar ve ile çalışmak daha kolay ve ' deki C#dil özelliklerinden faydalanır.
Uygulamasının LINQ - XML en önemli avantajı ile Dil ile Tümleşik Sorgu (LINQ )Tümleştirmesidir. Bu
tümleştirme, öğelerin ve özniteliklerin koleksiyonlarını almak için bellek içi XML belgesi üzerinde sorgular
yazmanızı sağlar. Öğesinin LINQ - XML sorgu özelliği, XPath ve XQuery için işlevsellik (sözdiziminde değil) ile
karşılaştırılabilir. LINQ ' De C# tümleştirmesi, daha güçlü yazma, derleme zamanı denetimi ve geliştirilmiş hata
ayıklayıcı desteği sağlar.
' In LINQ - XML başka bir avantajı, sorgu sonuçlarının XAttribute parametre olarak kullanılması ve nesne
oluşturucuları, xml ağaçları oluşturmaya yönelik güçlü bir yaklaşım sağlar. XElement İşlevsel oluşturmaolarak
adlandırılan bu yaklaşım, geliştiricilerin XML ağaçlarını bir şekilden diğerine kolayca dönüştürmelerine olanak
sağlar.
Örneğin, örnek xml dosyasında açıklandığı gibi tipik bir XML satın alma siparişiniz olabilir: Tipik satın alma
siparişi (LINQ to XML ). Kullanarak LINQ - XML, satın alma sırasındaki her öğe öğesi için bölüm numarası
öznitelik değerini almak üzere aşağıdaki sorguyu çalıştırabilirsiniz:
// Load the XML file from our project directory containing the purchase orders
var filename = "PurchaseOrder.xml";
var currentDirectory = Directory.GetCurrentDirectory();
var purchaseOrderFilepath = Path.Combine(currentDirectory, filename);

XElement purchaseOrder = XElement.Load(purchaseOrderFilepath);

IEnumerable<string> partNos = from item in purchaseOrder.Descendants("Item")


select (string) item.Attribute("PartNumber");

Bu, yöntem sözdizimi biçiminde yeniden yazılabilir:

IEnumerable<string> partNos = purchaseOrder.Descendants("Item").Select(x => (string)


x.Attribute("PartNumber"));

Başka bir örnek olarak, $100 'den büyük bir değere sahip olan öğelerin bölüm numarasına göre sıralanmış bir
liste olmasını isteyebilirsiniz. Bu bilgileri almak için aşağıdaki sorguyu çalıştırabilirsiniz:

// Load the XML file from our project directory containing the purchase orders
var filename = "PurchaseOrder.xml";
var currentDirectory = Directory.GetCurrentDirectory();
var purchaseOrderFilepath = Path.Combine(currentDirectory, filename);

XElement purchaseOrder = XElement.Load(purchaseOrderFilepath);

IEnumerable<XElement> pricesByPartNos = from item in purchaseOrder.Descendants("Item")


where (int) item.Element("Quantity") * (decimal) item.Element("USPrice") >
100
orderby (string)item.Element("PartNumber")
select item;

Bu, yöntem sözdizimi biçiminde yeniden yazılabilir:

IEnumerable<XElement> pricesByPartNos = purchaseOrder.Descendants("Item")


.Where(item => (int)item.Element("Quantity") *
(decimal)item.Element("USPrice") > 100)
.OrderBy(order => order.Element("PartNumber"));

Bu LINQ yeteneklere ek olarak, LINQ - XML geliştirilmiş bir XML programlama arabirimi sağlar. Kullanarak
LINQ - XMLşunları yapabilirsiniz:
Dosyalardan veya akışlardanXML yükleyin.
XML 'yi dosyalara veya akışlara seri hale getirme.
İşlevsel oluşturma kullanarak sıfırdan XML oluşturun.
XPath benzeri eksenleri kullanarak XML 'yi sorgula.
, Add, Ve Remove ReplaceWithgibi yöntemlerikullanarakbellekiçixmlağacınıişleme.SetValue
XSD kullanarak XML ağaçlarını doğrulayın.
XML ağaçlarını bir şekilden diğerine dönüştürmek için bu özelliklerin birleşimini kullanın.

XML Ağaçları Oluşturma


Programlama LINQ - XML kullanmanın en önemli avantajlarından biri, xml ağaçları oluşturmak kolaydır.
Örneğin, küçük bir XML ağacı oluşturmak için aşağıdaki gibi bir kod yazabilirsiniz:
XElement contacts =
new XElement("Contacts",
new XElement("Contact",
new XElement("Name", "Patrick Hines"),
new XElement("Phone", "206-555-0144",
new XAttribute("Type", "Home")),
new XElement("phone", "425-555-0145",
new XAttribute("Type", "Work")),
new XElement("Address",
new XElement("Street1", "123 Main St"),
new XElement("City", "Mercer Island"),
new XElement("State", "WA"),
new XElement("Postal", "68042")
)
)
);

Daha fazla bilgi için bkz. xml ağaçları oluşturmaC#().

Ayrıca bkz.
Başvuru (LINQ to XML )
LINQ to XML ile DOM (C#)
LINQ to XML ile Diğer XML Teknolojileri Karşılaştırması
System.Xml.Linq
LINQ to XML ile DOM (C#)
23.10.2019 • 9 minutes to read • Edit Online

Bu bölümde, geçerli önceden baskın XML LINQ - XML programlama API 'si, W3C belge nesne modeli (DOM )
arasındaki bazı önemli farklılıklar açıklanmaktadır.

XML ağaçları oluşturmak için yeni yollar


W3C DOM 'da, aşağıdan yukarıya bir XML ağacı oluşturursunuz; diğer bir deyişle, bir belge oluşturur, öğeler
oluşturur ve sonra öğeleri belgeye eklersiniz.
Örneğin, aşağıdaki, DOM XmlDocument'ın Microsoft UYGULAMASıNı kullanarak bir XML ağacı oluşturmanın
tipik bir yoludur:

XmlDocument doc = new XmlDocument();


XmlElement name = doc.CreateElement("Name");
name.InnerText = "Patrick Hines";
XmlElement phone1 = doc.CreateElement("Phone");
phone1.SetAttribute("Type", "Home");
phone1.InnerText = "206-555-0144";
XmlElement phone2 = doc.CreateElement("Phone");
phone2.SetAttribute("Type", "Work");
phone2.InnerText = "425-555-0145";
XmlElement street1 = doc.CreateElement("Street1");
street1.InnerText = "123 Main St";
XmlElement city = doc.CreateElement("City");
city.InnerText = "Mercer Island";
XmlElement state = doc.CreateElement("State");
state.InnerText = "WA";
XmlElement postal = doc.CreateElement("Postal");
postal.InnerText = "68042";
XmlElement address = doc.CreateElement("Address");
address.AppendChild(street1);
address.AppendChild(city);
address.AppendChild(state);
address.AppendChild(postal);
XmlElement contact = doc.CreateElement("Contact");
contact.AppendChild(name);
contact.AppendChild(phone1);
contact.AppendChild(phone2);
contact.AppendChild(address);
XmlElement contacts = doc.CreateElement("Contacts");
contacts.AppendChild(contact);
doc.AppendChild(contacts);

Bu kodlama stili, XML ağacının yapısı hakkında görsel olarak çok fazla bilgi sağlamaz. LINQ - XML, bir XML ağacı
oluşturmak için bu yaklaşımı destekler, ancak alternatif bir yaklaşım, işlevsel oluşturmada destekler. İşlevsel yapım
bir XML XElement ağacı XAttribute oluşturmak için ve oluşturucularını kullanır.
İşlevsel oluşturma kullanarak LINQ - XML aynı xml ağacını nasıl oluşturabileceğiniz aşağıda açıklanmıştır:
XElement contacts =
new XElement("Contacts",
new XElement("Contact",
new XElement("Name", "Patrick Hines"),
new XElement("Phone", "206-555-0144",
new XAttribute("Type", "Home")),
new XElement("phone", "425-555-0145",
new XAttribute("Type", "Work")),
new XElement("Address",
new XElement("Street1", "123 Main St"),
new XElement("City", "Mercer Island"),
new XElement("State", "WA"),
new XElement("Postal", "68042")
)
)
);

XML ağacını oluşturmak için kodun girintilendiği, temel alınan XML 'nin yapısını gösterir.
Daha fazla bilgi için bkz. xml ağaçları oluşturmaC#().

Doğrudan XML öğeleriyle çalışma


XML ile programlama yaptığınızda, birincil odağınızı genellikle XML öğelerinde ve belki de özniteliklerde
bulabilirsiniz. İçinde LINQ - XML, doğrudan XML öğeleri ve özniteliklerle çalışabilirsiniz. Örneğin, şunları
yapabilirsiniz:
Bir belge nesnesi kullanmadan XML öğeleri oluşturun. Bu, XML ağaçlarının parçaları ile çalışmanız
gerektiğinde programlamayı basitleştirir.
Nesneleri T:System.Xml.Linq.XElement doğrudan bir XML dosyasından yükleyin.
Nesneleri T:System.Xml.Linq.XElement bir dosyaya veya akışa serileştirme.

Bu, XML belgesinin XML ağacı için bir mantıksal kapsayıcı olarak kullanıldığı W3C DOM ile karşılaştırın. DOM 'da,
öğeler ve öznitelikler dahil XML düğümlerinin bir XML belgesi bağlamında oluşturulması gerekir. DOM 'da bir ad
öğesi oluşturmak için kodun bir parçası aşağıda verilmiştir:

XmlDocument doc = new XmlDocument();


XmlElement name = doc.CreateElement("Name");
name.InnerText = "Patrick Hines";
doc.AppendChild(name);

Birden çok belge genelinde bir öğe kullanmak istiyorsanız düğümleri belgeler arasında içeri aktarmanız gerekir.
LINQ - XMLBu karmaşıklık katmanını önler.
LINQ to XML kullanırken, yalnızca belgenin kök düzeyinde XDocument bir yorum veya işleme yönergesi eklemek
istiyorsanız sınıfını kullanırsınız.

Adları ve ad alanlarını Basitleştirilmiş olarak Işleme


Adları, ad alanlarını ve ad alanı öneklerini işleme genellikle XML programlamanın karmaşık bir parçasıdır. LINQ -
XMLad alanı önekleriyle uğraşmak için gereksinimi ortadan kaldırarak adları ve ad alanlarını basitleştirir. Ad alanı
öneklerini denetlemek istiyorsanız, kullanabilirsiniz. Ancak ad alanı öneklerini açıkça denetistemediğinize karar
verirseniz, LINQ - XML gerektiğinde serileştirme sırasında ad alanı öneklerini atar veya varsayılan ad alanları
kullanılarak serileştirilir. Varsayılan ad alanları kullanılırsa, sonuçta elde edilen belgede ad alanı önekleri
olmayacaktır. Daha fazla bilgi için bkz. ad alanlarına genel bakış (C#LINQ to XML ) ().
DOM ile ilgili başka bir sorun da bir düğümün adını değiştirmenize izin vermez. Bunun yerine, yeni bir düğüm
oluşturmanız ve tüm alt düğümleri buna kopyalamanız ve özgün düğüm kimliğini kaybetmemeniz gerekir. LINQ -
XMLbir düğümdeki XName özelliği ayarlamanıza olanak tanıyarak bu sorunu önler.

XML yükleme için statik yöntem desteği


LINQ - XMLörnek yöntemleri yerine statik yöntemler kullanarak XML yüklemenize imkan tanır. Bu, yükleme ve
ayrıştırma işlemlerini basitleştirir. Daha fazla bilgi için nasıl yapılır: Bir dosyadan (C#) XML yükleyin.

DTD yapıları için desteği kaldırma


LINQ - XMLvarlıklar ve varlık başvuruları desteğini kaldırarak XML programlamayı daha da basitleştirir. Varlıkların
yönetimi karmaşıktır ve nadiren kullanılır. Desteğinin kaldırılması performansı artırır ve programlama arabirimini
basitleştirir. Bir LINQ - XML ağaç doldurulduğunda, tüm DTD varlıkları genişletilir.

Parçalar için destek


LINQ - XML XmlDocumentFragment sınıf için bir eşdeğer sağlamaz. Ancak XmlDocumentFragment pek çok durumda,
kavram, veya IEnumerable<T> IEnumerable<T> XNode' nin yazıldığı bir sorgunun sonucu tarafından işlenebilir.
XElement

XPathNavigator desteği
LINQ - XMLSystem.Xml.XPath ad alanındaki genişletme yöntemlerine yönelik XPathNavigator destek sağlar. Daha
fazla bilgi için bkz. System.Xml.XPath.Extensions.

Boşluk ve girintileme desteği


LINQ - XMLboşluğu DOM 'dan daha fazla işler.
Yaygın bir senaryo, girintili XML 'yi okumak, boşluk metin düğümleri olmadan bir bellek içi XML ağacı
oluşturmaktır (diğer bir deyişle, beyaz alanı korumadan), XML üzerinde bazı işlemleri gerçekleştirir ve ardından
XML 'i girintilemeli olarak kaydeder. XML 'yi biçimlendirme ile serileştirçalıştığınızda, XML ağacında yalnızca
önemli boşluk korunur. Bu varsayılan davranıştır LINQ - XML.
Diğer bir yaygın senaryo, daha önce kasıtlı olarak girintili olan XML 'i okuyup değiştirmektir. Bu Girintiyi istediğiniz
şekilde değiştirmek istemeyebilirsiniz. ' LINQ - XMLDe, XML 'i yüklediğinizde veya ayrıştırdığınızda ve
biçimlendirmeyi devre dışı bıraktığınızda, bu alanı beyaz alanı koruyarak yapabilirsiniz.
LINQ - XML, Dom gibi özelleştirilmiş XText Whitespace bir düğüm türüne sahip olmak yerine boşluğu düğüm
olarak depolar.

Ek açıklamalar için destek


LINQ - XMLöğeleri, genişletilebilir bir ek açıklama kümesini destekler. Bu, şema bilgileri, öğenin bir kullanıcı
arabirimine bağlanıp bağlanmayacağı veya başka bir uygulamaya özgü bilgi türü gibi bir öğeyle ilgili çeşitli bilgileri
izlemek için yararlıdır. Daha fazla bilgi için bkz. LINQ to XML ek açıklamaları.

Şema bilgileri için destek


LINQ - XMLSystem.Xml.Schema ad alanındaki genişletme yöntemleri aracılığıyla XSD doğrulaması için destek
sağlar. Bir XML ağacının bir XSD ile uyumlu olduğunu doğrulayabilirsiniz. XML ağacını şema-doğrulama sonrası
bilgi kümesi (PSVı) ile doldurabilirsiniz. Daha fazla bilgi için nasıl yapılır: XSD veExtensionskullanarak doğrulayın.
Ayrıca bkz.
Başlarken (LINQ to XML )
LINQ to XML ile Diğer XML Teknolojileri
Karşılaştırması
23.10.2019 • 6 minutes to read • Edit Online

Bu konu, LINQ - XML aşağıdaki XML teknolojileriyle karşılaştırılmaktadır: XmlReader, XSLT, MSXML ve xmllite.
Bu bilgiler hangi teknolojiyi kullanacağınızı belirlemenize yardımcı olabilir.
Belge nesne modeli (DOM ) LINQ - XML ile bir karşılaştırma için, bkz . LINQ to XML vs. DOM (C#).

LINQ to XML ile Değerine


XmlReaderhızlı, salt iletme, önbelleğe alınmamış bir ayrıştırıcıdır.
LINQ - XML, üzerine uygulanır ve sıkı XmlReaderbir şekilde tümleşiktir. Ancak, kendisi tarafından da
kullanabilirsiniz XmlReader .
Örneğin, saniyede yüzlerce XML belgesini ayrıştıracak bir Web hizmeti oluşturduğunuzu ve belgeler aynı yapıya
sahip olduğundan, yalnızca XML 'i ayrıştırmak için kodun bir uygulamasını yazmanız gerekir. Bu durumda
muhtemelen kendisi tarafından kullanmak XmlReader istersiniz.
Buna karşılık, birçok küçük XML belgesini çözümleyen bir sistem oluşturuyorsanız ve her biri farklıysa, tarafından
LINQ - XML sağlanan üretkenlik geliştirmelerinden yararlanmak isteyebilirsiniz.

LINQ to XML ile XSLT


Hem LINQ - XML hem de XSLT kapsamlı xml belgesi dönüştürme özellikleri sağlar. XSLT, kural tabanlı, bildirime
dayalı bir yaklaşımdır. Gelişmiş XSLT programcıları, XSLT 'nin durum bilgisi olmayan bir yaklaşımı vurgulayarak
işlevsel programlama stilinde yazar. Dönüşümler, yan etkileri olmadan uygulanan saf işlevleri kullanılarak
yazılabilir. Bu kural tabanlı veya işlevsel yaklaşım birçok geliştiricilere tanıdık değildir ve öğrenmesi zor ve zaman
alıcı olabilir.
XSLT, yüksek performanslı uygulamalar veren çok üretken bir sistem olabilir. Örneğin, bazı büyük Web şirketleri
XSLT 'yi çeşitli veri depolarından çekilen XML 'den HTML oluşturmak için bir yol olarak kullanır. Yönetilen XSLT
altyapısı XSLT koduna XSLT derler ve yerel XSLT altyapısından daha iyi bir şekilde çalışır.
Ancak XSLT, birçok geliştiricinin sahip olduğu C# ve Visual Basic bilgilerden yararlanır. Geliştiricilerin farklı ve
karmaşık bir programlama dilinde kod yazmasını gerektirir. C# (Veya Visual Basic) gibi tümleşik olmayan iki
geliştirme SISTEMINI ve XSLT 'nin geliştirilmesi ve bakımının daha zor olduğu yazılım sistemlerinde sonuçları.
Ana Kopyalı LINQ - XML sorgu LINQ - XML ifadeleriniz olduktan sonra dönüşümler kullanımı kolay güçlü bir
teknolojidir. Temel olarak, işlevsel oluşturma, çeşitli kaynaklardan XElement veri çekme, nesneleri dinamik olarak
oluşturma ve tümünü yeni bir XML ağacına çevirme kullanarak XML belgenizi oluşturursunuz. Dönüştürme
tamamen yeni bir belge oluşturabilir. İçindeki LINQ - XML dönüştürmeleri oluşturmak nispeten kolaydır ve
sezgisel olur ve elde edilen kod okunabilir. Bu, geliştirme ve bakım maliyetlerini azaltır.
LINQ - XMLXSLT 'yi değiştirmek için tasarlanmamıştır. XSLT, özellikle de belgenin yapısı iyi tanımlanmamışsa,
karmaşık ve belge merkezli XML dönüştürmeleri için seçim aracı olmaya devam etmektedir.
XSLT, World Wide Web Konsorsiyumu (W3C ) standardı olmasının avantajına sahiptir. Yalnızca standartları olan
teknolojileri kullandığınız bir gereksinime sahipseniz, XSLT daha uygun olabilir.
XSLT XML 'dir ve bu nedenle programlı bir şekilde yönetilebilir.
LINQ to XML ile MSXML
MSXML, Microsoft Windows 'a dahil edilen XML 'yi işlemeye yönelik COM tabanlı teknolojisidir. MSXML, XPath
ve XSLT desteğiyle DOM 'ın yerel bir uygulamasını sağlar. Ayrıca, SAX2 önbelleğe alınmamış olay tabanlı
ayrıştırıcısı da içerir.
MSXML iyi çalışır, Çoğu senaryoda varsayılan olarak güvenlidir ve AJAX stili uygulamalarda istemci tarafı XML
işleme gerçekleştirmek için Internet Explorer 'da erişilebilir. MSXML, JavaScript ve Visual Basic 6,0 dahil olmak
üzere C++com desteği olan herhangi bir programlama dilinden kullanılabilir.
MSXML, ortak dil çalışma zamanı (CLR ) temelinde yönetilen kodda kullanım için önerilmez.

LINQ to XML ile Yönelik


XmlLite önbelleğe alma, iletme, çekme ayrıştırıcısıdır. Geliştiriciler öncelikle ile C++XmlLite kullanır. Geliştiricilerin
yönetilen kodla XmlLite kullanması önerilmez.
XmlLite 'ın başlıca avantajı, Çoğu senaryoda güvenli olan hafif ve hızlı bir XML ayrıştırıcısıdır. Tehdit yüzeyi alanı
çok küçük. Güvenilmeyen belgeleri ayrıştırmanıza ve hizmet reddi ya da veri pozlaması gibi saldırılara karşı
korunmak istiyorsanız, XmlLite iyi bir seçenek olabilir.
XmlLite ile Dil ile Tümleşik Sorgu (LINQ )tümleştirilmiştir. Bu, arka plandaki LINQzorlamaya yönelik programcı
üretkenlik geliştirmelerini vermez.

Ayrıca bkz.
Başlarken (LINQ to XML )
İşlevsel ve Yordamsal programlama (LINQ to XML)
(C#)
23.10.2019 • 2 minutes to read • Edit Online

Çeşitli türlerdeki XML uygulamaları vardır:


Bazı uygulamalar kaynak XML belgelerini alır ve kaynak belgelerden farklı bir şekilde yeni XML belgeleri
oluşturur.
Bazı uygulamalar kaynak XML belgelerini alır ve sonuç belgelerini HTML veya CSV metin dosyaları gibi
tamamen farklı bir biçimde oluşturur.
Bazı uygulamalar kaynak XML belgelerini alır ve bir veritabanına kayıt ekler.
Bazı uygulamalar, bir veritabanı gibi başka bir kaynaktan veri alır ve bundan XML belgesi oluşturur.
Bunlar, XML uygulaması türlerinin hepsi değildir, ancak bunlar bir XML Programlayıcısının uygulamak zorunda
olduğu işlevsellik türlerinin temsili bir kümesidir.
Bu tür uygulamaların tümünde, bir geliştiricinin uygulayabileceğiniz iki yaklaşım vardır:
Bildirim temelli bir yaklaşım kullanılarak işlevsel oluşturma.
Yordamsal kodu kullanarak bellek içi XML ağacı değişikliği.
LINQ to XML her iki yaklaşımı destekler.
İşlevsel yaklaşımı kullanırken, kaynak belgeleri alan ve istenen şekle sahip tamamen yeni sonuç belgeleri oluşturan
dönüşümler yazarsınız.
Bir XML ağacını yerinde değiştirirken, düğüm içi bir XML ağacındaki düğümlerde geçen ve gezinen, düğümleri
ekleme, silme ve değiştirme gibi bir kod yazın.
LINQ to XML iki yaklaşımla de kullanabilirsiniz. Aynı sınıfları ve bazı durumlarda aynı yöntemleri kullanırsınız.
Ancak, iki yaklaşımdan oluşan yapı ve hedefler çok farklıdır. Örneğin, farklı durumlarda, bir veya diğer yaklaşım
genellikle daha iyi performansa sahip olur ve daha fazla veya daha az bellek kullanır. Buna ek olarak, bir veya başka
bir yaklaşım daha fazla erişilebilir kod yazmak ve sağlamak daha kolay olacaktır.
Bu iki yaklaşımı görmek için bkz . bellek içi XML ağacı değişikliği vs. İşlevsel oluşturma (LINQ to XML ) (C#).
İşlev dönüştürmeleri yazma hakkında bir öğretici için bkz. XML (C#) saf işlevsel dönüştürmeleri.

Ayrıca bkz.
LINQ to XML programlamaya genel bakışC#()
LINQ to XML sınıflara genel bakışC#()
23.10.2019 • 4 minutes to read • Edit Online

Bu konu, LINQ - XML System.Xml.Linq ad alanındaki sınıfların bir listesini ve her birinin kısa bir açıklamasını sağlar.

LINQ to XML sınıfları


XAttribute sınıfı
XAttributebir XML özniteliğini temsil eder. Ayrıntılı bilgi ve örnekler için bkz. XAttribute sınıfına genel bakışC#().
XCData sınıfı
XCDataCDATA metin düğümünü temsil eder.
XComment sınıfı
XCommentbir XML açıklamasını temsil eder.
XContainer sınıfı
XContainer, alt düğümlere sahip olan tüm düğümler için soyut bir temel sınıftır. Aşağıdaki sınıflar XContainer
sınıfından türetilir:
XElement
XDocument
XDeclaration sınıfı
XDeclarationbir XML bildirimini temsil eder. XML bildirimi, XML sürümünü ve bir belgenin kodlamasını bildirmek
için kullanılır. Ayrıca, XML bildirimi XML belgesinin tek başına olup olmadığını belirtir. Bir belge bağımsız ise, dış bir
DTD 'de ya da iç alt kümeden başvurulan bir dış parametre varlığında dış biçimlendirme bildirimleri yoktur.
XDocument sınıfı
XDocumentbir XML belgesini temsil eder. Ayrıntılı bilgi ve örnekler için bkz. XDocument sınıfına genel bakışC#().
XDocumentType sınıfı
XDocumentTypebir XML belge türü tanımını (DTD ) temsil eder.
XElement sınıfı
XElementbir XML öğesini temsil eder. Ayrıntılı bilgi ve örnekler için bkz. XElement sınıfına genel bakışC#().
XName sınıfı
XNameöğelerin (XElement) ve özniteliklerin (XAttribute) adlarını temsil eder. Ayrıntılı bilgi ve örnekler için bkz.
XDocument sınıfına genel bakışC#().
LINQ - XMLXML adlarını mümkün olduğunca kolay hale getirmek için tasarlanmıştır. Karmaşıklığı nedeniyle XML
adları genellikle XML 'de gelişmiş bir konu olarak kabul edilir. Bu karmaşıklık, geliştiricilerin programlama içinde
düzenli olarak kullanıldığı, ancak ad alanı öneklerinden bağımsız olarak, ad alanlarından değildir. Ad alanı önekleri,
XML girişi yaparken veya XML 'in okunması daha kolay hale getirmek için gereken tuş vuruşlarını azaltmak için
faydalı olabilir. Ancak, ön ekler genellikle tam XML ad alanını kullanmak için bir kısayoldur ve çoğu durumda gerekli
değildir. LINQ - XMLTüm ön ekleri karşılık gelen XML ad uzayına çözümleyerek XML adlarını basitleştirir. Zorunlu
olmaları durumunda, ön ekler, GetPrefixOfNamespace yöntemi aracılığıyla kullanılabilir.
Gerekirse, ad alanı öneklerini denetlemek mümkündür. Bazı durumlarda, XSLT veya XAML gibi diğer XML
sistemleriyle çalışıyorsanız, ad alanı öneklerini kontrol etmeniz gerekir. Örneğin, ad alanı öneklerini kullanan ve
XSLT stil sayfasına gömülü bir XPath ifadeniz varsa, XML belgenizin XPath ifadesinde kullanılanlarla eşleşen ad
alanı önekleri ile serileştirildiğinizden emin olmanız gerekir.
XNamespace sınıfı
XNamespaceXElement orXAttributeiçin bir ad alanı temsil eder. Ad alanları bir XNamebileşenidir.
XNode sınıfı
XNode, bir XML ağacının düğümlerini temsil eden soyut bir sınıftır. Aşağıdaki sınıflar XNode sınıfından türetilir:
XText
XContainer
XComment
XProcessingInstruction
XDocumentType
XNodeDocumentOrderComparer sınıfı
XNodeDocumentOrderComparerdüğümlerini Belge sıralarına göre karşılaştırmak için işlevsellik sağlar.
XNodeEqualityComparer sınıfı
XNodeEqualityComparerdeğer eşitliği için düğümleri karşılaştırmak için işlevsellik sağlar.
XObject sınıfı
XObject, ve XNode XAttributeöğesinin soyut taban sınıfıdır. Ek açıklama ve olay işlevselliği sağlar.
XObjectChange sınıfı
XObjectChangebir XObjectolay oluşturulduğunda olay türünü belirtir.
XObjectChangeEventArgs sınıfı
XObjectChangeEventArgsChanging veChanged olayları için veri sağlar.
XProcessingInstruction sınıfı
XProcessingInstructionbir XML işleme yönergesini temsil eder. Bir işleme yönergesi, XML 'i işleyen bir
uygulamayla ilgili bilgiler iletir.
XText sınıfı
XTextbir metin düğümünü temsil eder. Çoğu durumda, bu sınıfı kullanmak zorunda değilsiniz. Bu sınıf öncelikle
karışık içerik için kullanılır.

Ayrıca bkz.
LINQ to XML programlamaya genel bakışC#()
XElement sınıfına genel bakışC#()
23.10.2019 • 3 minutes to read • Edit Online

Sınıfı, içindeki LINQ - XMLtemel sınıflardan biridir. XElement Bir XML öğesini temsil eder. Bu sınıfı, öğeler
oluşturmak için kullanabilirsiniz; öğenin içeriğini değiştirme; alt öğeleri ekleyin, değiştirin veya silin; özniteliği bir
öğeye ekleyin; veya metin biçimindeki bir öğenin içeriğini seri hale getirme. Ayrıca, ve System.Xml XmlWriter
XmlReader gibidiğersınıflarladabirliktekullanabilirsinizXslCompiledTransform.
Bu konu, XElement sınıfının sunduğu işlevselliği açıklar.

XML ağaçları oluşturma


Aşağıdakiler dahil olmak üzere çeşitli yollarla XML ağaçları oluşturabilirsiniz:
Kodda bir XML ağacı oluşturabilirsiniz. Daha fazla bilgi için bkz. xml ağaçları oluşturmaC#().
Bir TextReadermetin dosyası veya bir Web adresi (URL ) dahil olmak üzere çeşitli kaynaklardan XML
ayrıştırabilirsiniz. Daha fazla bilgi için bkz. XML (C#) ayrıştırma.
Ağacı doldurmak XmlReader için kullanabilirsiniz. Daha fazla bilgi için bkz. ReadFrom.
İçine içerik XmlWriteryazabileceği bir modülünüzün varsa, bir yazıcı oluşturmak, yazıcıyı modüle
CreateWriter geçirmek ve ardından XML ağacını doldurmak XmlWriter için öğesine yazılan içeriği
kullanmak için yöntemini kullanabilirsiniz.
Ancak, bir XML ağacı oluşturmanın en yaygın yolu aşağıdaki gibidir:

XElement contacts =
new XElement("Contacts",
new XElement("Contact",
new XElement("Name", "Patrick Hines"),
new XElement("Phone", "206-555-0144"),
new XElement("Address",
new XElement("Street1", "123 Main St"),
new XElement("City", "Mercer Island"),
new XElement("State", "WA"),
new XElement("Postal", "68042")
)
)
);

Bir XML ağacı oluşturmaya yönelik başka bir çok yaygın teknik, aşağıdaki örnekte gösterildiği gibi LINQ , bir xml
ağacını doldurmak için bir sorgunun sonuçlarının kullanılmasını içerir:
XElement srcTree = new XElement("Root",
new XElement("Element", 1),
new XElement("Element", 2),
new XElement("Element", 3),
new XElement("Element", 4),
new XElement("Element", 5)
);
XElement xmlTree = new XElement("Root",
new XElement("Child", 1),
new XElement("Child", 2),
from el in srcTree.Elements()
where (int)el > 2
select el
);
Console.WriteLine(xmlTree);

Bu örnek aşağıdaki çıktıyı üretir:

<Root>
<Child>1</Child>
<Child>2</Child>
<Element>3</Element>
<Element>4</Element>
<Element>5</Element>
</Root>

XML Ağaçlarını Serileştirme


XML ağacını bir File, a TextWriterveya XmlWriterolarak seri hale getirebilirsiniz.
Daha fazla bilgi için bkz. XML ağaçlarını serileştirmeC#().

XML verilerini eksen yöntemleri aracılığıyla alma


Öznitelikleri, alt öğeleri, alt öğeleri ve üst öğeleri almak için eksen yöntemlerini kullanabilirsiniz. LINQsorgular
eksen yöntemleri üzerinde çalışır ve bir XML ağacı üzerinde gezinmek ve işlemek için çeşitli esnek ve güçlü yollar
sunar.
Daha fazla bilgi için bkz. LINQ to XML eksenleriC#().

XML Ağaçlarını Sorgulama


XML ağacından veri LINQ çıkaran sorgular yazabilirsiniz.
Daha fazla bilgi için bkz. XML ağaçlarını sorgulamaC#().

XML ağaçlarını değiştirme


Bir öğeyi, içeriğini veya özniteliklerini değiştirme gibi çeşitli yollarla değiştirebilirsiniz. Ayrıca bir öğeyi üst
öğesinden da kaldırabilirsiniz.
Daha fazla bilgi için bkz. XML ağaçlarını değiştirme (LINQ to XML )C#().

Ayrıca bkz.
LINQ to XML programlamaya genel bakışC#()
XAttribute sınıfına genel bakışC#()
23.10.2019 • 2 minutes to read • Edit Online

Öznitelikler, bir öğesiyle ilişkili ad/değer çiftleridir. XAttribute Sınıfı XML özniteliklerini temsil eder.

Genel Bakış
İçindeki LINQ - XML özniteliklerle çalışma, öğelerle çalışmaya benzerdir. Oluşturucular benzerdir. Bunların
koleksiyonlarını almak için kullandığınız yöntemler benzerdir. Öznitelik koleksiyonu için bir LINQ
sorguifadesibiröğekoleksiyonuiçinsorguifadesineçokbenzerşekildegörünür.LINQ
Öznitelikleri bir öğeye eklenme sırası korunur. Diğer bir deyişle, özniteliklerde yineleme yaparken, bunları eklendiği
sırayla görürsünüz.

XAttribute Oluşturucusu
XAttribute Sınıfının aşağıdaki Oluşturucusu, en yaygın olarak kullanabileceğiniz bir sınıftır:

OLUŞTURUCU AÇIKLAMA

XAttribute(XName name, object content) Oluşturur bir XAttribute nesne. name Bağımsız değişken
özniteliğin adını belirtir; content özniteliğin içeriğini belirtir.

Özniteliği olan bir öğe oluşturma


Aşağıdaki kod, bir özniteliği içeren bir öğe oluşturma ortak görevini gösterir:

XElement phone = new XElement("Phone",


new XAttribute("Type", "Home"),
"555-555-5555");
Console.WriteLine(phone);

Bu örnek aşağıdaki çıktıyı üretir:

<Phone Type="Home">555-555-5555</Phone>

Özniteliklerin işlevsel olarak oluşturulması


Nesneleri oluşturmak XAttribute için XElement aşağıdaki gibi nesneleri satır içinde oluşturabilirsiniz:
XElement c = new XElement("Customers",
new XElement("Customer",
new XElement("Name", "John Doe"),
new XElement("PhoneNumbers",
new XElement("Phone",
new XAttribute("type", "home"),
"555-555-5555"),
new XElement("Phone",
new XAttribute("type", "work"),
"666-666-6666")
)
)
);
Console.WriteLine(c);

Bu örnek aşağıdaki çıktıyı üretir:

<Customers>
<Customer>
<Name>John Doe</Name>
<PhoneNumbers>
<Phone type="home">555-555-5555</Phone>
<Phone type="work">666-666-6666</Phone>
</PhoneNumbers>
</Customer>
</Customers>

Öznitelikler düğüm değil


Öznitelikler ve öğeler arasında bazı farklılıklar vardır. XAttributenesneler XML ağacındaki düğümler değildir. Bunlar
bir XML öğesiyle ilişkili ad/değer çiftleridir. Belge Nesne Modeli (DOM ) aksine bu, XML yapısını daha yakından
yansıtır. Nesneler XAttribute gerçekte XML ağacında düğümler olmasa da nesnelerle XAttribute çalışma, XElement
nesnelerle çalışmaya çok benzer.
Bu ayrım, birincil olarak yalnızca düğüm düzeyindeki XML ağaçları ile çalışan kod yazan geliştiriciler için önemlidir.
Birçok geliştirici bu ayrım ile ilgilenmeyecektir.

Ayrıca bkz.
LINQ to XML programlamaya genel bakışC#()
XDocument sınıfına genel bakışC#()
23.10.2019 • 3 minutes to read • Edit Online

Bu konu XDocument sınıfı tanıtır.

XDocument sınıfına genel bakış


Sınıfı XDocument , geçerli bir XML belgesi için gereken bilgileri içerir. Buna bir XML bildirimi, işleme yönergeleri
ve açıklamalar dahildir.
Yalnızca XDocument sınıfXDocument tarafından sunulan belirli işlevselliğe ihtiyacınız varsa nesneler oluşturmanız
gerektiğini unutmayın. Birçok durumda, doğrudan ile XElementçalışabilirsiniz. İle XElement doğrudan çalışmak
daha basit bir programlama modelidir.
XDocumenttüretiliyor XContainer. Bu nedenle, alt düğümler içerebilir. Ancak, XDocument nesneler yalnızca bir alt
XElement düğüme sahip olabilir. Bu, bir XML belgesinde yalnızca bir kök öğe olabilecek XML standardını yansıtır.

XDocument bileşenleri
XDocument , Aşağıdaki öğeleri içerebilir:
Bir XDeclaration nesne. XDeclarationXML bildiriminin ilgili parçalarını belirtmenizi sağlar: XML sürümü,
belgenin kodlaması ve XML belgesinin tek başına olup olmadığı.
Bir XElement nesne. Bu, XML belgesinin kök düğümüdür.
Herhangi bir sayıda XProcessingInstruction nesne. Bir işleme yönergesi, XML 'i işleyen bir uygulamayla
ilgili bilgiler iletir.
Herhangi bir sayıda XComment nesne. Yorumlar, kök öğesi için eşdüzey olacak. XComment Nesne, bir XML
belgesinin bir açıklama ile başlaması için geçerli olmadığından, listedeki ilk bağımsız değişken olamaz.
DTD XDocumentType için bir tane.
Bir XDocument Writer.Settings.OmitXmlDeclaration false seri hale getirmek istediğinizde,, yazıcı olarak
ayarlandıysa çıkış bir XML bildirimine sahip olacaktır (varsayılan). XDocument.Declaration null
Varsayılan olarak, LINQ - XML sürümü "1,0" olarak ayarlar ve kodlamayı "UTF -8" olarak ayarlar.

XDocument olmadan XElement kullanma


Daha önce belirtildiği gibi, XElement sınıfı LINQ - XML programlama arabirimindeki ana sınıftır. Çoğu durumda,
uygulamanız bir belge oluşturmanızı gerektirmez. XElement Sınıfını kullanarak bir XML ağacı oluşturabilir, buna
başka xml ağaçları ekleyebilir, xml ağacını değiştirebilir ve kaydedebilirsiniz.

XDocument kullanma
Oluşturmak XDocumentiçin, nesneleri oluşturmak XElement için yaptığınız gibi işlevsel oluşturma kullanın.
Aşağıdaki kod bir XDocument nesne ve ilişkili içerilen nesneleri oluşturur.
XDocument d = new XDocument(
new XComment("This is a comment."),
new XProcessingInstruction("xml-stylesheet",
"href='mystyle.css' title='Compact' type='text/css'"),
new XElement("Pubs",
new XElement("Book",
new XElement("Title", "Artifacts of Roman Civilization"),
new XElement("Author", "Moreno, Jordao")
),
new XElement("Book",
new XElement("Title", "Midieval Tools and Implements"),
new XElement("Author", "Gazit, Inbar")
)
),
new XComment("This is another comment.")
);
d.Declaration = new XDeclaration("1.0", "utf-8", "true");
Console.WriteLine(d);

d.Save("test.xml");

Test. xml dosyasını incelediğinizde aşağıdaki çıktıyı alırsınız:

<?xml version="1.0" encoding="utf-8"?>


<!--This is a comment.-->
<?xml-stylesheet href='mystyle.css' title='Compact' type='text/css'?>
<Pubs>
<Book>
<Title>Artifacts of Roman Civilization</Title>
<Author>Moreno, Jordao</Author>
</Book>
<Book>
<Title>Midieval Tools and Implements</Title>
<Author>Gazit, Inbar</Author>
</Book>
</Pubs>
<!--This is another comment.-->

Ayrıca bkz.
LINQ to XML programlamaya genel bakışC#()
LINQ to XML örnekleri oluşturma (C#)
25.11.2019 • 2 minutes to read • Edit Online

Bu belgelerdeki çeşitli kod parçacıkları ve örnekler çeşitli ad alanlarından sınıfları ve türleri kullanır. Kodu derlerken
C# uygun using yönergelerini sağlamanız gerekir.

Örnek
Aşağıdaki kod, C# örneklerin derlemek ve çalıştırmak için gereken using yönergelerini içerir. Her örnek için using
yönergelerinin hepsi gerekli değildir.

using System;
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Schema;
using System.Xml.XPath;
using System.Xml.Xsl;
using System.IO;
using System.Threading;
using System.Reflection;
using System.IO.Packaging;

Ayrıca bkz.
LINQ to XML programlamaya genel bakışC#()
İşlevsel oluşturma (LINQ to XML) (C#)
23.10.2019 • 2 minutes to read • Edit Online

LINQ - XML adlı XML öğeleri oluşturmak için güçlü bir yol sağlar işlevsel oluşturma. Tek bir deyimde bir XML
ağacı oluşturma olanağı işlevsel yapısıdır.
Birkaç temel özellikleri vardır LINQ - XML işlevsel oluşturma sağlayan bir programlama arabirimi:
XElement Oluşturucusu, çeşitli içerik için bağımsız değişkenleri alır. Örneğin, başka bir geçirebilirsiniz
XElement bir alt öğesi olan nesne. Geçirebilirsiniz bir XAttribute öğesinin bir özniteliği olan nesne. Veya
başka türde bir nesne bir dizeye dönüştürülür ve öğenin metin içeriğini olur geçirebilirsiniz.
XElement Oluşturucusu alır bir params türünde dizi Object, böylece herhangi bir sayıda nesneleri için
oluşturucu geçirebilirsiniz. Bu, karmaşık içeriğe sahip bir öğe oluşturmanıza olanak sağlar.
Bir nesne uyguluyorsa IEnumerable<T>, koleksiyon nesnesi içinde listelenmiş ve koleksiyondaki tüm
öğelerin eklenir. Koleksiyon içeriyorsa XElement veya XAttribute nesneler, koleksiyondaki her öğe ayrı olarak
eklenir. Sonuçlarını geçirmenize izin verdiğinden, bu önemli bir LINQ Sorgu Oluşturucusu.
Bu özellikleri bir XML ağacı oluşturmak için kod yazmanıza olanak sağlar. Bir örnek verilmiştir:

XElement contacts =
new XElement("Contacts",
new XElement("Contact",
new XElement("Name", "Patrick Hines"),
new XElement("Phone", "206-555-0144"),
new XElement("Address",
new XElement("Street1", "123 Main St"),
new XElement("City", "Mercer Island"),
new XElement("State", "WA"),
new XElement("Postal", "68042")
)
)
);

Bu özellikler ayrıca sonuçlarını kullanan kod yazmanıza etkinleştirme LINQ sorgular ne zaman bir XML ağacı şu
şekilde oluşturun:

XElement srcTree = new XElement("Root",


new XElement("Element", 1),
new XElement("Element", 2),
new XElement("Element", 3),
new XElement("Element", 4),
new XElement("Element", 5)
);
XElement xmlTree = new XElement("Root",
new XElement("Child", 1),
new XElement("Child", 2),
from el in srcTree.Elements()
where (int)el > 2
select el
);
Console.WriteLine(xmlTree);

Bu örnek aşağıdaki çıktıyı üretir:


<Root>
<Child>1</Child>
<Child>2</Child>
<Element>3</Element>
<Element>4</Element>
<Element>5</Element>
</Root>
İçinde C# xml ağaçları oluşturma (LINQ to XML)
23.10.2019 • 7 minutes to read • Edit Online

Bu bölüm içinde C#xml ağaçları oluşturma hakkında bilgi sağlar.


LINQ sorgularının sonuçlarını bir XElementiçin içerik olarak kullanma hakkında daha fazla bilgi için bkz. işlevsel
oluşturma (LINQ to XML ) (C#).

Öğeleri oluşturma
XElement VeXAttribute oluşturucuların imzaları, öğe veya özniteliğin içeriğini oluşturucuya bağımsız değişken
olarak geçirmenize olanak sağlar. Oluşturuculardan biri değişken sayıda bağımsız değişken kullandığından,
herhangi bir sayıda alt öğe geçirebilirsiniz. Kuşkusuz, bu alt öğelerin her biri kendi alt öğelerini içerebilir. Herhangi
bir öğe için istediğiniz sayıda öznitelik ekleyebilirsiniz.
(Dahil XNode XElement) veyaXAttribute nesneleri eklerken, yeni içeriğin üst öğesi yoksa, nesneler yalnızca XML
ağacına eklenir. Yeni içerik zaten üst öğe ise ve başka bir XML ağacının parçasıysa, yeni içerik kopyalanır ve yeni
kopyalanan içerik XML ağacına eklenir. Bu konudaki son örnekte bu gösterilmektedir.
contacts OluşturmakXElementiçin aşağıdaki kodu kullanabilirsiniz:

XElement contacts =
new XElement("Contacts",
new XElement("Contact",
new XElement("Name", "Patrick Hines"),
new XElement("Phone", "206-555-0144"),
new XElement("Address",
new XElement("Street1", "123 Main St"),
new XElement("City", "Mercer Island"),
new XElement("State", "WA"),
new XElement("Postal", "68042")
)
)
);

Doğru şekilde girintilense, nesneleri oluşturmak XElement için kullanılan kod, temel alınan XML yapısına benzer.

XElement oluşturucuları
XElement Sınıfı, işlevsel oluşturma için aşağıdaki oluşturucuları kullanır. İçin XElementbaşka bazı oluşturucular
olduğunu, ancak işlevsel oluşturma için kullanıldıklarından, burada listelenmediğini unutmayın.

OLUŞTURUCU AÇIKLAMA

XElement(XName name, object content) XElementOluşturur. name Parametresi, öğesinin adını belirtir;
content öğenin içeriğini belirtir.

XElement(XName name) Başlatıldıktan sonra XElement belirtilen ada sahip bir oluşturur.
XName

XElement(XName name, params object[] content) Başlatıldıktan sonra XElement belirtilen ada sahip bir oluşturur.
XName Öznitelikler ve/veya alt öğeleri parametre listesinin
içeriğinden oluşturulur.
content Parametresi son derece esnektir. Geçerli bir XElementalt öğesi olan herhangi bir nesne türünü destekler.
Bu parametreye geçirilen farklı nesne türleri için aşağıdaki kurallar geçerlidir:
Metin içeriği olarak bir dize eklenir.
Bir XElement alt öğesi olarak eklenir.
Bir XAttribute öznitelik olarak eklenir.
XProcessingInstruction, VeyaaltXTextiçerikolarakeklenir. XComment
Bir IEnumerable numaralandırılır ve bu kurallar sonuçlara özyinelemeli olarak uygulanır.
Diğer herhangi bir tür için, ToString metodu çağrılır ve sonuç metin içeriği olarak eklenir.
İçerikle XElement oluşturma
Tek bir yöntem çağrısıyla XElement basit içerik içeren bir oluşturabilirsiniz. Bunu yapmak için, içeriği ikinci
parametre olarak aşağıdaki gibi belirtin:

XElement n = new XElement("Customer", "Adventure Works");


Console.WriteLine(n);

Bu örnek aşağıdaki çıktıyı üretir:

<Customer>Adventure Works</Customer>

Herhangi bir nesne türünü içerik olarak geçirebilirsiniz. Örneğin, aşağıdaki kod, içerik olarak kayan noktalı sayı
içeren bir öğe oluşturur:

XElement n = new XElement("Cost", 324.50);


Console.WriteLine(n);

Bu örnek aşağıdaki çıktıyı üretir:

<Cost>324.5</Cost>

Kayan nokta numarası paketlenmelidir ve oluşturucuya geçirilir. Kutulanmış sayı bir dizeye dönüştürülür ve
öğesinin içeriği olarak kullanılır.
Alt öğesiyle XElement oluşturma
İçerik bağımsız değişkeni için XElement sınıfının bir örneğini geçirirseniz, Oluşturucu bir alt öğesi olan bir öğesi
oluşturur:

XElement shippingUnit = new XElement("ShippingUnit",


new XElement("Cost", 324.50)
);
Console.WriteLine(shippingUnit);

Bu örnek aşağıdaki çıktıyı üretir:

<ShippingUnit>
<Cost>324.5</Cost>
</ShippingUnit>
Birden çok alt öğe içeren bir XElement oluşturma
İçerik için bir dizi XElement nesne geçirebilirsiniz. XElement Nesnelerin her biri bir alt öğe olarak dahil edilir.

XElement address = new XElement("Address",


new XElement("Street1", "123 Main St"),
new XElement("City", "Mercer Island"),
new XElement("State", "WA"),
new XElement("Postal", "68042")
);
Console.WriteLine(address);

Bu örnek aşağıdaki çıktıyı üretir:

<Address>
<Street1>123 Main St</Street1>
<City>Mercer Island</City>
<State>WA</State>
<Postal>68042</Postal>
</Address>

Yukarıdaki örneği genişleterek, bir XML ağacının tamamını aşağıdaki gibi oluşturabilirsiniz:

XElement contacts =
new XElement("Contacts",
new XElement("Contact",
new XElement("Name", "Patrick Hines"),
new XElement("Phone", "206-555-0144"),
new XElement("Address",
new XElement("Street1", "123 Main St"),
new XElement("City", "Mercer Island"),
new XElement("State", "WA"),
new XElement("Postal", "68042")
)
)
);
Console.WriteLine(contacts);

Bu örnek aşağıdaki çıktıyı üretir:

<Contacts>
<Contact>
<Name>Patrick Hines</Name>
<Phone>206-555-0144</Phone>
<Address>
<Street1>123 Main St</Street1>
<City>Mercer Island</City>
<State>WA</State>
<Postal>68042</Postal>
</Address>
</Contact>
</Contacts>

XAttribute ile XElement oluşturma


İçerik bağımsız değişkeni için XAttribute sınıfının bir örneğini geçirirseniz, Oluşturucu bir özniteliği olan bir öğesi
oluşturur:
XElement phone = new XElement("Phone",
new XAttribute("Type", "Home"),
"555-555-5555");
Console.WriteLine(phone);

Bu örnek aşağıdaki çıktıyı üretir:

<Phone Type="Home">555-555-5555</Phone>

Boş bir öğe oluşturma


Boş XElementbir oluşturmak için, oluşturucuya herhangi bir içerik geçirmeyin. Aşağıdaki örnek boş bir öğe
oluşturur:

XElement n = new XElement("Customer");


Console.WriteLine(n);

Bu örnek aşağıdaki çıktıyı üretir:

<Customer />

Ekleme ile kopyalama


Daha önce belirtildiği gibi, ( XNode dahil) XElementveya XAttribute nesneleri eklerken (dahil), yeni içeriğin üst
öğesi yoksa, nesneler yalnızca XML ağacına eklenir. Yeni içerik zaten üst öğe ise ve başka bir XML ağacının
parçasıysa, yeni içerik kopyalanır ve yeni kopyalanan içerik XML ağacına eklenir.
Aşağıdaki örnek, bir ağaca bir üst öğeye sahip bir öğe eklediğinizde ve bir ağaca üst öğesi olmayan bir öğe
eklediğinizde davranışını gösterir.

// Create a tree with a child element.


XElement xmlTree1 = new XElement("Root",
new XElement("Child1", 1)
);

// Create an element that is not parented.


XElement child2 = new XElement("Child2", 2);

// Create a tree and add Child1 and Child2 to it.


XElement xmlTree2 = new XElement("Root",
xmlTree1.Element("Child1"),
child2
);

// Compare Child1 identity.


Console.WriteLine("Child1 was {0}",
xmlTree1.Element("Child1") == xmlTree2.Element("Child1") ?
"attached" : "cloned");

// Compare Child2 identity.


Console.WriteLine("Child2 was {0}",
child2 == xmlTree2.Element("Child2") ?
"attached" : "cloned");

// The example displays the following output:


// Child1 was cloned
// Child2 was attached
Ayrıca bkz.
XML ağaçları oluşturma (C#)
Nasıl yapılır: bir dizeyi ayrıştırma (C#)
25.11.2019 • 2 minutes to read • Edit Online

Bu konuda, içinde C#bir XML ağacı oluşturmak için bir dizeyi ayrıştırma gösterilmektedir.

Örnek
Aşağıdaki C# kod, bir XML dizesinin nasıl ayrıştıralınacağını gösterir:

XElement contacts = XElement.Parse(


@"<Contacts>
<Contact>
<Name>Patrick Hines</Name>
<Phone Type=""home"">206-555-0144</Phone>
<Phone Type=""work"">425-555-0145</Phone>
<Address>
<Street1>123 Main St</Street1>
<City>Mercer Island</City>
<State>WA</State>
<Postal>68042</Postal>
</Address>
<NetWorth>10</NetWorth>
</Contact>
<Contact>
<Name>Gretchen Rivas</Name>
<Phone Type=""mobile"">206-555-0163</Phone>
<Address>
<Street1>123 Main St</Street1>
<City>Mercer Island</City>
<State>WA</State>
<Postal>68042</Postal>
</Address>
<NetWorth>11</NetWorth>
</Contact>
</Contacts>");
Console.WriteLine(contacts);

Kök Contacts düğümünün iki Contact düğümü vardır. Ayrıştırılmış XML 'deki belirli verilere erişmek için, bu
örnekte kök Contacts düğümünün alt öğelerini döndüren XElement. Elements () yöntemini kullanın. Aşağıdaki
örnek, ilk Contact düğümünü konsola yazdırır:

List<XElement> contactNodes = contacts.Elements("Contact").ToList();


Console.WriteLine(contactNodes[0]);

Ayrıca bkz.
Belirli bir özniteliğe (C#) sahip bir öğe bulma
Nasıl yapılır: Dosyadan XML yükle (C#)
23.10.2019 • 2 minutes to read • Edit Online

Bu konuda, XElement.Load yöntemi kullanılarak bir URI 'den XML yükleme gösterilmektedir.

Örnek
Aşağıdaki örnek, bir dosyadan bir XML belgesinin nasıl yükleneceğini gösterir. Aşağıdaki örnek, Books. xml ' i
yükler ve XML ağacını konsola çıkarır.
Bu örnek aşağıdaki XML belgesini kullanır: Örnek XML dosyası: Kitaplar (LINQ to XML ).

XElement booksFromFile = XElement.Load(@"books.xml");


Console.WriteLine(booksFromFile);

Bu kod aşağıdaki çıktıyı üretir:

<Catalog>
<Book id="bk101">
<Author>Garghentini, Davide</Author>
<Title>XML Developer's Guide</Title>
<Genre>Computer</Genre>
<Price>44.95</Price>
<PublishDate>2000-10-01</PublishDate>
<Description>An in-depth look at creating applications
with XML.</Description>
</Book>
<Book id="bk102">
<Author>Garcia, Debra</Author>
<Title>Midnight Rain</Title>
<Genre>Fantasy</Genre>
<Price>5.95</Price>
<PublishDate>2000-12-16</PublishDate>
<Description>A former architect battles corporate zombies,
an evil sorceress, and her own childhood to become queen
of the world.</Description>
</Book>
</Catalog>
XML Yükleme veya Ayrıştırma Sırasında Boşluk
Koruma
23.10.2019 • 3 minutes to read • Edit Online

Bu konu, ' nin LINQ - XMLbeyaz boşluk davranışının nasıl kontrol edileceğini açıklar.
Yaygın bir senaryo, girintili XML 'yi okumak, boşluk metin düğümleri olmadan bir bellek içi XML ağacı
oluşturmaktır (diğer bir deyişle, beyaz alanı korumadan), XML üzerinde bazı işlemleri gerçekleştirir ve ardından
XML 'i girintilemeli olarak kaydeder. XML 'yi biçimlendirme ile serileştirçalıştığınızda, XML ağacında yalnızca
önemli boşluk korunur. Bu varsayılan davranıştır LINQ - XML.
Diğer bir yaygın senaryo, daha önce kasıtlı olarak girintili olan XML 'i okuyup değiştirmektir. Bu Girintiyi istediğiniz
şekilde değiştirmek istemeyebilirsiniz. Bunu yapmak LINQ - XMLiçin, XML 'i yüklediğinizde veya ayrıştırdığınızda
veya XML 'yi seri hale alırken biçimlendirmeyi devre dışı bıraktığınızda boşluğu koruyabilirsiniz.
Bu konuda, XML ağaçlarını dolduran yöntemlerin beyaz boşluk davranışı açıklanmaktadır. XML ağaçlarını seri hale
getirirken boşluk denetleme hakkında daha fazla bilgi için bkz. serileştirilirken boşluk koruma.

XML ağaçlarını dolduran yöntemlerin davranışı


XElement VeXDocument sınıflarında aşağıdaki yöntemler bir xml ağacını dolduracaktır. Bir dosya, bir TextReader
XmlReader, bir veya bir dizeden bir xml ağacını doldurabilirsiniz:
XElement.Load
XElement.Parse
XDocument.Load
XDocument.Parse
Yöntem bir bağımsız değişken LoadOptions olarak kullanmıyorsa, Yöntem önemli olmayan boşlukları korumaz.
Çoğu durumda, yöntemi bir bağımsız değişken olarak LoadOptions alırsa, isteğe bağlı boşluğu XML ağacında
metin düğümleri olarak koruyabilirsiniz. Ancak, yöntemi bir XmlReader XmlReader öğesinden XML 'yi
yüklüyorsanız, boşluk olup olmayacağını belirler. Ayarın PreserveWhitespace hiçbir etkisi olmayacaktır.
Bu yöntemlerle, boşluk korununca, düğüm olarak XText XML ağacına önemli bir boşluk eklenir. Boşluk korunmazsa,
metin düğümleri eklenmez.
Kullanarak bir XML ağacı oluşturabilirsiniz XmlWriter. Öğesine XmlWriter yazılan düğümler ağaçta doldurulur.
Ancak, bu yöntemi kullanarak bir XML ağacı oluşturduğunuzda, düğümün boşluk olup olmamasına veya boşluk
olmasına bakılmaksızın tüm düğümler korunur.
Ayrıştırma hatalarını yakalama (C#)
25.11.2019 • 2 minutes to read • Edit Online

Bu konu, hatalı biçimlendirilmiş veya geçersiz XML 'nin nasıl algılanacağını göstermektedir.
LINQ - XML, XmlReaderkullanılarak uygulanır. Hatalı biçimlendirilmiş veya geçersiz XML LINQ - XMLgeçirilirse,
temel alınan XmlReader sınıfı bir özel durum oluşturur. XElement.Parsegibi XML 'yi ayrıştırmaya yönelik çeşitli
yöntemler özel durumu yakalayamaz; özel durum daha sonra uygulamanız tarafından yakalanarak.

Örnek
Aşağıdaki kod geçersiz XML 'i ayrıştırmayı dener:

try {
XElement contacts = XElement.Parse(
@"<Contacts>
<Contact>
<Name>Jim Wilson</Name>
</Contact>
</Contcts>");

Console.WriteLine(contacts);
}
catch (System.Xml.XmlException e)
{
Console.WriteLine(e.Message);
}

Bu kodu çalıştırdığınızda, aşağıdaki özel durumu oluşturur:

The 'Contacts' start tag on line 1 does not match the end tag of 'Contcts'. Line 5, position 13.

XElement.Parse, XDocument.Parse, XElement.Loadve XDocument.Load yöntemlerini oluşturmak için beklediğinizi


belirten özel durumlar hakkında daha fazla bilgi için, bkz. XmlReader belgeleri.
XmlReader 'dan ağaç oluşturma (C#)
25.11.2019 • 2 minutes to read • Edit Online

Bu konu başlığında doğrudan bir XmlReader XML ağacının nasıl oluşturulacağı gösterilmektedir. Bir XmlReader
XElement oluşturmak için, XmlReader bir öğe düğümüne konumlandırmalısınız. XmlReader Yorumları ve işleme
talimatlarını atlar, ancak XmlReader bir metin düğümünde konumlandırılmışsa bir hata oluşturulur. Bu tür
hatalardan kaçınmak için, XmlReader bir XML ağacı oluşturmadan önce XmlReader her zaman bir öğe üzerinde
konumlandırın.

Örnek
Bu örnek, şu XML belgesini kullanır: örnek xml dosyası: kitaplar (LINQ to XML ).
Aşağıdaki kod bir T:System.Xml.XmlReader nesnesi oluşturur ve ilk öğe düğümünü bulana kadar düğümleri okur.
Daha sonra XElement nesnesini yükler.

XmlReader r = XmlReader.Create("books.xml");
while (r.NodeType != XmlNodeType.Element)
r.Read();
XElement e = XElement.Load(r);
Console.WriteLine(e);

Bu örnek aşağıdaki çıktıyı üretir:

<Catalog>
<Book id="bk101">
<Author>Garghentini, Davide</Author>
<Title>XML Developer's Guide</Title>
<Genre>Computer</Genre>
<Price>44.95</Price>
<PublishDate>2000-10-01</PublishDate>
<Description>An in-depth look at creating applications
with XML.</Description>
</Book>
<Book id="bk102">
<Author>Garcia, Debra</Author>
<Title>Midnight Rain</Title>
<Genre>Fantasy</Genre>
<Price>5.95</Price>
<PublishDate>2000-12-16</PublishDate>
<Description>A former architect battles corporate zombies,
an evil sorceress, and her own childhood to become queen
of the world.</Description>
</Book>
</Catalog>

Ayrıca bkz.
XML (C#) ayrıştırılıyor
Nasıl yapılır: XmlReader (C#) öğesinden XML
parçaları akışı
23.10.2019 • 3 minutes to read • Edit Online

Büyük XML dosyalarını işlemek zorunda olduğunuzda, tüm XML ağacının belleğe yüklenmesi mümkün
olmayabilir. Bu konuda, kullanarak XmlReaderparçaların nasıl akışının yapılacağı gösterilmektedir.
Nesneleri okumak XmlReader XElement için kullanmanın en etkili yöntemlerinden biri kendi özel eksen
yönteminizi yazmaktır. Bir Axis yöntemi XElement, bu konudaki örnekte gösterildiği gibi IEnumerable<T>
genellikle gibi bir koleksiyon döndürür. Özel eksen yönteminde, ReadFrom yöntemini çağırarak XML parçasını
oluşturduktan sonra, kullanarak yield return koleksiyonu döndürün. Bu, özel eksen yönteminiz için ertelenmiş
yürütme semantiğini sağlar.
XmlReader Nesnesinden bir XML ağacı oluşturduğunuzda, öğesinin bir öğe üzerinde konumlandırılmış
olmasıgerekir.XmlReader ReadFrom Yöntemi, öğenin kapanış etiketini okuuncaya kadar döndürmez.
Kısmi bir ağaç oluşturmak isterseniz, bir XmlReader XElement ağaca dönüştürmek istediğiniz düğümde okuyucuyu
konumlandırabilirsiniz ve sonra XElement nesneyi oluşturabilirsiniz. Bu, bir ağacı oluşturabilir.
Bu konuda nasıl yapılır: Üst bilgi bilgilerine (C#) erişimi olan akış XML parçaları, daha karmaşık bir belgenin nasıl
akışla ilgili bilgi ve bir örnek içerir.
Bu konuda nasıl yapılır: Büyük XML belgelerinin (C#) akış dönüşümünü gerçekleştirme, küçük bir bellek parmak
düzeyini koruyarak son derece büyük XML belgelerini dönüştürmek için LINQ to XML kullanma örneği içerir.

Örnek
Bu örnek bir özel eksen yöntemi oluşturur. LINQ Sorgu kullanarak sorgulama yapabilirsiniz. Özel eksen yöntemi
StreamRootChildDoc , bir yinelenen Child öğesi olan bir belgeyi okumak için özel olarak tasarlanan bir yöntemdir.
static IEnumerable<XElement> StreamRootChildDoc(StringReader stringReader)
{
using (XmlReader reader = XmlReader.Create(stringReader))
{
reader.MoveToContent();
// Parse the file and display each of the nodes.
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
if (reader.Name == "Child") {
XElement el = XElement.ReadFrom(reader) as XElement;
if (el != null)
yield return el;
}
break;
}
}
}
}

static void Main(string[] args)


{
string markup = @"<Root>
<Child Key=""01"">
<GrandChild>aaa</GrandChild>
</Child>
<Child Key=""02"">
<GrandChild>bbb</GrandChild>
</Child>
<Child Key=""03"">
<GrandChild>ccc</GrandChild>
</Child>
</Root>";

IEnumerable<string> grandChildData =
from el in StreamRootChildDoc(new StringReader(markup))
where (int)el.Attribute("Key") > 1
select (string)el.Element("GrandChild");

foreach (string str in grandChildData) {


Console.WriteLine(str);
}
}

Bu örnek aşağıdaki çıktıyı üretir:

bbb
ccc

Bu örnekte, kaynak belge çok küçüktür. Ancak milyonlarca Child öğe olsa bile, bu örnekte küçük bir bellek ayak
izine sahip olmaya devam edersiniz.
Nasıl yapılır: Bir XmlWriter ile bir XML ağacını
doldurma (LINQ to XML) (C#)
23.10.2019 • 2 minutes to read • Edit Online

Bir xml ağacını doldurmanın bir yolu CreateWriter XmlWriter, oluşturmak XmlWriterve sonra öğesine yazmak için
kullanmaktır. XML ağacı, XmlWriterüzerine yazılan tüm düğümlerle doldurulur.
Bu yöntemi genellikle, LINQ - XML XmlWritergibi bir öğesine yazmayı bekleyen başka bir sınıf ile kullandığınızda
kullanırsınız. XslCompiledTransform

Örnek
İçin CreateWriter olası bir kullanım XSLT dönüşümünü çağırırken olur. Bu örnek bir XML ağacı oluşturur, XML
ağacından XmlReader bir oluşturur, yeni bir belge oluşturur ve yeni belgeye yazmak için bir XmlWriter oluşturur.
Ardından, XmlReader ve XmlWritergeçirerek XSLT dönüşümünü çağırır. Dönüştürme başarıyla tamamlandıktan
sonra, yeni XML ağacı dönüştürmenin sonuçlarıyla doldurulur.

string xslMarkup = @"<?xml version='1.0'?>


<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
<xsl:template match='/Parent'>
<Root>
<C1>
<xsl:value-of select='Child1'/>
</C1>
<C2>
<xsl:value-of select='Child2'/>
</C2>
</Root>
</xsl:template>
</xsl:stylesheet>";

XDocument xmlTree = new XDocument(


new XElement("Parent",
new XElement("Child1", "Child1 data"),
new XElement("Child2", "Child2 data")
)
);

XDocument newTree = new XDocument();


using (XmlWriter writer = newTree.CreateWriter())
{
// Load the style sheet.
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(XmlReader.Create(new StringReader(xslMarkup)));

// Execute the transformation and output the results to a writer.


xslt.Transform(xmlTree.CreateReader(), writer);
}

Console.WriteLine(newTree);

Bu örnek aşağıdaki çıktıyı üretir:


<Root>
<C1>Child1 data</C1>
<C2>Child2 data</C2>
</Root>

Ayrıca bkz.
CreateWriter
XmlWriter
XslCompiledTransform
XML ağaçları oluşturma (C#)
Nasıl yapılır: XSD kullanarak doğrula (LINQ to XML)
(C#)
23.10.2019 • 2 minutes to read • Edit Online

Ad System.Xml.Schema alanı, bir xml ağacının bir XML şeması tanım dili (xsd) dosyasına göre doğrulanmasını
kolaylaştıran uzantı yöntemleri içerir. Daha fazla bilgi için Validate yöntem belgelerine bakın.

Örnek
Aşağıdaki örnek bir XmlSchemaSetoluşturur, sonra şema kümesinde iki XDocument nesneyi doğrular. Belgelerden
biri geçerli, diğeri değildir.

string xsdMarkup =
@"<xsd:schema xmlns:xsd='http://www.w3.org/2001/XMLSchema'>
<xsd:element name='Root'>
<xsd:complexType>
<xsd:sequence>
<xsd:element name='Child1' minOccurs='1' maxOccurs='1'/>
<xsd:element name='Child2' minOccurs='1' maxOccurs='1'/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>";
XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add("", XmlReader.Create(new StringReader(xsdMarkup)));

XDocument doc1 = new XDocument(


new XElement("Root",
new XElement("Child1", "content1"),
new XElement("Child2", "content1")
)
);

XDocument doc2 = new XDocument(


new XElement("Root",
new XElement("Child1", "content1"),
new XElement("Child3", "content1")
)
);

Console.WriteLine("Validating doc1");
bool errors = false;
doc1.Validate(schemas, (o, e) =>
{
Console.WriteLine("{0}", e.Message);
errors = true;
});
Console.WriteLine("doc1 {0}", errors ? "did not validate" : "validated");

Console.WriteLine();
Console.WriteLine("Validating doc2");
errors = false;
doc2.Validate(schemas, (o, e) =>
{
Console.WriteLine("{0}", e.Message);
errors = true;
});
Console.WriteLine("doc2 {0}", errors ? "did not validate" : "validated");
Bu örnek aşağıdaki çıktıyı üretir:

Validating doc1
doc1 validated

Validating doc2
The element 'Root' has invalid child element 'Child3'. List of possible elements expected: 'Child2'.
doc2 did not validate

Örnek
Aşağıdaki örnek, XML belgesinin örnek XML dosyasından bulunduğunu doğrular: Müşteriler ve siparişler (LINQ
to XML ) örnek xsd dosyasından şema başına geçerlidir: Müşteriler ve siparişler. Sonra kaynak XML belgesini
değiştirir. İlk Müşterideki CustomerID özniteliği değiştirir. Değişiklik sonrasında, siparişler var olmayan bir
müşteriye başvuracaktır, bu nedenle XML belgesi artık doğrulanmaz.
Bu örnek aşağıdaki XML belgesini kullanır: Örnek XML dosyası: Müşteriler ve siparişler (LINQ to XML ).
Bu örnek, aşağıdaki XSD şemasını kullanır: Örnek XSD Dosyası: Müşteriler ve siparişler.

XmlSchemaSet schemas = new XmlSchemaSet();


schemas.Add("", "CustomersOrders.xsd");

Console.WriteLine("Attempting to validate");
XDocument custOrdDoc = XDocument.Load("CustomersOrders.xml");
bool errors = false;
custOrdDoc.Validate(schemas, (o, e) =>
{
Console.WriteLine("{0}", e.Message);
errors = true;
});
Console.WriteLine("custOrdDoc {0}", errors ? "did not validate" : "validated");

Console.WriteLine();
// Modify the source document so that it will not validate.
custOrdDoc.Root.Element("Orders").Element("Order").Element("CustomerID").Value = "AAAAA";
Console.WriteLine("Attempting to validate after modification");
errors = false;
custOrdDoc.Validate(schemas, (o, e) =>
{
Console.WriteLine("{0}", e.Message);
errors = true;
});
Console.WriteLine("custOrdDoc {0}", errors ? "did not validate" : "validated");

Bu örnek aşağıdaki çıktıyı üretir:

Attempting to validate
custOrdDoc validated

Attempting to validate after modification


The key sequence 'AAAAA' in Keyref fails to refer to some key.
custOrdDoc did not validate

Ayrıca bkz.
Validate
XML ağaçları oluşturma (C#)
XElement ve XDocument Nesnelerinin Geçerli İçeriği
23.10.2019 • 4 minutes to read • Edit Online

Bu konuda, öğelere ve belgelere içerik eklemek için kullandığınız oluşturuculara ve yöntemlere geçirilebilecek
geçerli bağımsız değişkenler açıklanmaktadır.

Geçerli Içerik
IEnumerable<T> Sorgular genellikle XElement veya IEnumerable<T> 'XAttributenin sonucunu vermez. XElement
VeyaXAttribute nesneXElement koleksiyonlarını oluşturucuya geçirebilirsiniz. Bu nedenle, bir sorgunun sonuçlarını,
XML ağaçlarını doldurmak için kullandığınız yöntemlere ve oluşturuculara içerik olarak geçirmek kullanışlı olur.
Basit içerik eklerken bu yönteme çeşitli türler geçirilebilir. Geçerli türler şunlardır:
String
Double
Single
Decimal
Boolean
DateTime
TimeSpan
DateTimeOffset
Uygulayan Object.ToString herhangi bir tür.
Uygulayan IEnumerable<T>herhangi bir tür.
Karmaşık içerik eklerken bu yönteme çeşitli türler geçirilebilir:
XObject
XNode
XAttribute
Uygulayan herhangi bir türIEnumerable<T>
Bir nesne uygularsa IEnumerable<T>, nesne içindeki koleksiyon numaralandırılır ve koleksiyondaki tüm öğeler
eklenir. Koleksiyon veya XNode XAttribute nesneler içeriyorsa, koleksiyondaki her öğe ayrı ayrı eklenir. Koleksiyon
metin içeriyorsa (veya metne dönüştürülen nesneler), koleksiyondaki metin birleştirilir ve tek bir metin düğümü
olarak eklenir.
İçerik null varsa, hiçbir şey eklenmez. Koleksiyonda bir koleksiyon öğelerini geçirirken olabilir null .
Koleksiyondaki null bir öğenin ağacı üzerinde hiçbir etkisi yoktur.
Eklenen bir öznitelik, kapsayan öğesi içinde benzersiz bir ada sahip olmalıdır.
XNode VeyaXAttribute nesneleri eklerken, yeni içeriğin üst öğesi yoksa, nesneler yalnızca XML ağacına eklenir. Yeni
içerik zaten üst öğe ise ve başka bir XML ağacının parçasıysa, yeni içerik kopyalanır ve yeni kopyalanan içerik XML
ağacına eklenir.
Belgeler için geçerli Içerik
Öznitelikler ve basit içerik belgeye eklenemez.
Oluşturmanız gereken pek çok senaryo yoktur XDocument. Bunun yerine, genellikle bir XElement kök düğümü
olan XML ağaçlarınızı oluşturabilirsiniz. Bir belge oluşturmak için özel bir gereksinime sahip değilseniz (örneğin, en
üst düzeyde işlem yönergeleri ve açıklamalar oluşturmanız veya belge türlerini desteklemeniz gerektiğinden),
genellikle kök düğümünüz olarak kullanılması XElement daha uygundur.
Bir belge için geçerli içerik şunları içerir:
Sıfır veya bir XDocumentType nesne. Belge türlerinin öğeden önce gelmesi gerekir.
Sıfır veya bir öğe.
Sıfır veya daha fazla açıklama.
Sıfır veya daha fazla işleme yönergesi.
Yalnızca boşluk içeren sıfır veya daha fazla metin düğümü.

Içerik eklemeye Izin veren oluşturucular ve Işlevler


Aşağıdaki yöntemler bir XElement XDocumentveya öğesine alt içerik eklemenize olanak tanır:

YÖNTEM AÇIKLAMA

XElement XElementOluşturur.

XDocument Bir XDocumentoluşturur.

Add XElement VeyaXDocumentalt içeriğinin sonuna ekler.

AddAfterSelf Öğesinden sonra XNodeiçerik ekler.

AddBeforeSelf Öğesinden önce XNodeiçerik ekler.

AddFirst Öğesinin alt içeriğinin başlangıcına içerik ekler XContainer.

ReplaceAll Bir XElementöğesinin tüm içeriğini (alt düğümleri ve


öznitelikleri) değiştirir.

ReplaceAttributes İçindeki özniteliklerini XElementdeğiştirir.

ReplaceNodes Alt düğümleri yeni içerikle değiştirir.

ReplaceWith Bir düğümü yeni içerikle değiştirir.

Ayrıca bkz.
XML ağaçları oluşturma (C#)
Ad Alanlarına Genel Bakış (LINQ to XML)
23.10.2019 • 3 minutes to read • Edit Online

Bu makale ad alanlarını, XName sınıfı XNamespace ve sınıfı tanıtır.

XML adları
XML adları genellikle XML programlamada karmaşıklık kaynağıdır. Xml adı bir XML ad alanından (XML ad
alanı URI 'SI olarak da bilinir) ve yerel bir ada oluşur. XML ad alanı, .NET Framework tabanlı programdaki bir
ad alanına benzerdir. Öğelerin ve özniteliklerin adlarını benzersiz bir şekilde nitelemenize olanak sağlar. Bu, bir
XML belgesinin çeşitli bölümleri arasında ad çakışmalarını önlemeye yardımcı olur. Bir XML ad alanı
bildirdiyseniz, yalnızca bu ad alanı içinde benzersiz olması gereken yerel bir ad seçebilirsiniz.
XML adlarının başka bir yönü XML ad alanı ön ekleriolur. XML ön ekleri, XML adlarının birçok
karmaşıklığının oluşmasına neden olur. Bu ön ekler, XML belgesini daha kısa ve anlaşılır hale getiren bir XML
ad alanı için kısayol oluşturmanızı sağlar. Ancak, XML ön ekleri, karmaşıklık ekleyen anlamı olan bağlamına
bağımlıdır. Örneğin, XML ön eki aw bir xml ağacının tek bir bölümünde ve xml ağacının farklı bir bölümünde
farklı bir XML ad alanıyla ilişkilendirilebilir.
İle LINQ - XML C# kullanmanın avantajlarından biri, XML ön eklerini kullanmak zorunda değilsiniz. Bir XML
belgesi yüklediğinde veya ayrıştırdığında, her bir XML ön eki karşılık gelen XML ad alanına çözümlenir. LINQ
- XML Bundan sonra, ad alanları kullanan bir belgeyle çalışırken, ad alanı ön eki aracılığıyla değil, ad alanı URI
'SI aracılığıyla ad alanlarına neredeyse her zaman erişirsiniz. Geliştiriciler içindeki LINQ - XML XML adlarıyla
çalıştığında, her zaman tam olarak nitelenmiş bir xml adı (yani bir XML ad alanı ve yerel bir ad) ile çalışır.
Ancak, gerekli olduğunda, LINQ - XML ad alanı öneklerini birlikte çalışmanıza ve denetlemenize olanak tanır.
İçinde LINQ - XML, XML XNameadlarını temsil eden sınıf. XML adları, API 'nin LINQ - XML tamamında sık
görünür ve bir XML adının gerekli olduğu her yerde bir XName parametre bulacaksınız. Ancak, doğrudan ile
XNamenadiren çalışmanız gerekir. XNamedizeden örtük bir dönüştürme içerir.
Daha fazla bilgi için bkz. XNamespace ve XName.
Ad alanları (C#) ile belge oluşturma (LINQ to XML)
25.11.2019 • 4 minutes to read • Edit Online

Bu konu başlığı altında, ad alanları ile belgelerin nasıl oluşturulacağı gösterilmektedir.

Örnek
Bir ad alanında olan bir öğe veya öznitelik oluşturmak için, önce bir XNamespace nesnesi bildirip başlatın. Daha
sonra, ad alanını bir dize olarak ifade edilen yerel adla birleştirmek için ek işleç aşırı yüklemesi kullanabilirsiniz.
Aşağıdaki örnek, bir ad alanı olan bir belge oluşturur. Varsayılan olarak, LINQ - XML bu belgeyi varsayılan bir ad
alanıyla seri hale getirir.

// Create an XML tree in a namespace.


XNamespace aw = "http://www.adventure-works.com";
XElement root = new XElement(aw + "Root",
new XElement(aw + "Child", "child content")
);
Console.WriteLine(root);

Bu örnek aşağıdaki çıktıyı üretir:

<Root xmlns="http://www.adventure-works.com">
<Child>child content</Child>
</Root>

Örnek
Aşağıdaki örnek, bir ad alanı olan bir belge oluşturur. Ayrıca ad alanı öneki olan ad alanını bildiren bir öznitelik
oluşturur. Önekiyle bir ad alanı bildiren bir öznitelik oluşturmak için, özniteliğin adının ad alanı öneki olduğu ve bu
ad Xmlns ad alanında olduğu bir öznitelik oluşturursunuz. Bu özniteliğin değeri, ad alanının URI 'sidir.

// Create an XML tree in a namespace, with a specified prefix


XNamespace aw = "http://www.adventure-works.com";
XElement root = new XElement(aw + "Root",
new XAttribute(XNamespace.Xmlns + "aw", "http://www.adventure-works.com"),
new XElement(aw + "Child", "child content")
);
Console.WriteLine(root);

Bu örnek aşağıdaki çıktıyı üretir:

<aw:Root xmlns:aw="http://www.adventure-works.com">
<aw:Child>child content</aw:Child>
</aw:Root>

Örnek
Aşağıdaki örnek, iki ad alanı içeren bir belge oluşturmayı gösterir. Bunlardan biri varsayılan ad alanıdır. Diğeri öneki
olan bir ad alanıdır.
Ad alanı özniteliklerini kök öğesine ekleyerek, ad alanları, http://www.adventure-works.com varsayılan ad alanı
olacak şekilde serileştirilir ve www.fourthcoffee.com "FC" önekiyle serileştirilir. Varsayılan ad alanını bildiren bir
öznitelik oluşturmak için, ad alanı olmadan "xmlns" adlı bir öznitelik oluşturursunuz. Özniteliğin değeri varsayılan
ad alanı URI 'sidir.

// The http://www.adventure-works.com namespace is forced to be the default namespace.


XNamespace aw = "http://www.adventure-works.com";
XNamespace fc = "www.fourthcoffee.com";
XElement root = new XElement(aw + "Root",
new XAttribute("xmlns", "http://www.adventure-works.com"),
new XAttribute(XNamespace.Xmlns + "fc", "www.fourthcoffee.com"),
new XElement(fc + "Child",
new XElement(aw + "DifferentChild", "other content")
),
new XElement(aw + "Child2", "c2 content"),
new XElement(fc + "Child3", "c3 content")
);
Console.WriteLine(root);

Bu örnek aşağıdaki çıktıyı üretir:

<Root xmlns="http://www.adventure-works.com" xmlns:fc="www.fourthcoffee.com">


<fc:Child>
<DifferentChild>other content</DifferentChild>
</fc:Child>
<Child2>c2 content</Child2>
<fc:Child3>c3 content</fc:Child3>
</Root>

Örnek
Aşağıdaki örnek, ad alanı önekleri ile iki ad alanı içeren bir belge oluşturur.

XNamespace aw = "http://www.adventure-works.com";
XNamespace fc = "www.fourthcoffee.com";
XElement root = new XElement(aw + "Root",
new XAttribute(XNamespace.Xmlns + "aw", aw.NamespaceName),
new XAttribute(XNamespace.Xmlns + "fc", fc.NamespaceName),
new XElement(fc + "Child",
new XElement(aw + "DifferentChild", "other content")
),
new XElement(aw + "Child2", "c2 content"),
new XElement(fc + "Child3", "c3 content")
);
Console.WriteLine(root);

Bu örnek aşağıdaki çıktıyı üretir:

<aw:Root xmlns:aw="http://www.adventure-works.com" xmlns:fc="www.fourthcoffee.com">


<fc:Child>
<aw:DifferentChild>other content</aw:DifferentChild>
</fc:Child>
<aw:Child2>c2 content</aw:Child2>
<fc:Child3>c3 content</fc:Child3>
</aw:Root>

Örnek
Aynı sonucu gerçekleştirmenin başka bir yolu da XNamespace bir nesne bildirmek ve oluşturmak yerine
genişletilmiş adlar kullanmaktır.
Bu yaklaşımın performans etkileri vardır. LINQ - XMLbir genişletilmiş adı içeren bir dizeyi her geçirdiğinizde, LINQ
- XML adı ayrıştırmalıdır, atomlanmış ad alanını bulur ve atomlanmış adını bulur. Bu işlem CPU süresini alır.
Performans önemliyse, açıkça bir XNamespace nesnesi bildirmek ve kullanmak isteyebilirsiniz.
Performans önemli bir sorun ise, daha fazla bilgi için bkz. XName nesnelerinin ön atomitei (C#LINQ to XML ) ()

// Create an XML tree in a namespace, with a specified prefix


XElement root = new XElement("{http://www.adventure-works.com}Root",
new XAttribute(XNamespace.Xmlns + "aw", "http://www.adventure-works.com"),
new XElement("{http://www.adventure-works.com}Child", "child content")
);
Console.WriteLine(root);

Bu örnek aşağıdaki çıktıyı üretir:

<aw:Root xmlns:aw="http://www.adventure-works.com">
<aw:Child>child content</aw:Child>
</aw:Root>

Ayrıca bkz.
Ad alanlarına genel bakış (LINQ to XMLC#) ()
Ad alanı öneklerini denetleme (C#) (LINQ to XML)
25.11.2019 • 2 minutes to read • Edit Online

Bu konu, bir XML ağacını serileştirilirken ad alanı öneklerini nasıl denetleyebileceğinizi açıklar.
Birçok durumda, ad alanı öneklerini denetlemek gerekli değildir.
Ancak bazı XML programlama araçları, ad alanı önekleri için belirli bir denetim gerektirir. Örneğin, bir XSLT stil
sayfasını veya belirli ad alanı öneklerine başvuran gömülü XPath ifadeleri içeren bir XAML belgesini düzenleme Bu
durumda, belgenin bu özel öneklerle serileştirilmesi önemlidir.
Bu, ad alanı öneklerini denetlemenin en yaygın nedenidir.
Ad alanı öneklerini denetlemenin bir diğer yaygın nedeni, kullanıcıların XML belgesini el ile düzenlemesini ve
kullanıcının yazması için uygun olan ad alanı önekleri oluşturmasını istemesidir. Örneğin, bir XSD belgesi
oluşturuluyor olabilirsiniz. Şemaların kuralları, şema ad alanı öneki olarak xs veya xsd kullanmanızı önerir.
Ad alanı öneklerini denetlemek için ad alanlarını bildiren öznitelikleri eklersiniz. Ad alanlarını belirli öneklerle
bildirirseniz LINQ - XML serileştirilirken ad alanı öneklerini kabul etmeye çalışır.
Önekiyle bir ad alanı bildiren bir öznitelik oluşturmak için, özniteliğin adının ad alanının Xmlnsolduğu ve özniteliğin
adının ad alanı öneki olduğu bir öznitelik oluşturursunuz. Özniteliğin değeri, ad alanının URI 'sidir.

Örnek
Bu örnek iki ad alanı bildirir. http://www.adventure-works.com ad alanının aw öneki olduğunu ve
www.fourthcoffee.com ad alanının fc ön ekine sahip olduğunu belirtir.

XNamespace aw = "http://www.adventure-works.com";
XNamespace fc = "www.fourthcoffee.com";
XElement root = new XElement(aw + "Root",
new XAttribute(XNamespace.Xmlns + "aw", "http://www.adventure-works.com"),
new XAttribute(XNamespace.Xmlns + "fc", "www.fourthcoffee.com"),
new XElement(fc + "Child",
new XElement(aw + "DifferentChild", "other content")
),
new XElement(aw + "Child2", "c2 content"),
new XElement(fc + "Child3", "c3 content")
);
Console.WriteLine(root);

Bu örnek aşağıdaki çıktıyı üretir:

<aw:Root xmlns:aw="http://www.adventure-works.com" xmlns:fc="www.fourthcoffee.com">


<fc:Child>
<aw:DifferentChild>other content</aw:DifferentChild>
</fc:Child>
<aw:Child2>c2 content</aw:Child2>
<fc:Child3>c3 content</fc:Child3>
</aw:Root>

Ayrıca bkz.
Ad alanlarına genel bakış (LINQ to XMLC#) ()
C 'de varsayılan ad alanlarının kapsamı#
23.10.2019 • 2 minutes to read • Edit Online

XML ağacında temsil edilen varsayılan ad alanları sorgular kapsamında değildir. Varsayılan bir ad alanında olan
XML varsa, sorguda kullanılacak nitelikli bir ad oluşturmak için bir XNamespace değişken bildirmeniz ve bunu yerel
adla birleştirmeniz gerekir.
XML ağaçlarını sorgularken en yaygın sorunlardan biri, XML ağacının varsayılan bir ad alanına sahip olması ve
geliştiricinin bazen sorguyu bir ad alanında olmamasına rağmen yazar.
Bu konudaki ilk örnek kümesi, varsayılan bir ad alanındaki XML 'nin yüklendiği, ancak yanlış sorgulandığı tipik bir
yöntemi gösterir.
İkinci örnek kümesinde, bir ad alanında XML 'yi sorgulayabilmeniz için gerekli düzeltmeler gösterilmektedir.

Örnek
Bu örnek, bir ad alanında XML oluşturmayı ve boş bir sonuç kümesi döndüren bir sorguyu gösterir.
Kod

XElement root = XElement.Parse(


@"<Root xmlns='http://www.adventure-works.com'>
<Child>1</Child>
<Child>2</Child>
<Child>3</Child>
<AnotherChild>4</AnotherChild>
<AnotherChild>5</AnotherChild>
<AnotherChild>6</AnotherChild>
</Root>");
IEnumerable<XElement> c1 =
from el in root.Elements("Child")
select el;
Console.WriteLine("Result set follows:");
foreach (XElement el in c1)
Console.WriteLine((int)el);
Console.WriteLine("End of result set");

Açıklamalar
Bu örnek aşağıdaki sonucu üretir:

Result set follows:


End of result set

Örnek
Bu örnek, bir ad alanında XML oluşturmayı ve düzgün kodlanmış bir sorguyu gösterir.
Yukarıdaki yanlış kodlanmış örneğin aksine, kullanırken C# doğru yaklaşım bir XNamespace nesneyi bildirmek ve
başlatmak ve nesneleri belirtirken XName kullanmak. Bu durumda, Elements yöntemin bağımsız değişkeni bir
XName nesnedir.
Kod
XElement root = XElement.Parse(
@"<Root xmlns='http://www.adventure-works.com'>
<Child>1</Child>
<Child>2</Child>
<Child>3</Child>
<AnotherChild>4</AnotherChild>
<AnotherChild>5</AnotherChild>
<AnotherChild>6</AnotherChild>
</Root>");
XNamespace aw = "http://www.adventure-works.com";
IEnumerable<XElement> c1 =
from el in root.Elements(aw + "Child")
select el;
Console.WriteLine("Result set follows:");
foreach (XElement el in c1)
Console.WriteLine((int)el);
Console.WriteLine("End of result set");

Açıklamalar
Bu örnek aşağıdaki sonucu üretir:

Result set follows:


1
2
3
End of result set

Ayrıca bkz.
Ad alanlarına genel bakış (LINQ to XMLC#) ()
Nasıl yapılır: Ad alanlarında XML üzerinde sorgu
yazma (C#)
23.10.2019 • 2 minutes to read • Edit Online

Bir ad alanında olan XML üzerinde bir sorgu yazmak için, doğru ad alanına sahip XName nesneleri kullanmanız
gerekir.
İçin C#en yaygın yaklaşım, URI 'yi içeren bir dize XNamespace kullanarak başlatmak, ardından ad alanını yerel adla
birleştirmek için ek işleç aşırı yüklemesi kullanmaktır.
Bu konudaki ilk örnek kümesi, varsayılan bir ad alanında bir XML ağacının nasıl oluşturulacağını gösterir. İkinci
küme, öneki olan bir ad alanında bir XML ağacının nasıl oluşturulacağını gösterir.

Örnek
Aşağıdaki örnek, varsayılan bir ad alanında bulunan bir XML ağacı oluşturur. Daha sonra bir öğe koleksiyonu alır.

XNamespace aw = "http://www.adventure-works.com";
XElement root = XElement.Parse(
@"<Root xmlns='http://www.adventure-works.com'>
<Child>1</Child>
<Child>2</Child>
<Child>3</Child>
<AnotherChild>4</AnotherChild>
<AnotherChild>5</AnotherChild>
<AnotherChild>6</AnotherChild>
</Root>");
IEnumerable<XElement> c1 =
from el in root.Elements(aw + "Child")
select el;
foreach (XElement el in c1)
Console.WriteLine((int)el);

Bu örnek aşağıdaki çıktıyı üretir:

1
2
3

Örnek
' C#De, ön ek içeren bir ad alanı kullanan bir XML ağacına veya varsayılan bir ad alanına sahıp bir XML ağacına
sorgu yazarken aynı şekilde sorgular yazarsınız.
Aşağıdaki örnek, öneki olan bir ad alanında olan bir XML ağacı oluşturur. Daha sonra bir öğe koleksiyonu alır.
XNamespace aw = "http://www.adventure-works.com";
XElement root = XElement.Parse(
@"<aw:Root xmlns:aw='http://www.adventure-works.com'>
<aw:Child>1</aw:Child>
<aw:Child>2</aw:Child>
<aw:Child>3</aw:Child>
<aw:AnotherChild>4</aw:AnotherChild>
<aw:AnotherChild>5</aw:AnotherChild>
<aw:AnotherChild>6</aw:AnotherChild>
</aw:Root>");
IEnumerable<XElement> c1 =
from el in root.Elements(aw + "Child")
select el;
foreach (XElement el in c1)
Console.WriteLine((int)el);

Bu örnek aşağıdaki çıktıyı üretir:

1
2
3

Ayrıca bkz.
Ad alanlarına genel bakış (LINQ to XMLC#) ()
Serileştirirken Boşlukları Koruma
23.10.2019 • 2 minutes to read • Edit Online

Bu konuda, bir XML ağacı serileştirilirken boşluk denetlemek nasıl açıklanmaktadır.


Sık karşılaşılan bir senaryodur girintili XML oku, herhangi bir boşluk metin düğümleri (diğer bir deyişle, beyaz
boşluk olmayan koruma) olmadan bir bellek içi XML ağacı oluşturmak, bazı XML işlemleri ve XML girintilemeli
kaydedin sağlamaktır. Biçimlendirme ile XML serileştirme, yalnızca önemli boşluk XML ağacındaki korunur.
Varsayılan davranışı budur LINQ - XML.
Başka bir yaygın bir senaryo, okuma ve değiştirme kasıtlı olarak girintili zaten XML sağlamaktır. Bu girinti
herhangi bir şekilde değiştirmek istemeyebilirsiniz. Bunu yapmak için LINQ - XML, yükleme veya XML Ayrıştırma
ve XML serileştirme seçildiğinde biçimlendirmeyi devre dışı olduğunda bölünemez boşluğu koruyacak.

XML ağaçlarını serileştirme yöntemleri boşluk davranışını


Aşağıdaki yöntemleri XElement ve XDocument sınıfların serileştirmek bir XML ağacı. Bir dosyaya bir XML ağacı
serileştirebilen bir TextReader, veya bir XmlReader. ToString Yöntemi bir dizeye serileştirir.
XElement.Save
XDocument.Save
XElement.ToString()
XDocument.ToString()
Yöntem değil izlerseniz SaveOptions bağımsız değişken olarak, ardından yöntemi biçimlendirir (Girinti)
serileştirilmiş XML. Bu durumda, XML ağacı Önemsiz tüm bölünemez boşluğu göz ardı edilir.
Yöntem alırsanız SaveOptions bağımsız değişken olarak, ardından yöntemi olmayan biçimlendirme
belirtebilirsiniz (Girinti) serileştirilmiş XML. Bu durumda, XML ağacındaki tüm boşluk korunur.
(C#) bir XML bildirimi ile serileştirme
23.10.2019 • 2 minutes to read • Edit Online

Bu konuda, serileştirme bir XML bildirimi oluşturup oluşturmayacağını denetlemek nasıl açıklanmaktadır.

XML bildirimi oluşturma


Seri hale getirme için bir File veya TextWriter kullanarak XElement.Save yöntemi veya XDocument.Save yöntem bir
XML bildirimi oluşturur. Ne zaman serileştirmek için bir XmlWriter, yazıcı ayarları (belirtilen bir XmlWriterSettings
nesne) veya bir XML bildirimi oluşturulup oluşturulmayacağını belirler.
Kullanarak bir dize cricheditdoc::m_brtf ToString elde edilen XML yöntemi, bir XML bildirimi içermez.
XML Bildirimi ile Serileştirme
Aşağıdaki örnek, oluşturur bir XElement, belgeyi bir dosyaya kaydeder ve sonra dosyanın konsola yazdırır:

XElement root = new XElement("Root",


new XElement("Child", "child content")
);
root.Save("Root.xml");
string str = File.ReadAllText("Root.xml");
Console.WriteLine(str);

Bu örnek aşağıdaki çıktıyı üretir:

<?xml version="1.0" encoding="utf-8"?>


<Root>
<Child>child content</Child>
</Root>

Bir XML bildirimi seri hale getirme


Aşağıdaki örnek nasıl kaydedileceğini gösterir bir XElement için bir XmlWriter.

StringBuilder sb = new StringBuilder();


XmlWriterSettings xws = new XmlWriterSettings();
xws.OmitXmlDeclaration = true;

using (XmlWriter xw = XmlWriter.Create(sb, xws)) {


XElement root = new XElement("Root",
new XElement("Child", "child content")
);
root.Save(xw);
}
Console.WriteLine(sb.ToString());

Bu örnek aşağıdaki çıktıyı üretir:

<Root><Child>child content</Child></Root>

Ayrıca bkz.
Serileştirmek XML ağaçları (C#)
Dosya, TextWriters ve XmlWriters Serileştirme
23.10.2019 • 2 minutes to read • Edit Online

XML ağaçlarını bir File, a TextWriterveya XmlWriterolarak seri hale getirebilirsiniz.


Yöntemini kullanarak, ve XDocument XElementdahil olmak üzere herhangi bir XML bileşenini bir dizeye seri hale
getirebilirsiniz. ToString
Bir dizeye serileştirilirken biçimlendirmeyi bastırmak istiyorsanız XNode.ToString yöntemini kullanabilirsiniz.
Bir dosyaya serileştirilirken varsayılan davranış, elde edilen XML belgesini biçimlendirmek (Girintile). Girinti
yaptığınızda XML ağacındaki önemli boşluk korunmaz. Biçimlendirme ile seri hale getirmek için, aşağıdaki
yöntemlerin SaveOptions bağımsız değişken olarak olmayan aşırı yüklemelerinin birini kullanın:
XDocument.Save
XElement.Save
Seçeneği girintileme ve XML ağacındaki önemli boşlukları korumak istiyorsanız bağımsız değişken SaveOptions
olarak kullanılan aşağıdaki yöntemlerin aşırı yüklemelerinin birini kullanın:
XDocument.Save
XElement.Save
Örnekler için, ilgili başvuru konusuna bakın.

Ayrıca bkz.
XML ağaçlarını serileştirme (C#)
(Çağrılıyor XSLT) XmlReader'a serileştirme (C#)
23.10.2019 • 2 minutes to read • Edit Online

Kullanırken System.Xml birlikte çalışabilirlik özelliklerini LINQ - XML, kullanabileceğiniz CreateReader oluşturmak
için bir XmlReader. Buradan okur Modülü XmlReader XML ağacından düğümleri okur ve bunları uygun şekilde
işler.

XSLT dönüşümü çağırma


Bu yöntem bir olası kullanım XSLT dönüştürmesi çağrılırken içindir. Bir XML ağacı oluşturma, oluşturun bir
XmlReader XML ağacından bir yeni belge oluşturun ve ardından oluşturmak bir XmlWriter yeni belgesine
yazılacak. Öğesinde geçen XSLT dönüşümü, daha sonra çağırabilirsiniz XmlReader ve XmlWriter. Dönüştürme
başarıyla tamamlandıktan sonra yeni bir XML ağacı dönüşümü sonuçları ile doldurulur.

string xslMarkup = @"<?xml version='1.0'?>


<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
<xsl:template match='/Parent'>
<Root>
<C1>
<xsl:value-of select='Child1'/>
</C1>
<C2>
<xsl:value-of select='Child2'/>
</C2>
</Root>
</xsl:template>
</xsl:stylesheet>";

XDocument xmlTree = new XDocument(


new XElement("Parent",
new XElement("Child1", "Child1 data"),
new XElement("Child2", "Child2 data")
)
);

XDocument newTree = new XDocument();


using (XmlWriter writer = newTree.CreateWriter()) {
// Load the style sheet.
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(XmlReader.Create(new StringReader(xslMarkup)));

// Execute the transformation and output the results to a writer.


xslt.Transform(xmlTree.CreateReader(), writer);
}

Console.WriteLine(newTree);

Bu örnek aşağıdaki çıktıyı üretir:

<Root>
<C1>Child1 data</C1>
<C2>Child2 data</C2>
</Root>

Ayrıca bkz.
Serileştirmek XML ağaçları (C#)
LINQ to XML eksenlerine genelC#bakış ()
4.11.2019 • 5 minutes to read • Edit Online

Bir xml ağacını oluşturduktan veya bir XML ağacına bir XML belgesi yükledikten sonra, öğeleri ve öznitelikleri
bulmak ve değerlerini almak için onu sorgulayabilirsiniz. Koleksiyonları, eksen olarak da adlandırılan eksen
yöntemleriaracılığıyla alırsınız. Eksenlerden bazıları, IEnumerable<T> koleksiyonları döndüren XElement ve
XDocument sınıflarında yöntemlerdir. Eksenlerden bazıları Extensions sınıfında uzantı yöntemleridir. Uzantı
yöntemleri olarak uygulanan eksenler koleksiyonlar üzerinde çalışır ve koleksiyonlar döndürülür.
XElement sınıfına genel bakışbölümünde açıklandığı gibi, bir XElement nesnesi tek bir öğe düğümünü temsil eder.
Bir öğenin içeriği karmaşık olabilir (bazen yapılandırılmış içerik olarak adlandırılır) veya basit bir öğe olabilir. Basit
bir öğe boş olabilir veya bir değer içerebilir. Düğüm yapısal içerik içeriyorsa, alt öğelerin numaralandırmalar
almak için çeşitli eksen yöntemlerini kullanabilirsiniz. En yaygın kullanılan eksen yöntemleri Elements ve
Descendants.
Koleksiyonları döndüren eksen yöntemlerine ek olarak, LINQ - XML sorgularda yaygın olarak kullanabileceğiniz
iki yöntem vardır. Element yöntemi tek bir XElementdöndürür. Attribute yöntemi tek bir XAttributedöndürür.
Birçok amaç için LINQ sorguları, bir ağacı incelemek, verileri dosyadan ayıklamak ve dönüştürmek için en güçlü
yolu sağlar. LINQ sorguları IEnumerable<T>uygulayan nesneler üzerinde çalışır ve LINQ - XML eksenleri
XElement koleksiyonlarının IEnumerable<T> ve IEnumerable<T> koleksiyonlarının XAttribute döndürür.
Sorgularınızı gerçekleştirmek için bu koleksiyonlara ihtiyacınız vardır.
Öğe ve özniteliklerin koleksiyonlarını alan eksen yöntemlerine ek olarak, ağaç üzerinde harika ayrıntılarla
yineleme yapmanızı sağlayan eksen yöntemleri vardır. Örneğin, öğeleri ve öznitelikleri kullanmak yerine, ağacın
düğümleri ile çalışabilirsiniz. Düğümler, öğe ve özniteliklerin daha ayrıntılı bir düzeyde ayrıntı düzeyidir.
Düğümlerle çalışırken, XML açıklamalarını, metin düğümlerini, işleme talimatlarını ve daha fazlasını
inceleyebilirsiniz. Bu işlevsellik, örneğin, bir sözcük işlemcisi yazan ve belgeleri XML olarak kaydetmek isteyen bir
kişiye önemlidir. Ancak, XML programcılarının çoğunluğu öncelikle öğeler, öznitelikler ve değerleri ile ilgilidir.

Öğe koleksiyonunu alma yöntemleri


Aşağıda bir öğe koleksiyonu döndürmek için bir XElement çağırdığınız XElement sınıfının (veya temel sınıflarının)
yöntemlerinin bir özeti verilmiştir.

YÖNTEM AÇIKLAMA

XNode.Ancestors Bu öğenin üst öğelerinden XElement IEnumerable<T>


döndürür. Aşırı yükleme, belirtilen XNamesahip olan üst
öğelerinden XElement IEnumerable<T> döndürür.

XContainer.Descendants Bu öğenin alt öğelerinin XElement IEnumerable<T> döndürür.


Aşırı yükleme, belirtilen XNamesahip alt öğelerin XElement
IEnumerable<T> döndürür.

XContainer.Elements Bu öğenin alt öğelerinin XElement IEnumerable<T> döndürür.


Aşırı yükleme, belirtilen XNamesahip alt öğelerin XElement
IEnumerable<T> döndürür.
YÖNTEM AÇIKLAMA

XNode.ElementsAfterSelf Bu öğeden sonra gelen öğelerin XElement IEnumerable<T>


döndürür. Aşırı yükleme, belirtilen XNamesahip olan bu
öğeden sonra gelen öğelerin XElement IEnumerable<T>
döndürür.

XNode.ElementsBeforeSelf Bu öğeden önce gelen öğelerin XElement IEnumerable<T>


döndürür. Aşırı yükleme, belirtilen XNamesahip olan bu
öğeden önceki öğelerin XElement IEnumerable<T> döndürür.

XElement.AncestorsAndSelf Bu öğenin ve onun üst öğelerinden XElement


IEnumerable<T> döndürür. Aşırı yükleme, belirtilen
XNamesahip öğelerin XElement IEnumerable<T> döndürür.

XElement.DescendantsAndSelf Bu öğenin ve alt öğelerinin XElement IEnumerable<T>


döndürür. Aşırı yükleme, belirtilen XNamesahip öğelerin
XElement IEnumerable<T> döndürür.

Tek bir öğe alma yöntemi


Aşağıdaki yöntem XElement nesnesinden tek bir alt öğe alır.

YÖNTEM AÇIKLAMA

XContainer.Element Belirtilen XNamesahip olan ilk alt XElement nesnesini


döndürür.

Özniteliklerin koleksiyonunu alma yöntemi


Aşağıdaki yöntem bir XElement nesnesinden öznitelikleri alır.

YÖNTEM AÇIKLAMA

XElement.Attributes Tüm özniteliklerin XAttribute IEnumerable<T> döndürür.

Tek bir özniteliği alma yöntemi


Aşağıdaki yöntem XElement nesnesinden tek bir özniteliği alır.

YÖNTEM AÇIKLAMA

XElement.Attribute Belirtilen XNamesahip XAttribute döndürür.

Ayrıca bkz.
LINQ to XML eksenleri (C#)
Nasıl yapılır: Öğelerin koleksiyonunu al (LINQ to
XML) (C#)
23.10.2019 • 2 minutes to read • Edit Online

Bu konuda Elements yöntemi gösterilmektedir. Bu yöntem, bir öğesinin alt öğelerinin bir koleksiyonunu alır.

Örnek
Bu örnek, purchaseOrder öğesinin alt öğeleri boyunca yinelenir.
Bu örnek aşağıdaki XML belgesini kullanır: Örnek XML dosyası: Tipik satın alma siparişi (LINQ to XML ).

XElement po = XElement.Load("PurchaseOrder.xml");
IEnumerable<XElement> childElements =
from el in po.Elements()
select el;
foreach (XElement el in childElements)
Console.WriteLine("Name: " + el.Name);

Bu örnek aşağıdaki çıktıyı üretir.

Name: Address
Name: Address
Name: DeliveryNotes
Name: Items

Ayrıca bkz.
LINQ to XML eksenleri (C#)
Nasıl yapılır: Bir öğenin değerini Al (LINQ to XML)
(C#)
23.10.2019 • 4 minutes to read • Edit Online

Bu konu, öğelerin değerinin nasıl alınacağını gösterir. Bunu iki ana şekilde yapabilirsiniz. Tek yönlü bir XElement
XAttribute veya öğesini istenen türe atama yöntemidir. Daha sonra açık dönüştürme işleci, öğe veya özniteliğin
içeriğini belirtilen türe dönüştürür ve değişkenine atar. Alternatif olarak, XElement.Value özelliğini XAttribute.Value
veya özelliğini de kullanabilirsiniz.
C#Ancak, atama genellikle daha iyi bir yaklaşımdır. Öğesi veya özniteliğini null yapılabilir bir türe ayarlarsanız, kod,
var olabilen veya varolmayan bir öğenin (veya özniteliğin) değeri alınırken yazmak daha basittir. Bu konudaki son
örnekte bu gösterilmektedir. Ancak, özelliğini kullanarak XElement.Value bir öğenin içeriğini atama aracılığıyla
ayarlayamazsınız.

Örnek
Bir öğenin değerini almak için, XElement nesneyi istediğiniz türe atamalısınız. Bir öğeyi aşağıdaki gibi her zaman
bir dizeye çevirebilirsiniz:

XElement e = new XElement("StringElement", "abcde");


Console.WriteLine(e);
Console.WriteLine("Value of e:" + (string)e);

Bu örnek aşağıdaki çıktıyı üretir:

<StringElement>abcde</StringElement>
Value of e:abcde

Örnek
Ayrıca, öğeleri dize dışındaki türlere de çevirebilirsiniz. Örneğin, bir tamsayı içeren bir öğeye sahipseniz, aşağıdaki
kodda gösterildiği gibi, öğesini öğesine int çevirebilirsiniz:

XElement e = new XElement("Age", "44");


Console.WriteLine(e);
Console.WriteLine("Value of e:" + (int)e);

Bu örnek aşağıdaki çıktıyı üretir:

<Age>44</Age>
Value of e:44

LINQ - XMLŞu veri türleri string için açık atama işleçleri sağlar:, uint? int? int bool , bool? ,,, uint ,, long ,
long? ,, ulong ulong? ,,, DateTime? , , double? , GUID , , DateTime , , TimeSpan , , TimeSpan? ve float float? double
decimal decimal? GUID? .

LINQ - XMLnesneler için XAttribute aynı atama işleçlerini sağlar.


Örnek
Bir öğenin içeriğini almak Value için özelliğini kullanabilirsiniz:

XElement e = new XElement("StringElement", "abcde");


Console.WriteLine(e);
Console.WriteLine("Value of e:" + e.Value);

Bu örnek aşağıdaki çıktıyı üretir:

<StringElement>abcde</StringElement>
Value of e:abcde

Örnek
Bazen, var olmadığından emin olmasanız da bir öğenin değerini almaya çalışırsınız. Bu durumda, bulunan öğeyi
null olabilen bir türe (ya da string .NET Framework null yapılabilir türlerden biri) atadığınızda, öğe yoksa atanan
değişken olarak null ayarlanır. Aşağıdaki kod, öğe ne zaman olabileceği veya mevcut olmadığında, Value özelliği
kullanmak için, atama kullanmanın daha kolay olduğunu gösterir.
XElement root = new XElement("Root",
new XElement("Child1", "child 1 content"),
new XElement("Child2", "2")
);

// The following assignments show why it is easier to use


// casting when the element might or might not exist.

string c1 = (string)root.Element("Child1");
Console.WriteLine("c1:{0}", c1 == null ? "element does not exist" : c1);

int? c2 = (int?)root.Element("Child2");
Console.WriteLine("c2:{0}", c2 == null ? "element does not exist" : c2.ToString());

string c3 = (string)root.Element("Child3");
Console.WriteLine("c3:{0}", c3 == null ? "element does not exist" : c3);

int? c4 = (int?)root.Element("Child4");
Console.WriteLine("c4:{0}", c4 == null ? "element does not exist" : c4.ToString());

Console.WriteLine();

// The following assignments show the required code when using


// the Value property when the element might or might not exist.
// Notice that this is more difficult than the casting approach.

XElement e1 = root.Element("Child1");
string v1;
if (e1 == null)
v1 = null;
else
v1 = e1.Value;
Console.WriteLine("v1:{0}", v1 == null ? "element does not exist" : v1);

XElement e2 = root.Element("Child2");
int? v2;
if (e2 == null)
v2 = null;
else
v2 = Int32.Parse(e2.Value);
Console.WriteLine("v2:{0}", v2 == null ? "element does not exist" : v2.ToString());

XElement e3 = root.Element("Child3");
string v3;
if (e3 == null)
v3 = null;
else
v3 = e3.Value;
Console.WriteLine("v3:{0}", v3 == null ? "element does not exist" : v3);

XElement e4 = root.Element("Child4");
int? v4;
if (e4 == null)
v4 = null;
else
v4 = Int32.Parse(e4.Value);
Console.WriteLine("v4:{0}", v4 == null ? "element does not exist" : v4.ToString());

Bu kod aşağıdaki çıktıyı üretir:


c1:child 1 content
c2:2
c3:element does not exist
c4:element does not exist

v1:child 1 content
v2:2
v3:element does not exist
v4:element does not exist

Genel olarak, öğelerin ve özniteliklerin içeriğini almak için atama kullanırken daha basit bir kod yazabilirsiniz.

Ayrıca bkz.
LINQ to XML eksenleri (C#)
Öğe adlarını filtreleme (LINQ to XML) (C#)
25.11.2019 • 2 minutes to read • Edit Online

XElementIEnumerable<T> döndüren yöntemlerden birini çağırdığınızda, öğe adı üzerinde filtre uygulayabilirsiniz.

Örnek
Bu örnek, yalnızca belirtilen ada sahip alt öğeleri içerecek şekilde filtrelenen alt öğelerin bir koleksiyonunu alır.
Bu örnek, şu XML belgesini kullanır: örnek xml dosyası: tipik satın alma siparişi (LINQ to XML ).

XElement po = XElement.Load("PurchaseOrder.xml");
IEnumerable<XElement> items =
from el in po.Descendants("ProductName")
select el;
foreach(XElement prdName in items)
Console.WriteLine(prdName.Name + ":" + (string) prdName);

Bu kod aşağıdaki çıktıyı üretir:

ProductName:Lawnmower
ProductName:Baby Monitor

XElement koleksiyonlarının IEnumerable<T> döndüren diğer yöntemler aynı kalıbı izler. İmzaları Elements ve
Descendantsbenzerdir. Aşağıda benzer yöntem imzaları olan yöntemlerin tamamı listelenmiştir:
Ancestors
Descendants
Elements
ElementsAfterSelf
ElementsBeforeSelf
AncestorsAndSelf
DescendantsAndSelf

Örnek
Aşağıdaki örnek, bir ad alanında bulunan XML için aynı sorguyu gösterir. Daha fazla bilgi için bkz. ad alanlarına
genel bakış (C#LINQ to XML ) ().
Bu örnek, şu XML belgesini kullanır: örnek xml dosyası: bir ad alanında tipik satın alma siparişi.

XNamespace aw = "http://www.adventure-works.com";
XElement po = XElement.Load("PurchaseOrderInNamespace.xml");
IEnumerable<XElement> items =
from el in po.Descendants(aw + "ProductName")
select el;
foreach (XElement prdName in items)
Console.WriteLine(prdName.Name + ":" + (string)prdName);
Bu kod aşağıdaki çıktıyı üretir:

{http://www.adventure-works.com}ProductName:Lawnmower
{http://www.adventure-works.com}ProductName:Baby Monitor

Ayrıca bkz.
LINQ to XML eksenleri (C#)
Eksen yöntemi çağrılarının zinciri oluşturma (LINQ to
XML) (C#)
25.11.2019 • 2 minutes to read • Edit Online

Kodunuzda kullanacağınız ortak bir model, bir eksen yöntemi çağırmak ve sonra uzantı yöntemi eksenlerinden
birini çağırmalıdır.
Bir öğe koleksiyonu döndüren Elements adında iki eksen vardır: XContainer.Elements yöntemi ve
Extensions.Elements yöntemi. Ağaçta verilen bir derinlikte belirtilen bir adın tüm öğelerini bulmak için bu iki ekseni
birleştirebilirsiniz.

Örnek
Bu örnek XContainer.Elements ve Extensions.Elements kullanarak tüm PurchaseOrder öğelerindeki tüm Address
öğelerinde tüm Name öğelerini bulur.
Bu örnek, şu XML belgesini kullanır: örnek xml dosyası: birden fazla satın alma siparişi (LINQ to XML ).

XElement purchaseOrders = XElement.Load("PurchaseOrders.xml");


IEnumerable<XElement> names =
from el in purchaseOrders
.Elements("PurchaseOrder")
.Elements("Address")
.Elements("Name")
select el;
foreach (XElement e in names)
Console.WriteLine(e);

Bu örnek aşağıdaki çıktıyı üretir:

<Name>Ellen Adams</Name>
<Name>Tai Yee</Name>
<Name>Cristian Osorio</Name>
<Name>Cristian Osorio</Name>
<Name>Jessica Arnold</Name>
<Name>Jessica Arnold</Name>

Bu, Elements ekseninin uygulamalarından biri XContainerIEnumerable<T> bir genişletme yöntemi olduğundan bu
işe yarar. XElement XContainertüretilir, böylece XContainer.Elements yöntemine yapılan çağrının sonuçlarında
Extensions.Elements yöntemini çağırabilirsiniz.

Örnek
Bazı durumlarda, üst öğelerinden oluşan veya aradaki bir işlem olduğunda, belirli bir öğe derinliğinde tüm öğeleri
almak istersiniz. Örneğin, aşağıdaki belgede, Root öğesinin bir alt öğesi olan ConfigParameter değil, Customer
öğesinin alt öğesi olan tüm ConfigParameter öğelerini almak isteyebilirsiniz.
<Root>
<ConfigParameter>RootConfigParameter</ConfigParameter>
<Customer>
<Name>Frank</Name>
<Config>
<ConfigParameter>FirstConfigParameter</ConfigParameter>
</Config>
</Customer>
<Customer>
<Name>Bob</Name>
<!--This customer doesn't have a Config element-->
</Customer>
<Customer>
<Name>Bill</Name>
<Config>
<ConfigParameter>SecondConfigParameter</ConfigParameter>
</Config>
</Customer>
</Root>

Bunu yapmak için Extensions.Elements eksenini aşağıda gösterildiği gibi kullanabilirsiniz:

XElement root = XElement.Load("Irregular.xml");


IEnumerable<XElement> configParameters =
root.Elements("Customer").Elements("Config").
Elements("ConfigParameter");
foreach (XElement cp in configParameters)
Console.WriteLine(cp);

Bu örnek aşağıdaki çıktıyı üretir:

<ConfigParameter>FirstConfigParameter</ConfigParameter>
<ConfigParameter>SecondConfigParameter</ConfigParameter>

Örnek
Aşağıdaki örnek, bir ad alanında bulunan XML için aynı tekniği gösterir. Daha fazla bilgi için bkz. ad alanlarına genel
bakış (C#LINQ to XML ) ().
Bu örnek, şu XML belgesini kullanır: örnek xml dosyası: bir ad alanında birden fazla satın alma siparişi.

XNamespace aw = "http://www.adventure-works.com";
XElement purchaseOrders = XElement.Load("PurchaseOrdersInNamespace.xml");
IEnumerable<XElement> names =
from el in purchaseOrders
.Elements(aw + "PurchaseOrder")
.Elements(aw + "Address")
.Elements(aw + "Name")
select el;
foreach (XElement e in names)
Console.WriteLine(e);

Bu örnek aşağıdaki çıktıyı üretir:


<aw:Name xmlns:aw="http://www.adventure-works.com">Ellen Adams</aw:Name>
<aw:Name xmlns:aw="http://www.adventure-works.com">Tai Yee</aw:Name>
<aw:Name xmlns:aw="http://www.adventure-works.com">Cristian Osorio</aw:Name>
<aw:Name xmlns:aw="http://www.adventure-works.com">Cristian Osorio</aw:Name>
<aw:Name xmlns:aw="http://www.adventure-works.com">Jessica Arnold</aw:Name>
<aw:Name xmlns:aw="http://www.adventure-works.com">Jessica Arnold</aw:Name>

Ayrıca bkz.
LINQ to XML eksenleri (C#)
Nasıl yapılır: Tek bir alt öğe al (LINQ to XML) (C#)
23.10.2019 • 2 minutes to read • Edit Online

Bu konu, alt öğenin adı verildiğinde tek bir alt öğenin nasıl alınacağını açıklar. Alt öğenin adını bildiğiniz ve bu ada
sahip yalnızca bir öğe olduğunda, bir koleksiyon yerine yalnızca bir öğe almak kullanışlı olabilir.
Yöntemi, XElement belirtilenXNameilk alt öğesini döndürür. Element
Visual Basic tek bir alt öğe almak istiyorsanız, yaygın bir yaklaşım XML özelliğini kullanmak ve sonra dizi dizin
oluşturucu gösterimini kullanarak ilk öğeyi alır.

Örnek
Aşağıdaki örnek Element yönteminin kullanımını gösterir. Bu örnek adlı po xml ağacını alır ve adlı Comment ilk
öğeyi bulur.
Visual Basic örnek, tek bir öğeyi almak için dizi dizin oluşturucu gösterimini kullanmayı gösterir.
Bu örnek aşağıdaki XML belgesini kullanır: Örnek XML dosyası: Tipik satın alma siparişi (LINQ to XML ).

XElement po = XElement.Load("PurchaseOrder.xml");
XElement e = po.Element("DeliveryNotes");
Console.WriteLine(e);

Bu örnek aşağıdaki çıktıyı üretir:

<DeliveryNotes>Please leave packages in shed by driveway.</DeliveryNotes>

Örnek
Aşağıdaki örnek, bir ad alanında bulunan XML için aynı kodu gösterir. Daha fazla bilgi için bkz. ad alanlarına genel
bakış (C#LINQ to XML ) ().
Bu örnek aşağıdaki XML belgesini kullanır: Örnek XML dosyası: Bir ad alanındatipik satın alma siparişi.

XElement po = XElement.Load("PurchaseOrderInNamespace.xml");
XNamespace aw = "http://www.adventure-works.com";
XElement e = po.Element(aw + "DeliveryNotes");
Console.WriteLine(e);

Bu örnek aşağıdaki çıktıyı üretir:

<aw:DeliveryNotes xmlns:aw="http://www.adventure-works.com">Please leave packages in shed by driveway.


</aw:DeliveryNotes>

Ayrıca bkz.
LINQ to XML eksenleri (C#)
Nasıl yapılır: Öznitelik koleksiyonu alma (LINQ to
XML) (C#)
23.10.2019 • 2 minutes to read • Edit Online

Bu konuda Attributes yöntemi tanıtılmaktadır. Bu yöntem bir öğenin özniteliklerini alır.

Örnek
Aşağıdaki örnek, bir öğenin özniteliklerinin toplanması arasında nasıl yineleme yapılacağını gösterir.

XElement val = new XElement("Value",


new XAttribute("ID", "1243"),
new XAttribute("Type", "int"),
new XAttribute("ConvertableTo", "double"),
"100");
IEnumerable<XAttribute> listOfAttributes =
from att in val.Attributes()
select att;
foreach (XAttribute a in listOfAttributes)
Console.WriteLine(a);

Bu kod aşağıdaki çıktıyı üretir:

ID="1243"
Type="int"
ConvertableTo="double"

Ayrıca bkz.
LINQ to XML eksenleri (C#)
Nasıl yapılır: Tek bir öznitelik al (LINQ to XML) (C#)
23.10.2019 • 2 minutes to read • Edit Online

Bu konu, öznitelik adı verilen bir öğenin tek bir özniteliğinin nasıl alınacağını açıklamaktadır. Bu, belirli bir özniteliğe
sahip bir öğeyi bulmak istediğiniz sorgu ifadeleri yazmak için yararlıdır.
Sınıfının yöntemi ,XAttributebelirtilen ada Attributesahipöğesinidöndürür. XElement

Örnek
Aşağıdaki örnek Attribute yöntemini kullanır.

XElement cust = new XElement("PhoneNumbers",


new XElement("Phone",
new XAttribute("type", "home"),
"555-555-5555"),
new XElement("Phone",
new XAttribute("type", "work"),
"555-555-6666")
);
IEnumerable<XElement> elList =
from el in cust.Descendants("Phone")
select el;
foreach (XElement el in elList)
Console.WriteLine((string)el.Attribute("type"));

Bu örnek adlı Phone ağaçtaki tüm alt öğeleri bulur ve sonra adlı type özniteliği bulur.
Bu kod aşağıdaki çıktıyı üretir:

home
work

Örnek
Özniteliğin değerini almak istiyorsanız, nesneleri ile XElement yaptığınız gibi, bu özniteliği de çevirebilirsiniz.
Aşağıdaki örnek bunu gösterir.

XElement cust = new XElement("PhoneNumbers",


new XElement("Phone",
new XAttribute("type", "home"),
"555-555-5555"),
new XElement("Phone",
new XAttribute("type", "work"),
"555-555-6666")
);
IEnumerable<XElement> elList =
from el in cust.Descendants("Phone")
select el;
foreach (XElement el in elList)
Console.WriteLine((string)el.Attribute("type"));

Bu kod aşağıdaki çıktıyı üretir:


home
work

LINQ - XMLXAttribute sınıfına bool? , ,, uint? ,,,,, ,,,,,,,,,,,, long? bool string int int? uint long ulong ,,,
double? , TimeSpan ,, , decimal , GUID ,,, , TimeSpan? , ve DateTime decimal? float? double ulong? float
DateTime? GUID? .

Örnek
Aşağıdaki örnek, bir ad alanında olan bir özniteliği için aynı kodu gösterir. Daha fazla bilgi için bkz. ad alanlarına
genel bakış (C#LINQ to XML ) ().

XNamespace aw = "http://www.adventure-works.com";
XElement cust = new XElement(aw + "PhoneNumbers",
new XElement(aw + "Phone",
new XAttribute(aw + "type", "home"),
"555-555-5555"),
new XElement(aw + "Phone",
new XAttribute(aw + "type", "work"),
"555-555-6666")
);
IEnumerable<XElement> elList =
from el in cust.Descendants(aw + "Phone")
select el;
foreach (XElement el in elList)
Console.WriteLine((string)el.Attribute(aw + "type"));

Bu kod aşağıdaki çıktıyı üretir:

home
work

Ayrıca bkz.
LINQ to XML eksenleri (C#)
Nasıl yapılır: Bir özniteliğin değerini alma (LINQ to
XML) (C#)
23.10.2019 • 2 minutes to read • Edit Online

Bu konu, özniteliklerin değerinin nasıl alınacağını gösterir. İki ana yol vardır: İstediğiniz türe çevirebilirsiniz
XAttribute ; açık dönüştürme işleci daha sonra öğenin veya özniteliğin içeriğini belirtilen türe dönüştürür. Alternatif
olarak, Value özelliğini de kullanabilirsiniz. Ancak, atama genellikle daha iyi bir yaklaşımdır. Özniteliğini null
yapılabilir bir türe çevirebilirsiniz, bu, var olabilen veya varolmayan bir özniteliğin değeri alınırken yazmak daha
basittir. Bu tekniğin örnekleri için bkz . nasıl yapılır: Bir öğenin değerini Al (LINQ to XML ) (C#).

Örnek
Bir özniteliğin değerini almak için, XAttribute nesneyi istediğiniz türe atamalısınız.

XElement root = new XElement("Root",


new XAttribute("Attr", "abcde")
);
Console.WriteLine(root);
string str = (string)root.Attribute("Attr");
Console.WriteLine(str);

Bu örnek aşağıdaki çıktıyı üretir:

<Root Attr="abcde" />


abcde

Örnek
Aşağıdaki örnek, özniteliğinin bir ad alanında olduğu bir özniteliğin değerinin nasıl alınacağını gösterir. Daha fazla
bilgi için bkz. ad alanlarına genel bakış (C#LINQ to XML ) ().

XNamespace aw = "http://www.adventure-works.com";
XElement root = new XElement(aw + "Root",
new XAttribute(aw + "Attr", "abcde")
);
string str = (string)root.Attribute(aw + "Attr");
Console.WriteLine(str);

Bu örnek aşağıdaki çıktıyı üretir:

abcde

Ayrıca bkz.
LINQ to XML eksenleri (C#)
Nasıl yapılır: Bir öğenin (C#) Yüzeysel değerini alma
23.10.2019 • 2 minutes to read • Edit Online

Bu konu, bir öğenin yüzeysel değerinin nasıl alınacağını gösterir. Yüzeysel değer, tek bir dizeye birleştirilmiş tüm alt
öğelerin değerlerini içeren derin değeri aksine, yalnızca belirli bir öğenin değeridir.
Ya da XElement.Value özelliğini kullanarak bir öğe değeri aldığınızda, derin değeri alırsınız. Yüzeysel değeri almak
için, aşağıdaki örnekte gösterildiği gibi ShallowValue genişletme yöntemini kullanabilirsiniz. Yüzeysel değer alma,
içeriğine göre öğeleri seçmek istediğinizde faydalıdır.
Aşağıdaki örnek, bir öğenin yüzeysel değerini alan bir genişletme yöntemi bildirir. Daha sonra, hesaplanmış bir
değer içeren tüm öğeleri listelemek için bir sorgudaki genişletme yöntemini kullanır.

Örnek
Aşağıdaki metin dosyası, Report. xml, bu örneğin kaynağıdır.

<?xml version="1.0" encoding="utf-8" ?>


<Report>
<Section>
<Heading>
<Column Name="CustomerId">=Customer.CustomerId.Heading</Column>
<Column Name="Name">=Customer.Name.Heading</Column>
</Heading>
<Detail>
<Column Name="CustomerId">=Customer.CustomerId</Column>
<Column Name="Name">=Customer.Name</Column>
</Detail>
</Section>
</Report>
public static class MyExtensions
{
public static string ShallowValue(this XElement xe)
{
return xe
.Nodes()
.OfType<XText>()
.Aggregate(new StringBuilder(),
(s, c) => s.Append(c),
s => s.ToString());
}
}

class Program
{
static void Main(string[] args)
{
XElement root = XElement.Load("Report.xml");

IEnumerable<XElement> query = from el in root.Descendants()


where el.ShallowValue().StartsWith("=")
select el;

foreach (var q in query)


{
Console.WriteLine("{0}{1}{2}",
q.Name.ToString().PadRight(8),
q.Attribute("Name").ToString().PadRight(20),
q.ShallowValue());
}
}
}

Bu örnek aşağıdaki çıktıyı üretir:

Column Name="CustomerId" =Customer.CustomerId.Heading


Column Name="Name" =Customer.Name.Heading
Column Name="CustomerId" =Customer.CustomerId
Column Name="Name" =Customer.Name

Ayrıca bkz.
LINQ to XML eksenleri (C#)
Belirli bir özniteliğe (C#) sahip bir öğe bulma
25.11.2019 • 2 minutes to read • Edit Online

Bu konu, belirli bir değere sahip bir özniteliğe sahip olan bir öğenin nasıl bulunacağını gösterir.

Örnek
Örnek, "Faturalandırma" değerine sahip bir Type özniteliğine sahip Address öğesinin nasıl bulunacağını gösterir.
Bu örnek, şu XML belgesini kullanır: örnek xml dosyası: tipik satın alma siparişi (LINQ to XML ).

XElement root = XElement.Load("PurchaseOrder.xml");


IEnumerable<XElement> address =
from el in root.Elements("Address")
where (string)el.Attribute("Type") == "Billing"
select el;
foreach (XElement el in address)
Console.WriteLine(el);

Bu kod aşağıdaki çıktıyı üretir:

<Address Type="Billing">
<Name>Tai Yee</Name>
<Street>8 Oak Avenue</Street>
<City>Old Town</City>
<State>PA</State>
<Zip>95819</Zip>
<Country>USA</Country>
</Address>

Örnek
Aşağıdaki örnek, bir ad alanında bulunan XML için aynı sorguyu gösterir. Daha fazla bilgi için bkz. ad alanlarına
genel bakış (C#LINQ to XML ) ().
Bu örnek, şu XML belgesini kullanır: örnek xml dosyası: bir ad alanında tipik satın alma siparişi.

XElement root = XElement.Load("PurchaseOrderInNamespace.xml");


XNamespace aw = "http://www.adventure-works.com";
IEnumerable<XElement> address =
from el in root.Elements(aw + "Address")
where (string)el.Attribute(aw + "Type") == "Billing"
select el;
foreach (XElement el in address)
Console.WriteLine(el);

Bu kod aşağıdaki çıktıyı üretir:


<aw:Address aw:Type="Billing" xmlns:aw="http://www.adventure-works.com">
<aw:Name>Tai Yee</aw:Name>
<aw:Street>8 Oak Avenue</aw:Street>
<aw:City>Old Town</aw:City>
<aw:State>PA</aw:State>
<aw:Zip>95819</aw:Zip>
<aw:Country>USA</aw:Country>
</aw:Address>

Ayrıca bkz.
Attribute
Elements
Standart sorgu Işleçlerine genelC#bakış ()
Projeksiyon Işlemleri (C#)
Belirli bir alt öğe (C#) ile bir öğe bulma
25.11.2019 • 2 minutes to read • Edit Online

Bu konu, belirli bir değere sahip bir alt öğesi olan belirli bir öğenin nasıl bulunacağını gösterir.

Örnek
Örnek, "Examp2. EXE" değerine sahip bir CommandLine alt öğesi olan Test öğesi bulur.
Bu örnek, şu XML belgesini kullanır: örnek xml dosyası: test yapılandırması (LINQ to XML ).

XElement root = XElement.Load("TestConfig.xml");


IEnumerable<XElement> tests =
from el in root.Elements("Test")
where (string)el.Element("CommandLine") == "Examp2.EXE"
select el;
foreach (XElement el in tests)
Console.WriteLine((string)el.Attribute("TestId"));

Bu kod aşağıdaki çıktıyı üretir:

0002
0006

Örnek
Aşağıdaki örnek, bir ad alanında bulunan XML için aynı sorguyu gösterir. Daha fazla bilgi için bkz. ad alanlarına
genel bakış (C#LINQ to XML ) ().
Bu örnek, şu XML belgesini kullanır: örnek xml dosyası: bir ad alanında test yapılandırması.

XElement root = XElement.Load("TestConfigInNamespace.xml");


XNamespace ad = "http://www.adatum.com";
IEnumerable<XElement> tests =
from el in root.Elements(ad + "Test")
where (string)el.Element(ad + "CommandLine") == "Examp2.EXE"
select el;
foreach (XElement el in tests)
Console.WriteLine((string)el.Attribute("TestId"));

Bu kod aşağıdaki çıktıyı üretir:

0002
0006

Ayrıca bkz.
Attribute
Elements
Standart sorgu Işleçlerine genelC#bakış ()
Projeksiyon Işlemleri (C#)
XDocument Sorgulama ve XElement (C#) sorgulama
23.10.2019 • 2 minutes to read • Edit Online

Aracılığıyla XDocument.Loadbir belge yüklediğinizde, ile XElement.Loadyükleme yaparken sorguları biraz farklı
yazacağınız fark edeceksiniz.

XDocument. Load ve XElement. Load karşılaştırması


Bir XElement XML belgesini aracılığıyla XElement.Loadyüklediğinizde, XElement xml ağacının kök öğesi yüklenen
belgenin kök öğesini içerir. Ancak XDocument , bir XDocumentile XDocument.Loadaynı XML belgesini
yüklediğinizde, ağacın kökü bir XDocument düğümdür ve yüklenen belgenin kök öğesi, öğesinin izin verilen alt
XElement düğümüdür. LINQ - XML Eksenler kök düğüme göre çalışır.
Bu ilk örnek kullanarak Loadbir XML ağacı yükler. Daha sonra ağacın kök öğelerinin alt öğelerini sorgular.

// Create a simple document and write it to a file


File.WriteAllText("Test.xml", @"<Root>
<Child1>1</Child1>
<Child2>2</Child2>
<Child3>3</Child3>
</Root>");

Console.WriteLine("Querying tree loaded with XElement.Load");


Console.WriteLine("----");
XElement doc = XElement.Load("Test.xml");
IEnumerable<XElement> childList =
from el in doc.Elements()
select el;
foreach (XElement e in childList)
Console.WriteLine(e);

Beklendiği gibi, bu örnek aşağıdaki çıktıyı üretir:

Querying tree loaded with XElement.Load


----
<Child1>1</Child1>
<Child2>2</Child2>
<Child3>3</Child3>

Aşağıdaki örnek, xml ağacının bir XDocument XElementyerine bir olarak yüklendiği özel durum ile, yukarıdaki bir
ile aynıdır.
// Create a simple document and write it to a file
File.WriteAllText("Test.xml", @"<Root>
<Child1>1</Child1>
<Child2>2</Child2>
<Child3>3</Child3>
</Root>");

Console.WriteLine("Querying tree loaded with XDocument.Load");


Console.WriteLine("----");
XDocument doc = XDocument.Load("Test.xml");
IEnumerable<XElement> childList =
from el in doc.Elements()
select el;
foreach (XElement e in childList)
Console.WriteLine(e);

Bu örnek aşağıdaki çıktıyı üretir:

Querying tree loaded with XDocument.Load


----
<Root>
<Child1>1</Child1>
<Child2>2</Child2>
<Child3>3</Child3>
</Root>

Aynı sorgunun üç alt düğüm yerine bir Root düğümü döndürtiğine dikkat edin.
Bu ile ilgilenmeye yönelik bir yaklaşım, aşağıdaki gibi Root , eksen yöntemlerine erişmeden önce özelliğini
kullanmaktır:

// Create a simple document and write it to a file


File.WriteAllText("Test.xml", @"<Root>
<Child1>1</Child1>
<Child2>2</Child2>
<Child3>3</Child3>
</Root>");

Console.WriteLine("Querying tree loaded with XDocument.Load");


Console.WriteLine("----");
XDocument doc = XDocument.Load("Test.xml");
IEnumerable<XElement> childList =
from el in doc.Root.Elements()
select el;
foreach (XElement e in childList)
Console.WriteLine(e);

Bu sorgu artık, içinde XElementkök ağaçtaki sorgu ile aynı şekilde gerçekleştirilir. Örnek aşağıdaki çıktıyı üretir:

Querying tree loaded with XDocument.Load


----
<Child1>1</Child1>
<Child2>2</Child2>
<Child3>3</Child3>
Belirli bir öğe adı (C#) ile alt öğeleri bulma
25.11.2019 • 2 minutes to read • Edit Online

Bazen belirli bir ada sahip tüm alt öğeleri bulmak isteyebilirsiniz. Tüm alt öğeler boyunca yinelemek için kod
yazabilirsiniz, ancak Descendants eksenini kullanmak daha kolaydır.

Örnek
Aşağıdaki örnek, öğe adına göre alt öğelerin nasıl bulunacağını gösterir.

XElement root = XElement.Parse(@"<root>


<para>
<r>
<t>Some text </t>
</r>
<n>
<r>
<t>that is broken up into </t>
</r>
</n>
<n>
<r>
<t>multiple segments.</t>
</r>
</n>
</para>
</root>");
IEnumerable<string> textSegs =
from seg in root.Descendants("t")
select (string)seg;

string str = textSegs.Aggregate(new StringBuilder(),


(sb, i) => sb.Append(i),
sp => sp.ToString()
);

Console.WriteLine(str);

Bu kod aşağıdaki çıktıyı üretir:

Some text that is broken up into multiple segments.

Örnek
Aşağıdaki örnek, bir ad alanında bulunan XML için aynı sorguyu gösterir. Daha fazla bilgi için bkz. ad alanlarına
genel bakış (C#LINQ to XML ) ().
XElement root = XElement.Parse(@"<root xmlns='http://www.adatum.com'>
<para>
<r>
<t>Some text </t>
</r>
<n>
<r>
<t>that is broken up into </t>
</r>
</n>
<n>
<r>
<t>multiple segments.</t>
</r>
</n>
</para>
</root>");
XNamespace ad = "http://www.adatum.com";
IEnumerable<string> textSegs =
from seg in root.Descendants(ad + "t")
select (string)seg;

string str = textSegs.Aggregate(new StringBuilder(),


(sb, i) => sb.Append(i),
sp => sp.ToString()
);

Console.WriteLine(str);

Bu kod aşağıdaki çıktıyı üretir:

Some text that is broken up into multiple segments.

Ayrıca bkz.
Descendants
Alt öğeler yöntemini kullanarak tek bir alt öğe bulma
(C#)
25.11.2019 • 2 minutes to read • Edit Online

Tek bir benzersiz şekilde adlandırılmış öğe bulmak için kodu hızlı bir şekilde yazmak üzere Descendants eksen
yöntemini kullanabilirsiniz. Bu teknik özellikle belirli bir ada sahip belirli bir alt öğe bulmak istediğinizde yararlıdır.
İstenen öğeye gitmek için kodu yazabilirsiniz, ancak Descendants ekseni kullanılarak kodun yazılması genellikle
daha hızlı ve kolaydır.

Örnek
Bu örnek First standart sorgu işlecini kullanır.

XElement root = XElement.Parse(@"<Root>


<Child1>
<GrandChild1>GC1 Value</GrandChild1>
</Child1>
<Child2>
<GrandChild2>GC2 Value</GrandChild2>
</Child2>
<Child3>
<GrandChild3>GC3 Value</GrandChild3>
</Child3>
<Child4>
<GrandChild4>GC4 Value</GrandChild4>
</Child4>
</Root>");
string grandChild3 = (string)
(from el in root.Descendants("GrandChild3")
select el).First();
Console.WriteLine(grandChild3);

Bu kod aşağıdaki çıktıyı üretir:

GC3 Value

Örnek
Aşağıdaki örnek, bir ad alanında bulunan XML için aynı sorguyu gösterir. Daha fazla bilgi için bkz. ad alanlarına
genel bakış (C#LINQ to XML ) ().
XElement root = XElement.Parse(@"<aw:Root xmlns:aw='http://www.adventure-works.com'>
<aw:Child1>
<aw:GrandChild1>GC1 Value</aw:GrandChild1>
</aw:Child1>
<aw:Child2>
<aw:GrandChild2>GC2 Value</aw:GrandChild2>
</aw:Child2>
<aw:Child3>
<aw:GrandChild3>GC3 Value</aw:GrandChild3>
</aw:Child3>
<aw:Child4>
<aw:GrandChild4>GC4 Value</aw:GrandChild4>
</aw:Child4>
</aw:Root>");
XNamespace aw = "http://www.adventure-works.com";
string grandChild3 = (string)
(from el in root.Descendants(aw + "GrandChild3")
select el).First();
Console.WriteLine(grandChild3);

Bu kod aşağıdaki çıktıyı üretir:

GC3 Value
Nasıl yapılır: Karmaşık filtrelemeye (C#) sahip
sorguları yazma
23.10.2019 • 2 minutes to read • Edit Online

Bazen karmaşık filtrelerle LINQ to XML sorguları yazmak isteyebilirsiniz. Örneğin, belirli bir ada ve değere sahip
bir alt öğesi olan tüm öğeleri bulmanız gerekebilir. Bu konu, karmaşık filtrelemeye sahip sorgu yazma örneği sağlar.

Örnek
Bu PurchaseOrder örnek, Address State bir özniteliği "Shipping" ve alt öğesi "NY" değerine eşit olan bir alt öğesi
olan tüm öğelerin nasıl bulunacağını gösterir. Type Where Yan tümcesinde iç içe geçmiş bir sorgu kullanır Any ve
koleksiyonda herhangi bir öğe true varsa işleç döndürülür. Yöntem tabanlı sorgu söz dizimini kullanma hakkında
daha fazla bilgi için bkz. LINQ 'Te sorgu sözdizimi ve Yöntem sözdizimi.
Bu örnek aşağıdaki XML belgesini kullanır: Örnek XML dosyası: Birden çok satın alma siparişi (LINQ to XML ).
Any İşleci hakkında daha fazla bilgi için bkz. nicelik belirteci işlemleriC#() .

XElement root = XElement.Load("PurchaseOrders.xml");


IEnumerable<XElement> purchaseOrders =
from el in root.Elements("PurchaseOrder")
where
(from add in el.Elements("Address")
where
(string)add.Attribute("Type") == "Shipping" &&
(string)add.Element("State") == "NY"
select add)
.Any()
select el;
foreach (XElement el in purchaseOrders)
Console.WriteLine((string)el.Attribute("PurchaseOrderNumber"));

Bu kod aşağıdaki çıktıyı üretir:

99505

Örnek
Aşağıdaki örnek, bir ad alanında bulunan XML için aynı sorguyu gösterir. Daha fazla bilgi için bkz. ad alanlarına
genel bakış (C#LINQ to XML ) ().
Bu örnek aşağıdaki XML belgesini kullanır: Örnek XML dosyası: Bir ad alanındabirden fazla satın alma siparişi.
XElement root = XElement.Load("PurchaseOrdersInNamespace.xml");
XNamespace aw = "http://www.adventure-works.com";
IEnumerable<XElement> purchaseOrders =
from el in root.Elements(aw + "PurchaseOrder")
where
(from add in el.Elements(aw + "Address")
where
(string)add.Attribute(aw + "Type") == "Shipping" &&
(string)add.Element(aw + "State") == "NY"
select add)
.Any()
select el;
foreach (XElement el in purchaseOrders)
Console.WriteLine((string)el.Attribute(aw + "PurchaseOrderNumber"));

Bu kod aşağıdaki çıktıyı üretir:

99505

Ayrıca bkz.
Attribute
Elements
Projeksiyon Işlemleri (C#)
Nicelik belirteci IşlemleriC#()
İsteğe bağlı bir öğeyi filtreleme (C#)
25.11.2019 • 2 minutes to read • Edit Online

Bazen, XML belgenizde bulunduğundan emin olmasanız da bir öğeye filtre uygulamak isteyebilirsiniz. Arama, belirli
bir öğede alt öğe yoksa, filtre uygulayarak bir null başvuru özel durumu tetiklememesi için yürütülmelidir. Aşağıdaki
örnekte, Child5 öğesinin bir Type alt öğesi yoktur, ancak sorgu yine de doğru yürütülür.

Örnek
Bu örnek Elements uzantısı yöntemini kullanır.

XElement root = XElement.Parse(@"<Root>


<Child1>
<Text>Child One Text</Text>
<Type Value=""Yes""/>
</Child1>
<Child2>
<Text>Child Two Text</Text>
<Type Value=""Yes""/>
</Child2>
<Child3>
<Text>Child Three Text</Text>
<Type Value=""No""/>
</Child3>
<Child4>
<Text>Child Four Text</Text>
<Type Value=""Yes""/>
</Child4>
<Child5>
<Text>Child Five Text</Text>
</Child5>
</Root>");
var cList =
from typeElement in root.Elements().Elements("Type")
where (string)typeElement.Attribute("Value") == "Yes"
select (string)typeElement.Parent.Element("Text");
foreach(string str in cList)
Console.WriteLine(str);

Bu kod aşağıdaki çıktıyı üretir:

Child One Text


Child Two Text
Child Four Text

Örnek
Aşağıdaki örnek, bir ad alanında bulunan XML için aynı sorguyu gösterir. Daha fazla bilgi için bkz. ad alanlarına
genel bakış (C#LINQ to XML ) ().
XElement root = XElement.Parse(@"<Root xmlns='http://www.adatum.com'>
<Child1>
<Text>Child One Text</Text>
<Type Value=""Yes""/>
</Child1>
<Child2>
<Text>Child Two Text</Text>
<Type Value=""Yes""/>
</Child2>
<Child3>
<Text>Child Three Text</Text>
<Type Value=""No""/>
</Child3>
<Child4>
<Text>Child Four Text</Text>
<Type Value=""Yes""/>
</Child4>
<Child5>
<Text>Child Five Text</Text>
</Child5>
</Root>");
XNamespace ad = "http://www.adatum.com";
var cList =
from typeElement in root.Elements().Elements(ad + "Type")
where (string)typeElement.Attribute("Value") == "Yes"
select (string)typeElement.Parent.Element(ad + "Text");
foreach (string str in cList)
Console.WriteLine(str);

Bu kod aşağıdaki çıktıyı üretir:

Child One Text


Child Two Text
Child Four Text

Ayrıca bkz.
XElement.Attribute
XContainer.Elements
Extensions.Elements
Standart sorgu Işleçlerine genelC#bakış ()
Projeksiyon Işlemleri (C#)
Bir ad alanındaki tüm düğümleri bulma (C#)
25.11.2019 • 2 minutes to read • Edit Online

Söz konusu ad alanındaki tüm düğümleri bulmak için her öğe veya özniteliğin ad alanı üzerinde filtre
uygulayabilirsiniz.

Örnek
Aşağıdaki örnek iki ad alanı olan bir XML ağacı oluşturur. Daha sonra ağaç üzerinde dolaşır ve bu ad alanlarından
birindeki tüm öğelerin ve özniteliklerin adlarını yazdırır.

string markup = @"<aw:Root xmlns:aw='http://www.adventure-works.com' xmlns:fc='www.fourthcoffee.com'>


<fc:Child1>abc</fc:Child1>
<fc:Child2>def</fc:Child2>
<aw:Child3>ghi</aw:Child3>
<fc:Child4>
<fc:GrandChild1>jkl</fc:GrandChild1>
<aw:GrandChild2>mno</aw:GrandChild2>
</fc:Child4>
</aw:Root>";
XElement xmlTree = XElement.Parse(markup);
Console.WriteLine("Nodes in the http://www.adventure-works.com namespace");
IEnumerable<XElement> awElements =
from el in xmlTree.Descendants()
where el.Name.Namespace == "http://www.adventure-works.com"
select el;
foreach (XElement el in awElements)
Console.WriteLine(el.Name.ToString());

Bu kod aşağıdaki çıktıyı üretir:

Nodes in the http://www.adventure-works.com namespace


{http://www.adventure-works.com}Child3
{http://www.adventure-works.com}GrandChild2

Örnek
Aşağıdaki sorgu tarafından erişilen XML dosyası, satın alma emirlerini iki farklı ad alanında içerir. Sorgu, yalnızca ad
alanlarından birindeki öğeleri içeren yeni bir ağaç oluşturur.
Bu örnek, şu XML belgesini kullanır: örnek xml dosyası: birleştirilmiş satın alma siparişleri.

XDocument cpo = XDocument.Load("ConsolidatedPurchaseOrders.xml");


XNamespace aw = "http://www.adventure-works.com";
XElement newTree = new XElement("Root",
from el in cpo.Root.Elements()
where el.Name.Namespace == aw
select el
);
Console.WriteLine(newTree);

Bu kod aşağıdaki çıktıyı üretir:


<Root>
<aw:PurchaseOrder PONumber="11223" Date="2000-01-15" xmlns:aw="http://www.adventure-works.com">
<aw:ShippingAddress>
<aw:Name>Chris Preston</aw:Name>
<aw:Street>123 Main St.</aw:Street>
<aw:City>Seattle</aw:City>
<aw:State>WA</aw:State>
<aw:Zip>98113</aw:Zip>
<aw:Country>USA</aw:Country>
</aw:ShippingAddress>
<aw:BillingAddress>
<aw:Name>Chris Preston</aw:Name>
<aw:Street>123 Main St.</aw:Street>
<aw:City>Seattle</aw:City>
<aw:State>WA</aw:State>
<aw:Zip>98113</aw:Zip>
<aw:Country>USA</aw:Country>
</aw:BillingAddress>
<aw:DeliveryInstructions>Ship only complete order.</aw:DeliveryInstructions>
<aw:Item PartNum="LIT-01">
<aw:ProductID>Litware Networking Card</aw:ProductID>
<aw:Qty>1</aw:Qty>
<aw:Price>20.99</aw:Price>
</aw:Item>
<aw:Item PartNum="LIT-25">
<aw:ProductID>Litware 17in LCD Monitor</aw:ProductID>
<aw:Qty>1</aw:Qty>
<aw:Price>199.99</aw:Price>
</aw:Item>
</aw:PurchaseOrder>
</Root>
Nasıl yapılır: Öğeleri Sırala (C#)
23.10.2019 • 2 minutes to read • Edit Online

Bu örnek, sonuçlarını sıralayan bir sorgunun nasıl yazılacağını gösterir.

Örnek
Bu örnek aşağıdaki XML belgesini kullanır: Örnek XML dosyası: Sayısal veri (LINQ to XML ).

XElement root = XElement.Load("Data.xml");


IEnumerable<decimal> prices =
from el in root.Elements("Data")
let price = (decimal)el.Element("Price")
orderby price
select price;
foreach (decimal el in prices)
Console.WriteLine(el);

Bu kod aşağıdaki çıktıyı üretir:

0.99
4.95
6.99
24.50
29.00
66.00
89.99

Örnek
Aşağıdaki örnek, bir ad alanında bulunan XML için aynı sorguyu gösterir. Daha fazla bilgi için bkz. ad alanlarına
genel bakış (C#LINQ to XML ) ().
Bu örnek aşağıdaki XML belgesini kullanır: Örnek XML dosyası: Bir ad alanındakisayısal veri.

XElement root = XElement.Load("DataInNamespace.xml");


XNamespace aw = "http://www.adatum.com";
IEnumerable<decimal> prices =
from el in root.Elements(aw + "Data")
let price = (decimal)el.Element(aw + "Price")
orderby price
select price;
foreach (decimal el in prices)
Console.WriteLine(el);

Bu kod aşağıdaki çıktıyı üretir:


0.99
4.95
6.99
24.50
29.00
66.00
89.99

Ayrıca bkz.
Verileri sıralama (C#)
Nasıl yapılır: Birden çok anahtardaki öğeleri SıralaC#()
23.10.2019 • 2 minutes to read • Edit Online

Bu konu başlığı altında, birden çok anahtar üzerinde nasıl sıralama yapılacağı gösterilmektedir.

Örnek
Bu örnekte, sonuçlar önce sevkiyat posta kodu tarafından, ardından sipariş tarihine göre sıralanır.
Bu örnek aşağıdaki XML belgesini kullanır: Örnek XML dosyası: Müşteriler ve siparişler (LINQ to XML ).

XElement co = XElement.Load("CustomersOrders.xml");
var sortedElements =
from c in co.Element("Orders").Elements("Order")
orderby (string)c.Element("ShipInfo").Element("ShipPostalCode"),
(DateTime)c.Element("OrderDate")
select new {
CustomerID = (string)c.Element("CustomerID"),
EmployeeID = (string)c.Element("EmployeeID"),
ShipPostalCode = (string)c.Element("ShipInfo").Element("ShipPostalCode"),
OrderDate = (DateTime)c.Element("OrderDate")
};
foreach (var r in sortedElements)
Console.WriteLine("CustomerID:{0} EmployeeID:{1} ShipPostalCode:{2} OrderDate:{3:d}",
r.CustomerID, r.EmployeeID, r.ShipPostalCode, r.OrderDate);

Bu kod aşağıdaki çıktıyı üretir:

CustomerID:LETSS EmployeeID:1 ShipPostalCode:94117 OrderDate:6/25/1997


CustomerID:LETSS EmployeeID:8 ShipPostalCode:94117 OrderDate:10/27/1997
CustomerID:LETSS EmployeeID:6 ShipPostalCode:94117 OrderDate:11/10/1997
CustomerID:LETSS EmployeeID:4 ShipPostalCode:94117 OrderDate:2/12/1998
CustomerID:GREAL EmployeeID:6 ShipPostalCode:97403 OrderDate:5/6/1997
CustomerID:GREAL EmployeeID:8 ShipPostalCode:97403 OrderDate:7/4/1997
CustomerID:GREAL EmployeeID:1 ShipPostalCode:97403 OrderDate:7/31/1997
CustomerID:GREAL EmployeeID:4 ShipPostalCode:97403 OrderDate:7/31/1997
CustomerID:GREAL EmployeeID:6 ShipPostalCode:97403 OrderDate:9/4/1997
CustomerID:GREAL EmployeeID:3 ShipPostalCode:97403 OrderDate:9/25/1997
CustomerID:GREAL EmployeeID:4 ShipPostalCode:97403 OrderDate:1/6/1998
CustomerID:GREAL EmployeeID:3 ShipPostalCode:97403 OrderDate:3/9/1998
CustomerID:GREAL EmployeeID:3 ShipPostalCode:97403 OrderDate:4/7/1998
CustomerID:GREAL EmployeeID:4 ShipPostalCode:97403 OrderDate:4/22/1998
CustomerID:GREAL EmployeeID:4 ShipPostalCode:97403 OrderDate:4/30/1998
CustomerID:HUNGC EmployeeID:3 ShipPostalCode:97827 OrderDate:12/6/1996
CustomerID:HUNGC EmployeeID:1 ShipPostalCode:97827 OrderDate:12/25/1996
CustomerID:HUNGC EmployeeID:3 ShipPostalCode:97827 OrderDate:1/15/1997
CustomerID:HUNGC EmployeeID:4 ShipPostalCode:97827 OrderDate:7/16/1997
CustomerID:HUNGC EmployeeID:8 ShipPostalCode:97827 OrderDate:9/8/1997
CustomerID:LAZYK EmployeeID:1 ShipPostalCode:99362 OrderDate:3/21/1997
CustomerID:LAZYK EmployeeID:8 ShipPostalCode:99362 OrderDate:5/22/1997

Örnek
Aşağıdaki örnek, bir ad alanında bulunan XML için aynı sorguyu gösterir. Daha fazla bilgi için bkz. ad alanlarına
genel bakış (C#LINQ to XML ) ().
Bu örnek aşağıdaki XML belgesini kullanır: Örnek XML dosyası: Bir ad alanındakimüşteriler ve siparişler.

XElement co = XElement.Load("CustomersOrdersInNamespace.xml");
XNamespace aw = "http://www.adventure-works.com";
var sortedElements =
from c in co.Element(aw + "Orders").Elements(aw + "Order")
orderby (string)c.Element(aw + "ShipInfo").Element(aw + "ShipPostalCode"),
(DateTime)c.Element(aw + "OrderDate")
select new
{
CustomerID = (string)c.Element(aw + "CustomerID"),
EmployeeID = (string)c.Element(aw + "EmployeeID"),
ShipPostalCode = (string)c.Element(aw + "ShipInfo").Element(aw + "ShipPostalCode"),
OrderDate = (DateTime)c.Element(aw + "OrderDate")
};
foreach (var r in sortedElements)
Console.WriteLine("CustomerID:{0} EmployeeID:{1} ShipPostalCode:{2} OrderDate:{3:d}",
r.CustomerID, r.EmployeeID, r.ShipPostalCode, r.OrderDate);

Bu kod aşağıdaki çıktıyı üretir:

CustomerID:LETSS EmployeeID:1 ShipPostalCode:94117 OrderDate:6/25/1997


CustomerID:LETSS EmployeeID:8 ShipPostalCode:94117 OrderDate:10/27/1997
CustomerID:LETSS EmployeeID:6 ShipPostalCode:94117 OrderDate:11/10/1997
CustomerID:LETSS EmployeeID:4 ShipPostalCode:94117 OrderDate:2/12/1998
CustomerID:GREAL EmployeeID:6 ShipPostalCode:97403 OrderDate:5/6/1997
CustomerID:GREAL EmployeeID:8 ShipPostalCode:97403 OrderDate:7/4/1997
CustomerID:GREAL EmployeeID:1 ShipPostalCode:97403 OrderDate:7/31/1997
CustomerID:GREAL EmployeeID:4 ShipPostalCode:97403 OrderDate:7/31/1997
CustomerID:GREAL EmployeeID:6 ShipPostalCode:97403 OrderDate:9/4/1997
CustomerID:GREAL EmployeeID:3 ShipPostalCode:97403 OrderDate:9/25/1997
CustomerID:GREAL EmployeeID:4 ShipPostalCode:97403 OrderDate:1/6/1998
CustomerID:GREAL EmployeeID:3 ShipPostalCode:97403 OrderDate:3/9/1998
CustomerID:GREAL EmployeeID:3 ShipPostalCode:97403 OrderDate:4/7/1998
CustomerID:GREAL EmployeeID:4 ShipPostalCode:97403 OrderDate:4/22/1998
CustomerID:GREAL EmployeeID:4 ShipPostalCode:97403 OrderDate:4/30/1998
CustomerID:HUNGC EmployeeID:3 ShipPostalCode:97827 OrderDate:12/6/1996
CustomerID:HUNGC EmployeeID:1 ShipPostalCode:97827 OrderDate:12/25/1996
CustomerID:HUNGC EmployeeID:3 ShipPostalCode:97827 OrderDate:1/15/1997
CustomerID:HUNGC EmployeeID:4 ShipPostalCode:97827 OrderDate:7/16/1997
CustomerID:HUNGC EmployeeID:8 ShipPostalCode:97827 OrderDate:9/8/1997
CustomerID:LAZYK EmployeeID:1 ShipPostalCode:99362 OrderDate:3/21/1997
CustomerID:LAZYK EmployeeID:8 ShipPostalCode:99362 OrderDate:5/22/1997
Ara değerleri hesaplama (C#)
25.11.2019 • 2 minutes to read • Edit Online

Bu örnek, sıralama, filtreleme ve seçme için kullanılabilen ara değerlerin nasıl hesaplanacağını gösterir.

Örnek
Aşağıdaki örnek Let yan tümcesini kullanır.
Bu örnek, şu XML belgesini kullanır: örnek xml dosyası: sayısal veri (LINQ to XML ).

XElement root = XElement.Load("Data.xml");


IEnumerable<decimal> extensions =
from el in root.Elements("Data")
let extension = (decimal)el.Element("Quantity") * (decimal)el.Element("Price")
where extension >= 25
orderby extension
select extension;
foreach (decimal ex in extensions)
Console.WriteLine(ex);

Bu kod aşağıdaki çıktıyı üretir:

55.92
73.50
89.99
198.00
435.00

Örnek
Aşağıdaki örnek, bir ad alanında bulunan XML için aynı sorguyu gösterir. Daha fazla bilgi için bkz. ad alanlarına
genel bakış (C#LINQ to XML ) ().
Bu örnek, şu XML belgesini kullanır: örnek xml dosyası: bir ad alanında sayısal veri.

XElement root = XElement.Load("DataInNamespace.xml");


XNamespace ad = "http://www.adatum.com";
IEnumerable<decimal> extensions =
from el in root.Elements(ad + "Data")
let extension = (decimal)el.Element(ad + "Quantity") * (decimal)el.Element(ad + "Price")
where extension >= 25
orderby extension
select extension;
foreach (decimal ex in extensions)
Console.WriteLine(ex);

Bu kod aşağıdaki çıktıyı üretir:


55.92
73.50
89.99
198.00
435.00
Nasıl yapılır: Bağlam (C#) temelinde öğeleri bulan bir
sorgu yazın
23.10.2019 • 2 minutes to read • Edit Online

Bazen, bağlamlarına göre öğeleri seçen bir sorgu yazmanız gerekebilir. Önceki veya sonraki eşdüzey öğelere göre
filtrelemek isteyebilirsiniz. Alt veya üst öğe öğelerine göre filtrelemek isteyebilirsiniz.
Bunu, where bir sorgu yazarak ve yan tümcesindeki sorgunun sonuçlarını kullanarak yapabilirsiniz. İlk olarak null
ile test etmeniz ve sonra değeri test etmeniz gerekiyorsa, bir let yan tümce içinde sorgu yapmak daha uygundur
ve sonra sonuçları where yan tümce içinde kullanın.

Örnek
Aşağıdaki örnek, hemen arkasından p bir ul öğesi olan tüm öğeleri seçer.

XElement doc = XElement.Parse(@"<Root>


<p id=""1""/>
<ul>abc</ul>
<Child>
<p id=""2""/>
<notul/>
<p id=""3""/>
<ul>def</ul>
<p id=""4""/>
</Child>
<Child>
<p id=""5""/>
<notul/>
<p id=""6""/>
<ul>abc</ul>
<p id=""7""/>
</Child>
</Root>");

IEnumerable<XElement> items =
from e in doc.Descendants("p")
let z = e.ElementsAfterSelf().FirstOrDefault()
where z != null && z.Name.LocalName == "ul"
select e;

foreach (XElement e in items)


Console.WriteLine("id = {0}", (string)e.Attribute("id"));

Bu kod aşağıdaki çıktıyı üretir:

id = 1
id = 3
id = 6

Örnek
Aşağıdaki örnek, bir ad alanında bulunan XML için aynı sorguyu gösterir. Daha fazla bilgi için bkz. ad alanlarına
genel bakış (C#LINQ to XML ) ().
XElement doc = XElement.Parse(@"<Root xmlns='http://www.adatum.com'>
<p id=""1""/>
<ul>abc</ul>
<Child>
<p id=""2""/>
<notul/>
<p id=""3""/>
<ul>def</ul>
<p id=""4""/>
</Child>
<Child>
<p id=""5""/>
<notul/>
<p id=""6""/>
<ul>abc</ul>
<p id=""7""/>
</Child>
</Root>");

XNamespace ad = "http://www.adatum.com";

IEnumerable<XElement> items =
from e in doc.Descendants(ad + "p")
let z = e.ElementsAfterSelf().FirstOrDefault()
where z != null && z.Name == ad.GetName("ul")
select e;

foreach (XElement e in items)


Console.WriteLine("id = {0}", (string)e.Attribute("id"));

Bu kod aşağıdaki çıktıyı üretir:

id = 1
id = 3
id = 6

Ayrıca bkz.
Parse
Descendants
ElementsAfterSelf
FirstOrDefault
Boş sorgu sonuçları kümelerinde hata ayıklama (C#)
25.11.2019 • 2 minutes to read • Edit Online

XML ağaçlarını sorgularken en yaygın sorunlardan biri, XML ağacının varsayılan bir ad alanına sahip olması ve
geliştiricinin bazen sorguyu bir ad alanında olmamasına rağmen yazar.
Bu konudaki ilk örnek kümesi, varsayılan bir ad alanındaki XML 'nin yüklendiği ve yanlış sorgulandığı tipik bir
yöntemi gösterir.
İkinci örnek kümesinde, bir ad alanında XML 'yi sorgulayabilmeniz için gerekli düzeltmeler gösterilmektedir.
Daha fazla bilgi için bkz. ad alanlarına genel bakış (C#LINQ to XML ) ().

Örnek
Bu örnek, bir ad alanında XML oluşturmayı ve boş bir sonuç kümesi döndüren bir sorguyu gösterir.

XElement root = XElement.Parse(


@"<Root xmlns='http://www.adventure-works.com'>
<Child>1</Child>
<Child>2</Child>
<Child>3</Child>
<AnotherChild>4</AnotherChild>
<AnotherChild>5</AnotherChild>
<AnotherChild>6</AnotherChild>
</Root>");
IEnumerable<XElement> c1 =
from el in root.Elements("Child")
select el;
Console.WriteLine("Result set follows:");
foreach (XElement el in c1)
Console.WriteLine((int)el);
Console.WriteLine("End of result set");

Bu örnek aşağıdaki sonucu üretir:

Result set follows:


End of result set

Örnek
Bu örnek, bir ad alanında XML oluşturmayı ve düzgün kodlanmış bir sorguyu gösterir.
Çözüm, bir XNamespace nesnesi bildirmek ve başlatmak ve XName nesneleri belirtirken kullanmak için kullanılır.
Bu durumda, Elements yönteminin bağımsız değişkeni bir XName nesnesidir.
XElement root = XElement.Parse(
@"<Root xmlns='http://www.adventure-works.com'>
<Child>1</Child>
<Child>2</Child>
<Child>3</Child>
<AnotherChild>4</AnotherChild>
<AnotherChild>5</AnotherChild>
<AnotherChild>6</AnotherChild>
</Root>");
XNamespace aw = "http://www.adventure-works.com";
IEnumerable<XElement> c1 =
from el in root.Elements(aw + "Child")
select el;
Console.WriteLine("Result set follows:");
foreach (XElement el in c1)
Console.WriteLine((int)el);
Console.WriteLine("End of result set");

Bu örnek aşağıdaki sonucu üretir:

Result set follows:


1
2
3
End of result set
Nasıl yapılır: LINQ to XML (C#) kullanarak sözlüklerle
çalışma
23.10.2019 • 2 minutes to read • Edit Online

Çok sayıda veri yapısını XML 'e ve XML 'e diğer veri yapılarına dönüştürmek genellikle yararlıdır. Bu konu, bir
Dictionary<TKey,TValue> XML ve geri dönüştürerek bu genel yaklaşımın belirli bir uygulamasını gösterir.

Örnek
Bu örnek, bir sorgu projelerinin yeni XElement nesne ve elde edilen koleksiyonun bir bağımsız değişken olarak kök
XElement nesnenin oluşturucusuna geçirildiği işlevsel oluşturma formunu kullanır.

Dictionary<string, string> dict = new Dictionary<string, string>();


dict.Add("Child1", "Value1");
dict.Add("Child2", "Value2");
dict.Add("Child3", "Value3");
dict.Add("Child4", "Value4");
XElement root = new XElement("Root",
from keyValue in dict
select new XElement(keyValue.Key, keyValue.Value)
);
Console.WriteLine(root);

Bu kod aşağıdaki çıktıyı üretir:

<Root>
<Child1>Value1</Child1>
<Child2>Value2</Child2>
<Child3>Value3</Child3>
<Child4>Value4</Child4>
</Root>

Örnek
Aşağıdaki kod XML 'den bir sözlük oluşturur.

XElement root = new XElement("Root",


new XElement("Child1", "Value1"),
new XElement("Child2", "Value2"),
new XElement("Child3", "Value3"),
new XElement("Child4", "Value4")
);

Dictionary<string, string> dict = new Dictionary<string, string>();


foreach (XElement el in root.Elements())
dict.Add(el.Name.LocalName, el.Value);
foreach (string str in dict.Keys)
Console.WriteLine("{0}:{1}", str, dict[str]);

Bu kod aşağıdaki çıktıyı üretir:


Child1:Value1
Child2:Value2
Child3:Value3
Child4:Value4
Nasıl yapılır: XML ağacının (C#) şeklini dönüştürme
23.10.2019 • 3 minutes to read • Edit Online

Bir XML belgesinin şekli öğe adlarına, öznitelik adlarına ve hiyerarşisinin özelliklerine başvurur.
Bazen bir XML belgesinin şeklini değiştirmeniz gerekir. Örneğin, var olan bir XML belgesini farklı öğe ve öznitelik
adları gerektiren başka bir sisteme göndermeniz gerekebilir. Belgeyi, gereken şekilde silip yeniden adlandırarak,
ancak işlevsel oluşturmayı kullanmak daha okunabilir ve sürdürülebilir kod ile sonuçlanır. İşlevsel oluşturma
hakkında daha fazla bilgi için bkz. Işlevsel oluşturma (LINQ to XML )C#().
İlk örnek, XML belgesi organizasyonunu değiştirir. Karmaşık öğeleri ağaçtaki bir konumdan diğerine taşımıştır.
Bu konudaki ikinci örnek, kaynak belgeden farklı bir şekle sahip bir XML belgesi oluşturur. Öğe adlarının büyük
küçük harflerini değiştirir, bazı öğeleri yeniden adlandırır ve dışarı dönüştürülen ağacın bazı öğelerini kaynak
ağacından bırakır.

Örnek
Aşağıdaki kod, ekli sorgu ifadeleri kullanarak bir XML dosyasının şeklini değiştirir.
Bu örnekteki kaynak XML belgesi, Customers Root tüm müşterileri içeren öğesi altında bir öğesi içerir. Ayrıca,
Orders Root tüm siparişleri içeren öğesi altında bir öğesi de içerir. Bu örnek, her müşteriye ait siparişlerin Orders
Customer öğesi içindeki bir öğede bulunduğu yeni bir XML ağacı oluşturur. Özgün belge ayrıca Order öğesi
içindeki bir CustomerID öğesi de içerir; bu öğe, yeniden şekillendirilmiş belgeden kaldırılır.
Bu örnek aşağıdaki XML belgesini kullanır: Örnek XML dosyası: Müşteriler ve siparişler (LINQ to XML ).

XElement co = XElement.Load("CustomersOrders.xml");
XElement newCustOrd =
new XElement("Root",
from cust in co.Element("Customers").Elements("Customer")
select new XElement("Customer",
cust.Attributes(),
cust.Elements(),
new XElement("Orders",
from ord in co.Element("Orders").Elements("Order")
where (string)ord.Element("CustomerID") == (string)cust.Attribute("CustomerID")
select new XElement("Order",
ord.Attributes(),
ord.Element("EmployeeID"),
ord.Element("OrderDate"),
ord.Element("RequiredDate"),
ord.Element("ShipInfo")
)
)
)
);
Console.WriteLine(newCustOrd);

Bu kod aşağıdaki çıktıyı üretir:


<Root>
<Customer CustomerID="GREAL">
<CompanyName>Great Lakes Food Market</CompanyName>
<ContactName>Howard Snyder</ContactName>
<ContactTitle>Marketing Manager</ContactTitle>
<Phone>(503) 555-7555</Phone>
<FullAddress>
<Address>2732 Baker Blvd.</Address>
<City>Eugene</City>
<Region>OR</Region>
<PostalCode>97403</PostalCode>
<Country>USA</Country>
</FullAddress>
<Orders />
</Customer>
<Customer CustomerID="HUNGC">
<CompanyName>Hungry Coyote Import Store</CompanyName>
<ContactName>Yoshi Latimer</ContactName>
<ContactTitle>Sales Representative</ContactTitle>
<Phone>(503) 555-6874</Phone>
<Fax>(503) 555-2376</Fax>
<FullAddress>
<Address>City Center Plaza 516 Main St.</Address>
<City>Elgin</City>
<Region>OR</Region>
<PostalCode>97827</PostalCode>
<Country>USA</Country>
</FullAddress>
<Orders />
</Customer>
. . .

Örnek
Bu örnek bazı öğeleri yeniden adlandırır ve bazı öznitelikleri öğelere dönüştürür.
Bir ConvertAddress nesneXElement listesi döndüren kod çağırır. Yöntemin bağımsız değişkeni, Address Type
özniteliğinin değeri olan karmaşık öğeyi belirleyen bir sorgudur. "Shipping"
Bu örnek aşağıdaki XML belgesini kullanır: Örnek XML dosyası: Tipik satın alma siparişi (LINQ to XML ).
static IEnumerable<XElement> ConvertAddress(XElement add)
{
List<XElement> fragment = new List<XElement>() {
new XElement("NAME", (string)add.Element("Name")),
new XElement("STREET", (string)add.Element("Street")),
new XElement("CITY", (string)add.Element("City")),
new XElement("ST", (string)add.Element("State")),
new XElement("POSTALCODE", (string)add.Element("Zip")),
new XElement("COUNTRY", (string)add.Element("Country"))
};
return fragment;
}

static void Main(string[] args)


{
XElement po = XElement.Load("PurchaseOrder.xml");
XElement newPo = new XElement("PO",
new XElement("ID", (string)po.Attribute("PurchaseOrderNumber")),
new XElement("DATE", (DateTime)po.Attribute("OrderDate")),
ConvertAddress(
(from el in po.Elements("Address")
where (string)el.Attribute("Type") == "Shipping"
select el)
.First()
)
);
Console.WriteLine(newPo);
}

Bu kod aşağıdaki çıktıyı üretir:

<PO>
<ID>99503</ID>
<DATE>1999-10-20T00:00:00</DATE>
<NAME>Ellen Adams</NAME>
<STREET>123 Maple Street</STREET>
<CITY>Mill Valley</CITY>
<ST>CA</ST>
<POSTALCODE>10999</POSTALCODE>
<COUNTRY>USA</COUNTRY>
</PO>
Projeksiyon türünü denetleme (C#)
25.11.2019 • 2 minutes to read • Edit Online

Projeksiyon, tek bir veri kümesini alma, filtreleme, şeklini değiştirme ve hatta türünü değiştirme işlemidir. Çoğu
sorgu ifadesi tahminleri gerçekleştirir. Bu bölümde gösterilen sorgu ifadelerinin çoğu, XElementIEnumerable<T>
değerlendirin, ancak başka türden Koleksiyonlar oluşturmak için projeksiyonun türünü kontrol edebilirsiniz. Bu
konuda bunun nasıl yapılacağı gösterilmektedir.

Örnek
Aşağıdaki örnek, Customer yeni bir türü tanımlar. Sorgu ifadesi daha sonra Select yan tümcesinde yeni Customer
nesneleri başlatır. Bu, sorgu ifadesinin türünün Customer IEnumerable<T> olmasına neden olur.
Bu örnek, şu XML belgesini kullanır: örnek xml dosyası: müşteriler ve siparişler (LINQ to XML ).

public class Customer


{
private string customerID;
public string CustomerID{ get{return customerID;} set{customerID = value;}}

private string companyName;


public string CompanyName{ get{return companyName;} set{companyName = value;}}

private string contactName;


public string ContactName { get{return contactName;} set{contactName = value;}}

public Customer(string customerID, string companyName, string contactName)


{
CustomerID = customerID;
CompanyName = companyName;
ContactName = contactName;
}

public override string ToString()


{
return $"{this.customerID}:{this.companyName}:{this.contactName}";
}
}

class Program
{
static void Main(string[] args)
{
XElement custOrd = XElement.Load("CustomersOrders.xml");
IEnumerable<Customer> custList =
from el in custOrd.Element("Customers").Elements("Customer")
select new Customer(
(string)el.Attribute("CustomerID"),
(string)el.Element("CompanyName"),
(string)el.Element("ContactName")
);
foreach (Customer cust in custList)
Console.WriteLine(cust);
}
}

Bu kod aşağıdaki çıktıyı üretir:


GREAL:Great Lakes Food Market:Howard Snyder
HUNGC:Hungry Coyote Import Store:Yoshi Latimer
LAZYK:Lazy K Kountry Store:John Steel
LETSS:Let's Stop N Shop:Jaime Yorres

Ayrıca bkz.
Select
Nasıl yapılır: Yeni bir tür projesi (LINQ to XML) (C#)
23.10.2019 • 2 minutes to read • Edit Online

Bu bölümdeki diğer örneklerde IEnumerable<T> IEnumerable<T> string ,,IEnumerable<T> ve ' den itibaren
sonuç int döndürensorgulargösterilmiştir. XElement Bunlar yaygın sonuç türleridir, ancak her senaryo için uygun
değildir. Çoğu durumda, sorgularınızın başka bir IEnumerable<T> türden birini döndürmesini isteyeceksiniz.

Örnek
Bu örnek, select yan tümcesindeki nesnelerin örneğini oluşturmayı gösterir. Kod ilk olarak bir Oluşturucu içeren
yeni bir sınıf tanımlar ve ardından select deyimi, ifadenin yeni bir sınıf örneği olacak şekilde değiştirir.
Bu örnek aşağıdaki XML belgesini kullanır: Örnek XML dosyası: Tipik satın alma siparişi (LINQ to XML ).

class NameQty
{
public string name;
public int qty;
public NameQty(string n, int q)
{
name = n;
qty = q;
}
};

class Program {
public static void Main()
{
XElement po = XElement.Load("PurchaseOrder.xml");

IEnumerable<NameQty> nqList =
from n in po.Descendants("Item")
select new NameQty(
(string)n.Element("ProductName"),
(int)n.Element("Quantity")
);

foreach (NameQty n in nqList)


Console.WriteLine(n.name + ":" + n.qty);
}
}

Bu örnekte, konusunda Element açıklanan yöntemi kullanılmıştır: Tek bir alt öğe al (LINQ to XML ) (C#) . Ayrıca,
Element yöntemi tarafından döndürülen öğelerin değerlerini almak için yayınları kullanır.
Bu örnek aşağıdaki çıktıyı üretir:

Lawnmower:1
Baby Monitor:2
Nasıl yapılır: Nesne grafiğini (C#) proje
23.10.2019 • 3 minutes to read • Edit Online

Bu konu, XML 'deki bir nesne grafiğinin nasıl proje veya doldurma yapılacağını gösterir.

Örnek
Aşağıdaki kod, bir Address nesne grafiğini örnek XML dosyasındaki, PurchaseOrder , ve PurchaseOrderItem
sınıflarıyla doldurur: Tipik satın alma siparişi (LINQ to XML ) XML belgesi.

class Address
{
public enum AddressUse
{
Shipping,
Billing,
}

private AddressUse addressType;


private string name;
private string street;
private string city;
private string state;
private string zip;
private string country;

public AddressUse AddressType {


get { return addressType; } set { addressType = value; }
}

public string Name {


get { return name; } set { name = value; }
}

public string Street {


get { return street; } set { street = value; }
}

public string City {


get { return city; } set { city = value; }
}

public string State {


get { return state; } set { state = value; }
}

public string Zip {


get { return zip; } set { zip = value; }
}

public string Country {


get { return country; } set { country = value; }
}

public override string ToString()


{
StringBuilder sb = new StringBuilder();
sb.Append($"Type: {(addressType == AddressUse.Shipping ? "Shipping" : "Billing")}\n");
sb.Append($"Name: {name}\n");
sb.Append($"Street: {street}\n");
sb.Append($"City: {city}\n");
sb.Append($"City: {city}\n");
sb.Append($"State: {state}\n");
sb.Append($"Zip: {zip}\n");
sb.Append($"Country: {country}\n");
return sb.ToString();
}
}

class PurchaseOrderItem
{
private string partNumber;
private string productName;
private int quantity;
private Decimal usPrice;
private string comment;
private DateTime shipDate;

public string PartNumber {


get { return partNumber; } set { partNumber = value; }
}

public string ProductName {


get { return productName; } set { productName = value; }
}

public int Quantity {


get { return quantity; } set { quantity = value; }
}

public Decimal USPrice {


get { return usPrice; } set { usPrice = value; }
}

public string Comment {


get { return comment; } set { comment = value; }
}

public DateTime ShipDate {


get { return shipDate; } set { shipDate = value; }
}

public override string ToString()


{
StringBuilder sb = new StringBuilder();
sb.Append($"PartNumber: {partNumber}\n");
sb.Append($"ProductName: {productName}\n");
sb.Append($"Quantity: {quantity}\n");
sb.Append($"USPrice: {usPrice}\n");
if (comment != null)
sb.Append($"Comment: {comment}\n");
if (shipDate != DateTime.MinValue)
sb.Append($"ShipDate: {shipDate:d}\n");
return sb.ToString();
}
}

class PurchaseOrder
{
private string purchaseOrderNumber;
private DateTime orderDate;
private string comment;
private List<Address> addresses;
private List<PurchaseOrderItem> items;

public string PurchaseOrderNumber {


get { return purchaseOrderNumber; } set { purchaseOrderNumber = value; }
}

public DateTime OrderDate {


get { return orderDate; } set { orderDate = value; }
get { return orderDate; } set { orderDate = value; }
}

public string Comment {


get { return comment; } set { comment = value; }
}

public List<Address> Addresses {


get { return addresses; } set { addresses = value; }
}

public List<PurchaseOrderItem> Items {


get { return items; } set { items = value; }
}

public override string ToString()


{
StringBuilder sb = new StringBuilder();
sb.Append($"PurchaseOrderNumber: {purchaseOrderNumber}\n");
sb.Append($"OrderDate: {orderDate:d}\n");
sb.Append("\n");
sb.Append("Addresses\n");
sb.Append("=====\n");
foreach (Address address in addresses)
{
sb.Append(address);
sb.Append("\n");
}
sb.Append("Items\n");
sb.Append("=====\n");
foreach (PurchaseOrderItem item in items)
{
sb.Append(item);
sb.Append("\n");
}
return sb.ToString();
}
}

class Program {
public static void Main()
{
XElement po = XElement.Load("PurchaseOrder.xml");
PurchaseOrder purchaseOrder = new PurchaseOrder {
PurchaseOrderNumber = (string)po.Attribute("PurchaseOrderNumber"),
OrderDate = (DateTime)po.Attribute("OrderDate"),
Addresses = (
from a in po.Elements("Address")
select new Address {
AddressType = ((string)a.Attribute("Type") == "Shipping") ?
Address.AddressUse.Shipping :
Address.AddressUse.Billing,
Name = (string)a.Element("Name"),
Street = (string)a.Element("Street"),
City = (string)a.Element("City"),
State = (string)a.Element("State"),
Zip = (string)a.Element("Zip"),
Country = (string)a.Element("Country")
}
).ToList(),
Items = (
from i in po.Element("Items").Elements("Item")
select new PurchaseOrderItem {
PartNumber = (string)i.Attribute("PartNumber"),
ProductName = (string)i.Element("ProductName"),
Quantity = (int)i.Element("Quantity"),
USPrice = (Decimal)i.Element("USPrice"),
Comment = (string)i.Element("Comment"),
ShipDate = (i.Element("ShipDate") != null) ?
(DateTime)i.Element("ShipDate") :
(DateTime)i.Element("ShipDate") :
DateTime.MinValue
}
).ToList()
};
Console.WriteLine(purchaseOrder);
}
}

Bu örnekte, LINQ sorgunun sonucu ' a döndürülür IEnumerable<T> PurchaseOrderItem . PurchaseOrder Sınıfındaki
IEnumerable<T> öğeler PurchaseOrderItem türündedir. Kod, sorgu sonuçlarından ToList bir List<T> koleksiyon
oluşturmak için genişletme yöntemini kullanır.
Örnek aşağıdaki çıktıyı üretir:

PurchaseOrderNumber: 99503
OrderDate: 10/20/1999

Addresses
=====
Type: Shipping
Name: Ellen Adams
Street: 123 Maple Street
City: Mill Valley
State: CA
Zip: 10999
Country: USA

Type: Billing
Name: Tai Yee
Street: 8 Oak Avenue
City: Old Town
State: PA
Zip: 95819
Country: USA

Items
=====
PartNumber: 872-AA
ProductName: Lawnmower
Quantity: 1
USPrice: 148.95
Comment: Confirm this is electric

PartNumber: 926-AA
ProductName: Baby Monitor
Quantity: 2
USPrice: 39.98
ShipDate: 5/21/1999

Ayrıca bkz.
Select
ToList
Nasıl yapılır: Anonim bir tür (C#) proje
23.10.2019 • 2 minutes to read • Edit Online

Bazı durumlarda, bu türü yalnızca kısa bir süre kullanacağınızı bildiğiniz halde yeni bir türe bir sorgu için proje
yapmak isteyebilirsiniz. Projeksiyon içinde kullanmak için yeni bir tür oluşturmaya yönelik çok fazla iş vardır. Bu
örnekte daha verimli bir yaklaşım, bir anonim türe projem değildir. Anonim türler sınıfı tanımlamanızı sağlar, sonra
sınıfa bir ad vermeden bu sınıfın bir nesnesini bildirip başlatabilir.
Anonim türler, bir C# tanımlamagrubunun matematik kavramının uygulamasıdır. Matematiksel terim tanımlama
grubu, tek, Çift, Üçlü, dörtlü, quintuple, n-Tuple dizisinden kaynakdır. Belirli bir türün her biri, sınırlı bir nesne
dizisine başvurur. Bazen buna ad/değer çiftleri listesi denir. Örneğin, örnek XML dosyasındaki bir adresin içeriği:
Tipik satın alma siparişi (LINQ to XML ) XML belgesi şu şekilde ifade edilebilir:

Name: Ellen Adams


Street: 123 Maple Street
City: Mill Valley
State: CA
Zip: 90952
Country: USA

Anonim bir türün bir örneğini oluşturduğunuzda, bunu bir sıra n grubu oluşturarak düşünmek kullanışlıdır. select
Yan tümcesinde bir tanımlama grubu oluşturan bir sorgu yazarsanız sorgu, kayıt düzeni IEnumerable döndürür.

Örnek
Bu örnekte select yan tümce, anonim bir tür. Örnek daha sonra IEnumerable nesneyi var oluşturmak için
kullanır. foreach Döngü içinde, yineleme değişkeni sorgu ifadesinde oluşturulan anonim türün bir örneği olur.
Bu örnek aşağıdaki XML belgesini kullanır: Örnek XML dosyası: Müşteriler ve siparişler (LINQ to XML ).

XElement custOrd = XElement.Load("CustomersOrders.xml");


var custList =
from el in custOrd.Element("Customers").Elements("Customer")
select new {
CustomerID = (string)el.Attribute("CustomerID"),
CompanyName = (string)el.Element("CompanyName"),
ContactName = (string)el.Element("ContactName")
};
foreach (var cust in custList)
Console.WriteLine("{0}:{1}:{2}", cust.CustomerID, cust.CompanyName, cust.ContactName);

Bu kod aşağıdaki çıktıyı üretir:

GREAL:Great Lakes Food Market:Howard Snyder


HUNGC:Hungry Coyote Import Store:Yoshi Latimer
LAZYK:Lazy K Kountry Store:John Steel
LETSS:Let's Stop N Shop:Jaime Yorres
Nasıl yapılır: XML 'den metin dosyaları oluşturma (C#)
4.11.2019 • 2 minutes to read • Edit Online

Bu örnek, bir XML dosyasından bir virgülle ayrılmış değerler (CSV ) dosyasının nasıl oluşturulacağını gösterir.

Örnek
Bu C# örneğin sürümü, tek bir IFADEDE bir XML belgesinden CSV dosyası oluşturmak için yöntem sözdizimini ve
Aggregate işlecini kullanır. Daha fazla bilgi için bkz. LINQ 'Te sorgu sözdizimi ve Yöntem sözdizimi.

Bu örnek, şu XML belgesini kullanır: örnek xml dosyası: müşteriler ve siparişler (LINQ to XML ).

XElement custOrd = XElement.Load("CustomersOrders.xml");


string csv =
(from el in custOrd.Element("Customers").Elements("Customer")
select
String.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9}{10}",
(string)el.Attribute("CustomerID"),
(string)el.Element("CompanyName"),
(string)el.Element("ContactName"),
(string)el.Element("ContactTitle"),
(string)el.Element("Phone"),
(string)el.Element("FullAddress").Element("Address"),
(string)el.Element("FullAddress").Element("City"),
(string)el.Element("FullAddress").Element("Region"),
(string)el.Element("FullAddress").Element("PostalCode"),
(string)el.Element("FullAddress").Element("Country"),
Environment.NewLine
)
)
.Aggregate(
new StringBuilder(),
(sb, s) => sb.Append(s),
sb => sb.ToString()
);
Console.WriteLine(csv);

Bu kod aşağıdaki çıktıyı üretir:

GREAL,Great Lakes Food Market,Howard Snyder,Marketing Manager,(503) 555-7555,2732 Baker


Blvd.,Eugene,OR,97403,USA
HUNGC,Hungry Coyote Import Store,Yoshi Latimer,Sales Representative,(503) 555-6874,City Center Plaza 516 Main
St.,Elgin,OR,97827,USA
LAZYK,Lazy K Kountry Store,John Steel,Marketing Manager,(509) 555-7969,12 Orchestra Terrace,Walla
Walla,WA,99362,USA
LETSS,Let's Stop N Shop,Jaime Yorres,Owner,(415) 555-5938,87 Polk St. Suite 5,San Francisco,CA,94117,USA

Ayrıca bkz.
Projeksiyonlar ve dönüşümler (LINQ to XMLC#) ()
Nasıl yapılır: CSV dosyalarından XML oluşturma (C#)
23.10.2019 • 2 minutes to read • Edit Online

Bu örnek nasıl kullanılacağını gösterir Dil ile Tümleşik Sorgu (LINQ ) ve LINQ - XML bir virgülle ayrılmış değer
(CSV ) dosyasından bir XML dosyası oluşturmak için.

Örnek
Aşağıdaki kod gerçekleştiren bir LINQ dizelerden oluşan bir dizi üzerindeki sorgu.
Sorgu kullanan let her dize alanları bir diziye bölmek için yan tümcesi.

// Create the text file.


string csvString = @"GREAL,Great Lakes Food Market,Howard Snyder,Marketing Manager,(503) 555-7555,2732 Baker
Blvd.,Eugene,OR,97403,USA
HUNGC,Hungry Coyote Import Store,Yoshi Latimer,Sales Representative,(503) 555-6874,City Center Plaza 516 Main
St.,Elgin,OR,97827,USA
LAZYK,Lazy K Kountry Store,John Steel,Marketing Manager,(509) 555-7969,12 Orchestra Terrace,Walla
Walla,WA,99362,USA
LETSS,Let's Stop N Shop,Jaime Yorres,Owner,(415) 555-5938,87 Polk St. Suite 5,San Francisco,CA,94117,USA";
File.WriteAllText("cust.csv", csvString);

// Read into an array of strings.


string[] source = File.ReadAllLines("cust.csv");
XElement cust = new XElement("Root",
from str in source
let fields = str.Split(',')
select new XElement("Customer",
new XAttribute("CustomerID", fields[0]),
new XElement("CompanyName", fields[1]),
new XElement("ContactName", fields[2]),
new XElement("ContactTitle", fields[3]),
new XElement("Phone", fields[4]),
new XElement("FullAddress",
new XElement("Address", fields[5]),
new XElement("City", fields[6]),
new XElement("Region", fields[7]),
new XElement("PostalCode", fields[8]),
new XElement("Country", fields[9])
)
)
);
Console.WriteLine(cust);

Bu kod aşağıdaki çıktıyı üretir:


<Root>
<Customer CustomerID="GREAL">
<CompanyName>Great Lakes Food Market</CompanyName>
<ContactName>Howard Snyder</ContactName>
<ContactTitle>Marketing Manager</ContactTitle>
<Phone>(503) 555-7555</Phone>
<FullAddress>
<Address>2732 Baker Blvd.</Address>
<City>Eugene</City>
<Region>OR</Region>
<PostalCode>97403</PostalCode>
<Country>USA</Country>
</FullAddress>
</Customer>
<Customer CustomerID="HUNGC">
<CompanyName>Hungry Coyote Import Store</CompanyName>
<ContactName>Yoshi Latimer</ContactName>
<ContactTitle>Sales Representative</ContactTitle>
<Phone>(503) 555-6874</Phone>
<FullAddress>
<Address>City Center Plaza 516 Main St.</Address>
<City>Elgin</City>
<Region>OR</Region>
<PostalCode>97827</PostalCode>
<Country>USA</Country>
</FullAddress>
</Customer>
<Customer CustomerID="LAZYK">
<CompanyName>Lazy K Kountry Store</CompanyName>
<ContactName>John Steel</ContactName>
<ContactTitle>Marketing Manager</ContactTitle>
<Phone>(509) 555-7969</Phone>
<FullAddress>
<Address>12 Orchestra Terrace</Address>
<City>Walla Walla</City>
<Region>WA</Region>
<PostalCode>99362</PostalCode>
<Country>USA</Country>
</FullAddress>
</Customer>
<Customer CustomerID="LETSS">
<CompanyName>Let's Stop N Shop</CompanyName>
<ContactName>Jaime Yorres</ContactName>
<ContactTitle>Owner</ContactTitle>
<Phone>(415) 555-5938</Phone>
<FullAddress>
<Address>87 Polk St. Suite 5</Address>
<City>San Francisco</City>
<Region>CA</Region>
<PostalCode>94117</PostalCode>
<Country>USA</Country>
</FullAddress>
</Customer>
</Root>
Nasıl yapılır: Iki koleksiyonu birleştirin (LINQ to XML)
(C#)
23.10.2019 • 3 minutes to read • Edit Online

XML belgesindeki bir öğe veya öznitelik, bazen başka bir öğe veya özniteliğe başvurabilir. Örneğin, örnek xml
dosyası: Müşteriler ve siparişler (LINQ to XML ) XML belgesi, müşterilerin ve siparişlerin listesinin bir listesini içerir.
Her Customer öğe bir CustomerID özniteliği içerir. Her Order öğe bir CustomerID öğesi içerir. Her siparişte
bulunan CustomerID CustomerID öğe, bir müşterinin özniteliği anlamına gelir.
Örnek örnek xsd dosyası: Müşteriler ve siparişler , bu belgeyi doğrulamak için kullanılabilecek bir xsd içerir. xs:key
CustomerID xs:keyref Öğeözniteliğinin biranahtar CustomerID olduğunu ve her Order öğe ve içindeki öğe
arasında bir ilişki oluşturmasını sağlamak için xsd 'nin ve özelliklerini kullanır. Customer CustomerID her Customer
öğe için özniteliği.
İle LINQ - XML, join yan tümcesini kullanarak bu ilişkiyi kullanabilirsiniz.
Kullanılabilir dizin olmadığından, bu tür bir birleştirme çalışma zamanı performansına sahip olacaktır.
Hakkında join daha ayrıntılı bilgi için bkz. JOIN Operations (C#).

Örnek
Aşağıdaki örnek öğeleri Order öğelerine birleştirir Customer ve siparişlerdeki CompanyName öğesini içeren yeni bir
XML belgesi oluşturur.
Sorguyu yürütmeden önce örnek, belgenin örnek xsd dosyasındaki şemayla uyumlu olduğunu doğrular:
Müşteriler ve siparişler. Bu, JOIN yan tümcesinin her zaman çalışmasına de sağlar.
Bu sorgu önce tüm Customer öğeleri alır ve ardından bunları Order öğelerine birleştirir. Yalnızca "K" dan
CustomerID büyük müşterilere ait siparişleri seçer. Ardından, her bir sırada Order müşteri bilgilerini içeren yeni bir
öğesi projeler.
Bu örnek aşağıdaki XML belgesini kullanır: Örnek XML dosyası: Müşteriler ve siparişler (LINQ to XML ).
Bu örnek, aşağıdaki XSD şemasını kullanır: Örnek XSD Dosyası: Müşteriler ve siparişler.
Bu biçimde birleştirme işlemi çok iyi gerçekleştirmez. Birleşimler, doğrusal bir arama yoluyla yapılır. Performansla
ilgili yardım için hiçbir karma tablo veya dizin yok.
XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add("", "CustomersOrders.xsd");

Console.Write("Attempting to validate, ");


XDocument custOrdDoc = XDocument.Load("CustomersOrders.xml");

bool errors = false;


custOrdDoc.Validate(schemas, (o, e) =>
{
Console.WriteLine("{0}", e.Message);
errors = true;
});
Console.WriteLine("custOrdDoc {0}", errors ? "did not validate" : "validated");

if (!errors)
{
// Join customers and orders, and create a new XML document with
// a different shape.

// The new document contains orders only for customers with a


// CustomerID > 'K'
XElement custOrd = custOrdDoc.Element("Root");
XElement newCustOrd = new XElement("Root",
from c in custOrd.Element("Customers").Elements("Customer")
join o in custOrd.Element("Orders").Elements("Order")
on (string)c.Attribute("CustomerID") equals
(string)o.Element("CustomerID")
where ((string)c.Attribute("CustomerID")).CompareTo("K") > 0
select new XElement("Order",
new XElement("CustomerID", (string)c.Attribute("CustomerID")),
new XElement("CompanyName", (string)c.Element("CompanyName")),
new XElement("ContactName", (string)c.Element("ContactName")),
new XElement("EmployeeID", (string)o.Element("EmployeeID")),
new XElement("OrderDate", (DateTime)o.Element("OrderDate"))
)
);
Console.WriteLine(newCustOrd);
}

Bu kod aşağıdaki çıktıyı üretir:


Attempting to validate, custOrdDoc validated
<Root>
<Order>
<CustomerID>LAZYK</CustomerID>
<CompanyName>Lazy K Kountry Store</CompanyName>
<ContactName>John Steel</ContactName>
<EmployeeID>1</EmployeeID>
<OrderDate>1997-03-21T00:00:00</OrderDate>
</Order>
<Order>
<CustomerID>LAZYK</CustomerID>
<CompanyName>Lazy K Kountry Store</CompanyName>
<ContactName>John Steel</ContactName>
<EmployeeID>8</EmployeeID>
<OrderDate>1997-05-22T00:00:00</OrderDate>
</Order>
<Order>
<CustomerID>LETSS</CustomerID>
<CompanyName>Let's Stop N Shop</CompanyName>
<ContactName>Jaime Yorres</ContactName>
<EmployeeID>1</EmployeeID>
<OrderDate>1997-06-25T00:00:00</OrderDate>
</Order>
<Order>
<CustomerID>LETSS</CustomerID>
<CompanyName>Let's Stop N Shop</CompanyName>
<ContactName>Jaime Yorres</ContactName>
<EmployeeID>8</EmployeeID>
<OrderDate>1997-10-27T00:00:00</OrderDate>
</Order>
<Order>
<CustomerID>LETSS</CustomerID>
<CompanyName>Let's Stop N Shop</CompanyName>
<ContactName>Jaime Yorres</ContactName>
<EmployeeID>6</EmployeeID>
<OrderDate>1997-11-10T00:00:00</OrderDate>
</Order>
<Order>
<CustomerID>LETSS</CustomerID>
<CompanyName>Let's Stop N Shop</CompanyName>
<ContactName>Jaime Yorres</ContactName>
<EmployeeID>4</EmployeeID>
<OrderDate>1998-02-12T00:00:00</OrderDate>
</Order>
</Root>
Gruplandırma (C#) kullanarak hiyerarşi oluşturma
25.11.2019 • 2 minutes to read • Edit Online

Bu örnek, verilerin nasıl gruplanıp gruplandırılmasının yanı sıra gruplandırma temelli XML oluşturmayı gösterir.

Örnek
Bu örnek öncelikle verileri bir kategoriye göre gruplandırır, ardından XML hiyerarşisinin gruplamayı yansıtan yeni
bir XML dosyası oluşturur.
Bu örnek, şu XML belgesini kullanır: örnek xml dosyası: sayısal veri (LINQ to XML ).

XElement doc = XElement.Load("Data.xml");


var newData =
new XElement("Root",
from data in doc.Elements("Data")
group data by (string)data.Element("Category") into groupedData
select new XElement("Group",
new XAttribute("ID", groupedData.Key),
from g in groupedData
select new XElement("Data",
g.Element("Quantity"),
g.Element("Price")
)
)
);
Console.WriteLine(newData);

Bu örnek aşağıdaki çıktıyı üretir:


<Root>
<Group ID="A">
<Data>
<Quantity>3</Quantity>
<Price>24.50</Price>
</Data>
<Data>
<Quantity>5</Quantity>
<Price>4.95</Price>
</Data>
<Data>
<Quantity>3</Quantity>
<Price>66.00</Price>
</Data>
<Data>
<Quantity>15</Quantity>
<Price>29.00</Price>
</Data>
</Group>
<Group ID="B">
<Data>
<Quantity>1</Quantity>
<Price>89.99</Price>
</Data>
<Data>
<Quantity>10</Quantity>
<Price>.99</Price>
</Data>
<Data>
<Quantity>8</Quantity>
<Price>6.99</Price>
</Data>
</Group>
</Root>
Nasıl yapılır: LINQ to XML XPath kullanarak sorgula
(C#)
23.10.2019 • 2 minutes to read • Edit Online

Bu konu, bir XML ağacı XPath kullanarak sorgula olanak tanıyan uzantı yöntemleri tanıtır. Bu uzantı yöntemleri
kullanma hakkında ayrıntılı bilgi için bkz System.Xml.XPath.Extensions.
Kullanarak sorgulamak için çok özel bir nedeniniz yoksa, XPath XPath ile LINQ to XML kullanarak eski kod
kapsamlı kullanımını gibi önerilmez. XPath sorguları gerçekleştirme yanı LINQ - XML sorgular.

Örnek
Aşağıdaki örnek, küçük bir XML ağacı oluşturur ve kullanır XPathSelectElements öğe kümesini seçin.

XElement root = new XElement("Root",


new XElement("Child1", 1),
new XElement("Child1", 2),
new XElement("Child1", 3),
new XElement("Child2", 4),
new XElement("Child2", 5),
new XElement("Child2", 6)
);
IEnumerable<XElement> list = root.XPathSelectElements("./Child2");
foreach (XElement el in list)
Console.WriteLine(el);

Bu örnek aşağıdaki çıktıyı üretir:

<Child2>4</Child2>
<Child2>5</Child2>
<Child2>6</Child2>
Nasıl yapılır: LINQ to XML Axis yöntemi (C#) yazın
23.10.2019 • 4 minutes to read • Edit Online

Bir XML ağacından koleksiyonları almak için kendi eksen yöntemlerinizi yazabilirsiniz. Bunu gerçekleştirmenin en
iyi yöntemlerinden biri, öğe veya özniteliklerin bir koleksiyonunu döndüren bir genişletme yöntemi yazmaktır.
Uygulamanızın gereksinimlerine bağlı olarak, öğelerin veya özniteliklerin belirli alt kümelerini döndürmek için
uzantı yönteminizi yazabilirsiniz.

Örnek
Aşağıdaki örnekte iki genişletme yöntemi kullanılmaktadır. İlk genişletme yöntemi GetXPath ,, üzerinde
XObjectçalışır ve değerlendirilen bir XPath ifadesi döndürür ve değerlendirildiğinde düğüm veya öznitelik
döndürülür. İkinci uzantı yöntemi Find üzerinde XElementçalışır. Belirli bir metni içeren XAttribute nesne ve
XElement nesnelerin bir koleksiyonunu döndürür.
Bu örnek aşağıdaki XML belgesini kullanır: Örnek XML dosyası: Birden çok satın alma siparişi (LINQ to XML ).

public static class MyExtensions


{
private static string GetQName(XElement xe)
{
string prefix = xe.GetPrefixOfNamespace(xe.Name.Namespace);
if (xe.Name.Namespace == XNamespace.None || prefix == null)
return xe.Name.LocalName.ToString();
else
return prefix + ":" + xe.Name.LocalName.ToString();
}

private static string GetQName(XAttribute xa)


{
string prefix =
xa.Parent.GetPrefixOfNamespace(xa.Name.Namespace);
if (xa.Name.Namespace == XNamespace.None || prefix == null)
return xa.Name.ToString();
else
return prefix + ":" + xa.Name.LocalName;
}

private static string NameWithPredicate(XElement el)


{
if (el.Parent != null && el.Parent.Elements(el.Name).Count() != 1)
return GetQName(el) + "[" +
(el.ElementsBeforeSelf(el.Name).Count() + 1) + "]";
else
return GetQName(el);
}

public static string StrCat<T>(this IEnumerable<T> source,


string separator)
{
return source.Aggregate(new StringBuilder(),
(sb, i) => sb
.Append(i.ToString())
.Append(separator),
s => s.ToString());
}

public static string GetXPath(this XObject xobj)


{
if (xobj.Parent == null)
{
XDocument doc = xobj as XDocument;
if (doc != null)
return ".";
XElement el = xobj as XElement;
if (el != null)
return "/" + NameWithPredicate(el);
// the XPath data model does not include white space text nodes
// that are children of a document, so this method returns null.
XText xt = xobj as XText;
if (xt != null)
return null;
XComment com = xobj as XComment;
if (com != null)
return
"/" +
(
com
.Document
.Nodes()
.OfType<XComment>()
.Count() != 1 ?
"comment()[" +
(com
.NodesBeforeSelf()
.OfType<XComment>()
.Count() + 1) +
"]" :
"comment()"
);
XProcessingInstruction pi = xobj as XProcessingInstruction;
if (pi != null)
return
"/" +
(
pi.Document.Nodes()
.OfType<XProcessingInstruction>()
.Count() != 1 ?
"processing-instruction()[" +
(pi
.NodesBeforeSelf()
.OfType<XProcessingInstruction>()
.Count() + 1) +
"]" :
"processing-instruction()"
);
return null;
}
else
{
XElement el = xobj as XElement;
if (el != null)
{
return
"/" +
el
.Ancestors()
.InDocumentOrder()
.Select(e => NameWithPredicate(e))
.StrCat("/") +
NameWithPredicate(el);
}
XAttribute at = xobj as XAttribute;
if (at != null)
return
"/" +
at
.Parent
.AncestorsAndSelf()
.InDocumentOrder()
.Select(e => NameWithPredicate(e))
.StrCat("/") +
"@" + GetQName(at);
XComment com = xobj as XComment;
if (com != null)
return
"/" +
com
.Parent
.AncestorsAndSelf()
.InDocumentOrder()
.Select(e => NameWithPredicate(e))
.StrCat("/") +
(
com
.Parent
.Nodes()
.OfType<XComment>()
.Count() != 1 ?
"comment()[" +
(com
.NodesBeforeSelf()
.OfType<XComment>()
.Count() + 1) + "]" :
"comment()"
);
XCData cd = xobj as XCData;
if (cd != null)
return
"/" +
cd
.Parent
.AncestorsAndSelf()
.InDocumentOrder()
.Select(e => NameWithPredicate(e))
.StrCat("/") +
(
cd
.Parent
.Nodes()
.OfType<XText>()
.Count() != 1 ?
"text()[" +
(cd
.NodesBeforeSelf()
.OfType<XText>()
.Count() + 1) + "]" :
"text()"
);
XText tx = xobj as XText;
if (tx != null)
return
"/" +
tx
.Parent
.AncestorsAndSelf()
.InDocumentOrder()
.Select(e => NameWithPredicate(e))
.StrCat("/") +
(
tx
.Parent
.Nodes()
.OfType<XText>()
.Count() != 1 ?
"text()[" +
(tx
(tx
.NodesBeforeSelf()
.OfType<XText>()
.Count() + 1) + "]" :
"text()"
);
XProcessingInstruction pi = xobj as XProcessingInstruction;
if (pi != null)
return
"/" +
pi
.Parent
.AncestorsAndSelf()
.InDocumentOrder()
.Select(e => NameWithPredicate(e))
.StrCat("/") +
(
pi
.Parent
.Nodes()
.OfType<XProcessingInstruction>()
.Count() != 1 ?
"processing-instruction()[" +
(pi
.NodesBeforeSelf()
.OfType<XProcessingInstruction>()
.Count() + 1) + "]" :
"processing-instruction()"
);
return null;
}
}

public static IEnumerable<XObject> Find(this XElement source, string value)


{
if (source.Attributes().Any())
{
foreach (XAttribute att in source.Attributes())
{
string contents = (string)att;
if (contents.Contains(value))
yield return att;
}
}
if (source.Elements().Any())
{
foreach (XElement child in source.Elements())
foreach (XObject s in child.Find(value))
yield return s;
}
else
{
string contents = (string)source;
if (contents.Contains(value))
yield return source;
}
}
}

class Program
{
static void Main(string[] args)
{
XElement purchaseOrders = XElement.Load("PurchaseOrders.xml");

IEnumerable<XObject> subset =
from xobj in purchaseOrders.Find("1999")
select xobj;

foreach (XObject obj in subset)


foreach (XObject obj in subset)
{
Console.WriteLine(obj.GetXPath());
if (obj.GetType() == typeof(XElement))
Console.WriteLine(((XElement)obj).Value);
else if (obj.GetType() == typeof(XAttribute))
Console.WriteLine(((XAttribute)obj).Value);
}
}
}

Bu kod aşağıdaki çıktıyı üretir:

/PurchaseOrders/PurchaseOrder[1]/@OrderDate
1999-10-20
/PurchaseOrders/PurchaseOrder[1]/Items/Item[2]/ShipDate
1999-05-21
/PurchaseOrders/PurchaseOrder[2]/@OrderDate
1999-10-22
/PurchaseOrders/PurchaseOrder[3]/@OrderDate
1999-10-22
Nasıl yapılır: XML 'e (C#) metin akışı dönüşümleri
gerçekleştirme
23.10.2019 • 2 minutes to read • Edit Online

Bir metin dosyasını işlemeye yönelik bir yaklaşım, yield return yapıyı kullanarak metin dosyasını bir kerede bir
satır akışı yapan bir genişletme yöntemi yazmaktır. Daha sonra, metin dosyasını yavaş ertelenmiş bir biçimde
işleyen bir LINQ sorgusu yazabilirsiniz. Daha sonra çıktıyı akışa XStreamingElement almak için öğesini
kullanırsanız, kaynak metin dosyasının boyutundan bağımsız olarak en az miktarda bellek kullanan metin
dosyasından XML 'e bir dönüşüm oluşturabilirsiniz.
Akış dönüşümleriyle ilgili bazı uyarılar vardır. Bir akış dönüştürmesi en iyi şekilde, dosyanın tamamını bir kez
işleyebileceğiniz ve satırları kaynak belgede gerçekleştikleri sırada işleyebileceğiniz durumlarda en iyi şekilde
uygulanır. Dosyayı birden çok kez işlemek istiyorsanız veya satırları işleyebilmeniz için öncelikle sıralama yapmanız
gerekiyorsa, bir akış tekniği kullanmanın avantajlarından çoğunu kaybedersiniz.

Örnek
Aşağıdaki metin dosyası, kişiler. txt, bu örneğin kaynağıdır.

#This is a comment
1,Tai,Yee,Writer
2,Nikolay,Grachev,Programmer
3,David,Wright,Inventor

Aşağıdaki kod, metin dosyasının satırlarını ertelenmiş bir biçimde akıp bir genişletme yöntemi içerir.
public static class StreamReaderSequence
{
public static IEnumerable<string> Lines(this StreamReader source)
{
if (source == null)
throw new ArgumentNullException(nameof(source));

string line;
while ((line = source.ReadLine()) != null)
{
yield return line;
}
}
}

class Program
{
static void Main(string[] args)
{
var sr = new StreamReader("People.txt");
var xmlTree = new XStreamingElement("Root",
from line in sr.Lines()
let items = line.Split(',')
where !line.StartsWith("#")
select new XElement("Person",
new XAttribute("ID", items[0]),
new XElement("First", items[1]),
new XElement("Last", items[2]),
new XElement("Occupation", items[3])
)
);
Console.WriteLine(xmlTree);
sr.Close();
}
}

Bu örnek aşağıdaki çıktıyı üretir:

<Root>
<Person ID="1">
<First>Tai</First>
<Last>Yee</Last>
<Occupation>Writer</Occupation>
</Person>
<Person ID="2">
<First>Nikolay</First>
<Last>Grachev</Last>
<Occupation>Programmer</Occupation>
</Person>
<Person ID="3">
<First>David</First>
<Last>Wright</Last>
<Occupation>Inventor</Occupation>
</Person>
</Root>

Ayrıca bkz.
XStreamingElement
Nasıl yapılır: Bir ağaçtaki tüm düğümleri listeleme
(C#)
23.10.2019 • 5 minutes to read • Edit Online

Bazen bir ağaçtaki tüm düğümleri listelemek yararlı olur. Bu, bir yöntemin veya özelliğin ağacı nasıl etkilediğini tam
olarak öğrenirken yararlı olabilir. Bir metinsel form içindeki tüm düğümleri listelemek için bir yaklaşım, ağaçtaki
herhangi bir düğümü tam olarak ve özellikle tanımlayan bir XPath ifadesi oluşturmaktır.
Kullanılarak LINQ - XMLXPath ifadelerinin yürütülmesi özellikle yararlı değildir. XPath ifadeleri LINQ - XML
sorgulardan poorer performansa sahiptir ve LINQ - XML sorgular çok daha güçlüdür. Ancak, XML ağacındaki
düğümleri belirlemenin bir yolu olarak, XPath iyi bir sonuç verir.

Örnek
Bu örnek, XML ağacındaki herhangi GetXPath bir düğüm için belirli bir XPath ifadesi oluşturan adlı bir işlevi
gösterir. Düğümler bir ad alanında olduğunda bile uygun XPath ifadeleri oluşturur. XPath ifadeleri, ad alanı önekleri
kullanılarak oluşturulur.
Örnek daha sonra birkaç düğüm türüne örnek içeren küçük bir XML ağacı oluşturur. Daha sonra alt düğümler
boyunca yinelenir ve her düğüm için XPath ifadesini yazdırır.
XML bildiriminin ağaçta bir düğüm olmadığına dikkat edin.
Aşağıda, çeşitli düğüm türlerini içeren bir XML dosyası verilmiştir:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>


<?target data?>
<Root AttName="An Attribute" xmlns:aw="http://www.adventure-works.com">
<!--This is a comment-->
<Child>Text</Child>
<Child>Other Text</Child>
<ChildWithMixedContent>text<b>BoldText</b>otherText</ChildWithMixedContent>
<aw:ElementInNamespace>
<aw:ChildInNamespace />
</aw:ElementInNamespace>
</Root>

Aşağıda, XPath ifadeleri olarak ifade edilen Yukarıdaki XML ağacındaki düğümlerin listesi verilmiştir:
/processing-instruction()
/Root
/Root/@AttName
/Root/@xmlns:aw
/Root/comment()
/Root/Child[1]
/Root/Child[1]/text()
/Root/Child[2]
/Root/Child[2]/text()
/Root/ChildWithMixedContent
/Root/ChildWithMixedContent/text()[1]
/Root/ChildWithMixedContent/b
/Root/ChildWithMixedContent/b/text()
/Root/ChildWithMixedContent/text()[2]
/Root/aw:ElementInNamespace
/Root/aw:ElementInNamespace/aw:ChildInNamespace

public static class MyExtensions


{
private static string GetQName(XElement xe)
{
string prefix = xe.GetPrefixOfNamespace(xe.Name.Namespace);
if (xe.Name.Namespace == XNamespace.None || prefix == null)
return xe.Name.LocalName.ToString();
else
return prefix + ":" + xe.Name.LocalName.ToString();
}

private static string GetQName(XAttribute xa)


{
string prefix =
xa.Parent.GetPrefixOfNamespace(xa.Name.Namespace);
if (xa.Name.Namespace == XNamespace.None || prefix == null)
return xa.Name.ToString();
else
return prefix + ":" + xa.Name.LocalName;
}

private static string NameWithPredicate(XElement el)


{
if (el.Parent != null && el.Parent.Elements(el.Name).Count() != 1)
return GetQName(el) + "[" +
(el.ElementsBeforeSelf(el.Name).Count() + 1) + "]";
else
return GetQName(el);
}

public static string StrCat<T>(this IEnumerable<T> source,


string separator)
{
return source.Aggregate(new StringBuilder(),
(sb, i) => sb
.Append(i.ToString())
.Append(separator),
s => s.ToString());
}

public static string GetXPath(this XObject xobj)


{
if (xobj.Parent == null)
{
XDocument doc = xobj as XDocument;
if (doc != null)
return ".";
XElement el = xobj as XElement;
if (el != null)
return "/" + NameWithPredicate(el);
// the XPath data model does not include white space text nodes
// that are children of a document, so this method returns null.
XText xt = xobj as XText;
if (xt != null)
return null;
XComment com = xobj as XComment;
if (com != null)
return
"/" +
(
com
.Document
.Nodes()
.OfType<XComment>()
.Count() != 1 ?
"comment()[" +
(com
.NodesBeforeSelf()
.OfType<XComment>()
.Count() + 1) +
"]" :
"comment()"
);
XProcessingInstruction pi = xobj as XProcessingInstruction;
if (pi != null)
return
"/" +
(
pi.Document.Nodes()
.OfType<XProcessingInstruction>()
.Count() != 1 ?
"processing-instruction()[" +
(pi
.NodesBeforeSelf()
.OfType<XProcessingInstruction>()
.Count() + 1) +
"]" :
"processing-instruction()"
);
return null;
}
else
{
XElement el = xobj as XElement;
if (el != null)
{
return
"/" +
el
.Ancestors()
.InDocumentOrder()
.Select(e => NameWithPredicate(e))
.StrCat("/") +
NameWithPredicate(el);
}
XAttribute at = xobj as XAttribute;
if (at != null)
return
"/" +
at
.Parent
.AncestorsAndSelf()
.InDocumentOrder()
.Select(e => NameWithPredicate(e))
.StrCat("/") +
"@" + GetQName(at);
XComment com = xobj as XComment;
if (com != null)
return
"/" +
com
.Parent
.AncestorsAndSelf()
.InDocumentOrder()
.Select(e => NameWithPredicate(e))
.StrCat("/") +
(
com
.Parent
.Nodes()
.OfType<XComment>()
.Count() != 1 ?
"comment()[" +
(com
.NodesBeforeSelf()
.OfType<XComment>()
.Count() + 1) + "]" :
"comment()"
);
XCData cd = xobj as XCData;
if (cd != null)
return
"/" +
cd
.Parent
.AncestorsAndSelf()
.InDocumentOrder()
.Select(e => NameWithPredicate(e))
.StrCat("/") +
(
cd
.Parent
.Nodes()
.OfType<XText>()
.Count() != 1 ?
"text()[" +
(cd
.NodesBeforeSelf()
.OfType<XText>()
.Count() + 1) + "]" :
"text()"
);
XText tx = xobj as XText;
if (tx != null)
return
"/" +
tx
.Parent
.AncestorsAndSelf()
.InDocumentOrder()
.Select(e => NameWithPredicate(e))
.StrCat("/") +
(
tx
.Parent
.Nodes()
.OfType<XText>()
.Count() != 1 ?
"text()[" +
(tx
.NodesBeforeSelf()
.OfType<XText>()
.Count() + 1) + "]" :
"text()"
);
XProcessingInstruction pi = xobj as XProcessingInstruction;
if (pi != null)
if (pi != null)
return
"/" +
pi
.Parent
.AncestorsAndSelf()
.InDocumentOrder()
.Select(e => NameWithPredicate(e))
.StrCat("/") +
(
pi
.Parent
.Nodes()
.OfType<XProcessingInstruction>()
.Count() != 1 ?
"processing-instruction()[" +
(pi
.NodesBeforeSelf()
.OfType<XProcessingInstruction>()
.Count() + 1) + "]" :
"processing-instruction()"
);
return null;
}
}
}

class Program
{
static void Main(string[] args)
{
XNamespace aw = "http://www.adventure-works.com";
XDocument doc = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XProcessingInstruction("target", "data"),
new XElement("Root",
new XAttribute("AttName", "An Attribute"),
new XAttribute(XNamespace.Xmlns + "aw", aw.ToString()),
new XComment("This is a comment"),
new XElement("Child",
new XText("Text")
),
new XElement("Child",
new XText("Other Text")
),
new XElement("ChildWithMixedContent",
new XText("text"),
new XElement("b", "BoldText"),
new XText("otherText")
),
new XElement(aw + "ElementInNamespace",
new XElement(aw + "ChildInNamespace")
)
)
);
doc.Save("Test.xml");
Console.WriteLine(File.ReadAllText("Test.xml"));
Console.WriteLine("------");
foreach (XObject obj in doc.DescendantNodes())
{
Console.WriteLine(obj.GetXPath());
XElement el = obj as XElement;
if (el != null)
foreach (XAttribute at in el.Attributes())
Console.WriteLine(at.GetXPath());
}
}
}
Bu örnek aşağıdaki çıktıyı üretir:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>


<?target data?>
<Root AttName="An Attribute" xmlns:aw="http://www.adventure-works.com">
<!--This is a comment-->
<Child>Text</Child>
<Child>Other Text</Child>
<ChildWithMixedContent>text<b>BoldText</b>otherText</ChildWithMixedContent>
<aw:ElementInNamespace>
<aw:ChildInNamespace />
</aw:ElementInNamespace>
</Root>
------
/processing-instruction()
/Root
/Root/@AttName
/Root/@xmlns:aw
/Root/comment()
/Root/Child[1]
/Root/Child[1]/text()
/Root/Child[2]
/Root/Child[2]/text()
/Root/ChildWithMixedContent
/Root/ChildWithMixedContent/text()[1]
/Root/ChildWithMixedContent/b
/Root/ChildWithMixedContent/b/text()
/Root/ChildWithMixedContent/text()[2]
/Root/aw:ElementInNamespace
/Root/aw:ElementInNamespace/aw:ChildInNamespace
Nasıl yapılır: Office Open XML belgesinden
paragrafları alma (C#)
23.10.2019 • 3 minutes to read • Edit Online

Bu konuda, bir Office Open XML belgesi açan ve belgedeki tüm paragrafların bir koleksiyonunu alan bir örnek
sunulmaktadır.
Office Open XML hakkında daha fazla bilgi için bkz. Open XML SDK ve www.ericwhite.com.

Örnek
Bu örnek, bir Office Open XML paketi açar, belgeyi ve stil parçalarını bulmak için Open XML paketi içindeki ilişkileri
kullanır. Ardından, paragraf XElement düğümünü, her bir paragrafın stil adını ve her bir paragrafın metnini içeren
anonim bir türün koleksiyonunu yansıtırken belgeyi sorgular.
Örnek, örneğinde de verilen adlı StringConcatenate bir genişletme yöntemi kullanır.
Bu örneğin nasıl çalıştığını açıklayan ayrıntılı bir öğretici için bkz. XML (C#) saf işlevsel dönüştürmeleri.
Bu örnek, WindowsBase derlemesinde bulunan sınıfları kullanır. System.IO.Packaging Ad alanındaki türleri kullanır.

public static class LocalExtensions


{
public static string StringConcatenate(this IEnumerable<string> source)
{
StringBuilder sb = new StringBuilder();
foreach (string s in source)
sb.Append(s);
return sb.ToString();
}

public static string StringConcatenate<T>(this IEnumerable<T> source,


Func<T, string> func)
{
StringBuilder sb = new StringBuilder();
foreach (T item in source)
sb.Append(func(item));
return sb.ToString();
}

public static string StringConcatenate(this IEnumerable<string> source, string separator)


{
StringBuilder sb = new StringBuilder();
foreach (string s in source)
sb.Append(s).Append(separator);
return sb.ToString();
}

public static string StringConcatenate<T>(this IEnumerable<T> source,


Func<T, string> func, string separator)
{
StringBuilder sb = new StringBuilder();
foreach (T item in source)
sb.Append(func(item)).Append(separator);
return sb.ToString();
}
}

class Program
class Program
{
public static string ParagraphText(XElement e)
{
XNamespace w = e.Name.Namespace;
return e
.Elements(w + "r")
.Elements(w + "t")
.StringConcatenate(element => (string)element);
}

static void Main(string[] args)


{
const string fileName = "SampleDoc.docx";

const string documentRelationshipType =


"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
const string stylesRelationshipType =
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
const string wordmlNamespace =
"http://schemas.openxmlformats.org/wordprocessingml/2006/main";
XNamespace w = wordmlNamespace;

XDocument xDoc = null;


XDocument styleDoc = null;

using (Package wdPackage = Package.Open(fileName, FileMode.Open, FileAccess.Read))


{
PackageRelationship docPackageRelationship =
wdPackage
.GetRelationshipsByType(documentRelationshipType)
.FirstOrDefault();
if (docPackageRelationship != null)
{
Uri documentUri =
PackUriHelper
.ResolvePartUri(
new Uri("/", UriKind.Relative),
docPackageRelationship.TargetUri);
PackagePart documentPart =
wdPackage.GetPart(documentUri);

// Load the document XML in the part into an XDocument instance.


xDoc = XDocument.Load(XmlReader.Create(documentPart.GetStream()));

// Find the styles part. There will only be one.


PackageRelationship styleRelation =
documentPart.GetRelationshipsByType(stylesRelationshipType)
.FirstOrDefault();
if (styleRelation != null)
{
Uri styleUri = PackUriHelper.ResolvePartUri(documentUri, styleRelation.TargetUri);
PackagePart stylePart = wdPackage.GetPart(styleUri);

// Load the style XML in the part into an XDocument instance.


styleDoc = XDocument.Load(XmlReader.Create(stylePart.GetStream()));
}
}
}

string defaultStyle =
(string)(
from style in styleDoc.Root.Elements(w + "style")
where (string)style.Attribute(w + "type") == "paragraph" &&
(string)style.Attribute(w + "default") == "1"
select style
).First().Attribute(w + "styleId");

// Find all paragraphs in the document.


var paragraphs =
var paragraphs =
from para in xDoc
.Root
.Element(w + "body")
.Descendants(w + "p")
let styleNode = para
.Elements(w + "pPr")
.Elements(w + "pStyle")
.FirstOrDefault()
select new
{
ParagraphNode = para,
StyleName = styleNode != null ?
(string)styleNode.Attribute(w + "val") :
defaultStyle
};

// Retrieve the text of each paragraph.


var paraWithText =
from para in paragraphs
select new
{
ParagraphNode = para.ParagraphNode,
StyleName = para.StyleName,
Text = ParagraphText(para.ParagraphNode)
};

foreach (var p in paraWithText)


Console.WriteLine("StyleName:{0} >{1}<", p.StyleName, p.Text);
}
}

Kaynak Office Open XML belgesi (C#) oluşturmabölümünde açıklanan örnek Open XML belgesiyle birlikte
çalıştırıldığında, bu örnek aşağıdaki çıktıyı üretir:

StyleName:Heading1 >Parsing WordprocessingML with LINQ to XML<


StyleName:Normal ><
StyleName:Normal >The following example prints to the console.<
StyleName:Normal ><
StyleName:Code >using System;<
StyleName:Code ><
StyleName:Code >class Program {<
StyleName:Code > public static void (string[] args) {<
StyleName:Code > Console.WriteLine("Hello World");<
StyleName:Code > }<
StyleName:Code >}<
StyleName:Normal ><
StyleName:Normal >This example produces the following output:<
StyleName:Normal ><
StyleName:Code >Hello World<
Nasıl yapılır: Office Open XML belgesini değiştirme
(C#)
23.10.2019 • 2 minutes to read • Edit Online

Bu konu, bir Office Open XML belgesi açan, değiştiren ve kaydeden bir örnek gösterir.
Office Open XML hakkında daha fazla bilgi için bkz. Open XML SDK ve www.ericwhite.com.

Örnek
Bu örnek belgedeki ilk paragraf öğesini bulur. Paragraftan metni alır ve ardından paragraftaki tüm metin
çalıştırmalarını siler. Büyük harfe dönüştürülmüş ilk paragraf metniyle oluşan yeni bir metin çalıştırması oluşturur.
Daha sonra değiştirilmiş XML 'i Open XML paketine serileştirir ve kapatır.
Bu örnek, WindowsBase derlemesinde bulunan sınıfları kullanır. System.IO.Packaging Ad alanındaki türleri kullanır.

public static class LocalExtensions


{
public static string StringConcatenate(this IEnumerable<string> source)
{
StringBuilder sb = new StringBuilder();
foreach (string s in source)
sb.Append(s);
return sb.ToString();
}

public static string StringConcatenate<T>(this IEnumerable<T> source,


Func<T, string> func)
{
StringBuilder sb = new StringBuilder();
foreach (T item in source)
sb.Append(func(item));
return sb.ToString();
}

public static string StringConcatenate(this IEnumerable<string> source, string separator)


{
StringBuilder sb = new StringBuilder();
foreach (string s in source)
sb.Append(s).Append(separator);
return sb.ToString();
}

public static string StringConcatenate<T>(this IEnumerable<T> source,


Func<T, string> func, string separator)
{
StringBuilder sb = new StringBuilder();
foreach (T item in source)
sb.Append(func(item)).Append(separator);
return sb.ToString();
}
}

class Program
{
public static string ParagraphText(XElement e)
{
XNamespace w = e.Name.Namespace;
return e
.Elements(w + "r")
.Elements(w + "t")
.StringConcatenate(element => (string)element);
}

static void Main(string[] args)


{
const string fileName = "SampleDoc.docx";

const string documentRelationshipType =


"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
const string stylesRelationshipType =
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
const string wordmlNamespace =
"http://schemas.openxmlformats.org/wordprocessingml/2006/main";
XNamespace w = wordmlNamespace;

using (Package wdPackage = Package.Open(fileName, FileMode.Open, FileAccess.ReadWrite))


{
PackageRelationship docPackageRelationship =
wdPackage.GetRelationshipsByType(documentRelationshipType).FirstOrDefault();
if (docPackageRelationship != null)
{
Uri documentUri = PackUriHelper.ResolvePartUri(new Uri("/", UriKind.Relative),
docPackageRelationship.TargetUri);
PackagePart documentPart = wdPackage.GetPart(documentUri);

// Load the document XML in the part into an XDocument instance.


XDocument xDoc = XDocument.Load(XmlReader.Create(documentPart.GetStream()));

// Find the styles part. There will only be one.


PackageRelationship styleRelation =
documentPart.GetRelationshipsByType(stylesRelationshipType).FirstOrDefault();
PackagePart stylePart = null;
XDocument styleDoc = null;

if (styleRelation != null)
{
Uri styleUri = PackUriHelper.ResolvePartUri(documentUri, styleRelation.TargetUri);
stylePart = wdPackage.GetPart(styleUri);

// Load the style XML in the part into an XDocument instance.


styleDoc = XDocument.Load(XmlReader.Create(stylePart.GetStream()));
}

XElement paraNode = xDoc


.Root
.Element(w + "body")
.Descendants(w + "p")
.FirstOrDefault();

string paraText = ParagraphText(paraNode);

// remove all text runs


paraNode.Descendants(w + "r").Remove();

paraNode.Add(
new XElement(w + "r",
new XElement(w + "t", paraText.ToUpper())
)
);

// Save the XML into the package


using (XmlWriter xw =
XmlWriter.Create(documentPart.GetStream(FileMode.Create, FileAccess.Write)))
{
xDoc.Save(xw);
}
Console.WriteLine("New first paragraph: >{0}<", paraText.ToUpper());
}
}
}
}

Bu programı çalıştırdıktan SampleDoc.docx sonra açarsanız, bu programın belgedeki ilk paragrafı büyük harflere
dönüştürdüğünü görebilirsiniz.
Kaynak Office Open XML belgesi (C#) oluşturmabölümünde açıklanan örnek Open XML belgesiyle birlikte
çalıştırıldığında, bu örnek aşağıdaki çıktıyı üretir:

New first paragraph: >PARSING WORDPROCESSINGML WITH LINQ TO XML<


Nasıl yapılır: Dosya sisteminden bir XML ağacı
doldurma (C#)
23.10.2019 • 2 minutes to read • Edit Online

Bir ortak ve kullanışlı XML ağaçlarını hiyerarşik ad/değer veri deposu olarak uygulamasıdır. Hiyerarşik veriler ile
XML ağacı doldurma ve ardından, sorgulama yapabilir, dönüştürmek ve gerekirse, seri hale. Bu kullanım
senaryosunda, ad alanları ve boşluk davranışını gibi XML belirli semantikler birçok önemli değildir. Bunun yerine,
bellek, hiyerarşik veritabanı tek kullanıcı küçük bir olarak XML ağacı kullanıyor.

Örnek
Aşağıdaki örnek, özyineleme kullanarak yerel dosya sisteminden bir XML ağacı doldurur. Ardından, toplam
ağacındaki tüm dosyaların boyutunu hesaplama ağaç sorgular.

class Program
{
static XElement CreateFileSystemXmlTree(string source)
{
DirectoryInfo di = new DirectoryInfo(source);
return new XElement("Dir",
new XAttribute("Name", di.Name),
from d in Directory.GetDirectories(source)
select CreateFileSystemXmlTree(d),
from fi in di.GetFiles()
select new XElement("File",
new XElement("Name", fi.Name),
new XElement("Length", fi.Length)
)
);
}

static void Main(string[] args)


{
XElement fileSystemTree = CreateFileSystemXmlTree("C:/Tmp");
Console.WriteLine(fileSystemTree);
Console.WriteLine("------");
long totalFileSize =
(from f in fileSystemTree.Descendants("File")
select (long)f.Element("Length")).Sum();
Console.WriteLine("Total File Size:{0}", totalFileSize);
}
}

Bu örnekte aşağıdakine benzer bir çıktı oluşturulur:


<Dir Name="Tmp">
<Dir Name="ConsoleApplication1">
<Dir Name="bin">
<Dir Name="Debug">
<File>
<Name>ConsoleApplication1.exe</Name>
<Length>4608</Length>
</File>
<File>
<Name>ConsoleApplication1.pdb</Name>
<Length>11776</Length>
</File>
<File>
<Name>ConsoleApplication1.vshost.exe</Name>
<Length>9568</Length>
</File>
<File>
<Name>ConsoleApplication1.vshost.exe.manifest</Name>
<Length>473</Length>
</File>
</Dir>
</Dir>
<Dir Name="obj">
<Dir Name="Debug">
<Dir Name="TempPE" />
<File>
<Name>ConsoleApplication1.csproj.FileListAbsolute.txt</Name>
<Length>322</Length>
</File>
<File>
<Name>ConsoleApplication1.exe</Name>
<Length>4608</Length>
</File>
<File>
<Name>ConsoleApplication1.pdb</Name>
<Length>11776</Length>
</File>
</Dir>
</Dir>
<Dir Name="Properties">
<File>
<Name>AssemblyInfo.cs</Name>
<Length>1454</Length>
</File>
</Dir>
<File>
<Name>ConsoleApplication1.csproj</Name>
<Length>2546</Length>
</File>
<File>
<Name>ConsoleApplication1.sln</Name>
<Length>937</Length>
</File>
<File>
<Name>ConsoleApplication1.suo</Name>
<Length>10752</Length>
</File>
<File>
<Name>Program.cs</Name>
<Length>269</Length>
</File>
</Dir>
</Dir>
------
Total File Size:59089
XPath ile LINQ to XML Karşılaştırması
23.10.2019 • 5 minutes to read • Edit Online

XPath ile LINQ to XML benzer bir işlevsellik sağlar. Her ikisi de öğelerinin bir koleksiyonunu, özniteliklerin bir
koleksiyonu, düğümlerin koleksiyonunu veya bir öğe veya öznitelik değeri olarak böyle sonuçları döndüren bir
XML ağacı sorgulamak için kullanılabilir. Ancak, aynı zamanda bazı farklar vardır.

XML için XPath ile LINQ arasındaki farklar


XPath yeni tür projeksiyonu izin vermez. LINQ to XML bir sorgu yürütme ve bir nesne grafiğinin ya da yeni bir şekil
içinde bir XML ağacı proje, düğüm koleksiyonlarının ağacından yalnızca döndürebilir. LINQ to XML sorgularında
kapsayabilir ve çok daha fazla işlevsellik ve XPath ifadeleri çok daha güçlü.
XPath ifadeleri bir dize içinde yalıtımı yok. C# Derleyici derleme zamanında XPath ifadesi ayrıştırılamıyor yardımcı
olamaz. Bunun aksine, LINQ to XML sorgularında ayrıştırılır ve C# derleyicisi tarafından derlenir. Derleyici, çok
sayıda sorgu hataları yakaladığınızdan kuramıyor.
XPath sonuçları kesin türlü yapılır değil. Koşullar sayısı, bir XPath ifadesi değerlendirme sonucu bir nesnedir ve
uygun türde belirlemek ve sonucu gerekli olarak atama için geliştirici kadar olan. Buna karşılık gelen bir LINQ
projeksiyonlar XML sorgusu için kesin türlü yapılır.

Sıralama neden
XPath 1.0 öneri, bir XPath ifadesi değerlendirme sonucu olan bir koleksiyon sırasız olduğunu belirtir.
Ancak, XPath XML eksen yöntemi bir LINQ tarafından döndürülen bir koleksiyon üzerinden yineleme yapma,
koleksiyon düğümleri Belge düzeninde döndürülür. Bu XPath eksenleri bile erişirken burada doğrulamaları ters
belge sırayla açısından, gibi ifade edilir durumda preceding ve preceding-sibling .
Belge sırada ancak iki tanesi, LINQ to XML eksenleri çoğunu koleksiyonları aksine, iade Ancestors ve
AncestorsAndSelf, belge ters sırada koleksiyonlarını döndürür. Aşağıdaki tabloda, eksen numaralandırır ve her
koleksiyon sırasını gösterir:

LINQ TO XML EKSEN SIRALAMA

XContainer.DescendantNodes Belge sırada

XContainer.Descendants Belge sırada

XContainer.Elements Belge sırada

XContainer.Nodes Belge sırada

XContainer.NodesAfterSelf Belge sırada

XContainer.NodesBeforeSelf Belge sırada

XElement.AncestorsAndSelf Ters belge sırayla

XElement.Attributes Belge sırada


LINQ TO XML EKSEN SIRALAMA

XElement.DescendantNodesAndSelf Belge sırada

XElement.DescendantsAndSelf Belge sırada

XNode.Ancestors Ters belge sırayla

XNode.ElementsAfterSelf Belge sırada

XNode.ElementsBeforeSelf Belge sırada

XNode.NodesAfterSelf Belge sırada

XNode.NodesBeforeSelf Belge sırada

Konumsal doğrulamaları
Bir XPath ifadesi içinde konumsal koşullar açısından birçok eksenleri için belge sırada ifade edilir, ancak olan ters
eksenleri ters belge sırayla ifade preceding , preceding-sibling , ancestor , ve ancestor-or-self . Örneğin, XPath
ifadesi preceding-sibling::*[1] hemen önceki eşdüzey öğeyi döndürür. Son sonuç kümesi belge sırada sunulur
olsa bile bu durum geçerlidir.
Bunun aksine, tüm konumsal koşullarda LINQ to XML eksen sırası açısından her zaman ifade edilir. Örneğin,
anElement.ElementsBeforeSelf().ElementAt(0) değil önceki eşdüzeyi sorgulanan öğenin üst ilk alt öğesini döndürür.
Başka bir örnek: anElement.Ancestors().ElementAt(0) üst öğesini döndürür.
LINQ to XML hemen önceki öğeyi bulmak istiyorsanız, aşağıdaki ifade'ı yazmalısınız:

ElementsBeforeSelf().Last()

ElementsBeforeSelf().Last()

Performans farkları
LINQ to XML XPath işlevleri kullanın XPath sorguları, XML sorgularında LINQ yanı sıra gerçekleştirmez.

Birleşim karşılaştırması
Bir LINQ to XML sorgusu söz dizimi içinde çok farklı olsa bir XPath ifadesi, oluşumunu için biraz paralel
bileşimiyse.
Örneğin, bir öğenin adlı bir değişkende varsa customers , ve adlı en alt öğe bulmak istediğiniz CompanyName adlı tüm
alt öğeleri altında Customer , bir XPath ifadesi şu şekilde yazmalısınız:

customers.XPathSelectElements("./Customer/CompanyName")

customers.XPathSelectElements("./Customer/CompanyName")

Eşdeğer LINQ to XML sorgu aşağıdaki gibidir:


customers.Elements("Customer").Elements("CompanyName")

customers.Elements("Customer").Elements("CompanyName")

Her bir XPath eksenleri için benzer parallels vardır.

XPATH EKSEN LINQ TO XML EKSEN

Alt (varsayılan eksen) XContainer.Elements

Üst (.) XObject.Parent

öznitelik eksen (@) XElement.Attribute

veya

XElement.Attributes

üst öğe ekseni XNode.Ancestors

üst veya self ekseni XElement.AncestorsAndSelf

alt eksen (/ /) XContainer.Descendants

veya

XContainer.DescendantNodes

alt öğesi veya kendi kendine XElement.DescendantsAndSelf

veya

XElement.DescendantNodesAndSelf

Aşağıdaki eşdüzey XNode.ElementsAfterSelf

veya

XNode.NodesAfterSelf

Önceki eşdüzey XNode.ElementsBeforeSelf

veya

XNode.NodesBeforeSelf

Aşağıdaki Doğrudan eşdeğeri.

önceki Doğrudan eşdeğeri.


Alt öğe bulma (XPath-LINQ to XML) (C#)
25.11.2019 • 2 minutes to read • Edit Online

Bu konu, XPath alt öğe eksenini LINQ - XML Element yöntemiyle karşılaştırır.
XPath ifadesi DeliveryNotes .

Örnek
Bu örnek DeliveryNotes alt öğesi bulur.
Bu örnek, şu XML belgesini kullanır: örnek xml dosyası: birden fazla satın alma siparişi (LINQ to XML ).

XDocument cpo = XDocument.Load("PurchaseOrders.xml");


XElement po = cpo.Root.Element("PurchaseOrder");

// LINQ to XML query


XElement el1 = po.Element("DeliveryNotes");

// XPath expression
XElement el2 = po.XPathSelectElement("DeliveryNotes");
// same as "child::DeliveryNotes"
// same as "./DeliveryNotes"

if (el1 == el2)
Console.WriteLine("Results are identical");
else
Console.WriteLine("Results differ");
Console.WriteLine(el1);

Bu örnek aşağıdaki çıktıyı üretir:

Results are identical


<DeliveryNotes>Please leave packages in shed by driveway.</DeliveryNotes>
Alt öğelerin bir listesini bulma (XPath-LINQ to XML)
(C#)
25.11.2019 • 2 minutes to read • Edit Online

Bu konu, XPath alt öğeleri eksenini LINQ - XML Elements ekseni ile karşılaştırır.
XPath ifadesi: ./*

Örnek
Bu örnek Address öğesinin tüm alt öğelerini bulur.
Bu örnek, şu XML belgesini kullanır: örnek xml dosyası: birden fazla satın alma siparişi (LINQ to XML ).

XDocument cpo = XDocument.Load("PurchaseOrders.xml");


XElement po = cpo.Root.Element("PurchaseOrder").Element("Address");

// LINQ to XML query


IEnumerable<XElement> list1 = po.Elements();

// XPath expression
IEnumerable<XElement> list2 = po.XPathSelectElements("./*");

if (list1.Count() == list2.Count() &&


list1.Intersect(list2).Count() == list1.Count())
Console.WriteLine("Results are identical");
else
Console.WriteLine("Results differ");
foreach (XElement el in list1)
Console.WriteLine(el);

Bu örnek aşağıdaki çıktıyı üretir:

Results are identical


<Name>Ellen Adams</Name>
<Street>123 Maple Street</Street>
<City>Mill Valley</City>
<State>CA</State>
<Zip>10999</Zip>
<Country>USA</Country>
Nasıl yapılır: Kök öğeyi bul (XPath-LINQ to XML) (C#)
23.10.2019 • 2 minutes to read • Edit Online

Bu konu, XPath ve LINQ - XMLile kök öğesinin nasıl alınacağını gösterir.


XPath ifadesi:
/PurchaseOrders

Örnek
Bu örnek, kök öğesini bulur.
Bu örnek aşağıdaki XML belgesini kullanır: Örnek XML dosyası: Birden çok satın alma siparişi (LINQ to XML ).

XDocument po = XDocument.Load("PurchaseOrders.xml");

// LINQ to XML query


XElement el1 = po.Root;

// XPath expression
XElement el2 = po.XPathSelectElement("/PurchaseOrders");

if (el1 == el2)
Console.WriteLine("Results are identical");
else
Console.WriteLine("Results differ");
Console.WriteLine(el1.Name);

Bu örnek aşağıdaki çıktıyı üretir:

Results are identical


PurchaseOrders
Alt öğeleri bulma (XPath-LINQ to XML) (C#)
25.11.2019 • 2 minutes to read • Edit Online

Bu konu, belirli bir ada sahip alt öğelerin nasıl alınacağını gösterir.
XPath ifadesi //Name .

Örnek
Bu örnek Name adlı tüm alt öğeleri bulur.
Bu örnek, şu XML belgesini kullanır: örnek xml dosyası: birden fazla satın alma siparişi (LINQ to XML ).

XDocument po = XDocument.Load("PurchaseOrders.xml");

// LINQ to XML query


IEnumerable<XElement> list1 = po.Root.Descendants("Name");

// XPath expression
IEnumerable<XElement> list2 = po.XPathSelectElements("//Name");

if (list1.Count() == list2.Count() &&


list1.Intersect(list2).Count() == list1.Count())
Console.WriteLine("Results are identical");
else
Console.WriteLine("Results differ");
foreach (XElement el in list1)
Console.WriteLine(el);

Bu örnek aşağıdaki çıktıyı üretir:

Results are identical


<Name>Ellen Adams</Name>
<Name>Tai Yee</Name>
<Name>Cristian Osorio</Name>
<Name>Cristian Osorio</Name>
<Name>Jessica Arnold</Name>
<Name>Jessica Arnold</Name>
Bir özniteliğe filtre uygulama (XPath-LINQ to XML)
(C#)
25.11.2019 • 2 minutes to read • Edit Online

Bu konu, belirtilen bir ada sahip ve belirtilen değere sahip bir öznitelik ile alt öğelerin nasıl alınacağını gösterir.
XPath ifadesi:
.//Address[@Type='Shipping']

Örnek
Bu örnek, Address adı ve "Shipping" değerine sahip bir Type özniteliğiyle tüm alt öğeleri bulur.
Bu örnek, şu XML belgesini kullanır: örnek xml dosyası: birden fazla satın alma siparişi (LINQ to XML ).

XDocument po = XDocument.Load("PurchaseOrders.xml");

// LINQ to XML query


IEnumerable<XElement> list1 =
from el in po.Descendants("Address")
where (string)el.Attribute("Type") == "Shipping"
select el;

// XPath expression
IEnumerable<XElement> list2 = po.XPathSelectElements(".//Address[@Type='Shipping']");

if (list1.Count() == list2.Count() &&


list1.Intersect(list2).Count() == list1.Count())
Console.WriteLine("Results are identical");
else
Console.WriteLine("Results differ");
foreach (XElement el in list1)
Console.WriteLine(el);

Bu örnek aşağıdaki çıktıyı üretir:


Results are identical
<Address Type="Shipping">
<Name>Ellen Adams</Name>
<Street>123 Maple Street</Street>
<City>Mill Valley</City>
<State>CA</State>
<Zip>10999</Zip>
<Country>USA</Country>
</Address>
<Address Type="Shipping">
<Name>Cristian Osorio</Name>
<Street>456 Main Street</Street>
<City>Buffalo</City>
<State>NY</State>
<Zip>98112</Zip>
<Country>USA</Country>
</Address>
<Address Type="Shipping">
<Name>Jessica Arnold</Name>
<Street>4055 Madison Ave</Street>
<City>Seattle</City>
<State>WA</State>
<Zip>98112</Zip>
<Country>USA</Country>
</Address>
İlgili öğeleri bulma (XPath-LINQ to XML) (C#)
25.11.2019 • 2 minutes to read • Edit Online

Bu konu başlığı altında, başka bir öğenin değeri tarafından başvurulan bir özniteliği seçme öğesinin nasıl alınacağı
gösterilmektedir.
XPath ifadesi:
.//Customer[@CustomerID=/Root/Orders/Order[12]/CustomerID]

Örnek
Bu örnek, 12. Order öğesini bulur ve ardından o sipariş için müşteriyi bulur.
.NET 'teki bir listede dizin oluşturmanın ' sıfır ' tabanlı olduğunu unutmayın. XPath koşulunda bir düğümler
koleksiyonuna dizin oluşturma işlemi ' One ' tabanlıdır. Bu örnek, bu farkı yansıtır.
Bu örnek, şu XML belgesini kullanır: örnek xml dosyası: müşteriler ve siparişler (LINQ to XML ).

XDocument co = XDocument.Load("CustomersOrders.xml");

// LINQ to XML query


XElement customer1 =
(from el in co.Descendants("Customer")
where (string)el.Attribute("CustomerID") ==
(string)(co
.Element("Root")
.Element("Orders")
.Elements("Order")
.ToList()[11]
.Element("CustomerID"))
select el)
.First();

// An alternate way to write the query that avoids creation


// of a System.Collections.Generic.List:
XElement customer2 =
(from el in co.Descendants("Customer")
where (string)el.Attribute("CustomerID") ==
(string)(co
.Element("Root")
.Element("Orders")
.Elements("Order")
.Skip(11).First()
.Element("CustomerID"))
select el)
.First();

// XPath expression
XElement customer3 = co.XPathSelectElement(
".//Customer[@CustomerID=/Root/Orders/Order[12]/CustomerID]");

if (customer1 == customer2 && customer1 == customer3)


Console.WriteLine("Results are identical");
else
Console.WriteLine("Results differ");
Console.WriteLine(customer1);

Bu örnek aşağıdaki çıktıyı üretir:


Results are identical
<Customer CustomerID="HUNGC">
<CompanyName>Hungry Coyote Import Store</CompanyName>
<ContactName>Yoshi Latimer</ContactName>
<ContactTitle>Sales Representative</ContactTitle>
<Phone>(503) 555-6874</Phone>
<Fax>(503) 555-2376</Fax>
<FullAddress>
<Address>City Center Plaza 516 Main St.</Address>
<City>Elgin</City>
<Region>OR</Region>
<PostalCode>97827</PostalCode>
<Country>USA</Country>
</FullAddress>
</Customer>
Bir ad alanında öğeleri bulma (XPath-LINQ to XML)
(C#)
25.11.2019 • 2 minutes to read • Edit Online

XPath ifadeleri, belirli bir ad alanındaki düğümleri bulabilir. XPath ifadeleri ad alanlarını belirtmek için ad alanı
öneklerini kullanır. Ad alanı önekleri içeren bir XPath ifadesini ayrıştırmak için, IXmlNamespaceResolveruygulayan
XPath yöntemlerine bir nesne geçirmeniz gerekir. Bu örnek XmlNamespaceManagerkullanır.
XPath ifadesi:
./aw:*

Örnek
Aşağıdaki örnek, iki ad alanı içeren bir XML ağacını okur. XML belgesini okumak için bir XmlReader kullanır. Daha
sonra XmlReaderve XmlNameTableXmlNamespaceManager bir XmlNameTable alır. Öğeleri seçerken
XmlNamespaceManager kullanır.

XmlReader reader = XmlReader.Create("ConsolidatedPurchaseOrders.xml");


XElement root = XElement.Load(reader);
XmlNameTable nameTable = reader.NameTable;
XmlNamespaceManager namespaceManager = new XmlNamespaceManager(nameTable);
namespaceManager.AddNamespace("aw", "http://www.adventure-works.com");
IEnumerable<XElement> list1 = root.XPathSelectElements("./aw:*", namespaceManager);
IEnumerable<XElement> list2 =
from el in root.Elements()
where el.Name.Namespace == "http://www.adventure-works.com"
select el;
if (list1.Count() == list2.Count() &&
list1.Intersect(list2).Count() == list1.Count())
Console.WriteLine("Results are identical");
else
Console.WriteLine("Results differ");
foreach (XElement el in list2)
Console.WriteLine(el);

Bu örnek aşağıdaki çıktıyı üretir:


Results are identical
<aw:PurchaseOrder PONumber="11223" Date="2000-01-15" xmlns:aw="http://www.adventure-works.com">
<aw:ShippingAddress>
<aw:Name>Chris Preston</aw:Name>
<aw:Street>123 Main St.</aw:Street>
<aw:City>Seattle</aw:City>
<aw:State>WA</aw:State>
<aw:Zip>98113</aw:Zip>
<aw:Country>USA</aw:Country>
</aw:ShippingAddress>
<aw:BillingAddress>
<aw:Name>Chris Preston</aw:Name>
<aw:Street>123 Main St.</aw:Street>
<aw:City>Seattle</aw:City>
<aw:State>WA</aw:State>
<aw:Zip>98113</aw:Zip>
<aw:Country>USA</aw:Country>
</aw:BillingAddress>
<aw:DeliveryInstructions>Ship only complete order.</aw:DeliveryInstructions>
<aw:Item PartNum="LIT-01">
<aw:ProductID>Litware Networking Card</aw:ProductID>
<aw:Qty>1</aw:Qty>
<aw:Price>20.99</aw:Price>
</aw:Item>
<aw:Item PartNum="LIT-25">
<aw:ProductID>Litware 17in LCD Monitor</aw:ProductID>
<aw:Qty>1</aw:Qty>
<aw:Price>199.99</aw:Price>
</aw:Item>
</aw:PurchaseOrder>
Önceki eşdüzey öğeleri bulma (XPath-LINQ to XML)
(C#)
25.11.2019 • 2 minutes to read • Edit Online

Bu konu, XPath preceding-sibling eksenini LINQ - XML alt XNode.ElementsBeforeSelf ekseniyle karşılaştırır.
XPath ifadesi:
preceding-sibling::*

Hem XPathSelectElements hem de XNode.ElementsBeforeSelf sonuçlarının belge sırasıyla olduğunu unutmayın.

Örnek
Aşağıdaki örnek FullAddress öğesini bulur ve sonra preceding-sibling eksenini kullanarak önceki öğeleri alır.
Bu örnek, şu XML belgesini kullanır: örnek xml dosyası: müşteriler ve siparişler (LINQ to XML ).

XElement co = XElement.Load("CustomersOrders.xml");

XElement add = co.Element("Customers").Element("Customer").Element("FullAddress");

// LINQ to XML query


IEnumerable<XElement> list1 = add.ElementsBeforeSelf();

// XPath expression
IEnumerable<XElement> list2 = add.XPathSelectElements("preceding-sibling::*");

if (list1.Count() == list2.Count() &&


list1.Intersect(list2).Count() == list1.Count())
Console.WriteLine("Results are identical");
else
Console.WriteLine("Results differ");
foreach (XElement el in list2)
Console.WriteLine(el);

Bu örnek aşağıdaki çıktıyı üretir:

Results are identical


<CompanyName>Great Lakes Food Market</CompanyName>
<ContactName>Howard Snyder</ContactName>
<ContactTitle>Marketing Manager</ContactTitle>
<Phone>(503) 555-7555</Phone>
Bir alt öğenin alt öğelerini bulma (XPath-LINQ to
XML) (C#)
25.11.2019 • 2 minutes to read • Edit Online

Bu konu başlığı altında, bir alt öğenin belirli bir ada sahip öğeleri nasıl alınacağı gösterilmektedir.
XPath ifadesi:
./Paragraph//Text/text()

Örnek
Bu örnek, bir sözcük işleme belgesinin XML gösteriminden metin ayıklama sorunlarının benzetimini yapar. Önce
tüm Paragraph öğelerini seçer ve ardından her bir Paragraph öğesinin tüm Text alt öğelerini seçer. Bu, Comment
öğesinin alt öğe Text öğelerini seçmeyin.
XElement root = XElement.Parse(
@"<Root>
<Paragraph>
<Text>This is the start of</Text>
</Paragraph>
<Comment>
<Text>This comment is not part of the paragraph text.</Text>
</Comment>
<Paragraph>
<Annotation Emphasis='true'>
<Text> a sentence.</Text>
</Annotation>
</Paragraph>
<Paragraph>
<Text> This is a second sentence.</Text>
</Paragraph>
</Root>");

// LINQ to XML query


string str1 =
root
.Elements("Paragraph")
.Descendants("Text")
.Select(s => s.Value)
.Aggregate(
new StringBuilder(),
(s, i) => s.Append(i),
s => s.ToString()
);

// XPath expression
string str2 =
((IEnumerable)root.XPathEvaluate("./Paragraph//Text/text()"))
.Cast<XText>()
.Select(s => s.Value)
.Aggregate(
new StringBuilder(),
(s, i) => s.Append(i),
s => s.ToString()
);

if (str1 == str2)
Console.WriteLine("Results are identical");
else
Console.WriteLine("Results differ");
Console.WriteLine(str2);

Bu örnek aşağıdaki çıktıyı üretir:

Results are identical


This is the start of a sentence. This is a second sentence.
İki konum yolunun birleşimini bulma (XPath-LINQ to
XML) (C#)
25.11.2019 • 2 minutes to read • Edit Online

XPath, iki XPath konum yolunun sonuçlarının birleşimini bulmanızı sağlar.


XPath ifadesi:
//Category|//Price

Aynı sonuçları, Concat standart sorgu işlecini kullanarak elde edebilirsiniz.

Örnek
Bu örnek, tüm Category öğelerini ve tüm Price öğeleri bulur ve bunları tek bir koleksiyona ekler. LINQ - XML
sorgusunun sonuçları sıralamak için InDocumentOrder çağırdığına unutmayın. XPath ifadesi değerlendirmesi
sonuçları da belge sırasıyla bulunur.
Bu örnek, şu XML belgesini kullanır: örnek xml dosyası: sayısal veri (LINQ to XML ).

XDocument data = XDocument.Load("Data.xml");

// LINQ to XML query


IEnumerable<XElement> list1 =
data
.Descendants("Category")
.Concat(
data
.Descendants("Price")
)
.InDocumentOrder();

// XPath expression
IEnumerable<XElement> list2 = data.XPathSelectElements("//Category|//Price");

if (list1.Count() == list2.Count() &&


list1.Intersect(list2).Count() == list1.Count())
Console.WriteLine("Results are identical");
else
Console.WriteLine("Results differ");
foreach (XElement el in list1)
Console.WriteLine(el);

Bu örnek aşağıdaki çıktıyı üretir:


Results are identical
<Category>A</Category>
<Price>24.50</Price>
<Category>B</Category>
<Price>89.99</Price>
<Category>A</Category>
<Price>4.95</Price>
<Category>A</Category>
<Price>66.00</Price>
<Category>B</Category>
<Price>.99</Price>
<Category>A</Category>
<Price>29.00</Price>
<Category>B</Category>
<Price>6.99</Price>
Eşdüzey düğümleri bulma (XPath-LINQ to XML) (C#)
25.11.2019 • 2 minutes to read • Edit Online

Belirli bir ada sahip bir düğümün tüm eşdüzey düzeylerini bulmak isteyebilirsiniz. Bağlam düğümü de belirli bir ada
sahipse, sonuçta elde edilen koleksiyon bağlam düğümünü içerebilir.
XPath ifadesi:
../Book

Örnek
Bu örnek önce bir Book öğesi bulur ve sonra Book adlı tüm eşdüzey öğeleri bulur. Elde edilen koleksiyon, bağlam
düğümünü içerir.
Bu örnek, şu XML belgesini kullanır: örnek xml dosyası: kitaplar (LINQ to XML ).

XDocument books = XDocument.Load("Books.xml");

XElement book =
books
.Root
.Elements("Book")
.Skip(1)
.First();

// LINQ to XML query


IEnumerable<XElement> list1 =
book
.Parent
.Elements("Book");

// XPath expression
IEnumerable<XElement> list2 = book.XPathSelectElements("../Book");

if (list1.Count() == list2.Count() &&


list1.Intersect(list2).Count() == list1.Count())
Console.WriteLine("Results are identical");
else
Console.WriteLine("Results differ");
foreach (XElement el in list1)
Console.WriteLine(el);

Bu örnek aşağıdaki çıktıyı üretir:


Results are identical
<Book id="bk101">
<Author>Garghentini, Davide</Author>
<Title>XML Developer's Guide</Title>
<Genre>Computer</Genre>
<Price>44.95</Price>
<PublishDate>2000-10-01</PublishDate>
<Description>An in-depth look at creating applications
with XML.</Description>
</Book>
<Book id="bk102">
<Author>Garcia, Debra</Author>
<Title>Midnight Rain</Title>
<Genre>Fantasy</Genre>
<Price>5.95</Price>
<PublishDate>2000-12-16</PublishDate>
<Description>A former architect battles corporate zombies,
an evil sorceress, and her own childhood to become queen
of the world.</Description>
</Book>
Üst öğenin bir özniteliğini bulma (XPath-LINQ to
XML) (C#)
25.11.2019 • 2 minutes to read • Edit Online

Bu konu başlığı altında, üst öğeye gitme ve bir özniteliği bulma gösterilmektedir.
XPath ifadesi:
../@id

Örnek
Bu örnek öncelikle bir Author öğesi bulur. Daha sonra üst öğenin id özniteliğini bulur.
Bu örnek, şu XML belgesini kullanır: örnek xml dosyası: kitaplar (LINQ to XML ).

XDocument books = XDocument.Load("Books.xml");

XElement author =
books
.Root
.Element("Book")
.Element("Author");

// LINQ to XML query


XAttribute att1 =
author
.Parent
.Attribute("id");

// XPath expression
XAttribute att2 = ((IEnumerable)author.XPathEvaluate("../@id")).Cast<XAttribute>().First();

if (att1 == att2)
Console.WriteLine("Results are identical");
else
Console.WriteLine("Results differ");
Console.WriteLine(att1);

Bu örnek aşağıdaki çıktıyı üretir:

Results are identical


id="bk101"
Belirli bir ada sahip eşdüzey öğelerinin özniteliklerini
bulma (XPath-LINQ to XML) (C#)
25.11.2019 • 2 minutes to read • Edit Online

Bu konu, bağlam düğümünün eşdüzey öğelerinin tüm özniteliklerinin nasıl bulunacağını gösterir. Koleksiyonda
yalnızca belirli bir ada sahip öznitelikler döndürülür.
XPath ifadesi:
../Book/@id

Örnek
Bu örnek öncelikle bir Book öğesi bulur ve sonra Book adlı tüm eşdüzey öğeleri bulur ve ardından id adlı tüm
öznitelikleri bulur. Sonuç, özniteliklerin koleksiyonudur.
Bu örnek, şu XML belgesini kullanır: örnek xml dosyası: kitaplar (LINQ to XML ).

XDocument books = XDocument.Load("Books.xml");

XElement book =
books
.Root
.Element("Book");

// LINQ to XML query


IEnumerable<XAttribute> list1 =
from el in book.Parent.Elements("Book")
select el.Attribute("id");

// XPath expression
IEnumerable<XAttribute> list2 =
((IEnumerable)book.XPathEvaluate("../Book/@id")).Cast<XAttribute>();

if (list1.Count() == list2.Count() &&


list1.Intersect(list2).Count() == list1.Count())
Console.WriteLine("Results are identical");
else
Console.WriteLine("Results differ");
foreach (XAttribute el in list1)
Console.WriteLine(el);

Bu örnek aşağıdaki çıktıyı üretir:

Results are identical


id="bk101"
id="bk102"
Belirli bir özniteliğe sahip öğeleri bulma (XPath-LINQ
to XML) (C#)
25.11.2019 • 2 minutes to read • Edit Online

Bazen belirli bir özniteliğe sahip olan tüm öğeleri bulmak isteyebilirsiniz. Özniteliğin içeriğiyle ilgili endişeleriniz
yok. Bunun yerine, özniteliğinin varlığına göre ' ı seçmek istersiniz.
XPath ifadesi:
./*[@Select]

Örnek
Aşağıdaki kod yalnızca Select özniteliği olan öğeleri seçer.

XElement doc = XElement.Parse(


@"<Root>
<Child1>1</Child1>
<Child2 Select='true'>2</Child2>
<Child3>3</Child3>
<Child4 Select='true'>4</Child4>
<Child5>5</Child5>
</Root>");

// LINQ to XML query


IEnumerable<XElement> list1 =
from el in doc.Elements()
where el.Attribute("Select") != null
select el;

// XPath expression
IEnumerable<XElement> list2 =
((IEnumerable)doc.XPathEvaluate("./*[@Select]")).Cast<XElement>();

if (list1.Count() == list2.Count() &&


list1.Intersect(list2).Count() == list1.Count())
Console.WriteLine("Results are identical");
else
Console.WriteLine("Results differ");
foreach (XElement el in list1)
Console.WriteLine(el);

Bu örnek aşağıdaki çıktıyı üretir:

Results are identical


<Child2 Select="true">2</Child2>
<Child4 Select="true">4</Child4>
Konuma göre alt öğeleri bulma (XPath-LINQ to XML)
(C#)
25.11.2019 • 2 minutes to read • Edit Online

Bazen, konumlarına göre öğeleri bulmak isteyebilirsiniz. İkinci öğeyi bulmak isteyebilirsiniz veya beşinci öğe
aracılığıyla üçüncü öğeyi bulmak isteyebilirsiniz.
XPath ifadesi:
Test[position() >= 2 and position() <= 4]

Bu LINQ - XML sorgusunu geç bir şekilde yazmak için iki yaklaşım vardır. Skip ve Take işleçlerini kullanabilir veya
bir dizini alan Where aşırı yüklemeyi kullanabilirsiniz. Where aşırı yüklemeyi kullandığınızda, iki bağımsız değişken
alan bir lambda ifadesi kullanırsınız. Aşağıdaki örnek, konum temelinde seçim yapmak için her iki yöntemi gösterir.

Örnek
Bu örnek, dördüncü Test öğesi ile ikincisini bulur. Sonuç, öğelerin bir koleksiyonudur.
Bu örnek, şu XML belgesini kullanır: örnek xml dosyası: test yapılandırması (LINQ to XML ).

XElement testCfg = XElement.Load("TestConfig.xml");

// LINQ to XML query


IEnumerable<XElement> list1 =
testCfg
.Elements("Test")
.Skip(1)
.Take(3);

// LINQ to XML query


IEnumerable<XElement> list2 =
testCfg
.Elements("Test")
.Where((el, idx) => idx >= 1 && idx <= 3);

// XPath expression
IEnumerable<XElement> list3 =
testCfg.XPathSelectElements("Test[position() >= 2 and position() <= 4]");

if (list1.Count() == list2.Count() &&


list1.Count() == list3.Count() &&
list1.Intersect(list2).Count() == list1.Count() &&
list1.Intersect(list3).Count() == list1.Count())
Console.WriteLine("Results are identical");
else
Console.WriteLine("Results differ");
foreach (XElement el in list1)
Console.WriteLine(el);

Bu örnek aşağıdaki çıktıyı üretir:


Results are identical
<Test TestId="0002" TestType="CMD">
<Name>Find succeeding characters</Name>
<CommandLine>Examp2.EXE</CommandLine>
<Input>abc</Input>
<Output>def</Output>
</Test>
<Test TestId="0003" TestType="GUI">
<Name>Convert multiple numbers to strings</Name>
<CommandLine>Examp2.EXE /Verbose</CommandLine>
<Input>123</Input>
<Output>One Two Three</Output>
</Test>
<Test TestId="0004" TestType="GUI">
<Name>Find correlated key</Name>
<CommandLine>Examp3.EXE</CommandLine>
<Input>a1</Input>
<Output>b1</Output>
</Test>
Hemen önceki eşdüzey öğeyi bulma (XPath-LINQ to
XML) (C#)
25.11.2019 • 2 minutes to read • Edit Online

Bazen bir düğüme hemen önceki eşdüzey öğeyi bulmak isteyebilirsiniz. LINQ - XMLaksine, XPath 'teki önceki
eşdüzey eksenlerine yönelik konumsal koşulların semantiğinin farkı nedeniyle, bu daha ilginç karşılaştırmalardan
biridir.

Örnek
Bu örnekte, LINQ - XML sorgusu ElementsBeforeSelftarafından döndürülen koleksiyondaki son düğümü bulmak
için Last işlecini kullanır. Buna karşılık, XPath ifadesi hemen önceki öğeyi bulmak için değeri 1 olan bir koşul kullanır.

XElement root = XElement.Parse(


@"<Root>
<Child1/>
<Child2/>
<Child3/>
<Child4/>
</Root>");
XElement child4 = root.Element("Child4");

// LINQ to XML query


XElement el1 =
child4
.ElementsBeforeSelf()
.Last();

// XPath expression
XElement el2 =
((IEnumerable)child4
.XPathEvaluate("preceding-sibling::*[1]"))
.Cast<XElement>()
.First();

if (el1 == el2)
Console.WriteLine("Results are identical");
else
Console.WriteLine("Results differ");
Console.WriteLine(el1);

Bu örnek aşağıdaki çıktıyı üretir:

Results are identical


<Child3 />
Saf Işlevsel Dönüştürmelere giriş (C#)
23.10.2019 • 2 minutes to read • Edit Online

Bu bölümde, temel kavramlar ve destekleyici dil yapıları dahil işlevsel dönüşümler tanıtılmaktadır. İkinci öğesine
geçiş hakkında öneri de dahil olmak üzere, programlama için nesne yönelimli ve işlevsel dönüştürme
yaklaşımlarını karşıttır. İşlev dönüştürmeleri birçok programlama senaryosunda kullanılabilse de, XML dönüşümü
burada somut bir örnek olarak kullanılır.
Öğretici: WordprocessingML belgesi (C#) öğreticisindeki içerikleri işlemek, her biri bir öncekinden oluşan bir dizi
örnek sağlar. Bu örnekler, XML 'nin işlenmesine yönelik saf işlevsel dönüşüm yaklaşımını gösterir.Bu öğreticide,
hakkında C#bilgi sahibi olduğunuz varsayılmaktadır. Dil yapılarının ayrıntılı semantiği Bu öğreticide sağlanmaz,
ancak uygun şekilde dil belgelerine bağlantılar sağlanır.
XML ad alanları da dahil olmak üzere temel bilgisayar bilimi kavramları ve XML 'nin çalışma bilgisi de kabul edilir.

Bu Bölümde
KONU AÇIKLAMA

Kavramlar ve terminoloji (Işlevsel dönüşüm) (C#) Saf işlevsel dönüştürmelerin kavramlarını ve terminolojisini
tanıtır.

İşlevsel Programlama ve Kesinlik temelli programlamaC#() Fonksiyonel programlamayı daha geleneksel kesinlik
(yordamsal) programlamaya göre karşılaştırır ve karşıtın.

Saf IŞLEVLERE yeniden düzenleme (C#) Saf işlevleri tanıtır ve saf ve Impure işlevlerinin örneklerini
gösterir.

Işlevsel dönüşümün (C#) uygulanabilirliği İşlevsel dönüşümler için tipik senaryoları açıklar.

XML işlevsel dönüştürmesi (Visual Basic) XML ağaçlarını dönüştürme bağlamındaki işlevsel
dönüştürmeleri açıklar.
Kavramlar ve terminoloji (Işlevsel dönüşüm) (C#)
23.10.2019 • 7 minutes to read • Edit Online

Bu konu, saf işlevsel dönüştürmelerin kavramlarını ve terminolojisini tanıtır. Veri dönüştürme yaklaşımı, genellikle
programa, daha ayrıntılı bir şekilde daha hızlı ve hata ayıklama ve daha geleneksel, kesinlik temelli programlama
açısından daha kolay olan kodu verir.
Bu bölümdeki konuların işlevsel programlamayı tam olarak açıklamak için düşünülmediğini unutmayın. Bunun
yerine, bu konular XML 'i bir şekilden diğerine dönüştürmeyi kolaylaştıran bazı işlevsel programlama özelliklerini
belirler.

Saf Işlevsel dönüştürme nedir?


Saf işlevsel dönüşümde, saf işlevlerolarak adlandırılan bir işlevler kümesi, bir dizi yapısal veriyi özgün formdan
başka bir biçime dönüştürmeyi tanımlar. "Saf" sözcüğü, işlevlerin birleştirilebilen şekilde olduğunubelirtir ve şunları
gerektirir:
Kendi kendine dahilolmak üzere, bağımsız olarak sıralanmış ve daha sonra programın geri kalanı olmadan
bir arada ve yeniden düzenlenecek şekilde yeniden düzenlenebilir. Saf dönüşümler, ortamları hakkında bilgi
sahibi değildir veya etkilemez. Diğer bir deyişle, dönüşümde kullanılan işlevlerin yan etkileriyoktur.
Durum bilgisiz, aynı veya aynı girişte aynı işlevin veya belirli bir işlev kümesinin yürütülmesi her zaman aynı
çıkışa neden olur. Saf dönüşümlerinin önceki kullanımları belleği yoktur.

IMPORTANT
Bu öğreticinin geri kalanında, "saf işlev" terimi, belirli bir dil özelliği değil, programlama yaklaşımını göstermek için genel
anlamda kullanılır.
Saf işlevlerin ' de C#Yöntem olarak uygulanması gerektiğini unutmayın.
Ayrıca, saf işlevleri içinde C++saf sanal yöntemlerle karıştırmayın. İkincisi, kapsayan sınıfın soyut olduğunu ve hiçbir Yöntem
gövdesinin sağlanmadığını gösterir.

Fonksiyonel programlama
Fonksiyonel programlama , saf işlevsel dönüştürmeyi doğrudan destekleyen bir programlama yaklaşımıdır.
Geçmişte, genel amaçlı işlevsel programlama dilleri, örneğin, ML, düzen, Haskell ve F#, birincil olarak akademik
topluluk ile ilgilenmiştir. Üzerinde C#saf işlevsel dönüşümler yazmak her zaman mümkün olsa da, bunu yapmanın
zorluğunu çoğu programcıya etkileyici bir seçenek yapmamıştır. Ancak, ' nin C#son sürümlerinde, lambda ifadeleri
ve tür çıkarımı gibi yeni dil yapıları BT programlamanın çok daha kolay ve daha üretken olmasını sağlar.
Fonksiyonel programlama hakkında daha fazla bilgi için bkz . fonksiyonel programlama vs. Kesinlik temelli
programlamaC#().
Etki alanına özgü FP dilleri
Genel fonksiyonel programlama dilleri çok daha fazla benimsemese de, etki alanına özgü belirli işlevsel
programlama dillerinin başarısı daha iyidir. Örneğin, birçok Web sayfasının görünümünü ve kullanımını
belirlemede Geçişli Stil Sayfaları (CSS ) kullanılır ve Genişletilebilir Stil sayfası dil dönüşümleri (XSLT) stil sayfaları,
XML veri işleme açısından kapsamlı olarak kullanılır. XSLT hakkında daha fazla bilgi için bkz. XSLT dönüştürmeleri.

Terminoloji
Aşağıdaki tabloda, işlevsel dönüşümlerle ilgili bazı terimler tanımlanmaktadır.
daha yüksek sıralı (birinci sınıf) işlev
Programlı bir nesne olarak değerlendirilenebilir bir işlev. Örneğin, daha yüksek sıralı bir işlev başka işlevlere
geçirilebilir veya bu işlevlerden döndürülebilir. C # c 'de temsilciler ve lambda ifadeleri, daha yüksek sıralı işlevleri
destekleyen dil özelliklerdir. Daha yüksek sıralı bir işlev yazmak için temsilcileri almak üzere bir veya daha fazla
bağımsız değişken bildirir ve genellikle bunu çağırırken Lambda ifadelerini kullanırsınız. Standart sorgu işleçlerinin
birçoğu daha yüksek sıralı işlevlerdir.
Daha fazla bilgi için bkz. Standart sorgu IşleçlerineC#genel bakış ().
Lambda ifadesi
Temelde, bir temsilci türünün beklendiği her yerde kullanılabilecek bir satır içi anonim işlev. Bu, lambda ifadelerinin
basitleştirilmiş bir tanımıdır, ancak Bu öğreticinin amaçları doğrultusunda yeterlidir.
Hakkında daha fazla bilgi için bkz. lambda ifadeleri.
koleksiyon
tanımlama grubu (anonim türler)
Bir matematiksel kavram olan tanımlama grubu, belirli bir türün her biri için sınırlı bir nesne dizisidir. Bir tanımlama
grubu sıralı liste olarak da bilinir. Anonim türler, bu kavramın bir dil uygulamasıdır. Bu, adlandırılmamış bir sınıf
türünün bildirilmesini ve bu türden bir nesnenin aynı anda oluşturulmasını sağlar.
Daha fazla bilgi için bkz. anonim türler.
Tür çıkarımı (örtük yazma)
Bir derleyicinin açık tür bildirimi yokluğunda bir değişkenin türünü belirleme özelliği.
Daha fazla bilgi için bkz. örtülü olarak yazılan yerel değişkenler.
ertelenmiş yürütme ve geç değerlendirme
Çözümlenmiş değeri gerçekten gerekli olana kadar bir ifadenin değerlendirilme ertelenmesi. Ertelenmiş yürütme,
koleksiyonlarda desteklenir.
Daha fazla bilgi için bkz. LINQ Sorgularına Giriş (C#) ve LINQ to XML (C#) içinde ertelenmiş yürütme ve geç
değerlendirme.
Bu dil özellikleri, bu bölümün tamamında kod örneklerinde kullanılacaktır.

Ayrıca bkz.
Saf Işlevsel Dönüştürmelere giriş (C#)
İşlevsel Programlama ve Kesinlik temelli programlamaC#()
İşlevsel Programlama ve Kesinlik temelli
programlamaC#()
23.10.2019 • 7 minutes to read • Edit Online

Bu konu, daha geleneksel kesinlik (yordamsal) programlamaya yönelik fonksiyonel programlamayı karşılaştırır ve
karşıtın.

İşlevsel Programlama ve Kesin Programlama Karşılaştırması


İşlevsel programlama paradigması, sorun çözmeye yönelik saf işlevsel bir yaklaşımı desteklemek üzere açıkça
oluşturulmuştur. Fonksiyonel programlama bir bildirim temelli programlamabiçimidir. Buna karşılık, Visual Basic,
C# C++ve Java gibi nesne odaklı programlama (OOP ) dilleri de dahil olmak üzere çoğu temel dil, öncelikli olarak
(yordamsal) programlama desteği sağlayacak şekilde tasarlanmıştır.
Bir geliştirici, bir zorunlu yaklaşım ile, exacting detaylı olarak, bilgisayarın hedefi başarmak için gerçekleştirmesi
gereken adımları yazarak bu kodu yazar. Bu, bazen algoritmik programlama olarak adlandırılır. Buna karşılık,
işlevsel bir yaklaşım, sorunu yürütülecek bir işlevler kümesi olarak oluşturmayı içerir. Her işleve yönelik girişi
dikkatle tanımlarsınız ve her bir işlevin ne getirir. Aşağıdaki tabloda, bu iki yaklaşım arasındaki genel farklılıklar
açıklanmaktadır.

ÖZELLIK KESINLIK TEMELLI YAKLAŞIM İŞLEVSEL YAKLAŞIM

Programcı odağı Görevleri (algoritmalar) gerçekleştirme Hangi bilgiler istenir ve hangi


ve durumu değişiklikleri izleme. dönüşümler gereklidir?

Durum değişiklikleri Önemli. Mevcut değil.

Yürütme sırası Önemli. Düşük önem derecesi.

Birincil akış denetimi Döngüler, conditionals ve function Özyineleme dahil işlev çağrıları.
(Yöntem) çağrıları.

Birincil işleme birimi Yapıların veya sınıfların örnekleri. Birinci sınıf nesneler ve veri
koleksiyonları olarak işlevler.

Çoğu dil belirli bir programlama paradigmasını destekleyecek şekilde tasarlansa da birçok genel dil birden çok
paradigmalarına desteklemek için yeterince esnektir. Örneğin, işlev işaretçileri içeren çoğu dil işlevsel
programlamayı güvenilir bir şekilde desteklemek için kullanılabilir. Ayrıca, C# lambda ifadeleri ve tür çıkarımı dahil
olmak üzere fonksiyonel programlamayı desteklemek için açık dil uzantıları içerir. LINQ teknolojisi, bildirime
dayalı, işlevsel programlama biçimidir.

XSLT kullanarak işlevsel programlama


Birçok XSLT geliştiricisi, saf işlevsel yaklaşımla tanıdık gelecektir. XSLT stil sayfası geliştirmenin en etkili yolu, her
bir şablonu yalıtılmış, birleştirilebilir bir dönüşüm olarak değerlendirmektir. Yürütmenin sırası tamamen
vurgulandı. XSLT yan etkilere izin vermez (yordamsal kodu yürütmeye yönelik kaçış mekanizmalarının özel
durumu, işlevsel bir sorun oluşmasına neden olan yan etkileri ortaya çıkarabilir). Ancak XSLT etkin bir araç olsa da,
bazı özellikleri en uygun değildir. Örneğin, XML 'de programlama yapılarını ifade etmek, kod görece ayrıntılıdır ve
bu nedenle devam etmek zordur. Ayrıca, akış denetimi için özyineleme açısından ağır güvenilme, okunması zor
olan koda neden olabilir. XSLT hakkında daha fazla bilgi için bkz. XSLT dönüştürmeleri.
Ancak XSLT, XML 'yi bir şekilden diğerine dönüştürmek için saf işlevsel bir yaklaşım kullanma değerini uzamıştır.
LINQ to XML ile saf işlevsel programlama, XSLT 'nin birçok yolu ile benzerdir. Ancak, LINQ to XML tarafından
tanıtılan programlama yapıları, XSLT C# 'den daha okunaklı ve sürdürülebilir saf işlevsel dönüşümler yazmanızı
sağlar.

Saf Işlevlerin avantajları


İşlev dönüştürmelerinin saf işlevler olarak uygulanması için asıl neden, saf işlevlerin birleştirilamasıdır: Yani, kendi
içinde ve durumsuz. Bu özellikler, aşağıdakiler de dahil olmak üzere çeşitli avantajlar getirir:
Daha fazla okunabilirlik ve bakımma. Bunun nedeni, her işlevin bağımsız değişkenleri verilen belirli bir
görevi gerçekleştirmek için tasarlanmalıdır. İşlev herhangi bir dış duruma bağlı değil.
Daha kolay yeniden yinelemeli geliştirme. Kodun yeniden düzenlenmesi daha kolay olduğundan, tasarımın
değişikliklerinin uygulanması genellikle daha kolay olur. Örneğin, karmaşık bir dönüşüm yazdığınızı ve
sonra bazı kodların dönüşümde birkaç kez tekrarlanmış olduğunu fark edelim. Saf bir yöntemde yeniden
düzenleme yaparsanız, yan etkileri konusunda endişelenmenize gerek kalmadan saf yönteminizi ' de
çağırabilirsiniz.
Daha kolay test ve hata ayıklama. Saf işlevlerin yalıtımda daha kolay test edileceği için, saf işlevi çağıran test
kodunu tipik değerlerle, geçerli kenar çalışmalarından ve geçersiz kenar durumları ile yazabilirsiniz.

OOP geliştiricileri için geçiş


Geleneksel nesne odaklı programlamada (OOP ), çoğu geliştirici, zorunlu/yordamsal stilde programlanması için
tasarlanmıştır. Saf işlevsel stilde geliştirmeye geçiş yapmak için, düşünmelerde ve geliştirme yaklaşımında bir geçiş
yapması gerekir.
Sorunları gidermek için, OOP geliştiricileri sınıf hiyerarşilerini tasarlar, doğru kapsülleme üzerine odaklanmak ve
sınıf sözleşmeleri açısından düşünün. Nesne türlerinin davranışı ve durumu Paramount ve sınıflar, arabirimler,
devralma ve çok biçimlilik gibi dil özellikleri bu sorunları ele almak için sağlanır.
Buna karşılık, fonksiyonel programlama, veri koleksiyonlarının saf işlevsel dönüştürmelerinin değerlendirmesinde
bir alıştırma olarak sorun giderme konusunda yaklaşımlar. Fonksiyonel programlama durum ve değişebilir verileri
önler ve bunun yerine işlevlerin uygulamasını vurgular.
Neyse ki C# , hem zorunlu hem de işlevsel programlama yaklaşımlarını desteklediğinden işlevsel programlamaya
tam olarak gerek yoktur. Geliştirici, belirli bir senaryo için en uygun yaklaşımı seçebilir. Aslında, programlar
genellikle her iki yaklaşımı de birleştirir.

Ayrıca bkz.
Saf Işlevsel Dönüştürmelere giriş (C#)
XSLT Dönüşümleri
Saf IŞLEVLERE yeniden düzenleme (C#)
Saf IŞLEVLERE yeniden düzenleme (C#)
23.10.2019 • 5 minutes to read • Edit Online

Saf işlevsel dönüştürmelerin önemli bir yönü, saf işlevleri kullanarak kodu yeniden düzenleme hakkında bilgi
ediniyor.

NOTE
İşlevsel programlamada ortak terminoloji, programları saf işlevleri kullanarak yeniden düzenleme biçimleridir. Visual Basic ve
C++' de, bu, ilgili dillerdeki işlevlerin kullanımıyla hizalanır. Ancak, içindeki C#işlevleri yöntemler olarak adlandırılır. Bu
tartışmanın amaçları doğrultusunda, saf bir işlev ' de C#bir yöntem olarak uygulanır.

Daha önce bu bölümde belirtildiği gibi, saf bir işlev iki yararlı özelliğe sahiptir:
Yan etkileri yoktur. İşlev herhangi bir değişken veya işlev dışındaki herhangi bir türdeki veriyi değiştirmez.
Tutarlıdır. Aynı giriş verisi kümesi verildiğinde, her zaman aynı çıkış değerini döndürür.
İşlevsel programlamaya geçiş yapmanın bir yolu, gereksiz yan etkileri ve dış bağımlılıkları ortadan kaldırmak için
mevcut kodu yeniden düzenleme yöntemidir. Bu şekilde, var olan kodun saf işlev sürümlerini oluşturabilirsiniz.
Bu konuda, saf bir işlevin ne olduğu ve ne olmadığı açıklanmaktadır. Öğretici: WordprocessingML belgesi (C#)
öğreticisindeki içeriği işlemek bir WordprocessingML belgesinin nasıl düzenleneceğini gösterir ve saf bir işlev
kullanarak yeniden düzenleme ile iki örnek içerir.

Yan etkileri ve dış bağımlılıkları ortadan kaldırma


Aşağıdaki örneklerde, saf olmayan iki işlev ve bir saf işlev kontrast vardır.
Bir sınıf üyesini değiştiren saf olmayan Işlev
Aşağıdaki kodda, HyphenatedConcat işlev saf bir işlev değildir, çünkü sınıfındaki aMember veri üyesini değiştirir:

public class Program


{
private static string aMember = "StringOne";

public static void HyphenatedConcat(string appendStr)


{
aMember += '-' + appendStr;
}

public static void Main()


{
HyphenatedConcat("StringTwo");
Console.WriteLine(aMember);
}
}

Bu kod aşağıdaki çıktıyı üretir:

StringOne-StringTwo

Değiştirilen public static verilerin veya bir üye ya da bir örnek üyesi olup olmadığı konusunda ilgisiz olduğunu
unutmayın. private Saf bir işlev, işlevin dışındaki herhangi bir veriyi değiştirmez.
Bir bağımsız değişkeni değiştiren saf olmayan Işlev
Ayrıca, parametresinin sb içeriğini değiştirdiği için aynı işlevin aşağıdaki sürümü saf değildir.

public class Program


{
public static void HyphenatedConcat(StringBuilder sb, String appendStr)
{
sb.Append('-' + appendStr);
}

public static void Main()


{
StringBuilder sb1 = new StringBuilder("StringOne");
HyphenatedConcat(sb1, "StringTwo");
Console.WriteLine(sb1);
}
}

Programın bu sürümü ilk sürümle aynı çıktıyı üretir, çünkü HyphenatedConcat işlev Append üye işlevini çağırarak
ilk parametresinin değerini (durum) değiştirdi. Bu değişiklik, bu olguyu, çağrı- HyphenatedConcat değer
parametresini kullanan bir olgusuna rağmen oluştuğunu unutmayın.

IMPORTANT
Başvuru türleri için bir parametreyi değere göre geçirirseniz, başvurunun geçirildiği bir nesnenin kopyasına neden olur. Bu
kopya, özgün başvurusuyla aynı örnek verileriyle ilişkili olmaya devam eder (başvuru değişkeni yeni bir nesneye atanana
kadar). Bir parametreyi değiştirmek için bir işlev için başvuruya göre arama gerekli değildir.

Saf Işlev
Programın bu sonraki sürümü, HyphenatedConcat işlevinin saf işlev olarak nasıl uygulanacağını gösterir.

class Program
{
public static string HyphenatedConcat(string s, string appendStr)
{
return (s + '-' + appendStr);
}

public static void Main(string[] args)


{
string s1 = "StringOne";
string s2 = HyphenatedConcat(s1, "StringTwo");
Console.WriteLine(s2);
}
}

Yine, bu sürüm aynı çıkış satırını üretir: StringOne-StringTwo . Birleştirilmiş değeri bekletmek için, ara değişkende
s2 depolandığını unutmayın.

Çok yararlı olabilecek bir yaklaşım, yerel olarak etkileyici olan işlevleri yazmak (yani yerel değişkenleri bildirdikleri
ve değiştirdiklerinde), ancak Global olarak saf bir yaklaşımdır. Bu gibi işlevler, istenen ek özelliklerin çoğuna
sahiptir, ancak basit bir döngü aynı şeyi gerçekleştirirken özyineleme kullanmak zorunda kalmadan, daha fazla
çalışan işlevsel programlama deyimidir.

Standart sorgu Işleçleri


Standart sorgu işleçlerinin önemli bir özelliği, saf işlevler olarak uygulanırlar.
Daha fazla bilgi için bkz. Standart sorgu IşleçlerineC#genel bakış ().

Ayrıca bkz.
Saf Işlevsel Dönüştürmelere giriş (C#)
İşlevsel Programlama ve Kesinlik temelli programlamaC#()
Işlevsel dönüşümün (C#) uygulanabilirliği
23.10.2019 • 3 minutes to read • Edit Online

Saf işlevsel dönüşümler çok çeşitli durumlarda geçerlidir.


İşlev dönüştürme yaklaşımı, yapılandırılmış verileri sorgulamak ve işlemek için idealdir; Bu nedenle, LINQ
teknolojileriyle iyi uyum vardır. Ancak işlevsel dönüşümde LINQ ile kullanmaktan çok daha geniş bir
uygulanabilirlik vardır. Ana odağın bir formdan diğerine veri dönüştürmesiyle ilgili herhangi bir işlem, büyük
olasılıkla işlevsel dönüşüm için aday olarak kabul edilmelidir.
Bu yaklaşım, ilk bakışta aday olarak görünmeyebilir çok sayıda sorun için geçerlidir. LINQ ile birlikte veya LINQ
'tan ayrı olarak kullanıldığında, işlevsel dönüşümde aşağıdaki alanlarda göz önünde bulundurulmalıdır:
XML tabanlı belgeler. Her XML diyalekti için iyi biçimlendirilmiş veriler, işlevsel dönüşümde kolayca
değiştirilebilir. Daha fazla bilgi için bkz. XML (C#) işlevsel dönüşümü.
Diğer yapılandırılmış dosya biçimleri. Windows. ini dosyalarından düz metin belgelerine, çoğu dosya
çözümleme ve dönüştürme için kendisini hedefleyen bir yapıya sahiptir.
Veri akışı protokolleri. İletişim protokollerinden verileri içine ve kod çözmede verileri kodlama, genellikle
basit bir işlevsel dönüşümle temsil edilebilir.
RDBMS ve OODBMS verileri. XML gibi ilişkisel ve nesne odaklı veritabanları, yaygın olarak kullanılan
yapılandırılmış veri kaynaklarıdır.
Matematik ve bilimmatik, istatistiksel ve bilimi çözümleri. Bu alanlar, kullanıcının önemsiz olmayan sorunları
görselleştirirken, tahmin etmeye veya çözmeye yardımcı olmak için büyük veri kümelerini işlemeyi
eğilimlidir.
Saf işlevlerde yeniden düzenleme (C#)bölümünde açıklandığı gibi, saf işlevleri kullanmak fonksiyonel
programlamaya bir örnektir. Kendi anında avantajlarına ek olarak, saf işlevleri kullanmak işlevsel bir dönüşüm
perspektifinden ilgili sorunları düşünmeye yönelik değerli deneyim sağlar. Bu yaklaşım ayrıca program ve sınıf
tasarımına önemli bir etkiye sahip olabilir. Bu, özellikle bir sorun yukarıda açıklanan bir veri dönüştürme çözümüne
ait olduğunda geçerlidir.
Bu öğreticinin kapsamına aşmakla birlikte, işlevsel dönüştürme perspektifinden etkilenen tasarımlar, nesnelerin
aktörlere göre daha fazla işlem üzerinde ortalayarak, sonuçta elde edilen çözüm büyük ölçekli seriler olarak
uygulanabilmeye eğilimlidir tek tek nesne durumu değişiklikleri yerine dönüşümler.
Bu durumda, hem C# zorunlu hem de işlevsel yaklaşımların destekleyeceğini unutmayın. bu nedenle, uygulamanız
için en iyi tasarımın her ikisinin de öğeleri bulunabilir.

Ayrıca bkz.
Saf Işlevsel Dönüştürmelere giriş (C#)
XML (C#) işlevsel dönüştürmesi
Saf IŞLEVLERE yeniden düzenleme (C#)
XML (C#) işlevsel dönüştürmesi
23.10.2019 • 3 minutes to read • Edit Online

Bu konu, XML belgelerini değiştirmeye yönelik saf işlevsel dönüşüm yaklaşımını ve bunu bir yordamsal yaklaşımla
karşıtlıkları ele alır.

XML belgesini değiştirme


Bir XML programcı için en yaygın görevlerden biri, XML 'yi bir şekilden diğerine dönüştürmeye yöneliktir. XML
belgesinin şekli, belgenin yapısıdır ve şunları içerir:
Belge tarafından ifade edilen hiyerarşi.
Öğe ve öznitelik adları.
Öğelerin ve özniteliklerin veri türleri.
Genellikle, XML 'yi bir şekilden diğerine dönüştürmek için en etkili yaklaşım, saf işlevsel dönüşümden biridir. Bu
yaklaşımda, birincil programcı görevi tüm XML belgesine (veya bir veya daha fazla tanımlanmış düğüme)
uygulanan bir dönüşüm oluşturmaktır. İşlevsel dönüşüm, kodun en kolay kodu (programcılar yaklaşımı
öğrendikten sonra), en çok sürdürülebilir kodu oluşturur ve genellikle diğer yaklaşımlardan daha küçük olur.
XML Işlev dönüştürme teknolojileri
Microsoft, XML belgelerinde kullanılmak üzere iki işlevsel dönüştürme teknolojisi sunar: XSLT ve LINQ to XML.
XSLT, System.Xml.Xsl yönetilen ad alanında ve MSXML 'nin yerel com uygulamasında desteklenir. XSLT, XML
belgelerinin işlenmesine yönelik sağlam bir teknoloji olsa da, XSLT dili ve destekleyici API 'Leri gibi özelleştirilmiş
bir etki alanında uzmanlık gerektirir.
LINQ to XML, saf işlevsel dönüştürmeleri bir ifade ve güçlü bir biçimde, kod içinde C# veya Visual Basic kodda
kodladığı araçları sağlar. Örneğin, LINQ to XML belgelerindeki birçok örnek, saf işlevsel bir yaklaşım kullanır.
Ayrıca öğreticide: WordprocessingML belgesi (C#) öğreticisindeki içeriği işlemek, bir Microsoft Word belgesindeki
bilgileri işlemek için LINQ to XML işlevsel bir yaklaşımda kullanıyoruz.
Diğer Microsoft XML teknolojileriyle LINQ to XML daha kapsamlı bir karşılaştırması için, bkz . LINQ to XML vs.
Diğer XML Teknolojileri.
XSLT, kaynak belge düzensiz bir yapıya sahip olduğunda belge merkezli dönüşümler için önerilen araçtır. Ancak,
LINQ to XML belge merkezli dönüşümler de yapabilir. Daha fazla bilgi için nasıl yapılır: XSLT stilinde (C#) LINQ to
XML ağaçlarını dönüştürmek için ek açıklamaları kullanın.

Ayrıca bkz.
Saf Işlevsel Dönüştürmelere giriş (C#)
Öğretici: WordprocessingML belgesinde (C#) içeriği düzenleme
LINQ to XML ile Diğer XML Teknolojileri Karşılaştırması
LINQ to XML (C#) Içinde ertelenmiş yürütme ve geç
değerlendirme
23.10.2019 • 2 minutes to read • Edit Online

Sorgu ve eksen işlemleri genellikle ertelenmiş yürütmeyi kullanacak şekilde uygulanır. Bu konu, ertelenmiş
yürütmenin gereksinimlerini ve avantajlarını ve bazı uygulama konularını açıklamaktadır.

Ertelenmiş Yürütme
Ertelenmiş yürütme, istenen değer gerçekten gerekli olana kadar bir ifadenin değerlendirmesinin gecikildiği
anlamına gelir. Ertelenmiş yürütme, özellikle de bir dizi zincirleme sorgu veya işleme içeren programlarda büyük
veri koleksiyonlarını işlemek gerektiğinde performansı önemli ölçüde iyileştirebilir. En iyi durumda ertelenmiş
yürütme, kaynak koleksiyon aracılığıyla yalnızca tek bir yinelemeyi mümkün bir şekilde sunar.
LINQ teknolojileri, hem çekirdek System.Linq sınıfların üyelerinde hem de gibi çeşitli LINQ ad alanlarında uzantı
yöntemlerinde ertelenmiş yürütmenin yoğun bir şekilde System.Xml.Linq.Extensionskullanılmasını kolaylaştırır.
Ertelenmiş yürütme, bir yineleyici bloğunda kullanılan C# yield anahtar sözcüğü ( yield-return deyimin biçiminde)
tarafından doğrudan dilde desteklenir. Bu tür bir yineleyici, IEnumerator ya da IEnumerator<T> (ya da türetilmiş bir
tür) bir koleksiyon döndürmelidir.

Eager ile Geç değerlendirme


Ertelenmiş yürütmeyi uygulayan bir yöntem yazdığınızda, yavaş değerlendirme veya Eager değerlendirmesi
kullanarak yöntemi uygulayıp uygulamamaya de karar vermeniz gerekir.
Yavaş değerlendirmede, her Yineleyici çağrısı sırasında kaynak koleksiyonun tek bir öğesi işlenir.
Yineleyicilerin uygulanma tipik yoludur.
Eager değerlendirmesisırasında, Yineleyici için ilk çağrı, tüm koleksiyonun işlenmesine neden olur. Kaynak
koleksiyonun geçici bir kopyası da gerekebilir. Örneğin, OrderBy yöntemi ilk öğeyi döndürmadan önce tüm
koleksiyonu sıralamak zorunda olur.
Yavaş değerlendirme genellikle koleksiyonun değerlendirmesi boyunca ek yük işlemeyi eşit bir şekilde dağıttığı ve
geçici verilerin kullanımını en aza indirecek için daha iyi performans verir. Tabii ki, bazı işlemler için, ara sonuçları
gerçekleştirme dışında başka bir seçenek yoktur.

Sonraki Adımlar
Bu öğreticideki sonraki konu, ertelenmiş yürütmeyi gösterir:
Ertelenmiş yürütme örneği (C#)

Ayrıca bkz.
Öğretici: Sorguları birlikte zincirleme (C#)
Kavramlar ve terminoloji (Işlevsel dönüşüm) (C#)
Toplama Işlemleri (C#)
yield
Ertelenmiş yürütme örneği (C#)
23.10.2019 • 2 minutes to read • Edit Online

Bu konu, ertelenmiş yürütmenin ve yavaş değerlendirmenin LINQ to XML sorgularının yürütülmesini nasıl
etkilediğini gösterir.

Örnek
Aşağıdaki örnek, ertelenmiş yürütmeyi kullanan bir genişletme yöntemi kullanılırken yürütme sırasını gösterir.
Örnek, üç dizeden oluşan bir dizi bildirir. Daha sonra tarafından ConvertCollectionToUpperCase döndürülen
koleksiyon üzerinden yinelenir.

public static class LocalExtensions


{
public static IEnumerable<string>
ConvertCollectionToUpperCase(this IEnumerable<string> source)
{
foreach (string str in source)
{
Console.WriteLine("ToUpper: source {0}", str);
yield return str.ToUpper();
}
}
}

class Program
{
static void Main(string[] args)
{
string[] stringArray = { "abc", "def", "ghi" };

var q = from str in stringArray.ConvertCollectionToUpperCase()


select str;

foreach (string str in q)


Console.WriteLine("Main: str {0}", str);
}
}

Bu örnek aşağıdaki çıktıyı üretir:

ToUpper: source abc


Main: str ABC
ToUpper: source def
Main: str DEF
ToUpper: source ghi
Main: str GHI

Tarafından ConvertCollectionToUpperCase döndürülen koleksiyonda yineleme yapıldığında, her öğe kaynak dize
dizisinden alınır ve sonraki öğe kaynak dize dizisinden alınmadan önce büyük harfe dönüştürülür.
Döndürülen koleksiyondaki her öğe, içindeki foreach Main döngüde işlenmeden önce, tüm dizeler dizisinin büyük
harfe dönüştürülmediğine bakabilirsiniz.
Bu öğreticideki sonraki konu, zincirleme sorguları birlikte gösterir:
Zincirleme sorguları örneği (C#)

Ayrıca bkz.
Öğretici: Sorguları birlikte zincirleme (C#)
Zincirleme sorguları örneği (C#)
23.10.2019 • 2 minutes to read • Edit Online

Bu örnek, önceki örnekte oluşturulur ve hem ertelenmiş yürütme hem de yavaş değerlendirme kullanan iki sorguyu
zincirleyen ne olacağını gösterir.

Örnek
Bu örnekte, belirtilen bir dizeyi kaynak koleksiyondaki her dizeye AppendString bağlayan ve ardından yeni dizeleri
veren başka bir genişletme yöntemi tanıtılmıştır.

public static class LocalExtensions


{
public static IEnumerable<string>
ConvertCollectionToUpperCase(this IEnumerable<string> source)
{
foreach (string str in source)
{
Console.WriteLine("ToUpper: source >{0}<", str);
yield return str.ToUpper();
}
}

public static IEnumerable<string>


AppendString(this IEnumerable<string> source, string stringToAppend)
{
foreach (string str in source)
{
Console.WriteLine("AppendString: source >{0}<", str);
yield return str + stringToAppend;
}
}
}

class Program
{
static void Main(string[] args)
{
string[] stringArray = { "abc", "def", "ghi" };

IEnumerable<string> q1 =
from s in stringArray.ConvertCollectionToUpperCase()
select s;

IEnumerable<string> q2 =
from s in q1.AppendString("!!!")
select s;

foreach (string str in q2)


{
Console.WriteLine("Main: str >{0}<", str);
Console.WriteLine();
}
}
}

Bu örnek aşağıdaki çıktıyı üretir:


ToUpper: source >abc<
AppendString: source >ABC<
Main: str >ABC!!!<

ToUpper: source >def<


AppendString: source >DEF<
Main: str >DEF!!!<

ToUpper: source >ghi<


AppendString: source >GHI<
Main: str >GHI!!!<

Bu örnekte, her bir genişletme yönteminin, kaynak koleksiyondaki her öğe için tek bir kez çalıştığını görebilirsiniz.
Bu örnekte ne kadar net bir şekilde gruplandık, ancak koleksiyonları oluşturan sorguları birbirine zincirlediğimiz
halde ara koleksiyonlar gerçekleştirilmiş değildir. Bunun yerine, her öğe bir geç yönteminden bir sonrakine geçirilir.
Bu, ilk olarak bir dize dizisi alacak bir yaklaşımdan çok daha küçük bir bellek parmak izine neden olur, ardından
büyük harfe dönüştürülmüş bir ikinci dize dizisi oluşturur ve son olarak her bir dizenin ünlem işareti bulunan
üçüncü bir dizi dizeyi oluşturur Buna eklenen noktaları.
Bu öğreticideki sonraki konu, ara materialization gösterir:
Ara materialization (C#)

Ayrıca bkz.
Öğretici: Sorguları birlikte zincirleme (C#)
Ara materialization (C#)
23.10.2019 • 2 minutes to read • Edit Online

Dikkatli değilseniz, bazı durumlarda, Sorgularınızdaki koleksiyonların erken olarak kullanıma hazır hale gelmesine
neden olarak uygulamanızın bellek ve performans profilini büyük ölçüde değiştirebilirsiniz. Bazı standart sorgu
işleçleri, tek bir öğeyi oluşturmadan önce kaynak koleksiyonlarının çalışmasının oluşturulmasına neden olur.
Örneğin, Enumerable.OrderBy ilk olarak tüm kaynak koleksiyonu boyunca yinelenir, sonra tüm öğeleri sıralar ve
son olarak ilk öğeyi verir. Bu, sıralı bir koleksiyonun ilk öğesini almak pahalı olduğu anlamına gelir; Bundan sonra
her öğe pahalı değildir. Bu anlamlı olur: Başka bir sorgu işlecinin bunu yapması imkansız olabilir.

Örnek
Bu örnek, önceki örneği değiştirir. Yöntemi, kaynak üzerinde yineleme yapmadan önce çağırır ToList. AppendString
Bu, materialization oluşturulmasına neden olur.
public static class LocalExtensions
{
public static IEnumerable<string>
ConvertCollectionToUpperCase(this IEnumerable<string> source)
{
foreach (string str in source)
{
Console.WriteLine("ToUpper: source >{0}<", str);
yield return str.ToUpper();
}
}

public static IEnumerable<string>


AppendString(this IEnumerable<string> source, string stringToAppend)
{
// the following statement materializes the source collection in a List<T>
// before iterating through it
foreach (string str in source.ToList())
{
Console.WriteLine("AppendString: source >{0}<", str);
yield return str + stringToAppend;
}
}
}

class Program
{
static void Main(string[] args)
{
string[] stringArray = { "abc", "def", "ghi" };

IEnumerable<string> q1 =
from s in stringArray.ConvertCollectionToUpperCase()
select s;

IEnumerable<string> q2 =
from s in q1.AppendString("!!!")
select s;

foreach (string str in q2)


{
Console.WriteLine("Main: str >{0}<", str);
Console.WriteLine();
}
}
}

Bu örnek aşağıdaki çıktıyı üretir:

ToUpper: source >abc<


ToUpper: source >def<
ToUpper: source >ghi<
AppendString: source >ABC<
Main: str >ABC!!!<

AppendString: source >DEF<


Main: str >DEF!!!<

AppendString: source >GHI<


Main: str >GHI!!!<

Bu örnekte, çağrısının ToList ilk öğeyi bırakmadan önce tüm kaynağını numaralandırmasına neden AppendString
olduğunu görebilirsiniz. Kaynak büyük bir diziyse, bu, uygulamanın bellek profilini önemli ölçüde değiştirecek.
Standart sorgu işleçleri de birlikte zincirlenebilir. Bu öğreticideki son konu, bunu gösterir.
Standart sorgu Işleçlerini birlikte zincirleme (C#)

Ayrıca bkz.
Öğretici: Sorguları birlikte zincirleme (C#)
Standart sorgu Işleçlerini birlikte zincirleme (C#)
23.10.2019 • 2 minutes to read • Edit Online

Bu, öğreticideki son konudur: Sorguları birlikte sorgulama (C#) öğreticisi.


Standart sorgu işleçleri de birlikte zincirlenebilir. Örneğin, Enumerable.Where işlecini birbirine bağlayabilirsiniz ve
aynı zamanda bir geç şekilde çalışır. Hiçbir ara sonuç tarafından gerçekleştirilmeyeceğini.

Örnek
Bu örnekte, Where yöntemi çağrılmadan ConvertCollectionToUpperCase önce çağrılır. Yöntemi, bu
ConvertCollectionToUpperCase öğreticideki AppendString önceki örneklerde kullanılan Lazy yöntemleriyle neredeyse
tam olarak aynı şekilde çalışır. Where
Bunun farkı, bu durumda Where yöntem kaynak koleksiyonu aracılığıyla yinelenir, ilk öğenin koşulu geçirmediğini
belirler ve sonra geçecek bir sonraki öğeyi alır. Daha sonra ikinci öğeyi verir.
Ancak, temel düşünce aynıdır: Ara koleksiyonlar, olmaları gerekmedikçe gerçekleştirilmez.
Sorgu ifadeleri kullanıldığında, bunlar standart sorgu işleçleri çağrılarına dönüştürülür ve aynı ilkeler geçerlidir.
Bu bölümdeki Office Open XML belgelerini sorgulayan tüm örnekler aynı ilkeyi kullanır. Ertelenmiş yürütme ve
yavaş değerlendirme, LINQ (ve LINQ to XML ) etkin bir şekilde kullanmak için anlamanız gereken temel
kavramlardır.
public static class LocalExtensions
{
public static IEnumerable<string>
ConvertCollectionToUpperCase(this IEnumerable<string> source)
{
foreach (string str in source)
{
Console.WriteLine("ToUpper: source >{0}<", str);
yield return str.ToUpper();
}
}

public static IEnumerable<string>


AppendString(this IEnumerable<string> source, string stringToAppend)
{
foreach (string str in source)
{
Console.WriteLine("AppendString: source >{0}<", str);
yield return str + stringToAppend;
}
}
}

class Program
{
static void Main(string[] args)
{
string[] stringArray = { "abc", "def", "ghi" };

IEnumerable<string> q1 =
from s in stringArray.ConvertCollectionToUpperCase()
where s.CompareTo("D") >= 0
select s;

IEnumerable<string> q2 =
from s in q1.AppendString("!!!")
select s;

foreach (string str in q2)


{
Console.WriteLine("Main: str >{0}<", str);
Console.WriteLine();
}
}
}

Bu örnek aşağıdaki çıktıyı üretir:

ToUpper: source >abc<


ToUpper: source >def<
AppendString: source >DEF<
Main: str >DEF!!!<

ToUpper: source >ghi<


AppendString: source >GHI<
Main: str >GHI!!!<
LINQ to XML (C#) Içinde ertelenmiş yürütme ve
geç değerlendirme
23.10.2019 • 2 minutes to read • Edit Online

Sorgu ve eksen işlemleri genellikle ertelenmiş yürütmeyi kullanacak şekilde uygulanır. Bu konu, ertelenmiş
yürütmenin gereksinimlerini ve avantajlarını ve bazı uygulama konularını açıklamaktadır.

Ertelenmiş Yürütme
Ertelenmiş yürütme, istenen değer gerçekten gerekli olana kadar bir ifadenin değerlendirmesinin gecikildiği
anlamına gelir. Ertelenmiş yürütme, özellikle de bir dizi zincirleme sorgu veya işleme içeren programlarda
büyük veri koleksiyonlarını işlemek gerektiğinde performansı önemli ölçüde iyileştirebilir. En iyi durumda
ertelenmiş yürütme, kaynak koleksiyon aracılığıyla yalnızca tek bir yinelemeyi mümkün bir şekilde sunar.
LINQ teknolojileri, hem çekirdek System.Linq sınıfların üyelerinde hem de gibi çeşitli LINQ ad alanlarında
uzantı yöntemlerinde ertelenmiş yürütmenin yoğun bir şekilde System.Xml.Linq.Extensionskullanılmasını
kolaylaştırır.
Ertelenmiş yürütme, bir yineleyici bloğunda kullanılan C# yield anahtar sözcüğü ( yield-return deyimin
biçiminde) tarafından doğrudan dilde desteklenir. Bu tür bir yineleyici, IEnumerator ya da IEnumerator<T> (ya
da türetilmiş bir tür) bir koleksiyon döndürmelidir.

Eager ile Geç değerlendirme


Ertelenmiş yürütmeyi uygulayan bir yöntem yazdığınızda, yavaş değerlendirme veya Eager değerlendirmesi
kullanarak yöntemi uygulayıp uygulamamaya de karar vermeniz gerekir.
Yavaş değerlendirmede, her Yineleyici çağrısı sırasında kaynak koleksiyonun tek bir öğesi işlenir.
Yineleyicilerin uygulanma tipik yoludur.
Eager değerlendirmesisırasında, Yineleyici için ilk çağrı, tüm koleksiyonun işlenmesine neden olur.
Kaynak koleksiyonun geçici bir kopyası da gerekebilir. Örneğin, OrderBy yöntemi ilk öğeyi
döndürmadan önce tüm koleksiyonu sıralamak zorunda olur.
Yavaş değerlendirme genellikle koleksiyonun değerlendirmesi boyunca ek yük işlemeyi eşit bir şekilde dağıttığı
ve geçici verilerin kullanımını en aza indirecek için daha iyi performans verir. Tabii ki, bazı işlemler için, ara
sonuçları gerçekleştirme dışında başka bir seçenek yoktur.

Sonraki Adımlar
Bu öğreticideki sonraki konu, ertelenmiş yürütmeyi gösterir:
Ertelenmiş yürütme örneği (C#)

Ayrıca bkz.
Öğretici: Sorguları birlikte zincirleme (C#)
Kavramlar ve terminoloji (Işlevsel dönüşüm) (C#)
Toplama Işlemleri (C#)
yield
Ertelenmiş yürütme örneği (C#)
23.10.2019 • 2 minutes to read • Edit Online

Bu konu, ertelenmiş yürütmenin ve yavaş değerlendirmenin LINQ to XML sorgularının yürütülmesini nasıl
etkilediğini gösterir.

Örnek
Aşağıdaki örnek, ertelenmiş yürütmeyi kullanan bir genişletme yöntemi kullanılırken yürütme sırasını gösterir.
Örnek, üç dizeden oluşan bir dizi bildirir. Daha sonra tarafından ConvertCollectionToUpperCase döndürülen
koleksiyon üzerinden yinelenir.

public static class LocalExtensions


{
public static IEnumerable<string>
ConvertCollectionToUpperCase(this IEnumerable<string> source)
{
foreach (string str in source)
{
Console.WriteLine("ToUpper: source {0}", str);
yield return str.ToUpper();
}
}
}

class Program
{
static void Main(string[] args)
{
string[] stringArray = { "abc", "def", "ghi" };

var q = from str in stringArray.ConvertCollectionToUpperCase()


select str;

foreach (string str in q)


Console.WriteLine("Main: str {0}", str);
}
}

Bu örnek aşağıdaki çıktıyı üretir:

ToUpper: source abc


Main: str ABC
ToUpper: source def
Main: str DEF
ToUpper: source ghi
Main: str GHI

Tarafından ConvertCollectionToUpperCase döndürülen koleksiyonda yineleme yapıldığında, her öğe kaynak dize
dizisinden alınır ve sonraki öğe kaynak dize dizisinden alınmadan önce büyük harfe dönüştürülür.
Döndürülen koleksiyondaki her öğe, içindeki foreach Main döngüde işlenmeden önce, tüm dizeler dizisinin büyük
harfe dönüştürülmediğine bakabilirsiniz.
Bu öğreticideki sonraki konu, zincirleme sorguları birlikte gösterir:
Zincirleme sorguları örneği (C#)

Ayrıca bkz.
Öğretici: Sorguları birlikte zincirleme (C#)
Zincirleme sorguları örneği (C#)
23.10.2019 • 2 minutes to read • Edit Online

Bu örnek, önceki örnekte oluşturulur ve hem ertelenmiş yürütme hem de yavaş değerlendirme kullanan iki
sorguyu zincirleyen ne olacağını gösterir.

Örnek
Bu örnekte, belirtilen bir dizeyi kaynak koleksiyondaki her dizeye AppendString bağlayan ve ardından yeni dizeleri
veren başka bir genişletme yöntemi tanıtılmıştır.

public static class LocalExtensions


{
public static IEnumerable<string>
ConvertCollectionToUpperCase(this IEnumerable<string> source)
{
foreach (string str in source)
{
Console.WriteLine("ToUpper: source >{0}<", str);
yield return str.ToUpper();
}
}

public static IEnumerable<string>


AppendString(this IEnumerable<string> source, string stringToAppend)
{
foreach (string str in source)
{
Console.WriteLine("AppendString: source >{0}<", str);
yield return str + stringToAppend;
}
}
}

class Program
{
static void Main(string[] args)
{
string[] stringArray = { "abc", "def", "ghi" };

IEnumerable<string> q1 =
from s in stringArray.ConvertCollectionToUpperCase()
select s;

IEnumerable<string> q2 =
from s in q1.AppendString("!!!")
select s;

foreach (string str in q2)


{
Console.WriteLine("Main: str >{0}<", str);
Console.WriteLine();
}
}
}

Bu örnek aşağıdaki çıktıyı üretir:


ToUpper: source >abc<
AppendString: source >ABC<
Main: str >ABC!!!<

ToUpper: source >def<


AppendString: source >DEF<
Main: str >DEF!!!<

ToUpper: source >ghi<


AppendString: source >GHI<
Main: str >GHI!!!<

Bu örnekte, her bir genişletme yönteminin, kaynak koleksiyondaki her öğe için tek bir kez çalıştığını görebilirsiniz.
Bu örnekte ne kadar net bir şekilde gruplandık, ancak koleksiyonları oluşturan sorguları birbirine zincirlediğimiz
halde ara koleksiyonlar gerçekleştirilmiş değildir. Bunun yerine, her öğe bir geç yönteminden bir sonrakine geçirilir.
Bu, ilk olarak bir dize dizisi alacak bir yaklaşımdan çok daha küçük bir bellek parmak izine neden olur, ardından
büyük harfe dönüştürülmüş bir ikinci dize dizisi oluşturur ve son olarak her bir dizenin ünlem işareti bulunan
üçüncü bir dizi dizeyi oluşturur Buna eklenen noktaları.
Bu öğreticideki sonraki konu, ara materialization gösterir:
Ara materialization (C#)

Ayrıca bkz.
Öğretici: Sorguları birlikte zincirleme (C#)
Ara materialization (C#)
23.10.2019 • 2 minutes to read • Edit Online

Dikkatli değilseniz, bazı durumlarda, Sorgularınızdaki koleksiyonların erken olarak kullanıma hazır hale gelmesine
neden olarak uygulamanızın bellek ve performans profilini büyük ölçüde değiştirebilirsiniz. Bazı standart sorgu
işleçleri, tek bir öğeyi oluşturmadan önce kaynak koleksiyonlarının çalışmasının oluşturulmasına neden olur.
Örneğin, Enumerable.OrderBy ilk olarak tüm kaynak koleksiyonu boyunca yinelenir, sonra tüm öğeleri sıralar ve
son olarak ilk öğeyi verir. Bu, sıralı bir koleksiyonun ilk öğesini almak pahalı olduğu anlamına gelir; Bundan sonra
her öğe pahalı değildir. Bu anlamlı olur: Başka bir sorgu işlecinin bunu yapması imkansız olabilir.

Örnek
Bu örnek, önceki örneği değiştirir. Yöntemi, kaynak üzerinde yineleme yapmadan önce çağırır ToList. AppendString
Bu, materialization oluşturulmasına neden olur.
public static class LocalExtensions
{
public static IEnumerable<string>
ConvertCollectionToUpperCase(this IEnumerable<string> source)
{
foreach (string str in source)
{
Console.WriteLine("ToUpper: source >{0}<", str);
yield return str.ToUpper();
}
}

public static IEnumerable<string>


AppendString(this IEnumerable<string> source, string stringToAppend)
{
// the following statement materializes the source collection in a List<T>
// before iterating through it
foreach (string str in source.ToList())
{
Console.WriteLine("AppendString: source >{0}<", str);
yield return str + stringToAppend;
}
}
}

class Program
{
static void Main(string[] args)
{
string[] stringArray = { "abc", "def", "ghi" };

IEnumerable<string> q1 =
from s in stringArray.ConvertCollectionToUpperCase()
select s;

IEnumerable<string> q2 =
from s in q1.AppendString("!!!")
select s;

foreach (string str in q2)


{
Console.WriteLine("Main: str >{0}<", str);
Console.WriteLine();
}
}
}

Bu örnek aşağıdaki çıktıyı üretir:

ToUpper: source >abc<


ToUpper: source >def<
ToUpper: source >ghi<
AppendString: source >ABC<
Main: str >ABC!!!<

AppendString: source >DEF<


Main: str >DEF!!!<

AppendString: source >GHI<


Main: str >GHI!!!<

Bu örnekte, çağrısının ToList ilk öğeyi bırakmadan önce tüm kaynağını numaralandırmasına neden AppendString
olduğunu görebilirsiniz. Kaynak büyük bir diziyse, bu, uygulamanın bellek profilini önemli ölçüde değiştirecek.
Standart sorgu işleçleri de birlikte zincirlenebilir. Bu öğreticideki son konu, bunu gösterir.
Standart sorgu Işleçlerini birlikte zincirleme (C#)

Ayrıca bkz.
Öğretici: Sorguları birlikte zincirleme (C#)
Standart sorgu Işleçlerini birlikte zincirleme (C#)
23.10.2019 • 2 minutes to read • Edit Online

Bu, öğreticideki son konudur: Sorguları birlikte sorgulama (C#) öğreticisi.


Standart sorgu işleçleri de birlikte zincirlenebilir. Örneğin, Enumerable.Where işlecini birbirine bağlayabilirsiniz ve
aynı zamanda bir geç şekilde çalışır. Hiçbir ara sonuç tarafından gerçekleştirilmeyeceğini.

Örnek
Bu örnekte, Where yöntemi çağrılmadan ConvertCollectionToUpperCase önce çağrılır. Yöntemi, bu
ConvertCollectionToUpperCase öğreticideki AppendString önceki örneklerde kullanılan Lazy yöntemleriyle
neredeyse tam olarak aynı şekilde çalışır. Where
Bunun farkı, bu durumda Where yöntem kaynak koleksiyonu aracılığıyla yinelenir, ilk öğenin koşulu geçirmediğini
belirler ve sonra geçecek bir sonraki öğeyi alır. Daha sonra ikinci öğeyi verir.
Ancak, temel düşünce aynıdır: Ara koleksiyonlar, olmaları gerekmedikçe gerçekleştirilmez.
Sorgu ifadeleri kullanıldığında, bunlar standart sorgu işleçleri çağrılarına dönüştürülür ve aynı ilkeler geçerlidir.
Bu bölümdeki Office Open XML belgelerini sorgulayan tüm örnekler aynı ilkeyi kullanır. Ertelenmiş yürütme ve
yavaş değerlendirme, LINQ (ve LINQ to XML ) etkin bir şekilde kullanmak için anlamanız gereken temel
kavramlardır.
public static class LocalExtensions
{
public static IEnumerable<string>
ConvertCollectionToUpperCase(this IEnumerable<string> source)
{
foreach (string str in source)
{
Console.WriteLine("ToUpper: source >{0}<", str);
yield return str.ToUpper();
}
}

public static IEnumerable<string>


AppendString(this IEnumerable<string> source, string stringToAppend)
{
foreach (string str in source)
{
Console.WriteLine("AppendString: source >{0}<", str);
yield return str + stringToAppend;
}
}
}

class Program
{
static void Main(string[] args)
{
string[] stringArray = { "abc", "def", "ghi" };

IEnumerable<string> q1 =
from s in stringArray.ConvertCollectionToUpperCase()
where s.CompareTo("D") >= 0
select s;

IEnumerable<string> q2 =
from s in q1.AppendString("!!!")
select s;

foreach (string str in q2)


{
Console.WriteLine("Main: str >{0}<", str);
Console.WriteLine();
}
}
}

Bu örnek aşağıdaki çıktıyı üretir:

ToUpper: source >abc<


ToUpper: source >def<
AppendString: source >DEF<
Main: str >DEF!!!<

ToUpper: source >ghi<


AppendString: source >GHI<
Main: str >GHI!!!<
WordprocessingML belgelerinin şekli (C#)
23.10.2019 • 3 minutes to read • Edit Online

Bu konu, bir WordprocessingML belgesinin XML şeklini tanıtır.

Microsoft Office biçimleri


2007 Microsoft Office sistemi için yerel dosya biçimi Office Open XML 'dir (genellikle Open XML olarak
adlandırılır). Open XML, bir ECMA Standard ve şu anda ISO -ıEC standartları sürecinden geçen XML tabanlı bir
biçimdir. Open XML içindeki sözcük işleme dosyalarının biçimlendirme dili WordprocessingML olarak
adlandırılır. Bu öğretici, örnekler için giriş olarak WordprocessingML kaynak dosyalarını kullanır.
Microsoft Office 2003 kullanıyorsanız Word, Excel ve PowerPoint 2007 dosya biçimleri için Microsoft Office
Uyumluluk paketini yüklediyseniz Office Open XML biçimindeki belgeleri kaydedebilirsiniz.

WordprocessingML belgelerinin şekli


Anlaşılması gereken ilk şey WordprocessingML belgelerinin şekildir. WordprocessingML belgesi, belgenin
paragraflarını içeren bir body w:body öğesi (adlandırılmış) içerir. Her paragraf bir veya daha fazla metin
çalıştırması (adlandırılmış w:r ) içerir. Her metin çalışması bir veya daha fazla metin parçası (adlandırılmış w:t )
içerir.
Aşağıda çok basit bir WordprocessingML belgesi verilmiştir:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>


<w:document
xmlns:ve="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math"
xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"
xmlns:w10="urn:schemas-microsoft-com:office:word"
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml">
<w:body>
<w:p w:rsidR="00E22EB6"
w:rsidRDefault="00E22EB6">
<w:r>
<w:t>This is a paragraph.</w:t>
</w:r>
</w:p>
<w:p w:rsidR="00E22EB6"
w:rsidRDefault="00E22EB6">
<w:r>
<w:t>This is another paragraph.</w:t>
</w:r>
</w:p>
</w:body>
</w:document>

Bu belge iki paragraf içerir. Her ikisi de tek bir metin çalıştırması içerir ve her metin çalışması tek bir metin
parçası içerir.
XML biçiminde bir WordprocessingML belgesinin içeriğini görmenin en kolay yolu Microsoft Word 'Ü
kullanarak bir tane oluşturmak, kaydetmeniz ve ardından XML 'i konsola yazdıran aşağıdaki programı
çalıştırmalıdır.
Bu örnek, WindowsBase derlemesinde bulunan sınıfları kullanır. System.IO.Packaging Ad alanındaki türleri
kullanır.

const string documentRelationshipType =


"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
const string wordmlNamespace =
"http://schemas.openxmlformats.org/wordprocessingml/2006/main";
XNamespace w = wordmlNamespace;

using (Package wdPackage = Package.Open("SampleDoc.docx", FileMode.Open, FileAccess.Read))


{
PackageRelationship relationship =
wdPackage
.GetRelationshipsByType(documentRelationshipType)
.FirstOrDefault();
if (relationship != null)
{
Uri documentUri =
PackUriHelper.ResolvePartUri(
new Uri("/", UriKind.Relative),
relationship.TargetUri);
PackagePart documentPart = wdPackage.GetPart(documentUri);

// Get the officeDocument part from the package.


// Load the XML in the part into an XDocument instance.
XDocument xdoc =
XDocument.Load(XmlReader.Create(documentPart.GetStream()));
Console.WriteLine(xdoc.Root);
}
}

Dış Kaynaklar
Office (2007) Open XML dosya biçimlerine giriş
WordprocessingML 'ye Genel Bakış
WordProcessingML dosyasının anatomi
WordprocessingML 'ye giriş
Office 2003: XML başvuru şemaları Indirme sayfası

Ayrıca bkz.
Öğretici: WordprocessingML belgesinde (C#) içeriği düzenleme
Kaynak Office Open XML belgesi (C#) oluşturuluyor
23.10.2019 • 2 minutes to read • Edit Online

Bu konu başlığında, bu öğreticideki diğer örneklerin kullandığı Office Open XML WordprocessingML belgesinin
nasıl oluşturulacağı gösterilmektedir. Bu yönergeleri izlerseniz, çıktılarınız her örnekte girilen çıktıyla eşleşir.
Ancak, bu öğreticideki örnekler geçerli bir WordprocessingML belgesiyle çalışacaktır.
Bu öğreticinin kullandığı belgeyi oluşturmak için Microsoft Office 2007 veya sonraki bir sürümü yüklemiş
olmanız ya da Word, Excel ve PowerPoint 2007 dosya biçimleri için Microsoft Office Uyumluluk Paketi ile
Microsoft Office 2003 olmalıdır.

WordprocessingML belgesi oluşturma


WordprocessingML belgesi oluşturmak için
1. Yeni bir Microsoft Word belgesi oluşturun.
2. Aşağıdaki metni yeni belgeye yapıştırın:

Parsing WordprocessingML with LINQ to XML

The following example prints to the console.

using System;

class Program {
public static void Main(string[] args) {
Console.WriteLine("Hello World");
}
}

This example produces the following output:

Hello World

3. İlk satırı "Başlık 1" stiliyle biçimlendirin.


4. C# Kodu içeren satırları seçin. İlk satır using anahtar sözcüğüyle başlar. Son satır son kapanış ayracı.
Çizgileri Courier yazı tipiyle biçimlendirin. Bunları yeni bir stille biçimlendirin ve yeni "Code" stilini
adlandırın.
5. Son olarak, çıktıyı içeren satırın tamamını seçin ve Code stille biçimlendirin.
6. Belgeyi kaydedin ve SampleDoc. docx olarak adlandırın.

NOTE
Microsoft Word 2003 kullanıyorsanız, farklı kaydet türü açılan listesinde Word 2007 belgesi ' ni seçin.
Varsayılan paragraf stilini bulma (C#)
23.10.2019 • 2 minutes to read • Edit Online

WordprocessingML belgesi öğreticisindeki düzenleme bilgilerinde ilk görev, belgede varsayılan paragraf stilini
bullevidir.

Örnek
Açıklama
Aşağıdaki örnek, bir Office Open XML WordprocessingML belgesi açar, paketin belge ve stil parçalarını bulur ve
ardından varsayılan stil adını bulan bir sorgu yürütür. Office Open XML belge paketleri ve içerdikleri parçalar
hakkında daha fazla bilgi için bkz. Office Open XML WordprocessingML belgelerinin ayrıntıları (C#).
Sorgu, "paragraf" değeri w:style w:type ile adlandırılmış bir özniteliği olan adlı bir düğümü bulur ve ayrıca "1"
değerine sahip adlı w:default bir özniteliğe sahiptir. Bu özniteliklere sahip yalnızca bir XML düğümü olacağı için,
sorgu Enumerable.First işleci kullanarak bir koleksiyonu tek bir öğesine dönüştürür. Daha sonra, adlı w:styleId
özniteliğin değerini alır.
Bu örnek, WindowsBase derlemesinden sınıfları kullanır. System.IO.Packaging Ad alanındaki türleri kullanır.
Kod
const string fileName = "SampleDoc.docx";

const string documentRelationshipType =


"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
const string stylesRelationshipType =
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
const string wordmlNamespace =
"http://schemas.openxmlformats.org/wordprocessingml/2006/main";
XNamespace w = wordmlNamespace;

XDocument xDoc = null;


XDocument styleDoc = null;

using (Package wdPackage = Package.Open(fileName, FileMode.Open, FileAccess.Read))


{
PackageRelationship docPackageRelationship =
wdPackage.GetRelationshipsByType(documentRelationshipType).FirstOrDefault();
if (docPackageRelationship != null)
{
Uri documentUri = PackUriHelper.ResolvePartUri(new Uri("/", UriKind.Relative),
docPackageRelationship.TargetUri);
PackagePart documentPart = wdPackage.GetPart(documentUri);

// Load the document XML in the part into an XDocument instance.


xDoc = XDocument.Load(XmlReader.Create(documentPart.GetStream()));

// Find the styles part. There will only be one.


PackageRelationship styleRelation =
documentPart.GetRelationshipsByType(stylesRelationshipType).FirstOrDefault();
if (styleRelation != null)
{
Uri styleUri = PackUriHelper.ResolvePartUri(documentUri, styleRelation.TargetUri);
PackagePart stylePart = wdPackage.GetPart(styleUri);

// Load the style XML in the part into an XDocument instance.


styleDoc = XDocument.Load(XmlReader.Create(stylePart.GetStream()));
}
}
}

// The following query finds all the paragraphs that have the default style.
string defaultStyle =
(string)(
from style in styleDoc.Root.Elements(w + "style")
where (string)style.Attribute(w + "type") == "paragraph"&&
(string)style.Attribute(w + "default") == "1"
select style
).First().Attribute(w + "styleId");

Console.WriteLine("The default style is: {0}", defaultStyle);

Açıklamalar
Bu örnek aşağıdaki çıktıyı üretir:

The default style is: Normal

Sonraki Adımlar
Sonraki örnekte, bir belgedeki ve stillerinin tüm paragraflarını bulan benzer bir sorgu oluşturacaksınız:
Paragrafları ve stillerini alma (C#)
Paragrafları ve stillerini alma (C#)
23.10.2019 • 5 minutes to read • Edit Online

Bu örnekte, bir WordprocessingML belgesinden paragraf düğümlerini alan bir sorgu yazdık. Ayrıca her bir
paragrafın stilini belirler.
Bu sorgu, stil listesinden varsayılan stili alan varsayılan paragraf stilini (C#) bularak, önceki örnekteki sorgu
üzerinde oluşturulur. Bu bilgiler, sorgunun açıkça ayarlanmış bir stile sahip olmayan paragrafların stilini
belirleyebilmesi için gereklidir. Paragraf stilleri w:pPr öğe aracılığıyla ayarlanır; bir paragraf bu öğeyi içermiyorsa,
varsayılan stille biçimlendirilir.
Bu konuda, sorgunun bazı parçalarının önemi açıklanmakta ve sorgu tam, çalışan bir örnek kapsamında
gösteriliyor.

Örnek
Belgedeki tüm paragrafları ve bunların stillerini almak için sorgunun kaynağı aşağıdaki gibidir:

xDoc.Root.Element(w + "body").Descendants(w + "p")

Bu ifade, önceki örnekteki sorgunun kaynağına benzer, varsayılan paragraf stilini (C#) buluyor. Temel fark,
Descendants Elements eksen yerine eksenin kullanıldığı bir değer. Sorgu, bölümleri bulunan Descendants
belgelerde, paragrafları, gövde öğesinin doğrudan alt öğeleri olmayacak şekilde kullanır; bunun yerine, paragraflar
hiyerarşide iki düzey olur. Descendants Eksen kullanılarak, kod belgenin bölüm kullanıp kullanmadığını belirtir.

Örnek
Sorgu, stil düğümünü let içeren öğeyi belirlemede bir yan tümce kullanır. Öğe yoksa, styleNode şu şekilde null
ayarlanır:

let styleNode = para.Elements(w + "pPr").Elements(w + "pStyle").FirstOrDefault()

pPr pStyle FirstOrDefault YantümcesiElements ilk olarak adlı Elements tüm öğeleri bulmak için eksenini kullanır,
ardından adlı tüm alt öğeleri bulmak için genişletme yöntemini kullanır ve son olarak standart sorguyu kullanır
let koleksiyonu bir tekil öğesine dönüştürecek işleç. Koleksiyon boşsa, styleNode olarak null ayarlanır. Bu, alt
düğümü aramak pStyle için kullanışlı bir deyimdir. pPr Alt düğüm yoksa, bir özel durum oluşturarak kodun bir
istisna olduğunu veya başarısız olduğunu, styleNode bunun yerine, bu let yan tümcesinin istenen davranışı olan
null olarak ayarlandığını unutmayın.

Sorgu, StyleName iki üyeli anonim bir türün bir koleksiyonunu ve ParagraphNode .

Örnek
Bu örnek, WordprocessingML belgesinden paragraf düğümlerini alarak bir WordprocessingML belgesini işler.
Ayrıca her bir paragrafın stilini belirler. Bu örnekte, bu öğreticideki önceki örneklerde derleme yapılır. Yeni sorgu,
aşağıdaki koddaki açıklamalarda çağrılır.
Kaynak Office Open XML belgesiC#() oluşturmabölümünde bu örnek için kaynak belge oluşturma yönergelerini
bulabilirsiniz.
Bu örnek, WindowsBase derlemesinde bulunan sınıfları kullanır. System.IO.Packaging Ad alanındaki türleri kullanır.

const string fileName = "SampleDoc.docx";

const string documentRelationshipType =


"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
const string stylesRelationshipType =
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
const string wordmlNamespace = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
XNamespace w = wordmlNamespace;

XDocument xDoc = null;


XDocument styleDoc = null;

using (Package wdPackage = Package.Open(fileName, FileMode.Open, FileAccess.Read))


{
PackageRelationship docPackageRelationship =
wdPackage.GetRelationshipsByType(documentRelationshipType).FirstOrDefault();
if (docPackageRelationship != null)
{
Uri documentUri = PackUriHelper.ResolvePartUri(new Uri("/", UriKind.Relative),
docPackageRelationship.TargetUri);
PackagePart documentPart = wdPackage.GetPart(documentUri);

// Load the document XML in the part into an XDocument instance.


xDoc = XDocument.Load(XmlReader.Create(documentPart.GetStream()));

// Find the styles part. There will only be one.


PackageRelationship styleRelation =
documentPart.GetRelationshipsByType(stylesRelationshipType).FirstOrDefault();
if (styleRelation != null)
{
Uri styleUri = PackUriHelper.ResolvePartUri(documentUri, styleRelation.TargetUri);
PackagePart stylePart = wdPackage.GetPart(styleUri);

// Load the style XML in the part into an XDocument instance.


styleDoc = XDocument.Load(XmlReader.Create(stylePart.GetStream()));
}
}
}

string defaultStyle =
(string)(
from style in styleDoc.Root.Elements(w + "style")
where (string)style.Attribute(w + "type") == "paragraph"&&
(string)style.Attribute(w + "default") == "1"
select style
).First().Attribute(w + "styleId");

// Following is the new query that finds all paragraphs in the


// document and their styles.
var paragraphs =
from para in xDoc
.Root
.Element(w + "body")
.Descendants(w + "p")
let styleNode = para
.Elements(w + "pPr")
.Elements(w + "pStyle")
.FirstOrDefault()
select new
{
ParagraphNode = para,
StyleName = styleNode != null ?
(string)styleNode.Attribute(w + "val") :
defaultStyle
};
foreach (var p in paragraphs)
Console.WriteLine("StyleName:{0}", p.StyleName);

Bu örnek, kaynak Office Open XML belgesi (C#) oluşturmabölümünde açıklanan belgeye uygulandığında
aşağıdaki çıktıyı üretir.

StyleName:Heading1
StyleName:Normal
StyleName:Normal
StyleName:Normal
StyleName:Code
StyleName:Code
StyleName:Code
StyleName:Code
StyleName:Code
StyleName:Code
StyleName:Code
StyleName:Normal
StyleName:Normal
StyleName:Normal
StyleName:Code

Sonraki Adımlar
Bir sonraki konu başlığında, paragrafların (C#) metnini alırken, paragrafların metnini almak için bir sorgu
oluşturacaksınız.

Ayrıca bkz.
Öğretici: WordprocessingML belgesinde (C#) içeriği düzenleme
Paragrafların (C#) metnini alma
4.11.2019 • 5 minutes to read • Edit Online

Bu örnek, önceki örnekte yer alan ve paragrafları ve stilleriniC#() almahakkında daha fazla örnek oluşturur. Bu yeni
örnek, her bir paragrafın metnini dize olarak alır.
Bu örnek, metni almak için, anonim türler koleksiyonu aracılığıyla yinelenen bir sorgu ekler ve yeni bir üyenin
eklenmesiyle adsız bir türün yeni bir koleksiyonunu Text . Birden çok dizeyi tek bir dizede birleştirmek için
Aggregate standart sorgu işlecini kullanır.
Bu teknik (yani, ilk olarak anonim bir türün koleksiyonuna yansıtırken, daha sonra bu koleksiyonun yeni bir
anonim tür koleksiyonuna proje için kullanılması) ortak ve kullanışlı bir derlemedir. Bu sorgu, ilk anonim türe
yansıtılamadan yazılmış olabilir. Ancak, yavaş değerlendirme nedeniyle bunu yapmak çok daha fazla işlem gücü
kullanmaz. Deyim yığında daha kısa süreli nesneler oluşturur, ancak bu durum performansı önemli ölçüde düşürür.
Tabii ki, paragrafları alma işlevini, her bir paragrafın stilini ve her bir paragrafın metnini içeren tek bir sorgu
yazmak mümkün olacaktır. Ancak, sonuçta elde edilen kod daha modüler ve bakımını daha kolay olduğundan,
genellikle daha karmaşık bir sorguyu birden çok sorguya bölmek faydalı olur. Ayrıca, sorgunun bir bölümünü
yeniden kullanmanız gerekiyorsa, sorgular bu şekilde yazılmışsa yeniden düzenleme daha kolay olur.
Birlikte zincirleme olan bu sorgular, konu öğreticisinde ayrıntılı olarak incelenen işleme modelini kullanın :
sorguları birlikte zincirlemeC#().

Örnek
Bu örnekte, bir WordprocessingML belgesi işlenir, öğe düğümü, stil adı ve her paragrafın metni belirlenir.Bu
örnekte, bu öğreticideki önceki örneklerde derleme yapılır. Yeni sorgu, aşağıdaki koddaki açıklamalarda çağrılır.
Bu örnek için kaynak belge oluşturmaya ilişkin yönergeler için bkz. kaynak Office Open XML belgesi (C#)
oluşturma.
Bu örnek, WindowsBase derlemesinden sınıfları kullanır. System.IO.Packaging ad alanındaki türleri kullanır.

const string fileName = "SampleDoc.docx";

const string documentRelationshipType =


"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
const string stylesRelationshipType =
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
const string wordmlNamespace =
"http://schemas.openxmlformats.org/wordprocessingml/2006/main";
XNamespace w = wordmlNamespace;

XDocument xDoc = null;


XDocument styleDoc = null;

using (Package wdPackage = Package.Open(fileName, FileMode.Open, FileAccess.Read))


{
PackageRelationship docPackageRelationship =
wdPackage.GetRelationshipsByType(documentRelationshipType).FirstOrDefault();
if (docPackageRelationship != null)
{
Uri documentUri = PackUriHelper.ResolvePartUri(new Uri("/", UriKind.Relative),
docPackageRelationship.TargetUri);
PackagePart documentPart = wdPackage.GetPart(documentUri);

// Load the document XML in the part into an XDocument instance.


xDoc = XDocument.Load(XmlReader.Create(documentPart.GetStream()));

// Find the styles part. There will only be one.


PackageRelationship styleRelation =
documentPart.GetRelationshipsByType(stylesRelationshipType).FirstOrDefault();
if (styleRelation != null)
{
Uri styleUri = PackUriHelper.ResolvePartUri(documentUri, styleRelation.TargetUri);
PackagePart stylePart = wdPackage.GetPart(styleUri);

// Load the style XML in the part into an XDocument instance.


styleDoc = XDocument.Load(XmlReader.Create(stylePart.GetStream()));
}
}
}

string defaultStyle =
(string)(
from style in styleDoc.Root.Elements(w + "style")
where (string)style.Attribute(w + "type") == "paragraph"&&
(string)style.Attribute(w + "default") == "1"
select style
).First().Attribute(w + "styleId");

// Find all paragraphs in the document.


var paragraphs =
from para in xDoc
.Root
.Element(w + "body")
.Descendants(w + "p")
let styleNode = para
.Elements(w + "pPr")
.Elements(w + "pStyle")
.FirstOrDefault()
select new
{
ParagraphNode = para,
StyleName = styleNode != null ?
(string)styleNode.Attribute(w + "val") :
defaultStyle
};

// Following is the new query that retrieves the text of


// each paragraph.
var paraWithText =
from para in paragraphs
select new
{
ParagraphNode = para.ParagraphNode,
StyleName = para.StyleName,
Text = para
.ParagraphNode
.Elements(w + "r")
.Elements(w + "t")
.Aggregate(
new StringBuilder(),
(s, i) => s.Append((string)i),
s => s.ToString()
)
};

foreach (var p in paraWithText)


Console.WriteLine("StyleName:{0} >{1}<", p.StyleName, p.Text);

Bu örnek, kaynak Office Open XML belgesi (C#) oluşturmabölümünde açıklanan belgeye uygulandığında
aşağıdaki çıktıyı üretir.
StyleName:Heading1 >Parsing WordprocessingML with LINQ to XML<
StyleName:Normal ><
StyleName:Normal >The following example prints to the console.<
StyleName:Normal ><
StyleName:Code >using System;<
StyleName:Code ><
StyleName:Code >class Program {<
StyleName:Code > public static void (string[] args) {<
StyleName:Code > Console.WriteLine("Hello World");<
StyleName:Code > }<
StyleName:Code >}<
StyleName:Normal ><
StyleName:Normal >This example produces the following output:<
StyleName:Normal ><
StyleName:Code >Hello World<

Sonraki Adımlar
Sonraki örnek, birden çok dizeyi tek bir dizeye birleştirmek için Aggregateyerine bir genişletme yönteminin nasıl
kullanılacağını gösterir.
Bir genişletme yöntemi (C#) kullanılarak yeniden düzenleme

Ayrıca bkz.
Öğretici: bir WordprocessingML belgesinde (C#) içeriği düzenleme
LINQ to XML (C#) Içinde ertelenmiş yürütme ve geç değerlendirme
Bir genişletme yöntemi (C#) kullanılarak yeniden
düzenleme
23.10.2019 • 5 minutes to read • Edit Online

Bu örnek, bir genişletme yöntemi olarak uygulanan bir saf işlev kullanarak dizelerin birleştirilmesiyle yeniden
düzenleme yoluyla, önceki örnekte yer alan, paragrafların (C#) metnini alma.
Önceki örnek, birden çok Aggregate dizeyi tek bir dizede birleştirmek için standart sorgu işlecini kullandı. Bununla
birlikte, bunu yapmak için bir genişletme yöntemi yazmak daha uygundur, çünkü sonuçta elde edilen sorgu daha
küçük ve daha basit.

Örnek
Bu örnekte, bir WordprocessingML belgesi, paragrafları, her bir paragrafın stili ve her bir paragrafın metni işlenir.
Bu örnekte, bu öğreticideki önceki örneklerde derleme yapılır.
Örnek, StringConcatenate yönteminin birden çok aşırı yüklerini içerir.
Kaynak Office Open XML belgesiC#() oluşturmabölümünde bu örnek için kaynak belge oluşturma yönergelerini
bulabilirsiniz.
Bu örnek, WindowsBase derlemesinden sınıfları kullanır. System.IO.Packaging Ad alanındaki türleri kullanır.
public static class LocalExtensions
{
public static string StringConcatenate(this IEnumerable<string> source)
{
StringBuilder sb = new StringBuilder();
foreach (string s in source)
sb.Append(s);
return sb.ToString();
}

public static string StringConcatenate<T>(this IEnumerable<T> source,


Func<T, string> func)
{
StringBuilder sb = new StringBuilder();
foreach (T item in source)
sb.Append(func(item));
return sb.ToString();
}

public static string StringConcatenate(this IEnumerable<string> source, string separator)


{
StringBuilder sb = new StringBuilder();
foreach (string s in source)
sb.Append(s).Append(separator);
return sb.ToString();
}

public static string StringConcatenate<T>(this IEnumerable<T> source,


Func<T, string> func, string separator)
{
StringBuilder sb = new StringBuilder();
foreach (T item in source)
sb.Append(func(item)).Append(separator);
return sb.ToString();
}
}

Örnek
StringConcatenate Metodun dört aşırı yüklemesi vardır. Bir aşırı yükleme yalnızca bir dize koleksiyonu alır ve tek
bir dize döndürür. Başka bir aşırı yükleme, herhangi bir türün bir koleksiyonunu ve bir koleksiyonun tek bir
sınıfından bir dizeye olan bir temsilciyi alabilir. Bir ayırıcı dize belirtmenizi sağlayan iki aşırı yükleme daha vardır.
Aşağıdaki kod dört aşırı yüklemeyi kullanır.

string[] numbers = { "one", "two", "three" };

Console.WriteLine("{0}", numbers.StringConcatenate());
Console.WriteLine("{0}", numbers.StringConcatenate(":"));

int[] intNumbers = { 1, 2, 3 };
Console.WriteLine("{0}", intNumbers.StringConcatenate(i => i.ToString()));
Console.WriteLine("{0}", intNumbers.StringConcatenate(i => i.ToString(), ":"));

Bu örnek aşağıdaki çıktıyı üretir:

onetwothree
one:two:three:
123
1:2:3:
Örnek
Şimdi, örnek yeni uzantı yönteminden faydalanmak için değiştirilebilir:

public static class LocalExtensions


{
public static string StringConcatenate(this IEnumerable<string> source)
{
StringBuilder sb = new StringBuilder();
foreach (string s in source)
sb.Append(s);
return sb.ToString();
}

public static string StringConcatenate<T>(this IEnumerable<T> source,


Func<T, string> func)
{
StringBuilder sb = new StringBuilder();
foreach (T item in source)
sb.Append(func(item));
return sb.ToString();
}

public static string StringConcatenate(this IEnumerable<string> source, string separator)


{
StringBuilder sb = new StringBuilder();
foreach (string s in source)
sb.Append(s).Append(separator);
return sb.ToString();
}

public static string StringConcatenate<T>(this IEnumerable<T> source,


Func<T, string> func, string separator)
{
StringBuilder sb = new StringBuilder();
foreach (T item in source)
sb.Append(func(item)).Append(separator);
return sb.ToString();
}
}

class Program
{
static void Main(string[] args)
{
const string fileName = "SampleDoc.docx";

const string documentRelationshipType =


"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
const string stylesRelationshipType =
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
const string wordmlNamespace =
"http://schemas.openxmlformats.org/wordprocessingml/2006/main";
XNamespace w = wordmlNamespace;

XDocument xDoc = null;


XDocument styleDoc = null;

using (Package wdPackage = Package.Open(fileName, FileMode.Open, FileAccess.Read))


{
PackageRelationship docPackageRelationship =
wdPackage.GetRelationshipsByType(documentRelationshipType).FirstOrDefault();
if (docPackageRelationship != null)
{
Uri documentUri = PackUriHelper.ResolvePartUri(new Uri("/", UriKind.Relative),
docPackageRelationship.TargetUri);
PackagePart documentPart = wdPackage.GetPart(documentUri);
// Load the document XML in the part into an XDocument instance.
xDoc = XDocument.Load(XmlReader.Create(documentPart.GetStream()));

// Find the styles part. There will only be one.


PackageRelationship styleRelation =
documentPart.GetRelationshipsByType(stylesRelationshipType).FirstOrDefault();
if (styleRelation != null)
{
Uri styleUri =
PackUriHelper.ResolvePartUri(documentUri, styleRelation.TargetUri);
PackagePart stylePart = wdPackage.GetPart(styleUri);

// Load the style XML in the part into an XDocument instance.


styleDoc = XDocument.Load(XmlReader.Create(stylePart.GetStream()));
}
}
}

string defaultStyle =
(string)(
from style in styleDoc.Root.Elements(w + "style")
where (string)style.Attribute(w + "type") == "paragraph" &&
(string)style.Attribute(w + "default") == "1"
select style
).First().Attribute(w + "styleId");

// Find all paragraphs in the document.


var paragraphs =
from para in xDoc
.Root
.Element(w + "body")
.Descendants(w + "p")
let styleNode = para
.Elements(w + "pPr")
.Elements(w + "pStyle")
.FirstOrDefault()
select new
{
ParagraphNode = para,
StyleName = styleNode != null ?
(string)styleNode.Attribute(w + "val") :
defaultStyle
};

// Retrieve the text of each paragraph.


var paraWithText =
from para in paragraphs
select new
{
ParagraphNode = para.ParagraphNode,
StyleName = para.StyleName,
Text = para
.ParagraphNode
.Elements(w + "r")
.Elements(w + "t")
.StringConcatenate(e => (string)e)
};

foreach (var p in paraWithText)


Console.WriteLine("StyleName:{0} >{1}<", p.StyleName, p.Text);
}
}

Bu örnek, kaynak Office Open XML belgesi (C#) oluşturmabölümünde açıklanan belgeye uygulandığında
aşağıdaki çıktıyı üretir.
StyleName:Heading1 >Parsing WordprocessingML with LINQ to XML<
StyleName:Normal ><
StyleName:Normal >The following example prints to the console.<
StyleName:Normal ><
StyleName:Code >using System;<
StyleName:Code ><
StyleName:Code >class Program {<
StyleName:Code > public static void (string[] args) {<
StyleName:Code > Console.WriteLine("Hello World");<
StyleName:Code > }<
StyleName:Code >}<
StyleName:Normal ><
StyleName:Normal >This example produces the following output:<
StyleName:Normal ><
StyleName:Code >Hello World<

Bu yeniden düzenleme, saf bir işleve yeniden düzenleme çeşidine sahip olduğunu unutmayın. Sonraki konu,
düzenleme işlevlerini saf işlevlere daha ayrıntılı bir şekilde tanıtacaktır.

Sonraki Adımlar
Sonraki örnekte, saf işlevleri kullanılarak bu kodun başka bir şekilde nasıl yeniden düzenlenmesi gösterilmektedir:
Saf Işlev kullanarak yeniden düzenleme (Visual Basic)

Ayrıca bkz.
Öğretici: WordprocessingML belgesinde (C#) içeriği düzenleme
Saf IŞLEVLERE yeniden düzenleme (C#)
Saf Işlev kullanarak yeniden düzenleme (C#)
23.10.2019 • 3 minutes to read • Edit Online

Aşağıdaki örnek, bir genişletme yöntemi (C#) kullanılarak yeniden düzenleme, bu örnekte saf bir işlev kullanmak
için, bir paragrafın metnini bulmak için kod saf statik metoda ParagraphText taşınır.

Örnek
Bu örnek, WordprocessingML belgesinden paragraf düğümlerini alarak bir WordprocessingML belgesini işler.
Ayrıca her bir paragrafın stilini belirler. Bu örnekte, bu öğreticideki önceki örneklerde derleme yapılır. Yeniden
düzenlenmiş kodu, aşağıdaki koddaki açıklamalarda çağrılır.
Bu örnek için kaynak belge oluşturmaya ilişkin yönergeler için bkz. kaynak Office Open XML belgesi (C#)
oluşturma.
Bu örnek, WindowsBase derlemesinden sınıfları kullanır. System.IO.Packaging Ad alanındaki türleri kullanır.

public static class LocalExtensions


{
public static string StringConcatenate(this IEnumerable<string> source)
{
StringBuilder sb = new StringBuilder();
foreach (string s in source)
sb.Append(s);
return sb.ToString();
}

public static string StringConcatenate<T>(this IEnumerable<T> source,


Func<T, string> func)
{
StringBuilder sb = new StringBuilder();
foreach (T item in source)
sb.Append(func(item));
return sb.ToString();
}

public static string StringConcatenate(this IEnumerable<string> source, string separator)


{
StringBuilder sb = new StringBuilder();
foreach (string s in source)
sb.Append(s).Append(separator);
return sb.ToString();
}

public static string StringConcatenate<T>(this IEnumerable<T> source,


Func<T, string> func, string separator)
{
StringBuilder sb = new StringBuilder();
foreach (T item in source)
sb.Append(func(item)).Append(separator);
return sb.ToString();
}
}

class Program
{
// This is a new method that assembles the paragraph text.
public static string ParagraphText(XElement e)
{
XNamespace w = e.Name.Namespace;
XNamespace w = e.Name.Namespace;
return e
.Elements(w + "r")
.Elements(w + "t")
.StringConcatenate(element => (string)element);
}

static void Main(string[] args)


{
const string fileName = "SampleDoc.docx";

const string documentRelationshipType =


"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
const string stylesRelationshipType =
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
const string wordmlNamespace =
"http://schemas.openxmlformats.org/wordprocessingml/2006/main";
XNamespace w = wordmlNamespace;

XDocument xDoc = null;


XDocument styleDoc = null;

using (Package wdPackage = Package.Open(fileName, FileMode.Open, FileAccess.Read))


{
PackageRelationship docPackageRelationship =
wdPackage.GetRelationshipsByType(documentRelationshipType).FirstOrDefault();
if (docPackageRelationship != null)
{
Uri documentUri = PackUriHelper.ResolvePartUri(new Uri("/", UriKind.Relative),
docPackageRelationship.TargetUri);
PackagePart documentPart = wdPackage.GetPart(documentUri);

// Load the document XML in the part into an XDocument instance.


xDoc = XDocument.Load(XmlReader.Create(documentPart.GetStream()));

// Find the styles part. There will only be one.


PackageRelationship styleRelation =
documentPart.GetRelationshipsByType(stylesRelationshipType).FirstOrDefault();
if (styleRelation != null)
{
Uri styleUri = PackUriHelper.ResolvePartUri(documentUri,
styleRelation.TargetUri);
PackagePart stylePart = wdPackage.GetPart(styleUri);

// Load the style XML in the part into an XDocument instance.


styleDoc = XDocument.Load(XmlReader.Create(stylePart.GetStream()));
}
}
}

string defaultStyle =
(string)(
from style in styleDoc.Root.Elements(w + "style")
where (string)style.Attribute(w + "type") == "paragraph" &&
(string)style.Attribute(w + "default") == "1"
select style
).First().Attribute(w + "styleId");

// Find all paragraphs in the document.


var paragraphs =
from para in xDoc
.Root
.Element(w + "body")
.Descendants(w + "p")
let styleNode = para
.Elements(w + "pPr")
.Elements(w + "pStyle")
.FirstOrDefault()
select new
{
{
ParagraphNode = para,
StyleName = styleNode != null ?
(string)styleNode.Attribute(w + "val") :
defaultStyle
};

// Retrieve the text of each paragraph.


var paraWithText =
from para in paragraphs
select new
{
ParagraphNode = para.ParagraphNode,
StyleName = para.StyleName,
Text = ParagraphText(para.ParagraphNode)
};

foreach (var p in paraWithText)


Console.WriteLine("StyleName:{0} >{1}<", p.StyleName, p.Text);
}
}

Bu örnek, yeniden düzenlemeden önceki ile aynı çıktıyı üretir:

StyleName:Heading1 >Parsing WordprocessingML with LINQ to XML<


StyleName:Normal ><
StyleName:Normal >The following example prints to the console.<
StyleName:Normal ><
StyleName:Code >using System;<
StyleName:Code ><
StyleName:Code >class Program {<
StyleName:Code > public static void (string[] args) {<
StyleName:Code > Console.WriteLine("Hello World");<
StyleName:Code > }<
StyleName:Code >}<
StyleName:Normal ><
StyleName:Normal >This example produces the following output:<
StyleName:Normal ><
StyleName:Code >Hello World<

Sonraki Adımlar
Sonraki örnekte, XML 'in farklı bir şekle nasıl proje yapılacağı gösterilmektedir:
XML 'yi farklı bir şekilde yansıtma (C#)

Ayrıca bkz.
Öğretici: WordprocessingML belgesinde (C#) içeriği düzenleme
Bir genişletme yöntemi (C#) kullanılarak yeniden düzenleme
Saf IŞLEVLERE yeniden düzenleme (C#)
XML 'yi farklı bir şekilde yansıtma (C#)
23.10.2019 • 4 minutes to read • Edit Online

Bu konuda, kaynak XML 'den farklı bir şekilde XML yansıtma örneği gösterilmektedir.
Birçok tipik XML dönüştürmesi, bu örnekte olduğu gibi zincirleme sorgulardan oluşur. Bir dizi XML, proje ara
sonuçları anonim türlerin veya adlandırılmış türlerin koleksiyonları olarak, son olarak da sonuçları kaynak XML
'den tamamen farklı bir şekilde yeniden XML 'ye proje ile başlatmak için yaygındır.

Örnek
Bu örnek, WordprocessingML belgesinden paragraf düğümlerini alarak bir WordprocessingML belgesini işler.
Ayrıca, her bir paragrafın stilini ve metnini tanımlar. Son olarak, örnek proje XML 'SI farklı bir şekil ile. Bu örnekte,
bu öğreticideki önceki örneklerde derleme yapılır. Yansıtmayı yapan yeni ifadeye aşağıdaki koddaki açıklamalarda
bir tanesi çağırılır.
Bu örnek için kaynak belge oluşturmaya ilişkin yönergeler için bkz. kaynak Office Open XML belgesi (C#)
oluşturma.
Bu örnek, WindowsBase derlemesinden sınıfları kullanır. System.IO.Packaging Ad alanındaki türleri kullanır.

public static class LocalExtensions


{
public static string StringConcatenate(this IEnumerable<string> source)
{
StringBuilder sb = new StringBuilder();
foreach (string s in source)
sb.Append(s);
return sb.ToString();
}

public static string StringConcatenate<T>(this IEnumerable<T> source,


Func<T, string> func)
{
StringBuilder sb = new StringBuilder();
foreach (T item in source)
sb.Append(func(item));
return sb.ToString();
}

public static string StringConcatenate(this IEnumerable<string> source, string separator)


{
StringBuilder sb = new StringBuilder();
foreach (string s in source)
sb.Append(s).Append(separator);
return sb.ToString();
}

public static string StringConcatenate<T>(this IEnumerable<T> source,


Func<T, string> func, string separator)
{
StringBuilder sb = new StringBuilder();
foreach (T item in source)
sb.Append(func(item)).Append(separator);
return sb.ToString();
}
}

class Program
{
public static string ParagraphText(XElement e)
{
XNamespace w = e.Name.Namespace;
return e
.Elements(w + "r")
.Elements(w + "t")
.StringConcatenate(element => (string)element);
}

static void Main(string[] args)


{
const string fileName = "SampleDoc.docx";

const string documentRelationshipType =


"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
const string stylesRelationshipType =
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
const string wordmlNamespace =
"http://schemas.openxmlformats.org/wordprocessingml/2006/main";
XNamespace w = wordmlNamespace;

XDocument xDoc = null;


XDocument styleDoc = null;

using (Package wdPackage = Package.Open(fileName, FileMode.Open, FileAccess.Read))


{
PackageRelationship docPackageRelationship =
wdPackage.GetRelationshipsByType(documentRelationshipType).FirstOrDefault();
if (docPackageRelationship != null)
{
Uri documentUri = PackUriHelper.ResolvePartUri(new Uri("/", UriKind.Relative),
docPackageRelationship.TargetUri);
PackagePart documentPart = wdPackage.GetPart(documentUri);

// Load the document XML in the part into an XDocument instance.


xDoc = XDocument.Load(XmlReader.Create(documentPart.GetStream()));

// Find the styles part. There will only be one.


PackageRelationship styleRelation =
documentPart.GetRelationshipsByType(stylesRelationshipType).FirstOrDefault();
if (styleRelation != null)
{
Uri styleUri =
PackUriHelper.ResolvePartUri(documentUri, styleRelation.TargetUri);
PackagePart stylePart = wdPackage.GetPart(styleUri);

// Load the style XML in the part into an XDocument instance.


styleDoc = XDocument.Load(XmlReader.Create(stylePart.GetStream()));
}
}
}

string defaultStyle =
(string)(
from style in styleDoc.Root.Elements(w + "style")
where (string)style.Attribute(w + "type") == "paragraph" &&
(string)style.Attribute(w + "default") == "1"
select style
).First().Attribute(w + "styleId");

// Find all paragraphs in the document.


var paragraphs =
from para in xDoc
.Root
.Element(w + "body")
.Descendants(w + "p")
let styleNode = para
.Elements(w + "pPr")
.Elements(w + "pStyle")
.FirstOrDefault()
select new
{
ParagraphNode = para,
StyleName = styleNode != null ?
(string)styleNode.Attribute(w + "val") :
defaultStyle
};

// Retrieve the text of each paragraph.


var paraWithText =
from para in paragraphs
select new
{
ParagraphNode = para.ParagraphNode,
StyleName = para.StyleName,
Text = ParagraphText(para.ParagraphNode)
};

// The following is the new code that projects XML in a new shape.
XElement root = new XElement("Root",
from p in paraWithText
select new XElement("Paragraph",
new XElement("StyleName", p.StyleName),
new XElement("Text", p.Text)
)
);

Console.WriteLine(root);
}
}

Bu örnek aşağıdaki çıktıyı üretir:


<Root>
<Paragraph>
<StyleName>Heading1</StyleName>
<Text>Parsing WordprocessingML with LINQ to XML</Text>
</Paragraph>
<Paragraph>
<StyleName>Normal</StyleName>
<Text></Text>
</Paragraph>
<Paragraph>
<StyleName>Normal</StyleName>
<Text>The following example prints to the console.</Text>
</Paragraph>
<Paragraph>
<StyleName>Normal</StyleName>
<Text></Text>
</Paragraph>
<Paragraph>
<StyleName>Code</StyleName>
<Text>using System;</Text>
</Paragraph>
<Paragraph>
<StyleName>Code</StyleName>
<Text></Text>
</Paragraph>
<Paragraph>
<StyleName>Code</StyleName>
<Text>class Program {</Text>
</Paragraph>
<Paragraph>
<StyleName>Code</StyleName>
<Text> public static void (string[] args) {</Text>
</Paragraph>
<Paragraph>
<StyleName>Code</StyleName>
<Text> Console.WriteLine("Hello World");</Text>
</Paragraph>
<Paragraph>
<StyleName>Code</StyleName>
<Text> }</Text>
</Paragraph>
<Paragraph>
<StyleName>Code</StyleName>
<Text>}</Text>
</Paragraph>
<Paragraph>
<StyleName>Normal</StyleName>
<Text></Text>
</Paragraph>
<Paragraph>
<StyleName>Normal</StyleName>
<Text>This example produces the following output:</Text>
</Paragraph>
<Paragraph>
<StyleName>Normal</StyleName>
<Text></Text>
</Paragraph>
<Paragraph>
<StyleName>Code</StyleName>
<Text>Hello World</Text>
</Paragraph>
</Root>

Sonraki Adımlar
Sonraki örnekte, bir Word belgesinde tüm metni bulmak için sorgulama yapacaksınız:
Word belgelerinde metin bulma (C#)
Word belgelerinde metin bulma (C#)
23.10.2019 • 6 minutes to read • Edit Online

Bu konu, bir şeyi yararlı yapmak için önceki sorguları genişletir: belgede bir dizenin tüm yinelemelerini bulur.

Örnek
Bu örnek, belgedeki belirli bir metin parçasının tüm oluşumlarını bulmak için bir WordprocessingML belgesini işler.
Bunu yapmak için "Merhaba" dizesini bulan bir sorgu kullanıyoruz. Bu örnekte, bu öğreticideki önceki örneklerde
derleme yapılır. Yeni sorgu, aşağıdaki koddaki açıklamalarda çağrılır.
Bu örnek için kaynak belge oluşturmaya ilişkin yönergeler için bkz. kaynak Office Open XML belgesi (C#)
oluşturma.
Bu örnek, WindowsBase derlemesinde bulunan sınıfları kullanır. System.IO.Packaging Ad alanındaki türleri kullanır.

public static class LocalExtensions


{
public static string StringConcatenate(this IEnumerable<string> source)
{
StringBuilder sb = new StringBuilder();
foreach (string s in source)
sb.Append(s);
return sb.ToString();
}

public static string StringConcatenate<T>(this IEnumerable<T> source,


Func<T, string> func)
{
StringBuilder sb = new StringBuilder();
foreach (T item in source)
sb.Append(func(item));
return sb.ToString();
}

public static string StringConcatenate(this IEnumerable<string> source, string separator)


{
StringBuilder sb = new StringBuilder();
foreach (string s in source)
sb.Append(s).Append(separator);
return sb.ToString();
}

public static string StringConcatenate<T>(this IEnumerable<T> source,


Func<T, string> func, string separator)
{
StringBuilder sb = new StringBuilder();
foreach (T item in source)
sb.Append(func(item)).Append(separator);
return sb.ToString();
}
}

class Program
{
public static string ParagraphText(XElement e)
{
XNamespace w = e.Name.Namespace;
return e
.Elements(w + "r")
.Elements(w + "t")
.StringConcatenate(element => (string)element);
}

static void Main(string[] args)


{
const string fileName = "SampleDoc.docx";

const string documentRelationshipType =


"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
const string stylesRelationshipType =
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
const string wordmlNamespace =
"http://schemas.openxmlformats.org/wordprocessingml/2006/main";
XNamespace w = wordmlNamespace;

XDocument xDoc = null;


XDocument styleDoc = null;

using (Package wdPackage = Package.Open(fileName, FileMode.Open, FileAccess.Read))


{
PackageRelationship docPackageRelationship =
wdPackage.GetRelationshipsByType(documentRelationshipType).FirstOrDefault();
if (docPackageRelationship != null)
{
Uri documentUri = PackUriHelper.ResolvePartUri(new Uri("/", UriKind.Relative),
docPackageRelationship.TargetUri);
PackagePart documentPart = wdPackage.GetPart(documentUri);

// Load the document XML in the part into an XDocument instance.


xDoc = XDocument.Load(XmlReader.Create(documentPart.GetStream()));

// Find the styles part. There will only be one.


PackageRelationship styleRelation =
documentPart.GetRelationshipsByType(stylesRelationshipType).FirstOrDefault();
if (styleRelation != null)
{
Uri styleUri =
PackUriHelper.ResolvePartUri(documentUri, styleRelation.TargetUri);
PackagePart stylePart = wdPackage.GetPart(styleUri);

// Load the style XML in the part into an XDocument instance.


styleDoc = XDocument.Load(XmlReader.Create(stylePart.GetStream()));
}
}
}

string defaultStyle =
(string)(
from style in styleDoc.Root.Elements(w + "style")
where (string)style.Attribute(w + "type") == "paragraph" &&
(string)style.Attribute(w + "default") == "1"
select style
).First().Attribute(w + "styleId");

// Find all paragraphs in the document.


var paragraphs =
from para in xDoc
.Root
.Element(w + "body")
.Descendants(w + "p")
let styleNode = para
.Elements(w + "pPr")
.Elements(w + "pStyle")
.FirstOrDefault()
select new
{
ParagraphNode = para,
StyleName = styleNode != null ?
(string)styleNode.Attribute(w + "val") :
defaultStyle
};

// Retrieve the text of each paragraph.


var paraWithText =
from para in paragraphs
select new
{
ParagraphNode = para.ParagraphNode,
StyleName = para.StyleName,
Text = ParagraphText(para.ParagraphNode)
};

// Following is the new query that retrieves all paragraphs


// that have specific text in them.
var helloParagraphs =
from para in paraWithText
where para.Text.Contains("Hello")
select new
{
ParagraphNode = para.ParagraphNode,
StyleName = para.StyleName,
Text = para.Text
};

foreach (var p in helloParagraphs)


Console.WriteLine("StyleName:{0} >{1}<", p.StyleName, p.Text);
}
}

Bu örnek aşağıdaki çıktıyı üretir:

StyleName:Code > Console.WriteLine("Hello World");<


StyleName:Code >Hello World<

Tabii ki, belirli bir stille satırları arayacak şekilde aramayı değiştirebilirsiniz. Aşağıdaki sorgu, kod stiline sahip olan
tüm boş satırları bulur:

public static class LocalExtensions


{
public static string StringConcatenate(this IEnumerable<string> source)
{
StringBuilder sb = new StringBuilder();
foreach (string s in source)
sb.Append(s);
return sb.ToString();
}

public static string StringConcatenate<T>(this IEnumerable<T> source,


Func<T, string> func)
{
StringBuilder sb = new StringBuilder();
foreach (T item in source)
sb.Append(func(item));
return sb.ToString();
}

public static string StringConcatenate(this IEnumerable<string> source, string separator)


{
StringBuilder sb = new StringBuilder();
foreach (string s in source)
sb.Append(s).Append(separator);
return sb.ToString();
}
public static string StringConcatenate<T>(this IEnumerable<T> source,
Func<T, string> func, string separator)
{
StringBuilder sb = new StringBuilder();
foreach (T item in source)
sb.Append(func(item)).Append(separator);
return sb.ToString();
}
}

class Program
{
public static string ParagraphText(XElement e)
{
XNamespace w = e.Name.Namespace;
return e
.Elements(w + "r")
.Elements(w + "t")
.StringConcatenate(element => (string)element);
}

static void Main(string[] args)


{
const string fileName = "SampleDoc.docx";

const string documentRelationshipType =


"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
const string stylesRelationshipType =
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
const string wordmlNamespace = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
XNamespace w = wordmlNamespace;

XDocument xDoc = null;


XDocument styleDoc = null;

using (Package wdPackage = Package.Open(fileName, FileMode.Open, FileAccess.Read))


{
PackageRelationship docPackageRelationship =
wdPackage.GetRelationshipsByType(documentRelationshipType).FirstOrDefault();
if (docPackageRelationship != null)
{
Uri documentUri = PackUriHelper.ResolvePartUri(new Uri("/", UriKind.Relative),
docPackageRelationship.TargetUri);
PackagePart documentPart = wdPackage.GetPart(documentUri);

// Load the document XML in the part into an XDocument instance.


xDoc = XDocument.Load(XmlReader.Create(documentPart.GetStream()));

// Find the styles part. There will only be one.


PackageRelationship styleRelation =
documentPart.GetRelationshipsByType(stylesRelationshipType).FirstOrDefault();
if (styleRelation != null)
{
Uri styleUri = PackUriHelper.ResolvePartUri(documentUri, styleRelation.TargetUri);
PackagePart stylePart = wdPackage.GetPart(styleUri);

// Load the style XML in the part into an XDocument instance.


styleDoc = XDocument.Load(XmlReader.Create(stylePart.GetStream()));
}
}
}

string defaultStyle =
(string)(
from style in styleDoc.Root.Elements(w + "style")
where (string)style.Attribute(w + "type") == "paragraph" &&
(string)style.Attribute(w + "default") == "1"
select style
select style
).First().Attribute(w + "styleId");

// Find all paragraphs in the document.


var paragraphs =
from para in xDoc
.Root
.Element(w + "body")
.Descendants(w + "p")
let styleNode = para
.Elements(w + "pPr")
.Elements(w + "pStyle")
.FirstOrDefault()
select new
{
ParagraphNode = para,
StyleName = styleNode != null ?
(string)styleNode.Attribute(w + "val") :
defaultStyle
};

// Retrieve the text of each paragraph.


var paraWithText =
from para in paragraphs
select new
{
ParagraphNode = para.ParagraphNode,
StyleName = para.StyleName,
Text = ParagraphText(para.ParagraphNode)
};

// Retrieve all paragraphs that have no text and are styled Code.
var blankCodeParagraphs =
from para in paraWithText
where para.Text == "" && para.StyleName == "Code"
select new
{
ParagraphNode = para.ParagraphNode,
StyleName = para.StyleName,
Text = para.Text
};

foreach (var p in blankCodeParagraphs)


Console.WriteLine("StyleName:{0} >{1}<", p.StyleName, p.Text);
}
}

Bu örnek aşağıdaki çıktıyı üretir:

StyleName:Code ><

Tabii ki bu örnek çeşitli yollarla iyileştirilen olabilir. Örneğin, normal ifadeleri metin aramak için kullanabiliriz, belirli
bir dizindeki tüm Word dosyaları üzerinde yineliyoruz ve bu şekilde devam ediyoruz.
Bu örneğin, tek bir sorgu olarak yazılıp yazılmadığını ve bunun yaklaşık olarak gerçekleştiğini unutmayın. Her
sorgu geç, ertelenmiş bir biçimde uygulandığından, sorgu yinelenene kadar her sorgu kendi sonuçlarını vermez.
Yürütme ve yavaş değerlendirme hakkında daha fazla bilgi için bkz. C#LINQ to XML () içinde ertelenmiş yürütme
ve geç değerlendirme.

Sonraki Adımlar
Sonraki bölümde WordprocessingML belgeleri hakkında daha fazla bilgi verilmektedir:
Office Open XML WordprocessingML belgelerinin (C#) ayrıntıları
Ayrıca bkz.
Öğretici: WordprocessingML belgesinde (C#) içeriği düzenleme
Saf Işlev kullanarak yeniden düzenleme (C#)
LINQ to XML (C#) Içinde ertelenmiş yürütme ve geç değerlendirme
Stillerle WordprocessingML Belgesi
23.10.2019 • 3 minutes to read • Edit Online

Daha karmaşık WordprocessingML belgelerinin stillerle biçimlendirilen paragrafları vardır.


WordprocessingML belgelerinin organizasyonel ile ilgili birkaç not yararlı olur. WordprocessingML belgeleri
paketlere depolanır. Paketler birden çok parçaya sahiptir (parçalar, paketler bağlamında kullanıldığında belirgin bir
anlama sahiptir; temelde, parçalar bir paketi oluşturacak şekilde daraltılmış dosyalardır). Bir belge stillerle
biçimlendirilen paragraflar içeriyorsa, bu stillerin uygulanmış olduğu paragrafları içeren bir belge bölümü olur.
Ayrıca, belge tarafından başvurulan stilleri içeren bir stil bölümü de olacaktır.
Paketlere erişirken, bu işlemi, rastgele bir yol kullanmak yerine parçalar arasındaki ilişkilerle yapmanız önemlidir.
Bu sorun, WordprocessingML belge öğreticisindeki Içerik Işleme kapsamının ötesinde, ancak bu öğreticide yer
alan örnek programlar doğru yaklaşımı gösterir.

Stilleri kullanan bir belge


WordprocessingML belgeleriC#() konusunun şeklinde sunulan WordML örneği çok basit bir işlemdir. Aşağıdaki
belge daha karmaşıktır: Stillerle biçimlendirilen paragraflar içerir. Bir Office Open XML belgesi oluşturan XML 'yi
görmenin en kolay yolu, Office Open XML belge bölümlerinin (C#) çıkışı olan örneğiçalıştırmanız.
Aşağıdaki belgede, ilk paragraf stile Heading1 sahiptir. Varsayılan stili olan bir dizi paragraf vardır. Ayrıca, stili Code
olan bir dizi paragraf de vardır. Bu göreli karmaşıklık nedeniyle, LINQ to XML ayrıştırılmaya yönelik daha ilgi çekici
bir belgedir.
Varsayılan olmayan stillerdeki bu paragraflarda, paragraf öğelerinin adlı w:pPr bir alt öğesi vardır ve bu, sırasıyla
bir alt öğesi w:pStyle vardır. Bu öğenin, stil adını içeren w:val bir özniteliği vardır. Paragrafta varsayılan stil varsa,
paragraf öğesinin bir w:p.Pr alt öğesi olmadığı anlamına gelir.

<?xml version="1.0" encoding="utf-8"?>


<w:document
xmlns:ve="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math"
xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"
xmlns:w10="urn:schemas-microsoft-com:office:word"
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml">
<w:body>
<w:p w:rsidR="00A75AE0" w:rsidRDefault="00A75AE0" w:rsidP="006027C7">
<w:pPr>
<w:pStyle w:val="Heading1" />
</w:pPr>
<w:r>
<w:t>Parsing WordprocessingML with LINQ to XML</w:t>
</w:r>
</w:p>
<w:p w:rsidR="00A75AE0" w:rsidRDefault="00A75AE0" />
<w:p w:rsidR="00A75AE0" w:rsidRDefault="00A75AE0">
<w:r>
<w:t>The following example prints to the console.</w:t>
</w:r>
</w:p>
<w:p w:rsidR="00A75AE0" w:rsidRDefault="00A75AE0" />
<w:p w:rsidR="00A75AE0" w:rsidRDefault="00A75AE0" w:rsidP="006027C7">
<w:pPr>
<w:pStyle w:val="Code" />
</w:pPr>
<w:r>
<w:t>using System;</w:t>
</w:r>
</w:p>
<w:p w:rsidR="00A75AE0" w:rsidRDefault="00A75AE0" w:rsidP="006027C7">
<w:pPr>
<w:pStyle w:val="Code" />
</w:pPr>
</w:p>
<w:p w:rsidR="00A75AE0" w:rsidRPr="00876F34" w:rsidRDefault="00A75AE0" w:rsidP="006027C7">
<w:pPr>
<w:pStyle w:val="Code" />
</w:pPr>
<w:r w:rsidRPr="00876F34">
<w:t>class Program {</w:t>
</w:r>
</w:p>
<w:p w:rsidR="00A75AE0" w:rsidRPr="00876F34" w:rsidRDefault="00A75AE0" w:rsidP="006027C7">
<w:pPr>
<w:pStyle w:val="Code" />
</w:pPr>
<w:r w:rsidRPr="00876F34">
<w:t xml:space="preserve"> public static void </w:t>
</w:r>
<w:smartTag w:uri="urn:schemas-microsoft-com:office:smarttags" w:element="place">
<w:r w:rsidRPr="00876F34">
<w:t>Main</w:t>
</w:r>
</w:smartTag>
<w:r w:rsidRPr="00876F34">
<w:t>(string[] args) {</w:t>
</w:r>
</w:p>
<w:p w:rsidR="00A75AE0" w:rsidRPr="00876F34" w:rsidRDefault="00A75AE0" w:rsidP="006027C7">
<w:pPr>
<w:pStyle w:val="Code" />
</w:pPr>
<w:r w:rsidRPr="00876F34">
<w:t xml:space="preserve"> Console.WriteLine("Hello World");</w:t>
</w:r>
</w:p>
<w:p w:rsidR="00A75AE0" w:rsidRPr="00876F34" w:rsidRDefault="00A75AE0" w:rsidP="006027C7">
<w:pPr>
<w:pStyle w:val="Code" />
</w:pPr>
<w:r w:rsidRPr="00876F34">
<w:t xml:space="preserve"> }</w:t>
</w:r>
</w:p>
<w:p w:rsidR="00A75AE0" w:rsidRPr="00876F34" w:rsidRDefault="00A75AE0" w:rsidP="006027C7">
<w:pPr>
<w:pStyle w:val="Code" />
</w:pPr>
<w:r w:rsidRPr="00876F34">
<w:t>}</w:t>
</w:r>
</w:p>
<w:p w:rsidR="00A75AE0" w:rsidRDefault="00A75AE0" />
<w:p w:rsidR="00A75AE0" w:rsidRDefault="00A75AE0">
<w:r>
<w:t>This example produces the following output:</w:t>
</w:r>
</w:p>
<w:p w:rsidR="00A75AE0" w:rsidRDefault="00A75AE0" />
<w:p w:rsidR="00A75AE0" w:rsidRDefault="00A75AE0" w:rsidP="006027C7">
<w:pPr>
<w:pPr>
<w:pStyle w:val="Code" />
</w:pPr>
<w:r>
<w:t>Hello World</w:t>
</w:r>
</w:p>
<w:sectPr w:rsidR="00A75AE0" w:rsidSect="00A75AE0">
<w:pgSz w:w="12240" w:h="15840" />
<w:pgMar w:top="1440" w:right="1800" w:bottom="1440" w:left="1800" w:header="720" w:footer="720"
w:gutter="0" />
<w:cols w:space="720" />
<w:docGrid w:linePitch="360" />
</w:sectPr>
</w:body>
</w:document>
WordprocessingML Belgesinin Stil Kısmı
23.10.2019 • 2 minutes to read • Edit Online

Bu konuda, Office Open XML WordprocessingML belgesinin stil bölümünün bir örneği gösterilmektedir.

Örnek
Aşağıdaki örnek, bir Office Open XML WordprocessingML belgesinin stil parçasını oluşturan XML 'dir.
Varsayılan paragraf stilinin aşağıdaki açılış etiketiyle bir öğesi vardır:

<w:style w:type="paragraph" w:default="1" w:styleId="Normal">

Varsayılan stil tanımlayıcısını bulmak için sorguyu yazarken bu bilgileri bilmeniz gerekir, böylece sorgu varsayılan
stile sahip olan paragrafların stilini tanımlayabilir.
Bu belgelerin, Microsoft Word 'ün oluşturduğu tipik belgelerle karşılaştırıldığında çok basit olduğunu unutmayın.
Birçok durumda, Word ek bilgiler, ek biçimlendirme ve meta veriler için harika bir işlem kaydeder.Ayrıca, Word bu
örnekteki gibi kolayca okunabilecek satırları biçimlendirmez; Bunun yerine, XML girintileme olmadan kaydedilir.
Ancak, tüm WordprocessingML belgeleri aynı temel XML şeklini paylaşır. Bu nedenle, bu öğreticide sunulan
sorgular daha karmaşık belgelerle birlikte çalışacaktır.

<?xml version="1.0" encoding="utf-8"?>


<w:styles
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:docDefaults>
<w:rPrDefault>
<w:rPr>
<w:rFonts
w:ascii="Times New Roman"
w:eastAsia="Times New Roman"
w:hAnsi="Times New Roman"
w:cs="Times New Roman" />
<w:sz w:val="22" />
<w:szCs w:val="22" />
<w:lang w:val="en-US" w:eastAsia="en-US" w:bidi="ar-SA" />
</w:rPr>
</w:rPrDefault>
<w:pPrDefault />
</w:docDefaults>
<w:style w:type="paragraph" w:default="1" w:styleId="Normal">
<w:name w:val="Normal" />
<w:qFormat />
<w:rPr>
<w:sz w:val="24" />
<w:szCs w:val="24" />
</w:rPr>
</w:style>
<w:style w:type="paragraph" w:styleId="Heading1">
<w:name w:val="heading 1" />
<w:basedOn w:val="Normal" />
<w:next w:val="Normal" />
<w:link w:val="Heading1Char" />
<w:uiPriority w:val="99" />
<w:qFormat />
<w:rsid w:val="006027C7" />
<w:pPr>
<w:pPr>
<w:keepNext />
<w:spacing w:before="240" w:after="60" />
<w:outlineLvl w:val="0" />
</w:pPr>
<w:rPr>
<w:rFonts w:ascii="Arial" w:hAnsi="Arial" w:cs="Arial" />
<w:b />
<w:bCs />
<w:kern w:val="32" />
<w:sz w:val="32" />
<w:szCs w:val="32" />
</w:rPr>
</w:style>
<w:style w:type="character" w:default="1" w:styleId="DefaultParagraphFont">
<w:name w:val="Default Paragraph Font" />
<w:uiPriority w:val="99" />
<w:semiHidden />
</w:style>
<w:style w:type="table" w:default="1" w:styleId="TableNormal">
<w:name w:val="Normal Table" />
<w:uiPriority w:val="99" />
<w:semiHidden />
<w:unhideWhenUsed />
<w:qFormat />
<w:tblPr>
<w:tblInd w:w="0" w:type="dxa" />
<w:tblCellMar>
<w:top w:w="0" w:type="dxa" />
<w:left w:w="108" w:type="dxa" />
<w:bottom w:w="0" w:type="dxa" />
<w:right w:w="108" w:type="dxa" />
</w:tblCellMar>
</w:tblPr>
</w:style>
<w:style w:type="numbering" w:default="1" w:styleId="NoList">
<w:name w:val="No List" />
<w:uiPriority w:val="99" />
<w:semiHidden />
<w:unhideWhenUsed />
</w:style>
<w:style w:type="character" w:customStyle="1" w:styleId="Heading1Char">
<w:name w:val="Heading 1 Char" />
<w:basedOn w:val="DefaultParagraphFont" />
<w:link w:val="Heading1" />
<w:uiPriority w:val="9" />
<w:rsid w:val="009765E3" />
<w:rPr>
<w:rFonts
w:asciiTheme="majorHAnsi"
w:eastAsiaTheme="majorEastAsia"
w:hAnsiTheme="majorHAnsi"
w:cstheme="majorBidi" />
<w:b />
<w:bCs />
<w:kern w:val="32" />
<w:sz w:val="32" />
<w:szCs w:val="32" />
</w:rPr>
</w:style>
<w:style w:type="paragraph" w:customStyle="1" w:styleId="Code">
<w:name w:val="Code" />
<w:aliases w:val="c" />
<w:uiPriority w:val="99" />
<w:rsid w:val="006027C7" />
<w:pPr>
<w:spacing w:after="60" w:line="300" w:lineRule="exact" />
</w:pPr>
<w:rPr>
<w:rFonts w:ascii="Courier New" w:hAnsi="Courier New" />
<w:rFonts w:ascii="Courier New" w:hAnsi="Courier New" />
<w:noProof />
<w:color w:val="000080" />
<w:sz w:val="20" />
<w:szCs w:val="20" />
</w:rPr>
</w:style>
</w:styles>
Office Open XML belge kısımları (C#) çıkaran örnek
23.10.2019 • 2 minutes to read • Edit Online

Bu konuda, bir Office Open XML belgesi açın ve erişim bölümleri içindeki gösterilmektedir.

Örnek
Aşağıdaki örnek, bir Office Open XML belge açılır ve belge ve stil bölümlerini konsola yazdırır.
Bu örnek WindowsBase derlemesinden sınıfları kullanır. Türleri kullanan System.IO.Packaging ad alanı.

const string fileName = "SampleDoc.docx";

const string documentRelationshipType =


"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
const string stylesRelationshipType =
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
const string wordmlNamespace =
"http://schemas.openxmlformats.org/wordprocessingml/2006/main";
XNamespace w = wordmlNamespace;

using (Package wdPackage = Package.Open(fileName, FileMode.Open, FileAccess.Read))


{
PackageRelationship docPackageRelationship =
wdPackage.GetRelationshipsByType(documentRelationshipType).FirstOrDefault();
if (docPackageRelationship != null)
{
Uri documentUri = PackUriHelper.ResolvePartUri(new Uri("/", UriKind.Relative),
docPackageRelationship.TargetUri);
PackagePart documentPart = wdPackage.GetPart(documentUri);

// Load the document XML in the part into an XDocument instance.


XDocument xdoc = XDocument.Load(XmlReader.Create(documentPart.GetStream()));

Console.WriteLine("TargetUri:{0}", docPackageRelationship.TargetUri);
Console.WriteLine("==================================================================");
Console.WriteLine(xdoc.Root);
Console.WriteLine();

// Find the styles part. There will only be one.


PackageRelationship styleRelation =
documentPart.GetRelationshipsByType(stylesRelationshipType).FirstOrDefault();
if (styleRelation != null)
{
Uri styleUri = PackUriHelper.ResolvePartUri(documentUri, styleRelation.TargetUri);
PackagePart stylePart = wdPackage.GetPart(styleUri);

// Load the style XML in the part into an XDocument instance.


XDocument styleDoc = XDocument.Load(XmlReader.Create(stylePart.GetStream()));

Console.WriteLine("TargetUri:{0}", styleRelation.TargetUri);
Console.WriteLine("==================================================================");
Console.WriteLine(styleDoc.Root);
Console.WriteLine();
}
}
}
Bellek içi XML Ağacı Değişikliği ve İşlevsel oluşturma
(LINQ to XML) (C#)
23.10.2019 • 6 minutes to read • Edit Online

Bir XML ağacı yerde değiştirme, bir XML belgesi şeklini değiştirmek için geleneksel bir yaklaşımdır. Tipik bir
uygulama bir belge DOM gibi bir veri deposuna yükler ya da LINQ - XML; düğümleri eklediğinizde, düğümleri
silin veya düğümler; içeriğini değiştirmek için bir programlama arabirimi kullanır ve ardından XML bir dosyaya
kaydeder veya bir ağ üzerinden iletir.
LINQ - XML pek çok senaryoda kullanışlıdır başka bir yaklaşım sağlar: işlevsel oluşturma. İşlevsel oluşturma,
değiştirme veri dönüşümünün bir sorun, yerine ayrıntılı işleme bir veri deposu olarak değerlendirir. Bir veri
temsilini alın ve verimli bir şekilde bir formdan başka bir dönüştürme, bir veri deposu sürdü ve başka bir şekil
gerçekleştirilecek şekilde yönetilebilir gibi sonuç aynıdır. İşlevsel oluşturma yaklaşımını anahtarı için sorguların
sonuçlarını geçirmektir XDocument ve XElement oluşturucular.
Çoğu durumda veri deposu işlemek için harcadığım süreyi kesir dönüşümsel kodu yazabilirsiniz ve bu kodu daha
sağlam ve bakımı kolay. Daha fazla işlemci gücü, dönüşümsel yaklaşım sürebilir olsa bile bu gibi durumlarda, bu
verileri değiştirmek için bir daha etkili yoludur. Bir geliştirici işlevsel yaklaşım ile ilgili bilgi sahibi ise, çoğu
durumda Sonuç kodu anlamak daha kolay olur. Her ağacın parçası değiştiren bir kodun bulmak daha kolaydır.
İşlevsel yaklaşım kullanılarak yazılmış kod henüz bu yaklaşımı anlamıyor bir geliştirici için tanıdık gelmiyor ancak
burada bir XML ağacı yerinde değişiklik birçok DOM programcıları için daha tanıdık bir yaklaşımdır. Yalnızca
büyük bir XML ağacı için küçük bir değişiklik yapmak varsa, burada, çoğu durumda bir yerde bir ağaç değişiklik
yaklaşım daha az CPU zaman alabilir.
Bu konu, her iki yaklaşım ile uygulanan bir örnek sağlar.

Öğelerine dönüştürme öznitelikleri


Bu örnekte, böylece öznitelikleri öğelerine haline gelir. aşağıdaki basit XML belgesi değiştirmek istediğiniz
varsayalım. Bu konuda, ilk yerinde değişikliği geleneksel yaklaşım sunulmaktadır. Ardından, bir işlev oluşturma
yaklaşımı da gösterir.

<?xml version="1.0" encoding="utf-8" ?>


<Root Data1="123" Data2="456">
<Child1>Content</Child1>
</Root>

XML ağacı değiştirme


Öznitelikleri öğeleri oluşturmak için yordam kod yazma ve öznitelikleri gibi silin:

XElement root = XElement.Load("Data.xml");


foreach (XAttribute att in root.Attributes()) {
root.Add(new XElement(att.Name, (string)att));
}
root.Attributes().Remove();
Console.WriteLine(root);

Bu kod aşağıdaki çıktıyı üretir:


<Root>
<Child1>Content</Child1>
<Data1>123</Data1>
<Data2>456</Data2>
</Root>

İşlevsel oluşturma yaklaşımı


Bunun aksine, işlevsel bir yaklaşım çekme ve öğeler ve öznitelikler kaynak ağacından seçme ve bunları yeni
ağacına eklendikçe uygun şekilde dönüştürme yeni bir ağaç oluşturmak için kod oluşur. İşlevsel yaklaşım
aşağıdaki gibi görünür:

XElement root = XElement.Load("Data.xml");


XElement newTree = new XElement("Root",
root.Element("Child1"),
from att in root.Attributes()
select new XElement(att.Name, (string)att)
);
Console.WriteLine(newTree);

Bu örnekte, ilk örnekle aynı XML çıkarır. Ancak, elde edilen işlevsel yaklaşım yeni XML yapısını gerçekten
görebilirsiniz dikkat edin. Oluşturulmasını gördüğünüz Root öğesinde, kodu çeker Child1 kaynak ağacının ve
kaynak ağacının öznitelikleri öğelere yeni ağacında dönüştüren kod öğesi.
İşlevsel örneği bu durumda ilk örnek kısa herhangi değil ve gerçekten daha kolay değildir. Ancak, bir XML ağacına
yapmak için birçok değişiklik varsa, işlev olmayan bir yaklaşım oldukça karmaşık ve biraz geniş açılı olur. Buna
karşılık, işlevsel yaklaşım kullanırken, yalnızca form istenen XML, sorguları ve ifadeler, istenen içeriği çekmek
uygun olarak eklemeye devam. İşlevsel yaklaşım oluşturmanın kod üretir.
Bu durumda işlevsel yaklaşım büyük olasılıkla oldukça ağaç işleme yaklaşım yanı sıra gerçekleştirecek değil dikkat
edin. Ana sorunu işlevsel yaklaşım daha kısa süreli nesneleri oluşturmasıdır. Ancak işlevsel yaklaşım kullanarak
büyük Programcı verimliliği için izin veriyorsa etkili bir düşüş olur.
Bu çok basit bir örneği, ancak felsefesi iki yaklaşım arasındaki farkı göstermek için kullanılır. İşlevsel yaklaşım daha
büyük XML belgelerini dönüştürmek için büyük üretkenlik artışı sağlar.
(C#) XML ağacına öğe, öznitelik ve düğümleri ekleme
23.10.2019 • 2 minutes to read • Edit Online

Varolan bir XML ağacına içeriği (öğe, öznitelik, yorumlar, işleme yönergeleri, metin ve CDATA) ekleyebilirsiniz.

İçerik ekleme yöntemleri


Aşağıdaki yöntemler alt içeriğin bir XElement veya XDocument:

YÖNTEM AÇIKLAMA

Add İçeriği, içerik alt sonunda ekler XContainer.

AddFirst İçeriği, içerik alt başında ekler XContainer.

Aşağıdaki yöntemlerden içerik eşdüzey düğümleri olarak eklemek bir XNode. Eşdüzey içeriği için eklediğiniz en
yaygın düğüm XElement, geçerli eşdüzey içeriği gibi diğer düğümleri türlerine ekleyebilirsiniz ancak XText veya
XComment.

YÖNTEM AÇIKLAMA

AddAfterSelf Sonra içerik ekler XNode.

AddBeforeSelf Önce içeriği ekler XNode.

Örnek
Açıklama
Aşağıdaki örnek, iki XML ağaçlarını oluşturur ve bir ağaçları değiştirir.
Kod
XElement srcTree = new XElement("Root",
new XElement("Element1", 1),
new XElement("Element2", 2),
new XElement("Element3", 3),
new XElement("Element4", 4),
new XElement("Element5", 5)
);
XElement xmlTree = new XElement("Root",
new XElement("Child1", 1),
new XElement("Child2", 2),
new XElement("Child3", 3),
new XElement("Child4", 4),
new XElement("Child5", 5)
);
xmlTree.Add(new XElement("NewChild", "new content"));
xmlTree.Add(
from el in srcTree.Elements()
where (int)el > 3
select el
);
// Even though Child9 does not exist in srcTree, the following statement will not
// throw an exception, and nothing will be added to xmlTree.
xmlTree.Add(srcTree.Element("Child9"));
Console.WriteLine(xmlTree);

Açıklamalar
Bu kod aşağıdaki çıktıyı üretir:

<Root>
<Child1>1</Child1>
<Child2>2</Child2>
<Child3>3</Child3>
<Child4>4</Child4>
<Child5>5</Child5>
<NewChild>new content</NewChild>
<Element4>4</Element4>
<Element5>5</Element5>
</Root>
XML Ağacındaki Öğe, Öznitelik ve Düğümleri
Değiştirme
23.10.2019 • 2 minutes to read • Edit Online

Bir öğe, alt öğelerini ve özniteliklerini değiştirmek için kullanabileceğiniz özellikler ve yöntemler aşağıdaki tabloda
özetlenmiştir.
Aşağıdaki yöntemlerden değiştirme bir XElement.

YÖNTEM AÇIKLAMA

XElement.Parse Bir öğe ayrıştırılmış XML ile değiştirir.

XElement.RemoveAll Bir öğenin tüm içeriğin (alt düğümleri ve öznitelikleri) kaldırır.

XElement.RemoveAttributes Bir öğenin öznitelikleri kaldırır.

XElement.ReplaceAll Bir öğenin tüm içeriğin (alt düğümleri ve öznitelikleri) değiştirir.

XElement.ReplaceAttributes Bir öğenin öznitelikleri değiştirir.

XElement.SetAttributeValue Bir özniteliğin değerini ayarlar. Öznitelik yoksa oluşturur. Değer


ayarlanmışsa null , öznitelik kaldırır.

XElement.SetElementValue Bir alt öğenin değerini ayarlar. Öğe yoksa oluşturur. Değer
ayarlanmışsa null , öğeyi kaldırır.

XElement.Value Bir öğenin içeriğini (alt düğümleri) belirtilen metinle değiştirir.

XElement.SetValue Bir öğenin değerini ayarlar.

Aşağıdaki yöntemlerden değiştirme bir XAttribute.

YÖNTEM AÇIKLAMA

XAttribute.Value Bir özniteliğin değerini ayarlar.

XAttribute.SetValue Bir özniteliğin değerini ayarlar.

Aşağıdaki yöntemlerden değiştirme bir XNode (dahil olmak üzere bir XElement veya XDocument).

YÖNTEM AÇIKLAMA

XNode.ReplaceWith Bir düğüm, yeni içerikle değiştirir.

Aşağıdaki yöntemlerden değiştirme bir XContainer (bir XElement veya XDocument).


YÖNTEM AÇIKLAMA

XContainer.ReplaceNodes Alt düğüm, yeni içerikle değiştirir.


Öğeleri, öznitelikleri ve düğümleri bir XML ağacından
kaldırma (C#)
23.10.2019 • 2 minutes to read • Edit Online

Bir XML ağacını değiştirebilir, öğeleri, öznitelikleri ve diğer düğüm türlerini kaldırabilirsiniz.
Tek bir öğeyi veya bir XML belgesinden tek bir özniteliği kaldırmak basittir. Bununla birlikte, öğe veya öznitelik
koleksiyonları kaldırılırken, önce bir koleksiyonu bir liste halinde ve ardından listeden öğeleri veya öznitelikleri
silmelisiniz. En iyi yaklaşım, bunu sizin için Remove sağlayacak olan genişletme yöntemini kullanmaktır.
Bunu yapmanın asıl nedeni, bir XML ağacından aldığınız koleksiyonların çoğunun ertelenmiş yürütme kullanılarak
yapılır. İlk olarak bunları bir liste içine almayın veya uzantı yöntemlerini kullanmıyorsanız, belirli bir hata sınıfıyla
karşılaşmanız mümkündür. Daha fazla bilgi için bkz. karma bildirim kodu/zorunlu kod hataları (LINQ to XML )C#().
Aşağıdaki yöntemler bir XML ağacından düğümleri ve öznitelikleri kaldırır.

YÖNTEM AÇIKLAMA

XAttribute.Remove Bir XAttribute öğesini üst öğesinden kaldırır.

XContainer.RemoveNodes Alt düğümleri bir XContaineröğesinden kaldırır.

XElement.RemoveAll Öğesinden içerik ve öznitelikleri kaldırır XElement.

XElement.RemoveAttributes , Özniteliklerini XElementkaldırır.

XElement.SetAttributeValue Değerini geçirirseniz null , özniteliğini kaldırır.

XElement.SetElementValue Değer ' i null geçirirseniz, alt öğeyi kaldırır.

XNode.Remove Bir XNode öğesini üst öğesinden kaldırır.

Extensions.Remove Kaynak koleksiyondaki her özniteliği veya öğeyi üst öğesinden


kaldırır.

Örnek
Açıklama
Bu örnek, öğeleri kaldırmak için üç yaklaşımlar gösterir. İlk olarak, tek bir öğeyi kaldırır. İkincisi, bir öğe
koleksiyonunu alır, bunları Enumerable.ToList işlecini kullanarak bunları çıkarır ve koleksiyonu kaldırır. Son olarak,
bir öğe koleksiyonunu alır ve Remove genişletme yöntemini kullanarak onları kaldırır.
ToList İşleci hakkında daha fazla bilgi için bkz. veri türlerini dönüştürme (C#).
Kod
XElement root = XElement.Parse(@"<Root>
<Child1>
<GrandChild1/>
<GrandChild2/>
<GrandChild3/>
</Child1>
<Child2>
<GrandChild4/>
<GrandChild5/>
<GrandChild6/>
</Child2>
<Child3>
<GrandChild7/>
<GrandChild8/>
<GrandChild9/>
</Child3>
</Root>");
root.Element("Child1").Element("GrandChild1").Remove();
root.Element("Child2").Elements().ToList().Remove();
root.Element("Child3").Elements().Remove();
Console.WriteLine(root);

Açıklamalar
Bu kod aşağıdaki çıktıyı üretir:

<Root>
<Child1>
<GrandChild2 />
<GrandChild3 />
</Child1>
<Child2 />
<Child3 />
</Root>

İlk alt öğenin öğesinden Child1 çıkarıldığına dikkat edin. Tüm alt öğeler öğeleri öğesinden Child2 ve kaynağından
Child3 kaldırılmıştır.
Ad/değer çiftlerini koruma (C#)
23.10.2019 • 3 minutes to read • Edit Online

Birçok uygulamanın ad/değer çiftleri olarak en iyi şekilde tutulan bilgileri tutması gerekir. Bu bilgiler yapılandırma
bilgileri veya genel ayarlar olabilir. LINQ - XMLbir ad/değer çiftleri kümesini saklamayı kolaylaştıran bazı yöntemler
içerir. Bilgileri öznitelik olarak veya bir alt öğe kümesi olarak tutabilirsiniz.
Bilgileri öznitelik veya alt öğe olarak tutma arasındaki tek fark, özniteliklerin bir öğe için yalnızca belirli bir ada sahip
tek bir öznitelik olabilecek kısıtlamaya sahip olduğu kısıtlamadır. Bu sınırlama alt öğeler için geçerlidir.

SetAttributeValue ve SetElementValue
Ad/değer çiftlerini tutmaya yardımcı olan iki yöntem ve ' SetAttributeValue SetElementValuedir. Bu iki yöntem
benzer anlamlara sahiptir.
SetAttributeValuebir öğenin özniteliklerini ekleyebilir, değiştirebilir veya kaldırabilir.
Varolmayan bir özniteliğin SetAttributeValue adıyla çağırırsanız, yöntemi yeni bir öznitelik oluşturur ve
belirtilen öğeye ekler.
Var olan bir SetAttributeValue özniteliğin adı ile ve belirtilen içeriklerde bir çağrı yaparsanız, özniteliğin
içeriği belirtilen içerikle değiştirilmiştir.
Varolan bir özniteliğin SetAttributeValue adıyla çağrı yaparsanız ve içerik için null belirtirseniz, öznitelik üst
öğesinden kaldırılır.
SetElementValuebir öğenin alt öğelerini ekleyebilir, değiştirebilir veya kaldırabilir.
Var olmayan bir SetElementValue alt öğe adı ile çağırırsanız, yöntemi yeni bir öğesi oluşturur ve belirtilen
öğeye ekler.
Var olan bir SetElementValue öğenin adı ile ve belirtilen içeriklerle çağırırsanız, öğenin içeriği belirtilen
içerikle değiştirilmiştir.
Varsa, varolan SetElementValue bir öğenin adıyla çağrı yaparsanız ve içerik için null belirtirseniz, öğe üst
öğesinden kaldırılır.

Örnek
Aşağıdaki örnek, öznitelikleri olmayan bir öğesi oluşturur. Daha sonra bir ad SetAttributeValue /değer çiftleri listesi
oluşturmak ve korumak için yöntemini kullanır.
// Create an element with no content.
XElement root = new XElement("Root");

// Add a number of name/value pairs as attributes.


root.SetAttributeValue("Top", 22);
root.SetAttributeValue("Left", 20);
root.SetAttributeValue("Bottom", 122);
root.SetAttributeValue("Right", 300);
root.SetAttributeValue("DefaultColor", "Color.Red");
Console.WriteLine(root);

// Replace the value of Top.


root.SetAttributeValue("Top", 10);
Console.WriteLine(root);

// Remove DefaultColor.
root.SetAttributeValue("DefaultColor", null);
Console.WriteLine(root);

Bu örnek aşağıdaki çıktıyı üretir:

<Root Top="22" Left="20" Bottom="122" Right="300" DefaultColor="Color.Red" />


<Root Top="10" Left="20" Bottom="122" Right="300" DefaultColor="Color.Red" />
<Root Top="10" Left="20" Bottom="122" Right="300" />

Örnek
Aşağıdaki örnek, alt öğeleri olmayan bir öğe oluşturur. Daha sonra bir ad SetElementValue /değer çiftleri listesi
oluşturmak ve korumak için yöntemini kullanır.

// Create an element with no content.


XElement root = new XElement("Root");

// Add a number of name/value pairs as elements.


root.SetElementValue("Top", 22);
root.SetElementValue("Left", 20);
root.SetElementValue("Bottom", 122);
root.SetElementValue("Right", 300);
root.SetElementValue("DefaultColor", "Color.Red");
Console.WriteLine(root);
Console.WriteLine("----");

// Replace the value of Top.


root.SetElementValue("Top", 10);
Console.WriteLine(root);
Console.WriteLine("----");

// Remove DefaultColor.
root.SetElementValue("DefaultColor", null);
Console.WriteLine(root);

Bu örnek aşağıdaki çıktıyı üretir:


<Root>
<Top>22</Top>
<Left>20</Left>
<Bottom>122</Bottom>
<Right>300</Right>
<DefaultColor>Color.Red</DefaultColor>
</Root>
----
<Root>
<Top>10</Top>
<Left>20</Left>
<Bottom>122</Bottom>
<Right>300</Right>
<DefaultColor>Color.Red</DefaultColor>
</Root>
----
<Root>
<Top>10</Top>
<Left>20</Left>
<Bottom>122</Bottom>
<Right>300</Right>
</Root>

Ayrıca bkz.
SetAttributeValue
SetElementValue
XML ağaçlarını değiştirme (LINQ to XML ) (C#)
Tüm XML ağacının (C#) ad alanını değiştirme
25.11.2019 • 2 minutes to read • Edit Online

Bazen bir öğe veya öznitelik için ad alanını programlı olarak değiştirmeniz gerekebilir. LINQ to XML bu kadar kolay
hale gelir. XElement.Name özelliği ayarlanabilir. XAttribute.Name özelliği ayarlanamaz, ancak öznitelikleri kolayca
bir System.Collections.Generic.List<T>kopyalayabilir, var olan öznitelikleri kaldırabilir ve ardından yeni istenen ad
alanındaki yeni öznitelikler ekleyebilirsiniz.
Daha fazla bilgi için bkz. ad alanlarına genel bakış (C#LINQ to XML ) ().

Örnek
Aşağıdaki kod, ad alanı olmadan iki XML ağacı oluşturur. Daha sonra ağaçların her birinin ad alanını değiştirir ve
bunları tek bir ağaçta birleştirir.
XElement tree1 = new XElement("Data",
new XElement("Child", "content",
new XAttribute("MyAttr", "content")
)
);
XElement tree2 = new XElement("Data",
new XElement("Child", "content",
new XAttribute("MyAttr", "content")
)
);
XNamespace aw = "http://www.adventure-works.com";
XNamespace ad = "http://www.adatum.com";
// change the namespace of every element and attribute in the first tree
foreach (XElement el in tree1.DescendantsAndSelf())
{
el.Name = aw.GetName(el.Name.LocalName);
List<XAttribute> atList = el.Attributes().ToList();
el.Attributes().Remove();
foreach (XAttribute at in atList)
el.Add(new XAttribute(aw.GetName(at.Name.LocalName), at.Value));
}
// change the namespace of every element and attribute in the second tree
foreach (XElement el in tree2.DescendantsAndSelf())
{
el.Name = ad.GetName(el.Name.LocalName);
List<XAttribute> atList = el.Attributes().ToList();
el.Attributes().Remove();
foreach (XAttribute at in atList)
el.Add(new XAttribute(ad.GetName(at.Name.LocalName), at.Value));
}
// add attribute namespaces so that the tree will be serialized with
// the aw and ad namespace prefixes
tree1.Add(
new XAttribute(XNamespace.Xmlns + "aw", "http://www.adventure-works.com")
);
tree2.Add(
new XAttribute(XNamespace.Xmlns + "ad", "http://www.adatum.com")
);
// create a new composite tree
XElement root = new XElement("Root",
tree1,
tree2
);
Console.WriteLine(root);

Bu örnek aşağıdaki çıktıyı üretir:

<Root>
<aw:Data xmlns:aw="http://www.adventure-works.com">
<aw:Child aw:MyAttr="content">content</aw:Child>
</aw:Data>
<ad:Data xmlns:ad="http://www.adatum.com">
<ad:Child ad:MyAttr="content">content</ad:Child>
</ad:Data>
</Root>
Zincirleme sorgularının performansı (LINQ to XML)
(C#)
23.10.2019 • 3 minutes to read • Edit Online

LINQ 'in (ve LINQ to XML ) en önemli avantajlarından biri, zincir sorgularının ve çok daha karmaşık bir sorgunun
gerçekleştirebildiği bir işlemdir.
Zincirleme sorgu, kaynağı olarak başka bir sorgu kullanan bir sorgudur. Örneğin, aşağıdaki basit kodda query2
kaynağına sahiptir: query1

XElement root = new XElement("Root",


new XElement("Child", 1),
new XElement("Child", 2),
new XElement("Child", 3),
new XElement("Child", 4)
);

var query1 = from x in root.Elements("Child")


where (int)x >= 3
select x;

var query2 = from e in query1


where (int)e % 2 == 0
select e;

foreach (var i in query2)


Console.WriteLine("{0}", (int)i);

Bu örnek aşağıdaki çıktıyı üretir:

Bu zincirleme sorgu, bağlantılı bir liste ile yineleme ile aynı performans profilini sağlar.
Elements Eksen temelde, bağlantılı bir liste ile yineleme ile aynı performansa sahiptir. Elements, ertelenmiş
yürütme ile bir yineleyici olarak uygulanır. Bu, yineleyici nesnesini ayırma ve yürütme durumunu izleme gibi
bağlantılı listede yineleme yapmak için ek olarak bir iş yaptığı anlamına gelir. Bu iş iki kategoriye ayrılabilir:
yineleyicinin ayarlandığı sırada gerçekleştirilen iş ve her yineleme sırasında gerçekleştirilen iş. Kurulum işi
küçük, sabit bir iş miktarı ve her yineleme sırasında yapılan iş, kaynak koleksiyondaki öğelerin sayısıyla
orantılıdır.
İçinde query1 Where , yantümcesorgununyöntemiçağırmasınısağlar. where Bu yöntem ayrıca bir yineleyici
olarak uygulanır. Kurulum işi, lambda ifadesine başvuracak temsilciyi örnekledikten ve bir yineleyici için
normal kuruluma oluşur. Her yinelemeyle, bu temsilci, koşulu yürütmek için çağırılır. Kurulum işi ve her
yineleme sırasında yapılan iş, eksen boyunca yineleme sırasında yapılan işe benzer.
' query1 De, select yan tümcesi sorgunun Select yöntemi çağırmasını sağlar. Bu yöntem, Where yöntemiyle
aynı performans profiline sahiptir.
' query2 De, where yan tümcesi ve select query1 yan tümcesi, ile aynı performans profiline sahiptir.
Bu nedenle yineleme query2 , diğer bir deyişle, doğrusal saat olan ilk sorgunun kaynağındaki öğe sayısıyla
doğrudan orantılıdır. Karşılık gelen bir Visual Basic örneği aynı performans profiline sahip olabilir.
Yineleyiciler hakkında daha fazla bilgi için bkz. yield.
Sorguları birlikte zincirlemeye yönelik daha ayrıntılı bir öğretici için bkz . Öğretici: Sorguları birliktezincirleme.
Atomlanmış XName ve XNamespace nesneleri (LINQ
to XML) (C#)
23.10.2019 • 3 minutes to read • Edit Online

XNameve XNamespace nesneleri atomlanmışolur; diğer bir deyişle, aynı nitelikli adı içeriyorsa, aynı nesneye
başvurur. Bu, sorgular için performans avantajları verir: İki atomılı adı eşitlik için karşılaştırdığınızda, temel alınan
ara dilin yalnızca iki başvuruyu aynı nesneye işaret edip etmediğini belirlemesi gerekir. Temel alınan kodun, zaman
alıcı olabilecek dize karşılaştırmaları yapması gerekmez.

Atomleştirme semantiği
Atomleştirme, iki XName nesnenin aynı yerel ada sahip olması ve aynı ad alanında olmaları durumunda aynı
örneği paylaştıkları anlamına gelir. Aynı şekilde, iki XNamespace nesne aynı ad alanı URI 'sine sahip ise, aynı örneği
paylaşır.
Atomlanmış nesneleri etkinleştirmek için bir sınıf için, sınıf için Oluşturucu genel değil, özel olmalıdır. Bunun nedeni,
oluşturucunun genel olması, atomsuz olmayan bir nesne oluşturmanız olabilir. Ve sınıfları bir XName dizeyi bir
veya XNamespaceiçine dönüştürmek için örtük bir dönüştürme işleci uygular. XName XNamespace Bu nesnelerin
bir örneğini alma işlemi budur. Oluşturucuya erişilemediği için bir oluşturucuyu kullanarak bir örnek alınamaz.
XNameXNamespace Ayrıca, karşılaştırılan iki nesnenin aynı örneğe başvuru olup olmadığını anlamak için eşitlik ve
eşitsizlik işleçlerini da uygulayın.

Örnek
Aşağıdaki kod bazı XElement nesneler oluşturur ve aynı adların aynı örneği paylaşılacağını gösterir.

XElement r1 = new XElement("Root", "data1");


XElement r2 = XElement.Parse("<Root>data2</Root>");

if ((object)r1.Name == (object)r2.Name)
Console.WriteLine("r1 and r2 have names that refer to the same instance.");
else
Console.WriteLine("Different");

XName n = "Root";

if ((object)n == (object)r1.Name)
Console.WriteLine("The name of r1 and the name in 'n' refer to the same instance.");
else
Console.WriteLine("Different");

Bu örnek aşağıdaki çıktıyı üretir:

r1 and r2 have names that refer to the same instance.


The name of r1 and the name in 'n' refer to the same instance.

Daha önce belirtildiği gibi, atomlanmış nesnelerin avantajı bir parametre XName olarak alan eksen yöntemlerinden
birini kullandığınızda, eksen yönteminin yalnızca iki adların istenen öğeleri seçmek için aynı örneğe başvurmadığını
belirlemesi gerekir.
Aşağıdaki örnek, bir XName Descendants ' ı yöntem çağrısına geçirir ve daha sonra atomleştirme düzeniyle daha
iyi performansa sahiptir.

XElement root = new XElement("Root",


new XElement("C1", 1),
new XElement("Z1",
new XElement("C1", 2),
new XElement("C1", 1)
)
);

var query = from e in root.Descendants("C1")


where (int)e == 1
select e;

foreach (var z in query)


Console.WriteLine(z);

Bu örnek aşağıdaki çıktıyı üretir:

<C1>1</C1>
<C1>1</C1>
XName nesnelerinin (LINQ to XML) (C#) ön atomonu
23.10.2019 • 2 minutes to read • Edit Online

LINQ to XML performansını artırmanın bir yolu, önceden ayrılamaz XName nesneleri kullanmaktır. Ön
cekleştirme, XName XElement ve XAttribute sınıflarının oluşturucularını kullanarak xml ağacını oluşturmadan önce
bir nesneye bir dize atadığınız anlamına gelir. Ardından, dizeden öğesine XNameörtük dönüştürmeyi kullanan
oluşturucuya bir dize geçirmek yerine, başlatılan XName nesneyi geçirirsiniz.
Bu, belirli adların tekrarlandığı büyük bir XML ağacı oluşturduğunuzda performansı geliştirir. Bunu yapmak için,
xml ağacını oluşturmadan önce XName nesneleri bildirir ve başlatır ve sonra öğe ve öznitelik adları için dizeleri
XName belirtmek yerine nesneleri kullanın. Aynı ada sahip çok sayıda öğe (veya öznitelik) oluşturuyorsanız bu
teknik önemli performans artışı elde edebilir.
Kullanmanız gerekip gerekmediğini belirlemek için senaryolarınız ile önceden atomleştirme testi yapmanız gerekir.

Örnek
Aşağıdaki örnek bunu gösterir.

XName Root = "Root";


XName Data = "Data";
XName ID = "ID";

XElement root = new XElement(Root,


new XElement(Data,
new XAttribute(ID, "1"),
"4,100,000"),
new XElement(Data,
new XAttribute(ID, "2"),
"3,700,000"),
new XElement(Data,
new XAttribute(ID, "3"),
"1,150,000")
);

Console.WriteLine(root);

Bu örnek aşağıdaki çıktıyı üretir:

<Root>
<Data ID="1">4,100,000</Data>
<Data ID="2">3,700,000</Data>
<Data ID="3">1,150,000</Data>
</Root>

Aşağıdaki örnek, XML belgesinin bir ad alanında bulunduğu tekniği gösterir:


XNamespace aw = "http://www.adventure-works.com";
XName Root = aw + "Root";
XName Data = aw + "Data";
XName ID = "ID";

XElement root = new XElement(Root,


new XAttribute(XNamespace.Xmlns + "aw", aw),
new XElement(Data,
new XAttribute(ID, "1"),
"4,100,000"),
new XElement(Data,
new XAttribute(ID, "2"),
"3,700,000"),
new XElement(Data,
new XAttribute(ID, "3"),
"1,150,000")
);

Console.WriteLine(root);

Bu örnek aşağıdaki çıktıyı üretir:

<aw:Root xmlns:aw="http://www.adventure-works.com">
<aw:Data ID="1">4,100,000</aw:Data>
<aw:Data ID="2">3,700,000</aw:Data>
<aw:Data ID="3">1,150,000</aw:Data>
</aw:Root>

Aşağıdaki örnek, gerçek dünyada büyük olasılıkla karşılaşacağınız şekilde daha benzerdir. Bu örnekte, öğesinin
içeriği bir sorgu tarafından sağlanır:

XName Root = "Root";


XName Data = "Data";
XName ID = "ID";

DateTime t1 = DateTime.Now;
XElement root = new XElement(Root,
from i in System.Linq.Enumerable.Range(1, 100000)
select new XElement(Data,
new XAttribute(ID, i),
i * 5)
);
DateTime t2 = DateTime.Now;

Console.WriteLine("Time to construct:{0}", t2 - t1);

Önceki örnek, şu örnekteki adların ön cede olmadığı bir daha iyi şekilde çalışır:

DateTime t1 = DateTime.Now;
XElement root = new XElement("Root",
from i in System.Linq.Enumerable.Range(1, 100000)
select new XElement("Data",
new XAttribute("ID", i),
i * 5)
);
DateTime t2 = DateTime.Now;

Console.WriteLine("Time to construct:{0}", t2 - t1);


Ayrıca bkz.
Atomlanmış XName ve XNamespace nesneleri (LINQ to XML ) (C#)
Statik olarak derlenen sorgular (LINQ to XML)C#()
23.10.2019 • 4 minutes to read • Edit Online

En önemli performans avantajlarından biri de LINQ to XML XmlDocument, LINQ to XML içindeki sorguların statik
olarak derlenmesine karşın XPath sorgularının çalışma zamanında yorumlanması gerekir. Bu özellik LINQ to XML '
de yerleşiktir. bu nedenle, bundan faydalanmak için ek adımlar gerçekleştirmeniz gerekmez, ancak iki teknoloji
arasında seçim yaparken farkın anlaşılması yararlı olur. Bu konu, farkı açıklamaktadır.

Statik olarak derlenen sorgular ve XPath


Aşağıdaki örnek, belirtilen bir ada sahip ve belirtilen değere sahip bir öznitelik ile alt öğelerin nasıl alınacağını
gösterir.
Eşdeğer XPath ifadesi aşağıda verilmiştir: //Address[@Type='Shipping']

XDocument po = XDocument.Load("PurchaseOrders.xml");

IEnumerable<XElement> list1 =
from el in po.Descendants("Address")
where (string)el.Attribute("Type") == "Shipping"
select el;

foreach (XElement el in list1)


Console.WriteLine(el);

Bu örnekteki sorgu ifadesi derleyici tarafından Yöntem tabanlı sorgu söz dizimine yeniden yazılır. Yöntem tabanlı
sorgu sözdiziminde yazılan aşağıdaki örnek, öncekiyle aynı sonuçları üretir:

XDocument po = XDocument.Load("PurchaseOrders.xml");

IEnumerable<XElement> list1 =
po
.Descendants("Address")
.Where(el => (string)el.Attribute("Type") == "Shipping");

foreach (XElement el in list1)


Console.WriteLine(el);

Where Yöntemi bir genişletme yöntemidir. Daha fazla bilgi için bkz. Uzantı yöntemleri. Bir Where genişletme
yöntemi olduğundan, yukarıdaki sorgu aşağıdaki gibi yazılmış gibi derlenir:

XDocument po = XDocument.Load("PurchaseOrders.xml");

IEnumerable<XElement> list1 =
System.Linq.Enumerable.Where(
po.Descendants("Address"),
el => (string)el.Attribute("Type") == "Shipping");

foreach (XElement el in list1)


Console.WriteLine(el);

Bu örnek, önceki iki örnekle tam olarak aynı sonuçları üretir. Bu, sorguların statik olarak bağlı yöntem çağrılarına
etkin bir şekilde derlendiğini gösterir. Yineleyicilerin ertelenmiş yürütme semantiği ile birlikte, performansı geliştirir.
Yineleyicilerin ertelenmiş yürütme semantiği hakkında daha fazla bilgi için bkz. LINQ to XMLC#() içinde ertelenmiş
yürütme ve geç değerlendirme.

NOTE
Bu örnekler, derleyicinin yazabilmesi için kod temsilcisidir. Gerçek uygulama bu örneklerden biraz farklı olabilir, ancak
performans aynı veya bu örneklere benzer olacaktır.

XmlDocument ile XPath Ifadeleri yürütme


Aşağıdaki örnek, önceki XmlDocument örneklerle aynı sonuçları başarmak için kullanır:

XmlReader reader = XmlReader.Create("PurchaseOrders.xml");


XmlDocument doc = new XmlDocument();
doc.Load(reader);
XmlNodeList nl = doc.SelectNodes(".//Address[@Type='Shipping']");
foreach (XmlNode n in nl)
Console.WriteLine(n.OuterXml);
reader.Close();

Bu sorgu, LINQ to XML kullanan örneklerle aynı çıktıyı döndürür; Tek fark, LINQ to XML yazdırılan XML 'nin
girintilebilirken XmlDocument , bunun farklılığı değildir.
Ancak, SelectNodes yaklaşım genellikle LINQ to XML, ve yöntemi her çağrıldığında aşağıdaki işlemleri yapması
gerektiğinden, her zaman yaklaşım uygulanmaz: XmlDocument
XPath ifadesini içeren dizeyi ayrıştırır ve dizeyi belirteçlere ayırır.
XPath ifadesinin geçerli olduğundan emin olmak için belirteçleri doğrular.
İfadeyi bir iç ifade ağacına çevirir.
İfadenin değerlendirmesine bağlı olarak sonuç kümesi düğümlerini uygun şekilde seçerek düğümleri
üzerinde dolaşır.
Bu, karşılık gelen LINQ to XML sorgusu tarafından gerçekleştirilen işin önemli ölçüde daha yüksektir. Belirli
performans farkı farklı sorgu türleri için farklılık gösterir, ancak genel LINQ to XML sorgularında daha az iş olur ve
bu nedenle, kullanarak XmlDocumentXPath ifadelerini değerlendirmeden daha iyi gerçekleştirilir.
LINQ to XML Ek Açıklamaları
23.10.2019 • 2 minutes to read • Edit Online

Ek açıklamalarda LINQ - XML rasgele türden herhangi bir rastgele nesne XML ağacındaki herhangi bir XML
bileşeni ile ilişkilendirilecek olanak sağlar.
Ek açıklamanın gibi bir XML bileşenine eklemek için bir XElement veya XAttribute, çağırmanızı AddAnnotation
yöntemi. Türe göre ek açıklamaları aldığınız.
Ek açıklamaları XML bilgi kümesi parçası olmadığını unutmayın; Kullanıcılar seri durumdan veya.

Yöntemler
Ek açıklamalar ile çalışırken aşağıdaki yöntemleri kullanabilirsiniz:

YÖNTEM AÇIKLAMA

AddAnnotation Bir nesne ekler, ek açıklama listesine bir XObject.

Annotation Belirtilen türden ilk ek açıklama nesnesinin alır bir XObject.

Annotations Ek açıklamalar için belirtilen türün bir koleksiyonunu alır bir


XObject.

RemoveAnnotations Ek açıklamalar, belirtilen türden kaldırır bir XObject.


LINQ to XML olayları (C#)
23.10.2019 • 2 minutes to read • Edit Online

LINQ - XMLolaylar, bir XML ağacı değiştiğinde size bildirim gönderilmesini sağlar.
Herhangi XObjectbir örneğine olay ekleyebilirsiniz. Olay işleyicisi daha sonra bu XObject ve alt öğelerinden
herhangi birine değişiklikler için olaylar alır. Örneğin, ağacın köküne bir olay işleyicisi ekleyebilir ve ağaçtaki tüm
değişiklikleri bu olay işleyicisinden işleyebilirsiniz.
LINQ - XML Olay örnekleri için bkz Changing . ve Changed.

Türler ve olaylar
Olaylarla çalışırken aşağıdaki türleri kullanın:

TÜR AÇIKLAMA

XObjectChange Bir XObjectolay oluşturulduğunda olay türünü belirtir.

XObjectChangeEventArgs Changing VeChanged olayları için veri sağlar.

Bir XML ağacını değiştirirken aşağıdaki olaylar oluşturulur:

OLAY AÇIKLAMA

Changing Bu XObject veya alt öğelerinden herhangi birinin


değişmesinden hemen önce gerçekleşir.

Changed Bir XObject değiştiğinde veya alt öğelerinden herhangi biri


değiştiğinde gerçekleşir.

Örnek
Açıklama
Olaylar, bir XML ağacındaki bazı toplu bilgileri korumak istediğinizde faydalıdır. Örneğin, faturanın satır öğelerinin
toplamı olan bir fatura toplamı korumak isteyebilirsiniz. Bu örnek, karmaşık öğe Items altındaki tüm alt öğelerinin
toplamını korumak için olayları kullanır.
Kod
XElement root = new XElement("Root",
new XElement("Total", "0"),
new XElement("Items")
);
XElement total = root.Element("Total");
XElement items = root.Element("Items");
items.Changed += (object sender, XObjectChangeEventArgs cea) =>
{
switch (cea.ObjectChange)
{
case XObjectChange.Add:
if (sender is XElement)
total.Value = ((int)total + (int)(XElement)sender).ToString();
if (sender is XText)
total.Value = ((int)total + (int)((XText)sender).Parent).ToString();
break;
case XObjectChange.Remove:
if (sender is XElement)
total.Value = ((int)total - (int)(XElement)sender).ToString();
if (sender is XText)
total.Value = ((int)total - Int32.Parse(((XText)sender).Value)).ToString();
break;
}
Console.WriteLine("Changed {0} {1}",
sender.GetType().ToString(), cea.ObjectChange.ToString());
};
items.SetElementValue("Item1", 25);
items.SetElementValue("Item2", 50);
items.SetElementValue("Item2", 75);
items.SetElementValue("Item3", 133);
items.SetElementValue("Item1", null);
items.SetElementValue("Item4", 100);
Console.WriteLine("Total:{0}", (int)total);
Console.WriteLine(root);

Açıklamalar
Bu kod aşağıdaki çıktıyı üretir:

Changed System.Xml.Linq.XElement Add


Changed System.Xml.Linq.XElement Add
Changed System.Xml.Linq.XText Remove
Changed System.Xml.Linq.XText Add
Changed System.Xml.Linq.XElement Add
Changed System.Xml.Linq.XElement Remove
Changed System.Xml.Linq.XElement Add
Total:308
<Root>
<Total>308</Total>
<Items>
<Item2>75</Item2>
<Item3>133</Item3>
<Item4>100</Item4>
</Items>
</Root>
Düğümlerle programlama (C#)
23.10.2019 • 6 minutes to read • Edit Online

LINQ - XMLbir XML Düzenleyicisi, bir dönüşüm sistemi veya rapor yazıcısı gibi programlar yazması gereken
geliştiriciler genellikle öğeleri ve öznitelikleri daha ayrıntılı bir düzeyde ayrıntı düzeyinde çalışan programlar
yazması gerekir. Genellikle düğüm düzeyinde çalışmamaları, metin düğümlerini işlemek, yönergeleri ve açıklamaları
işlemek gerekir. Bu konu, düğüm düzeyinde programlama hakkında bazı ayrıntılar sağlar.

Düğüm ayrıntıları
Programlama, düğüm düzeyinde çalışan bir programcı 'nin bilmelidir bir dizi ayrıntı vardır.
XDocument 'in alt öğe düğümlerinin üst özelliği null olarak ayarlandı
Özelliği üst düğümü değil üst XElementöğeyi içerir. Parent Öğesinin XDocument alt düğümlerinin üst öğesi
XElementyok. Üst öğesi belgedir, bu nedenle Parent bu düğümlerin özelliği null olarak ayarlanır.
Aşağıdaki örnek şunu gösterir:

XDocument doc = XDocument.Parse(@"<!-- a comment --><Root/>");


Console.WriteLine(doc.Nodes().OfType<XComment>().First().Parent == null);
Console.WriteLine(doc.Root.Parent == null);

Bu örnek aşağıdaki çıktıyı üretir:

True
True

Bitişik metin düğümleri mümkündür


Bir dizi XML programlama modelinde, bitişik metin düğümleri her zaman birleştirilir. Bu bazen metin düğümlerinin
normalleştirilmesi olarak adlandırılır. LINQ - XMLmetin düğümlerini normalleştirilemez. Aynı öğeye iki metin
düğümü eklerseniz, bu, bitişik metin düğümlerine neden olur. Ancak, XText düğüm olarak değil, bir dize olarak
belirtilen içeriği eklerseniz, LINQ - XML dizeyi bitişik bir metin düğümü ile birleştirebilirsiniz.
Aşağıdaki örnek şunu gösterir:

XElement xmlTree = new XElement("Root", "Content");

Console.WriteLine(xmlTree.Nodes().OfType<XText>().Count());

// this does not add a new text node


xmlTree.Add("new content");
Console.WriteLine(xmlTree.Nodes().OfType<XText>().Count());

// this does add a new, adjacent text node


xmlTree.Add(new XText("more text"));
Console.WriteLine(xmlTree.Nodes().OfType<XText>().Count());

Bu örnek aşağıdaki çıktıyı üretir:


1
1
2

Boş metin düğümleri mümkündür


Bazı XML programlama modellerinde, metin düğümlerinin boş dize içermediği garanti edilir. Bu tür bir metin
düğümünün XML serileştirilmesi üzerinde hiçbir etkisi yoktur. Ancak, bitişik metin düğümlerinin mümkün
olmasının aynı nedeni için, değerini boş dizeye ayarlayarak metin düğümünden metin kaldırırsanız, metin
düğümünün kendisi silinmez.

XElement xmlTree = new XElement("Root", "Content");


XText textNode = xmlTree.Nodes().OfType<XText>().First();

// the following line does not cause the removal of the text node.
textNode.Value = "";

XText textNode2 = xmlTree.Nodes().OfType<XText>().First();


Console.WriteLine(">>{0}<<", textNode2);

Bu örnek aşağıdaki çıktıyı üretir:

>><<

Boş bir metin düğümü serileştirme etkiler


Bir öğe yalnızca boş olan bir alt metin düğümü içeriyorsa, Long Tag sözdizimi ile serileştirilir: <Child></Child> . Bir
öğe herhangi bir alt düğüm içermiyorsa, kısa etiket söz dizimi ile serileştirilir: <Child /> .

XElement child1 = new XElement("Child1",


new XText("")
);
XElement child2 = new XElement("Child2");
Console.WriteLine(child1);
Console.WriteLine(child2);

Bu örnek aşağıdaki çıktıyı üretir:

<Child1></Child1>
<Child2 />

Ad alanları LINQ to XML ağacındaki özniteliklerdir


Ad alanı bildirimleri özniteliklere aynı sözdizimine sahip olsa da XSLT ve XPath gibi bazı programlama
arabirimlerinde, ad alanı bildirimleri öznitelik olarak kabul edilmez. Ancak, içinde LINQ - XML, ad alanları XML
ağacında XAttribute nesneler olarak depolanır. Bir ad alanı bildirimi içeren bir öğe için öznitelikler üzerinde
yineleme yaparsanız, ad alanı bildirimini döndürülen koleksiyondaki öğelerden biri olarak görürsünüz.
Özelliği IsNamespaceDeclaration , bir özniteliğin ad alanı bildirimi olup olmadığını gösterir.
XElement root = XElement.Parse(
@"<Root
xmlns='http://www.adventure-works.com'
xmlns:fc='www.fourthcoffee.com'
AnAttribute='abc'/>");
foreach (XAttribute att in root.Attributes())
Console.WriteLine("{0} IsNamespaceDeclaration:{1}", att, att.IsNamespaceDeclaration);

Bu örnek aşağıdaki çıktıyı üretir:

xmlns="http://www.adventure-works.com" IsNamespaceDeclaration:True
xmlns:fc="www.fourthcoffee.com" IsNamespaceDeclaration:True
AnAttribute="abc" IsNamespaceDeclaration:False

XPath eksen yöntemleri, XDocument 'in alt boşluk değerini döndürmüyor


LINQ - XMLmetin düğümlerinde yalnızca boşluk bulunduğu sürece alt XDocumentmetin düğümlerine izin verir.
Ancak, XPath nesne modeli bir belgenin alt düğümleri olarak boşluk içermez, bu nedenle XDocument Nodes eksen
kullanarak alt öğeleri üzerinde yineleme yaptığınızda boşluk metin düğümleri döndürülür. Ancak, XPath eksen
yöntemlerini kullanarak bir XDocument öğesinin alt öğelerinde yineleme yaptığınızda, boşluk metin düğümleri
döndürülmez.

// Create a document with some white-space child nodes of the document.


XDocument root = XDocument.Parse(
@"<?xml version='1.0' encoding='utf-8' standalone='yes'?>

<Root/>

<!--a comment-->
", LoadOptions.PreserveWhitespace);

// count the white-space child nodes using LINQ to XML


Console.WriteLine(root.Nodes().OfType<XText>().Count());

// count the white-space child nodes using XPathEvaluate


Console.WriteLine(((IEnumerable)root.XPathEvaluate("text()")).OfType<XText>().Count());

Bu örnek aşağıdaki çıktıyı üretir:

3
0

XDeclaration nesneleri düğüm değil


Bir XDocument' ın alt düğümleri arasında yineleme yaparken, XML bildirim nesnesini görmezsiniz. Bunun bir alt
düğümü değil, belgenin bir özelliğidir.

XDocument doc = new XDocument(


new XDeclaration("1.0", "utf-8", "yes"),
new XElement("Root")
);
doc.Save("Temp.xml");
Console.WriteLine(File.ReadAllText("Temp.xml"));

// this shows that there is only one child node of the document
Console.WriteLine(doc.Nodes().Count());

Bu örnek aşağıdaki çıktıyı üretir:


<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Root />
1
Karma bildirime dayalı kod/zorunlu kod hataları
(LINQ to XML)C#()
23.10.2019 • 8 minutes to read • Edit Online

LINQ - XMLbir XML ağacını doğrudan değiştirmenize olanak sağlayan çeşitli yöntemler içerir. Öğe ekleyebilir,
öğeleri silebilir, bir öğenin içeriğini değiştirebilir, öznitelik ekleyebilir ve benzerlerini yapabilirsiniz. Bu programlama
arabirimi, XML ağaçlarını (LINQ to XML )C#() değiştirmekonusunda açıklanmaktadır. Ve gibi eksenlerden
Elementsbirini yinelemenize sahipseniz ve eksen boyunca yineleme yaparken xml ağacını değiştiriyorsanız, bazı
garip hatalara sahip olabilirsiniz.
Bu sorun bazen "Cadılar Bayramı sorunu" olarak bilinir.

Sorunun tanımı
Bir koleksiyon aracılığıyla yinelenen LINQ kullanarak bazı kodlar yazdığınızda, bildirime dayalı bir stilde kod
yazıyor demektir. İstediğiniz şeyi açıklamak, bunun yerine nasıl yapılacağını öğrenmek için daha fazla oturum
vardır. 1) ilk öğeyi alan bir kod yazarsanız, 2) onu bir koşul için sınar, 3) onu değiştirir ve 4) listeye geri koyar, bu da
zorunlu kod olacaktır. Bilgisayara ne yapılacağını istediğinizi söyleirsiniz.
Bu kod stillerinin aynı işlemde karıştırılması, sorunlara yol gösterir. Aşağıdakileri göz önünde bulundurun:
İçinde üç öğe (a, b ve c) içeren bağlı bir listeniz olduğunu varsayalım:
a -> b -> c

Şimdi, bağlantılı liste içinde, üç yeni öğe (', b ' ve c ') ekleyerek geçiş yapmak istediğinizi varsayalım. Elde edilen
bağlantılı listenin şuna benzer görünmesini istiyorsunuz:
a -> a' -> b -> b' -> c -> c'

Bu nedenle, liste boyunca yinelenen kod yazdığınızda ve her öğe için, hemen sonrasında yeni bir öğe ekler. Ne
olacağı, kodunuzun a öğeyi ilk göreceği ve sonra ekleneceği a' şeydir. Şimdi, kodunuz listede a' bir sonraki
düğüme geçmeyecektir. Bu, a'' listeye yeni bir öğe ekler.
Bunu gerçek dünyada nasıl çözirsiniz? Ayrıca, özgün bağlantılı listenin bir kopyasını oluşturabilir ve tamamen yeni
bir liste oluşturabilirsiniz. Ya da yalnızca zorunlu kod yazıyorsanız, ilk öğeyi bulabilir, yeni öğeyi ekleyebilir ve
ardından bağlantılı listede iki kez ilerledikten sonra yeni eklediğiniz öğeden ilerleyebilirsiniz.

Yineleme sırasında ekleme


Örneğin, bir ağaçtaki her öğe için bir kod yazmak istediğinizi, yinelenen bir öğe oluşturmak istediğinizi varsayalım:

XElement root = new XElement("Root",


new XElement("A", "1"),
new XElement("B", "2"),
new XElement("C", "3")
);
foreach (XElement e in root.Elements())
root.Add(new XElement(e.Name, (string)e));

Bu kod sonsuz bir döngüye girer. İfade, doc öğesine yeni öğeler Elements() ekleyerek eksen boyunca yinelenir.
foreach Aynı zamanda, yeni eklenen öğeler aracılığıyla yineleme sona erer. Ayrıca, döngünün her tekrarında yeni
nesneler ayırdığından, son olarak tüm kullanılabilir belleği tüketir.
Aşağıdaki gibi ToList standart sorgu işlecini kullanarak koleksiyonu belleğe çekerek bu sorunu çözebilirsiniz:

XElement root = new XElement("Root",


new XElement("A", "1"),
new XElement("B", "2"),
new XElement("C", "3")
);
foreach (XElement e in root.Elements().ToList())
root.Add(new XElement(e.Name, (string)e));
Console.WriteLine(root);

Kod artık işe yarar. Elde edilen XML ağacı aşağıda verilmiştir:

<Root>
<A>1</A>
<B>2</B>
<C>3</C>
<A>1</A>
<B>2</B>
<C>3</C>
</Root>

Yineleme sırasında silme


Tüm düğümleri belirli bir düzeyde silmek isterseniz, aşağıdaki gibi bir kod yazmayı düşünebilirsiniz:

XElement root = new XElement("Root",


new XElement("A", "1"),
new XElement("B", "2"),
new XElement("C", "3")
);
foreach (XElement e in root.Elements())
e.Remove();
Console.WriteLine(root);

Ancak, bu, istediğiniz şeyi yapmaz. Bu durumda, ilk öğesini kaldırıldıktan sonra, bir, kök içinde yer alan XML
ağacından kaldırılır ve yineleme yapan öğeler yöntemindeki kod bir sonraki öğeyi bulamaz.
Yukarıdaki kod aşağıdaki çıktıyı üretir:

<Root>
<B>2</B>
<C>3</C>
</Root>

Bu çözüm, koleksiyonu aşağıda gösterildiği ToList gibi yeniden gerçekleştirmek için çağrmaktır:

XElement root = new XElement("Root",


new XElement("A", "1"),
new XElement("B", "2"),
new XElement("C", "3")
);
foreach (XElement e in root.Elements().ToList())
e.Remove();
Console.WriteLine(root);
Bu, aşağıdaki çıktıyı üretir:

<Root />

Alternatif olarak, üst öğeyi çağırarak RemoveAll yinelemeyi tamamen ortadan kaldırabilirsiniz:

XElement root = new XElement("Root",


new XElement("A", "1"),
new XElement("B", "2"),
new XElement("C", "3")
);
root.RemoveAll();
Console.WriteLine(root);

LINQ neden bunu otomatik olarak Işleyemiyor?


Tek bir yaklaşım, her şeyi yavaş değerlendirme yapmak yerine her zaman belleğe getirmek olacaktır. Ancak,
performans ve bellek kullanımı bakımından çok pahalıdır. Aslında, LINQ ve (LINQ to XML ) bu yaklaşıma
ulaşacaksa, gerçek dünyada durumlarda başarısız olur.
Başka bir olası yaklaşım, bazı işlem söz dizimine LINQ 'a yerleştirilecek ve derleyicinin kodu analiz etmeyi
denemesini ve belirli bir koleksiyonun gerçekleştirilip gerçekleştirilmeyeceğini belirleyebilmesini sağlar. Ancak, yan
etkileri olan tüm kodları belirleme girişimi inanılmaz karmaşıktır. Aşağıdaki kodu göz önünde bulundurun:

var z =
from e in root.Elements()
where TestSomeCondition(e)
select DoMyProjection(e);

Bu tür analiz kodu, herhangi bir kodun yan etkilere sahip olup olmadığını anlamak için TestSomeCondition ve
DoMyProjection yöntemlerini ve bu yöntemlerin çağırdığı tüm yöntemleri analiz etmeniz gerekir. Ancak, analiz
kodu yalnızca yan etkileri olan herhangi bir koda bakamadı. Bu durumda yalnızca alt öğelerinde root yan etkileri
olan kod için seçim yapması gerekir.
LINQ to XML böyle bir analiz yapmayı denemez.
Bu sorunlardan kaçınmak sizin için.

Kılavuz
İlk olarak, bildirim temelli ve kesinlik temelli kodu karıştırmayın.
Koleksiyonlarınızın semantiğini ve xml ağacını değiştiren yöntemlerin semantiğini bildiğiniz halde, bu sorun
kategorilerini engelleyen bazı zekice kodu yazarsanız, kodunuzun gelecekte diğer geliştiriciler tarafından tutulması
gerekir , ve sorunlar üzerinde açık olmayabilir. Bildirime dayalı ve kesinlik temelli kodlama stillerini karıştırırsanız,
kodunuz daha Brittle olacaktır.
Bu sorunların kaçınılması için bir koleksiyonu üreten bir kod yazarsanız, bakım programcılarının sorunu
anlayabilmesi için kodunuzda uygun olan açıklamalara göz önünde bulabilirsiniz.
İkincisi, performans ve diğer hususlar izin veriyor ise yalnızca bildirim temelli kod kullanın. Mevcut XML ağacınızı
değiştirmeyin. Yeni bir tane oluşturun.
XElement root = new XElement("Root",
new XElement("A", "1"),
new XElement("B", "2"),
new XElement("C", "3")
);
XElement newRoot = new XElement("Root",
root.Elements(),
root.Elements()
);
Console.WriteLine(newRoot);
Nasıl yapılır: Üst bilgi bilgilerine erişimi olan XML
parçaları akışı (C#)
23.10.2019 • 5 minutes to read • Edit Online

Bazen rastgele büyük XML dosyalarını okumanız ve uygulamanın bellek parmak izin tahmin edilebilir olması için
uygulamanızı yazmanız gerekir. Bir XML ağacını büyük bir XML dosyası ile doldurmayı denerseniz, bellek
kullanımınız dosyanın boyutuyla orantılıdır; yani çok fazla. Bu nedenle, bunun yerine bir akış tekniği kullanmanız
gerekir.
Bir seçenek, kullanarak XmlReaderuygulamanızı yazmaktır. Ancak, xml ağacını sorgulamak için kullanmak LINQ
isteyebilirsiniz. Bu durumda, kendi özel eksen yönteminizi yazabilirsiniz. Daha fazla bilgi için nasıl yapılır: LINQ to
XML Axis yöntemi (C#)yazın.
Kendi eksen yönteminizi yazmak için, ilgilendiğiniz düğümlerin birine ulaşana kadar düğümleri okumak
XmlReader için kullanan küçük bir yöntem yazarsınız. Yöntemi, ReadFrom XmlReader öğesinden okuyan ve bir
XML parçasını örnekleyen öğesini çağırır. Ardından, her parçayı aracılığıyla yield return özel eksen yönteminizi
numaralandırma yöntemine verir. Daha sonra özel eksen yönteinizde LINQ sorguları yazabilirsiniz.
Akış teknikleri en iyi şekilde, kaynak belgeyi yalnızca bir kez işleyebilmeniz ve öğeleri belge düzeninde
işleyebilirsiniz. Gibi belirli standart sorgu işleçleri OrderBy, kaynaklarını yineleyebilir, tüm verileri toplar, sıralar ve
son olarak dizideki ilk öğeyi verir. İlk öğeyi bırakmadan önce kaynağını üreten bir sorgu işleci kullanırsanız, küçük
bir bellek parmak izini saklayacağınızı unutmayın.

Örnek
Bazen sorun biraz daha ilginç olur. Aşağıdaki XML belgesinde, özel eksen yönteminizin tüketicisi, her öğenin ait
olduğu müşterinin adını da bilmelidir.
<?xml version="1.0" encoding="utf-8" ?>
<Root>
<Customer>
<Name>A. Datum Corporation</Name>
<Item>
<Key>0001</Key>
</Item>
<Item>
<Key>0002</Key>
</Item>
<Item>
<Key>0003</Key>
</Item>
<Item>
<Key>0004</Key>
</Item>
</Customer>
<Customer>
<Name>Fabrikam, Inc.</Name>
<Item>
<Key>0005</Key>
</Item>
<Item>
<Key>0006</Key>
</Item>
<Item>
<Key>0007</Key>
</Item>
<Item>
<Key>0008</Key>
</Item>
</Customer>
<Customer>
<Name>Southridge Video</Name>
<Item>
<Key>0009</Key>
</Item>
<Item>
<Key>0010</Key>
</Item>
</Customer>
</Root>

Bu örnekte geçen yaklaşım ayrıca, bu üstbilgi bilgilerini izlemek, üst bilgi bilgilerini kaydetmek ve ardından hem
başlık bilgilerini hem de numaralandırdığınız ayrıntıyı içeren küçük bir XML ağacı oluşturmanızı kullanmaktır.
Ardından Axis yöntemi bu yeni, küçük XML ağacını verir. Sorgu daha sonra başlık bilgilerine ve ayrıntı bilgilerine
erişimi de vardır.
Bu yaklaşımın küçük bir bellek ayak izi vardır. Her ayrıntı XML parçası, bir önceki parçaya hiçbir başvuru
tutulmazsa ve çöp toplama için kullanılabilir. Bu tekniğin yığın üzerinde birçok kısa süreli nesne oluşturduğunu
unutmayın.
Aşağıdaki örnek, URI tarafından belirtilen dosyadan XML parçalarını akıyan bir özel eksen yönteminin nasıl
uygulanacağını ve kullanılacağını gösterir. Bu özel eksen Customer özellikle, Name , ve Item öğelerinin bulunduğu
bir belgeyi beklediğinden ve bu öğelerin Yukarıdaki Source.xml belgede olarak düzenlenebilmesini sağlayacak
şekilde yazılmıştır. Bu bir uyarlaması uygulamasıdır. Daha sağlam bir uygulama, geçersiz bir belgeyi ayrıştırmaya
hazırlanmalıdır.
static IEnumerable<XElement> StreamCustomerItem(string uri)
{
using (XmlReader reader = XmlReader.Create(uri))
{
XElement name = null;
XElement item = null;

reader.MoveToContent();

// Parse the file, save header information when encountered, and yield the
// Item XElement objects as they are created.

// loop through Customer elements


while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element
&& reader.Name == "Customer")
{
// move to Name element
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element &&
reader.Name == "Name")
{
name = XElement.ReadFrom(reader) as XElement;
break;
}
}

// loop through Item elements


while (reader.Read())
{
if (reader.NodeType == XmlNodeType.EndElement)
break;
if (reader.NodeType == XmlNodeType.Element
&& reader.Name == "Item")
{
item = XElement.ReadFrom(reader) as XElement;
if (item != null) {
XElement tempRoot = new XElement("Root",
new XElement(name)
);
tempRoot.Add(item);
yield return item;
}
}
}
}
}
}
}

static void Main(string[] args)


{
XElement xmlTree = new XElement("Root",
from el in StreamCustomerItem("Source.xml")
where (int)el.Element("Key") >= 3 && (int)el.Element("Key") <= 7
select new XElement("Item",
new XElement("Customer", (string)el.Parent.Element("Name")),
new XElement(el.Element("Key"))
)
);
Console.WriteLine(xmlTree);
}

Bu kod aşağıdaki çıktıyı üretir:


<Root>
<Item>
<Customer>A. Datum Corporation</Customer>
<Key>0003</Key>
</Item>
<Item>
<Customer>A. Datum Corporation</Customer>
<Key>0004</Key>
</Item>
<Item>
<Customer>Fabrikam, Inc.</Customer>
<Key>0005</Key>
</Item>
<Item>
<Customer>Fabrikam, Inc.</Customer>
<Key>0006</Key>
</Item>
<Item>
<Customer>Fabrikam, Inc.</Customer>
<Key>0007</Key>
</Item>
</Root>
Nasıl yapılır: Büyük XML belgelerinin (C#) akış
dönüşümünü gerçekleştirme
23.10.2019 • 6 minutes to read • Edit Online

Bazen büyük XML dosyalarını dönüştürmeniz ve uygulamanın bellek parmak izin tahmin edilebilir olması için
uygulamanızı yazmanız gerekir. Bir XML ağacını çok büyük bir XML dosyası ile doldurmayı denerseniz, bellek
kullanımınız dosyanın boyutuyla (aşırı) orantılı olacaktır. Bu nedenle, bunun yerine bir akış tekniği kullanmanız
gerekir.
Akış teknikleri en iyi şekilde, kaynak belgeyi yalnızca bir kez işleyebilmeniz ve öğeleri belge düzeninde
işleyebilirsiniz. Gibi belirli standart sorgu işleçleri OrderBy, kaynaklarını yineleyebilir, tüm verileri toplar, sıralar ve
son olarak dizideki ilk öğeyi verir. İlk öğeyi bırakmadan önce kaynağını üreten bir sorgu işleci kullanırsanız,
uygulamanız için küçük bir bellek parmak izini saklayacağınızı unutmayın.
Şu şekilde açıklanan tekniği kullanıyor olsanız da: Üst bilgi bilgilerine erişimi olan XML parçaları akışı (C#),
dönüştürülmüş belgeyi içeren bir xml ağacını birleştirmek istiyorsanız, bellek kullanımı çok büyük olur.
İki ana yaklaşım vardır. Bir yaklaşım, ertelenmiş işleme özelliklerini XStreamingElementkullanmaktır. Başka bir
yaklaşım ise oluşturmak XmlWriterve ' a öğeleri yazmak LINQ - XML XmlWriteriçin yeteneklerini kullanmaktır. Bu
konuda her iki yaklaşım da gösterilmektedir.

Örnek
Aşağıdaki örnek , nasıl yapılır: Üst bilgi bilgilerine (C#) erişimi olan XML parçalarını akışa ın.
Bu örnek, çıktıyı akışa XStreamingElement almak için ertelenmiş yürütme yeteneklerini kullanır. Bu örnek, küçük
bir bellek parmak izini koruyarak çok büyük bir belgeyi dönüştürebilir.
Özel eksenin ( StreamCustomerItem ) özellikle Customer , Name , ve Item öğelerinin bulunduğu bir belgeyi
beklediğinden ve bu öğelerin aşağıdaki Source. xml belgesinde düzenlenebilmesini sağlayacak şekilde yazıldığını
unutmayın. Ancak, daha güçlü bir uygulama, geçersiz bir belgeyi ayrıştırmaya hazırlanmalıdır.
Kaynak. xml kaynak belgesi aşağıda verilmiştir:
<?xml version="1.0" encoding="utf-8" ?>
<Root>
<Customer>
<Name>A. Datum Corporation</Name>
<Item>
<Key>0001</Key>
</Item>
<Item>
<Key>0002</Key>
</Item>
<Item>
<Key>0003</Key>
</Item>
<Item>
<Key>0004</Key>
</Item>
</Customer>
<Customer>
<Name>Fabrikam, Inc.</Name>
<Item>
<Key>0005</Key>
</Item>
<Item>
<Key>0006</Key>
</Item>
<Item>
<Key>0007</Key>
</Item>
<Item>
<Key>0008</Key>
</Item>
</Customer>
<Customer>
<Name>Southridge Video</Name>
<Item>
<Key>0009</Key>
</Item>
<Item>
<Key>0010</Key>
</Item>
</Customer>
</Root>
static IEnumerable<XElement> StreamCustomerItem(string uri)
{
using (XmlReader reader = XmlReader.Create(uri))
{
XElement name = null;
XElement item = null;

reader.MoveToContent();

// Parse the file, save header information when encountered, and yield the
// Item XElement objects as they are created.

// loop through Customer elements


while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element
&& reader.Name == "Customer")
{
// move to Name element
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element &&
reader.Name == "Name")
{
name = XElement.ReadFrom(reader) as XElement;
break;
}
}

// loop through Item elements


while (reader.Read())
{
if (reader.NodeType == XmlNodeType.EndElement)
break;
if (reader.NodeType == XmlNodeType.Element
&& reader.Name == "Item")
{
item = XElement.ReadFrom(reader) as XElement;
if (item != null)
{
XElement tempRoot = new XElement("Root",
new XElement(name)
);
tempRoot.Add(item);
yield return item;
}
}
}
}
}
}
}

static void Main(string[] args)


{
XStreamingElement root = new XStreamingElement("Root",
from el in StreamCustomerItem("Source.xml")
select new XElement("Item",
new XElement("Customer", (string)el.Parent.Element("Name")),
new XElement(el.Element("Key"))
)
);
root.Save("Test.xml");
Console.WriteLine(File.ReadAllText("Test.xml"));
}
Bu kod aşağıdaki çıktıyı üretir:

<?xml version="1.0" encoding="utf-8"?>


<Root>
<Item>
<Customer>A. Datum Corporation</Customer>
<Key>0001</Key>
</Item>
<Item>
<Customer>A. Datum Corporation</Customer>
<Key>0002</Key>
</Item>
<Item>
<Customer>A. Datum Corporation</Customer>
<Key>0003</Key>
</Item>
<Item>
<Customer>A. Datum Corporation</Customer>
<Key>0004</Key>
</Item>
<Item>
<Customer>Fabrikam, Inc.</Customer>
<Key>0005</Key>
</Item>
<Item>
<Customer>Fabrikam, Inc.</Customer>
<Key>0006</Key>
</Item>
<Item>
<Customer>Fabrikam, Inc.</Customer>
<Key>0007</Key>
</Item>
<Item>
<Customer>Fabrikam, Inc.</Customer>
<Key>0008</Key>
</Item>
<Item>
<Customer>Southridge Video</Customer>
<Key>0009</Key>
</Item>
<Item>
<Customer>Southridge Video</Customer>
<Key>0010</Key>
</Item>
</Root>

Örnek
Aşağıdaki örnek ayrıca nasıl yapılır: Üst bilgi bilgilerine (C#) erişimi olan XML parçalarını akışa ın.
Bu örnek, XmlWriteröğesine öğeleri yazmak LINQ - XML için özelliğini kullanır. Bu örnek, küçük bir bellek parmak
izini koruyarak çok büyük bir belgeyi dönüştürebilir.
Özel eksenin ( StreamCustomerItem ) özellikle Customer , Name , ve Item öğelerinin bulunduğu bir belgeyi
beklediğinden ve bu öğelerin aşağıdaki Source. xml belgesinde düzenlenebilmesini sağlayacak şekilde yazıldığını
unutmayın. Ancak daha sağlam bir uygulama, kaynak belgeyi bir XSD ile doğrular ya da geçersiz bir belgeyi
ayrıştırmaya hazırlanmalıdır.
Bu örnek, bu konudaki önceki örnekte olduğu gibi, Source. xml kaynak belgesini kullanır. Aynı zamanda tam olarak
aynı çıktıyı da üretir.
Akış XStreamingElement XML 'sini akışa almak için kullanmak, bir XmlWriteröğesine yazmak yerine tercih edilir.
static IEnumerable<XElement> StreamCustomerItem(string uri)
{
using (XmlReader reader = XmlReader.Create(uri))
{
XElement name = null;
XElement item = null;

reader.MoveToContent();

// Parse the file, save header information when encountered, and yield the
// Item XElement objects as they are created.

// loop through Customer elements


while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element
&& reader.Name == "Customer")
{
// move to Name element
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element &&
reader.Name == "Name")
{
name = XElement.ReadFrom(reader) as XElement;
break;
}
}

// loop through Item elements


while (reader.Read())
{
if (reader.NodeType == XmlNodeType.EndElement)
break;
if (reader.NodeType == XmlNodeType.Element
&& reader.Name == "Item")
{
item = XElement.ReadFrom(reader) as XElement;
if (item != null) {
XElement tempRoot = new XElement("Root",
new XElement(name)
);
tempRoot.Add(item);
yield return item;
}
}
}
}
}
}
}

static void Main(string[] args)


{
IEnumerable<XElement> srcTree =
from el in StreamCustomerItem("Source.xml")
select new XElement("Item",
new XElement("Customer", (string)el.Parent.Element("Name")),
new XElement(el.Element("Key"))
);
XmlWriterSettings xws = new XmlWriterSettings();
xws.OmitXmlDeclaration = true;
xws.Indent = true;
using (XmlWriter xw = XmlWriter.Create("Output.xml", xws)) {
xw.WriteStartElement("Root");
foreach (XElement el in srcTree)
el.WriteTo(xw);
xw.WriteEndElement();
}
string str = File.ReadAllText("Output.xml");
Console.WriteLine(str);
}

Bu kod aşağıdaki çıktıyı üretir:

<Root>
<Item>
<Customer>A. Datum Corporation</Customer>
<Key>0001</Key>
</Item>
<Item>
<Customer>A. Datum Corporation</Customer>
<Key>0002</Key>
</Item>
<Item>
<Customer>A. Datum Corporation</Customer>
<Key>0003</Key>
</Item>
<Item>
<Customer>A. Datum Corporation</Customer>
<Key>0004</Key>
</Item>
<Item>
<Customer>Fabrikam, Inc.</Customer>
<Key>0005</Key>
</Item>
<Item>
<Customer>Fabrikam, Inc.</Customer>
<Key>0006</Key>
</Item>
<Item>
<Customer>Fabrikam, Inc.</Customer>
<Key>0007</Key>
</Item>
<Item>
<Customer>Fabrikam, Inc.</Customer>
<Key>0008</Key>
</Item>
<Item>
<Customer>Southridge Video</Customer>
<Key>0009</Key>
</Item>
<Item>
<Customer>Southridge Video</Customer>
<Key>0010</Key>
</Item>
</Root>
Nasıl yapılır: Kodlanmış bir belgeyi okuma ve yazma
(C#)
23.10.2019 • 2 minutes to read • Edit Online

Kodlanmış bir XML belgesi oluşturmak için, XML ağacına bir XDeclaration ekler ve kodlamayı istenen kod sayfası
adına ayarlar.
Tarafından WebName döndürülen herhangi bir değer geçerli bir değerdir.
Kodlanmış bir belgeyi okuduğunuzda, Encoding özelliği kod sayfası adına ayarlanır.
Geçerli bir kod Encoding sayfası adı olarak ayarlarsanız, LINQ - XML belirtilen kodlamayla serileştirilir.

Örnek
Aşağıdaki örnek, biri UTF -8 kodlaması ve diğeri UTF -16 kodlaması ile iki belge oluşturur. Daha sonra belgeleri
yükler ve kodlamayı konsola yazdırır.

Console.WriteLine("Creating a document with utf-8 encoding");


XDocument encodedDoc8 = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XElement("Root", "Content")
);
encodedDoc8.Save("EncodedUtf8.xml");
Console.WriteLine("Encoding is:{0}", encodedDoc8.Declaration.Encoding);
Console.WriteLine();

Console.WriteLine("Creating a document with utf-16 encoding");


XDocument encodedDoc16 = new XDocument(
new XDeclaration("1.0", "utf-16", "yes"),
new XElement("Root", "Content")
);
encodedDoc16.Save("EncodedUtf16.xml");
Console.WriteLine("Encoding is:{0}", encodedDoc16.Declaration.Encoding);
Console.WriteLine();

XDocument newDoc8 = XDocument.Load("EncodedUtf8.xml");


Console.WriteLine("Encoded document:");
Console.WriteLine(File.ReadAllText("EncodedUtf8.xml"));
Console.WriteLine();
Console.WriteLine("Encoding of loaded document is:{0}", newDoc8.Declaration.Encoding);
Console.WriteLine();

XDocument newDoc16 = XDocument.Load("EncodedUtf16.xml");


Console.WriteLine("Encoded document:");
Console.WriteLine(File.ReadAllText("EncodedUtf16.xml"));
Console.WriteLine();
Console.WriteLine("Encoding of loaded document is:{0}", newDoc16.Declaration.Encoding);

Bu örnek aşağıdaki çıktıyı üretir:


Creating a document with utf-8 encoding
Encoding is:utf-8

Creating a document with utf-16 encoding


Encoding is:utf-16

Encoded document:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Root>Content</Root>

Encoding of loaded document is:utf-8

Encoded document:
<?xml version="1.0" encoding="utf-16" standalone="yes"?>
<Root>Content</Root>

Encoding of loaded document is:utf-16

Ayrıca bkz.
XDeclaration.Encoding
XML ağacını dönüştürmek için XSLT kullanma (C#)
25.11.2019 • 2 minutes to read • Edit Online

XML ağacı oluşturabilir, XML ağacından bir XmlReader oluşturabilir, yeni bir belge oluşturabilir ve yeni belgeye
yazılacak bir XmlWriter oluşturabilirsiniz. Sonra XSLT dönüşümünü çağırabilirsiniz, XmlReader ve XmlWriter
dönüştürmeye taşıyabilirsiniz. Dönüştürme başarıyla tamamlandıktan sonra, yeni XML ağacı dönüştürmenin
sonuçlarıyla doldurulur.

Örnek
string xslt = @"<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
<xsl:template match='/Parent'>
<Root>
<C1>
<xsl:value-of select='Child1'/>
</C1>
<C2>
<xsl:value-of select='Child2'/>
</C2>
</Root>
</xsl:template>
</xsl:stylesheet>";

var oldDocument = new XDocument(


new XElement("Parent",
new XElement("Child1", "Child1 data"),
new XElement("Child2", "Child2 data")
)
);

var newDocument = new XDocument();

using (var stringReader = new StringReader(xslt))


{
using (XmlReader xsltReader = XmlReader.Create(stringReader))
{
var transformer = new XslCompiledTransform();
transformer.Load(xsltReader);
using (XmlReader oldDocumentReader = oldDocument.CreateReader())
{
using (XmlWriter newDocumentWriter = newDocument.CreateWriter())
{
transformer.Transform(oldDocumentReader, newDocumentWriter);
}
}
}
}

string result = newDocument.ToString();


Console.WriteLine(result);

Bu örnek aşağıdaki çıktıyı üretir:


<Root>
<C1>Child1 data</C1>
<C2>Child2 data</C2>
</Root>

Ayrıca bkz.
XContainer.CreateWriter
XNode.CreateReader
Nasıl yapılır: XSLT stilinde (C#) LINQ to XML
ağaçlarını dönüştürmek Için ek açıklamaları kullanın
23.10.2019 • 9 minutes to read • Edit Online

Ek açıklamalar, bir XML ağacının dönüştürmelerini kolaylaştırmak için kullanılabilir.


Bazı XML belgeleri "karışık içerikli belge merkezli" dir. Bu tür belgeler sayesinde bir öğenin alt düğümlerinin şeklini
bilmeniz gerekmez. Örneğin, metin içeren bir düğüm şöyle görünebilir:

<text>A phrase with <b>bold</b> and <i>italic</i> text.</text>

Belirli bir metin düğümü için herhangi bir sayıda alt <b> öğe ve <i> öğe olabilir. Bu yaklaşım, normal paragraflar,
madde işaretli paragraflar ve bit eşlemler gibi çeşitli alt öğeler içerebilen sayfalar gibi bir dizi diğer durum için
genişler. Bir tablodaki hücreler metin, açılan liste veya bit eşlemler içerebilir. Belge merkezli XML 'in birincil
özelliklerinden biri, belirli bir öğenin hangi alt öğesi olacağını bilemezsiniz.
Dönüştürmek istediğiniz öğelerin alt öğeleri hakkında daha fazla bilgi sahibi olmadığınız bir ağaçtaki öğeleri
dönüştürmek istiyorsanız, ek açıklamaları kullanan bu yaklaşım etkili bir yaklaşımdır.
Yaklaşımın Özeti:
İlk olarak, ağaç içindeki öğeleri bir değiştirme öğesiyle birlikte not edin.
İkinci olarak, tüm ağaç üzerinde yineleme yapın, her öğeyi ek açıklamasına göre değiştirdiğiniz yeni bir ağaç
oluşturun. Bu örnek, adlı XForm bir işlevde yeni ağacın yinelemesini ve oluşturulmasını uygular.
Ayrıntılı olarak yaklaşım aşağıdakilerden oluşur:
Bir şekilden diğerine dönüştürmek istediğiniz öğe kümesini döndüren bir veya daha fazla LINQ to XML
sorgu yürütün. Sorgudaki her öğe için, öğesine ek açıklama olarak yeni XElement bir nesne ekleyin. Bu yeni
öğe, yeni, dönüştürülmüş ağaçtaki açıklamalı öğenin yerini alır. Bu, örnekte gösterildiği gibi yazılacak basit
koddur.
Ek açıklama olarak eklenen yeni öğe, yeni alt düğümler içerebilir; istediğiniz herhangi bir şekle sahip bir alt
ağaç oluşturabilir.
Özel bir kural vardır: Yeni öğenin bir alt düğümü farklı bir ad alanında, bu amaçla oluşturulmuş bir ad alanı
ise (Bu örnekte, ad alanı http://www.microsoft.com/LinqToXmlTransform/2007 ), bu alt öğe yeni ağaca
kopyalanmaz. Bunun yerine, ad alanı yukarıda belirtilen özel ad alanıdır ve öğesinin yerel adı ise, Kaynak
ağacındaki öğenin alt ApplyTransforms düğümleri yinelenir ve yeni ağaca kopyalanır (ek açıklamalı alt
öğelerin olduğu özel durum ile). kendileri bu kurallara göre dönüştürülür).
Bu, XSL 'teki dönüşümler belirtimine benzer. Düğüm kümesi seçen sorgu, bir şablon için XPath ifadesine
benzer. Bir ek açıklama olarak kaydedilen yeni XElement oluşturma kodu, XSL 'deki dizi oluşturucusuna
benzerdir ApplyTransforms ve öğesi xsl:apply-templates , XSL 'deki öğesine benzerdir.
Bu yaklaşımı almanın avantajlarından biri olan sorgular, her zaman değiştirilmemiş kaynak ağacına sorgu
yazırsınız. Ağaçta yapılan değişikliklerin yazmakta olduğunuz sorguları nasıl etkilediği konusunda
endişelenmeniz gerekmez.

Ağacı dönüştürme
Bu ilk örnek, tüm Paragraph düğümleri öğesine para yeniden adlandırır.

XNamespace xf = "http://www.microsoft.com/LinqToXmlTransform/2007";
XName at = xf + "ApplyTransforms";

XElement root = XElement.Parse(@"


<Root>
<Paragraph>This is a sentence with <b>bold</b> and <i>italic</i> text.</Paragraph>
<Paragraph>More text.</Paragraph>
</Root>");

// replace Paragraph with para


foreach (var el in root.Descendants("Paragraph"))
el.AddAnnotation(
new XElement("para",
// same idea as xsl:apply-templates
new XElement(xf + "ApplyTransforms")
)
);

// The XForm method, shown later in this topic, accomplishes the transform
XElement newRoot = XForm(root);

Console.WriteLine(newRoot);

Bu örnek aşağıdaki çıktıyı üretir:

<Root>
<para>This is a sentence with <b>bold</b> and <i>italic</i> text.</para>
<para>More text.</para>
</Root>

Daha karmaşık bir dönüşüm


Aşağıdaki örnek, ağacı sorgular ve Data öğelerin ortalamasını ve toplamını hesaplar ve bunları ağaca yeni öğeler
olarak ekler.
XNamespace xf = "http://www.microsoft.com/LinqToXmlTransform/2007";
XName at = xf + "ApplyTransforms";

XElement data = new XElement("Root",


new XElement("Data", 20),
new XElement("Data", 10),
new XElement("Data", 3)
);

// while adding annotations, you can query the source tree all you want,
// as the tree is not mutated while annotating.
var avg = data.Elements("Data").Select(z => (Decimal)z).Average();
data.AddAnnotation(
new XElement("Root",
new XElement(xf + "ApplyTransforms"),
new XElement("Average", $"{avg:F4}"),
new XElement("Sum",
data
.Elements("Data")
.Select(z => (int)z)
.Sum()
)
)
);

Console.WriteLine("Before Transform");
Console.WriteLine("----------------");
Console.WriteLine(data);
Console.WriteLine();
Console.WriteLine();

// The XForm method, shown later in this topic, accomplishes the transform
XElement newData = XForm(data);

Console.WriteLine("After Transform");
Console.WriteLine("----------------");
Console.WriteLine(newData);

Bu örnek aşağıdaki çıktıyı üretir:

Before Transform
----------------
<Root>
<Data>20</Data>
<Data>10</Data>
<Data>3</Data>
</Root>

After Transform
----------------
<Root>
<Data>20</Data>
<Data>10</Data>
<Data>3</Data>
<Average>11.0000</Average>
<Sum>33</Sum>
</Root>

Dönüşümü efekt
Küçük bir işlev XForm olan özgün, açıklamalı ağaç içinden yeni bir dönüştürülmüş ağaç oluşturur.
İşlevin sahte kodu oldukça basittir:
The function takes an XElement as an argument and returns an XElement.
If an element has an XElement annotation, then
Return a new XElement
The name of the new XElement is the annotation element's name.
All attributes are copied from the annotation to the new node.
All child nodes are copied from the annotation, with the
exception that the special node xf:ApplyTransforms is
recognized, and the source element's child nodes are
iterated. If the source child node is not an XElement, it
is copied to the new tree. If the source child is an
XElement, then it is transformed by calling this function
recursively.
If an element is not annotated
Return a new XElement
The name of the new XElement is the source element's name
All attributes are copied from the source element to the
destination's element.
All child nodes are copied from the source element.
If the source child node is not an XElement, it is copied to
the new tree. If the source child is an XElement, then it
is transformed by calling this function recursively.

Bu işlevin uygulanması aşağıda verilmiştir:


// Build a transformed XML tree per the annotations
static XElement XForm(XElement source)
{
XNamespace xf = "http://www.microsoft.com/LinqToXmlTransform/2007";
XName at = xf + "ApplyTransforms";

if (source.Annotation<XElement>() != null)
{
XElement anno = source.Annotation<XElement>();
return new XElement(anno.Name,
anno.Attributes(),
anno
.Nodes()
.Select(
(XNode n) =>
{
XElement annoEl = n as XElement;
if (annoEl != null)
{
if (annoEl.Name == at)
return (object)(
source.Nodes()
.Select(
(XNode n2) =>
{
XElement e2 = n2 as XElement;
if (e2 == null)
return n2;
else
return XForm(e2);
}
)
);
else
return n;
}
else
return n;
}
)
);
}
else
{
return new XElement(source.Name,
source.Attributes(),
source
.Nodes()
.Select(n =>
{
XElement el = n as XElement;
if (el == null)
return n;
else
return XForm(el);
}
)
);
}
}

Tam Örnek
Aşağıdaki kod, XForm işlevi içeren bir bütün örnektir. Bu tür bir dönüştürme için tipik kullanımları içerir:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

class Program
{
static XNamespace xf = "http://www.microsoft.com/LinqToXmlTransform/2007";
static XName at = xf + "ApplyTransforms";

// Build a transformed XML tree per the annotations


static XElement XForm(XElement source)
{
if (source.Annotation<XElement>() != null)
{
XElement anno = source.Annotation<XElement>();
return new XElement(anno.Name,
anno.Attributes(),
anno
.Nodes()
.Select(
(XNode n) =>
{
XElement annoEl = n as XElement;
if (annoEl != null)
{
if (annoEl.Name == at)
return (object)(
source.Nodes()
.Select(
(XNode n2) =>
{
XElement e2 = n2 as XElement;
if (e2 == null)
return n2;
else
return XForm(e2);
}
)
);
else
return n;
}
else
return n;
}
)
);
}
else
{
return new XElement(source.Name,
source.Attributes(),
source
.Nodes()
.Select(n =>
{
XElement el = n as XElement;
if (el == null)
return n;
else
return XForm(el);
}
)
);
}
}
}

static void Main(string[] args)


{
XElement root = new XElement("Root",
new XComment("A comment"),
new XAttribute("Att1", 123),
new XElement("Child", 1),
new XElement("Child", 2),
new XElement("Other",
new XElement("GC", 3),
new XElement("GC", 4)
),
XElement.Parse(
"<SomeMixedContent>This is <i>an</i> element that " +
"<b>has</b> some mixed content</SomeMixedContent>"),
new XElement("AnUnchangedElement", 42)
);

// each of the following serves the same semantic purpose as


// XSLT templates and sequence constructors

// replace Child with NewChild


foreach (var el in root.Elements("Child"))
el.AddAnnotation(new XElement("NewChild", (string)el));

// replace first GC with GrandChild, add an attribute


foreach (var el in root.Descendants("GC").Take(1))
el.AddAnnotation(
new XElement("GrandChild",
new XAttribute("ANewAttribute", 999),
(string)el
)
);

// replace Other with NewOther, add new child elements around original content
foreach (var el in root.Elements("Other"))
el.AddAnnotation(
new XElement("NewOther",
new XElement("MyNewChild", 1),
// same idea as xsl:apply-templates
new XElement(xf + "ApplyTransforms"),
new XElement("ChildThatComesAfter")
)
);

// change name of element that has mixed content


root.Descendants("SomeMixedContent").First().AddAnnotation(
new XElement("MixedContent",
new XElement(xf + "ApplyTransforms")
)
);

// replace <b> with <Bold>


foreach (var el in root.Descendants("b"))
el.AddAnnotation(
new XElement("Bold",
new XElement(xf + "ApplyTransforms")
)
);

// replace <i> with <Italic>


foreach (var el in root.Descendants("i"))
el.AddAnnotation(
new XElement("Italic",
new XElement(xf + "ApplyTransforms")
)
);

Console.WriteLine("Before Transform");
Console.WriteLine("Before Transform");
Console.WriteLine("----------------");
Console.WriteLine(root);
Console.WriteLine();
Console.WriteLine();
XElement newRoot = XForm(root);

Console.WriteLine("After Transform");
Console.WriteLine("----------------");
Console.WriteLine(newRoot);
}
}

Bu örnek aşağıdaki çıktıyı üretir:

Before Transform
----------------
<Root Att1="123">
<!--A comment-->
<Child>1</Child>
<Child>2</Child>
<Other>
<GC>3</GC>
<GC>4</GC>
</Other>
<SomeMixedContent>This is <i>an</i> element that <b>has</b> some mixed content</SomeMixedContent>
<AnUnchangedElement>42</AnUnchangedElement>
</Root>

After Transform
----------------
<Root Att1="123">
<!--A comment-->
<NewChild>1</NewChild>
<NewChild>2</NewChild>
<NewOther>
<MyNewChild>1</MyNewChild>
<GrandChild ANewAttribute="999">3</GrandChild>
<GC>4</GC>
<ChildThatComesAfter />
</NewOther>
<MixedContent>This is <Italic>an</Italic> element that <Bold>has</Bold> some mixed content</MixedContent>
<AnUnchangedElement>42</AnUnchangedElement>
</Root>
Nasıl yapılır: XmlSerializer (C#) kullanarak serileştirme
23.10.2019 • 2 minutes to read • Edit Online

Bu konuda, kullanarak XmlSerializerseri hale getirilen ve seri hale getirilen bir örnek gösterilmektedir.

Örnek
Aşağıdaki örnek, XElement nesneleri içeren bir dizi nesne oluşturur. Daha sonra bunları bir bellek akışına serileştirir
ve sonra bellek akışından serileştirir.
using System;
using System.IO;
using System.Linq;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.Linq;

public class XElementContainer


{
public XElement member;

public XElementContainer()
{
member = XLinqTest.CreateXElement();
}

public override string ToString()


{
return member.ToString();
}
}

public class XElementNullContainer


{
public XElement member;

public XElementNullContainer()
{
}
}

class XLinqTest
{
static void Main(string[] args)
{
Test<XElementNullContainer>(new XElementNullContainer());
Test<XElement>(CreateXElement());
Test<XElementContainer>(new XElementContainer());
}

public static XElement CreateXElement()


{
XNamespace ns = "http://www.adventure-works.com";
return new XElement(ns + "aw");
}

static void Test<T>(T obj)


{
using (MemoryStream stream = new MemoryStream())
{
XmlSerializer s = new XmlSerializer(typeof(T));
Console.WriteLine("Testing for type: {0}", typeof(T));
s.Serialize(XmlWriter.Create(stream), obj);
stream.Flush();
stream.Seek(0, SeekOrigin.Begin);
object o = s.Deserialize(XmlReader.Create(stream));
Console.WriteLine(" Deserialized type: {0}", o.GetType());
}
}
}

Bu örnek aşağıdaki çıktıyı üretir:


Testing for type: XElementNullContainer
Deserialized type: XElementNullContainer
Testing for type: System.Xml.Linq.XElement
Deserialized type: System.Xml.Linq.XElement
Testing for type: XElementContainer
Deserialized type: XElementContainer
Nasıl yapılır: DataContractSerializer (C#) kullanarak
serileştirme
23.10.2019 • 2 minutes to read • Edit Online

Bu konuda, kullanarak DataContractSerializerseri hale getirilen ve seri hale getirilen bir örnek gösterilmektedir.

Örnek
Aşağıdaki örnek, XElement nesneleri içeren bir dizi nesne oluşturur. Daha sonra bunları metin dosyalarına
serileştirir ve metin dosyalarından serileştirir.
using System;
using System.Xml;
using System.Xml.Linq;
using System.IO;
using System.Runtime.Serialization;

public class XLinqTest


{
public static void Main()
{
Test<XElement>(CreateXElement());
Test<XElementContainer>(new XElementContainer());
Test<XElementNullContainer>(new XElementNullContainer());
}

public static void Test<T>(T obj)


{
DataContractSerializer s = new DataContractSerializer(typeof(T));
using (FileStream fs = File.Open("test" + typeof(T).Name + ".xml", FileMode.Create))
{
Console.WriteLine("Testing for type: {0}", typeof(T));
s.WriteObject(fs, obj);
}
using (FileStream fs = File.Open("test" + typeof(T).Name + ".xml", FileMode.Open))
{
object s2 = s.ReadObject(fs);
if (s2 == null)
Console.WriteLine(" Deserialized object is null (Nothing in VB)");
else
Console.WriteLine(" Deserialized type: {0}", s2.GetType());
}
}

public static XElement CreateXElement()


{
return new XElement(XName.Get("NameInNamespace", "http://www.adventure-works.org"));
}
}

[DataContract]
public class XElementContainer
{
[DataMember]
public XElement member;

public XElementContainer()
{
member = XLinqTest.CreateXElement();
}
}

[DataContract]
public class XElementNullContainer
{
[DataMember]
public XElement member;

public XElementNullContainer()
{
member = null;
}
}

Bu örnek aşağıdaki çıktıyı üretir:


Testing for type: System.Xml.Linq.XElement
Deserialized type: System.Xml.Linq.XElement
Testing for type: XElementContainer
Deserialized type: XElementContainer
Testing for type: XElementNullContainer
Deserialized type: XElementNullContainer
LINQ to XML güvenliği (C#)
4.11.2019 • 13 minutes to read • Edit Online

Bu konuda LINQ to XML ilişkili güvenlik sorunları açıklanmaktadır. Ayrıca, güvenlik açısından etkilenme riskini
azaltmak için bazı kılavuzluk sağlar.

LINQ to XML güvenliğe genel bakış


LINQ to XML, katı güvenlik gereksinimlerine sahip sunucu tarafı uygulamalardan daha fazla programlama
kolaylığı için tasarlanmıştır. Çoğu XML senaryosu, bir sunucuya yüklenen güvenilmeyen XML belgelerini işlemek
yerine, güvenilen XML belgelerinin işlenmesini içerir. LINQ to XML, bu senaryolar için iyileştirilmiştir.
Bilinmeyen kaynaklardan güvenilmeyen verileri işleyebilmeniz gerekiyorsa, Microsoft, bilinen XML hizmet reddi
(DoS ) saldırılarını filtrelemek için yapılandırılmış XmlReader sınıfının bir örneğini kullanmanızı önerir.
Hizmet reddi saldırılarını azaltmak için bir XmlReader yapılandırdıysanız, bu okuyucuyu kullanarak bir LINQ to
XML ağacını doldurabilir ve LINQ to XML programcı üretkenlik geliştirmelerinden faydalanabilirsiniz. Birçok
azaltma tekniği, güvenlik sorununu hafifletmek üzere yapılandırılmış okuyucular oluşturmayı ve sonra
yapılandırılmış okuyucu aracılığıyla bir XML ağacını örneklamayı içerir.
Belgeler boyut, derinlik, öğe adı boyutu ve daha fazlası için sınırsız olduğundan, XML, hizmet reddi saldırılarına
karşı doğası gereği açıktır. XML işlemek için kullandığınız bileşenden bağımsız olarak, aşırı kaynak kullanıyorsa
uygulama etki alanını geri dönüştürmeye her zaman hazırlıklı olmalısınız.

XML, XSD, XPath ve XSLT saldırıları üzerinde risk azaltma


LINQ to XML, XmlReader ve XmlWriteroluşturulur. LINQ to XML, System.Xml.Schema ve System.Xml.XPath ad
alanlarında uzantı yöntemleri aracılığıyla XSD ve XPath 'i destekler. LINQ to XML ile birlikte XmlReader,
XPathNavigatorve XmlWriter sınıfları kullanarak XML ağaçlarını dönüştürmek için XSLT 'yi çağırabilirsiniz.
Daha az güvenli bir ortamda çalışıyorsanız, XML ile ilişkili çeşitli güvenlik sorunları ve System.Xml,
System.Xml.Schema, System.Xml.XPathve System.Xml.Xslsınıfların kullanımı vardır. Bu sorunlar şunları içerir, ancak
bunlarla sınırlı değildir:
XSD, XPath ve XSLT, çok fazla zamanı veya belleği kullanan işlemleri belirtebileceğiniz dize tabanlı dillerdir.
Dizelerin kötü amaçlı olmayan kaynaklardan XSD, XPath veya XSLT dizeleri alan ve bu dizeleri
değerlendirme olasılığını izlemek ve azaltmak için, aşırı sisteme yol açacağından kaynak tüketimi.
XSD şemaları (satır içi şemalar dahil), doğal olarak hizmet reddi saldırılarına karşı savunmasız kalır;
Güvenilmeyen kaynaklardan şemaları kabul etmemelisiniz.
XSD ve XSLT diğer dosyalara başvurular içerebilir ve bu tür başvurular, bölgeler arası ve etki alanları arası
saldırılara yol açabilir.
DTD 'lerde dış varlıklar, bölgeler arası ve etki alanları arası saldırılara yol açabilir.
DTD 'Ler hizmet reddi saldırılarına karşı savunmasızdır.
Daha fazla derin XML belgesi, hizmet reddi sorunları oluşturabilir; XML belgelerinin derinliğini kısıtlamak
isteyebilirsiniz.
Güvenilmeyen derlemelerden NameTable, XmlNamespaceManagerve XmlResolver nesneleri gibi
destekleyici bileşenleri kabul etmez.
Büyük belge saldırılarını azaltmak için öbeklerdeki verileri okuyun.
XSLT stil sayfalarındaki betik blokları çok sayıda saldırı sunabilir.
Dinamik XPath ifadelerini oluşturmadan önce dikkatle doğrulayın.

LINQ to XML güvenlik sorunları


Bu konudaki güvenlik sorunları belirli bir sırada sunulmaz. Tüm sorunlar önemlidir ve uygun şekilde ele alınmalıdır.
Başarılı bir ayrıcalık yükselmesi saldırısı, kendi ortamı üzerinde kötü amaçlı bir derlemeye daha fazla denetim
sağlar. Başarılı bir ayrıcalık yükseltme saldırısı, verilerin açığa çıkmasına, hizmet reddine ve daha fazlasına neden
olabilir.
Uygulamalar, verileri görme yetkisine sahip olmayan kullanıcılara verileri açıklamamalıdır.
Hizmet reddi saldırıları, XML ayrıştırıcısının veya LINQ to XML aşırı miktarda belleği veya CPU süresini
kullanmasına neden olur. Hizmet reddi saldırıları, ayrıcalık saldırılarının yükseltilmesinin veya veri saldırılarının
açıklanmasının daha az önemli olduğu kabul edilir. Ancak, bir sunucunun güvenilmeyen kaynaklardan XML
belgelerini işlemesi gereken bir senaryoda bu durumlar önemlidir.
Özel durumlar ve hata Iletileri verileri açığa çıkarmayabilir
Bir hatanın açıklaması, dönüştürülen veriler, dosya adları veya uygulama ayrıntıları gibi verileri açığa çıkarmayabilir.
Hata iletileri güvenilmeyen çağıranlara gösterilmemelidir. Kendi özel hata mesajlarınız ile tüm hataları ve rapor
hatalarını yakalamalı.
CodeAccessPermissions. bir olay Işleyicisinde onay çağrısı yapın
Bir derlemenin daha az veya daha fazla izni olabilir. Daha fazla izne sahip bir derleme, bilgisayar ve ortamları
üzerinde daha fazla denetime sahiptir.
Daha büyük izinlere sahip bir derlemede bulunan kod bir olay işleyicisinde CodeAccessPermission.Assert çağırır ve
sonra XML ağacı sınırlı izinlere sahip kötü amaçlı bir derlemeye geçirilirse, kötü amaçlı derleme bir olayın
oluşturulmasına neden olabilir. Olay derlemede daha fazla izinle kod çalıştırdığı için kötü amaçlı derleme
yükseltilmiş ayrıcalıklarla çalışır.
Microsoft, bir olay işleyicisinde CodeAccessPermission.Assert hiçbir şekilde çağırmanızı önerir.
DTD 'Ler güvenli değil
DTD 'lerde varlıklar, doğal olarak güvenli değildir.Bir DTD içeren kötü amaçlı bir XML belgesi, ayrıştırıcısının tüm
belleği ve CPU süresini kullanmasına neden olur ve bu da hizmet reddi saldırısına neden olur. Bu nedenle, LINQ to
XML öğesinde DTD işleme varsayılan olarak kapalıdır. Güvenilmeyen kaynaklardan DTD 'Leri kabul etmemelisiniz.
Güvenilmeyen kaynaklardan DTD 'Leri kabul etmenin bir örneği, Web kullanıcılarının bir DTD 'ye ve DTD
dosyasına başvuran bir XML dosyasını karşıya yüklemesine izin veren bir Web uygulamasıdır. Dosyanın
doğrulanması sırasında, kötü amaçlı bir DTD sunucunuz üzerinde bir hizmet reddi saldırısı yürütebilir.
Güvenilmeyen kaynaklardan DTD 'Lerin kabul edilmesi için başka bir örnek de, anonim FTP erişimine izin veren bir
ağ paylaşımındaki bir DTD 'ye başvurulmalıdır.
Aşırı arabellek ayırmayı önleyin
Uygulama geliştiricileri, son derece büyük veri kaynaklarının kaynak tükenmesi ve hizmet reddi saldırılarına yol
açabileceğini bilmelidir.
Kötü amaçlı bir Kullanıcı çok büyük bir XML belgesi gönderdiğinde veya karşıya yüklediğinde, LINQ to XML aşırı
sistem kaynağı kullanmasına neden olabilir. Bu, bir hizmet reddi saldırısı oluşturabilir. Bunu engellemek için
XmlReaderSettings.MaxCharactersInDocument özelliğini ayarlayabilir ve daha sonra yükleyebilen belgenin
boyutuyla sınırlı bir okuyucu oluşturabilirsiniz. Ardından, XML ağacı oluşturmak için okuyucuyu kullanın.
Örneğin, güvenilir olmayan bir kaynaktan gelen XML belgelerinin beklenen maksimum boyutunun 50 k bayttan
daha az olacağını biliyorsanız, XmlReaderSettings.MaxCharactersInDocument 100.000 olarak ayarlayın. Bu, XML
belgelerinin işlenmesini içermez ve aynı zamanda, belgelerin karşıya yüklenmesi, büyük miktarlarda bellek
tüketebileceği hizmet reddi tehditleri ortadan kaldırılır.
Aşırı varlık genişletmesinin önleyin
DTD kullanırken bilinen hizmet reddi saldırılarına bir, aşırı varlık genişlemesine neden olan bir belgedir.Bunu
engellemek için XmlReaderSettings.MaxCharactersFromEntities özelliğini ayarlayabilir ve daha sonra varlık
genişletmesinden kaynaklanan karakter sayısında sınırlı bir okuyucu oluşturabilirsiniz. Ardından, XML ağacı
oluşturmak için okuyucuyu kullanın.
XML hiyerarşisinin derinliğini sınırlayın
Olası bir hizmet reddi saldırısı, çok sayıda hiyerarşi içeren bir belge gönderildiğinde gönderilir. Bunu engellemek
için, öğelerin derinliğini sayan kendi sınıfınıza bir XmlReader sardırabilirsiniz. Derinlik önceden belirlenmiş makul
bir düzeyi aşarsa, kötü amaçlı belgeyi işlemeyi sonlandırabilirsiniz.
Güvenilmeyen XmlReader veya XmlWriter uygulamalarına karşı koruma
Yöneticiler dışarıdan sağlanan tüm XmlReader veya XmlWriter uygulamalarının tanımlayıcı adlara sahip olduğunu
ve makine yapılandırmasında kayıtlı olduğunu doğrulamalıdır. Bu, kötü amaçlı kodun bir okuyucu veya yazıcının
yüklenmesini önler.
XName 'e başvuran düzenli olarak ücretsiz nesneler
Uygulama programcılarının belirli türlerde saldırılara karşı korunması için, uygulama etki alanındaki bir XName
nesnesine düzenli olarak başvuran tüm nesneleri boşaltmalıdır.
Rastgele XML adlarına karşı koruma
Güvenilmeyen kaynaklardan veri alan uygulamalar, rastgele XML adları ve ad alanları olasılığını denetlemek için
özel kodda Sarmalanan bir XmlReader kullanmayı göz önünde bulundurmalıdır. Bu tür rastgele XML adları ve ad
alanları algılanırsa, uygulama kötü amaçlı belgenin işlenmesini sonlandırabilir.
Belirli bir ad alanındaki (ad alanı olmayan adlar dahil) ad sayısını makul bir sınıra sınırlamak isteyebilirsiniz.
Ek açıklamalar LINQ to XML ağacı paylaşan yazılım bileşenleri tarafından erişilebilir
LINQ to XML, farklı uygulama bileşenlerinin XML ağaçları olarak bileşenler arasında geçirilen XML verilerini
yükleme, doğrulama, sorgulama, dönüştürme, güncelleştirme ve kaydetme işlem hatlarını oluşturmak için
kullanılabilir. Bu, XML metnine nesne yükleme ve serileştirilmesinin yükü yalnızca işlem hattının sonunda
yapıldığından performansı iyileştirmenize yardımcı olabilir. Ancak geliştiriciler, bir bileşen tarafından oluşturulan
tüm ek açıklamaların ve olay işleyicilerinin diğer bileşenler tarafından erişilebilir olduğunu bilmelidir. Bu,
bileşenlerin farklı düzeylerde güven düzeyine sahip olması halinde bir dizi güvenlik açığı oluşturabilir. Daha az
güvenilir bileşenlere güvenli işlem hatları oluşturmak için, verileri güvenilmeyen bir bileşene geçirmeden önce
LINQ to XML nesneleri XML metnine serileştirmelidir.
Bazı güvenlik, ortak dil çalışma zamanı (CLR ) tarafından sağlanır. Örneğin, özel bir sınıf içermeyen bir bileşen, bu
sınıf tarafından anahtarlanan ek açıklamaların erişimine erişemez. Ancak, ek açıklamalar bunları
okuyadesteklemeyen bileşenler tarafından silinebilir. Bu, bir izinsiz saldırı olarak kullanılabilir.

Ayrıca bkz.
Programlama Kılavuzu (LINQ to XML ) (C#)
Örnek XML Dosyası: Tipik Satın Alma Siparişi
(LINQ to XML)
23.10.2019 • 2 minutes to read • Edit Online

Aşağıdaki XML dosyasını çeşitli örneklerde kullanılan LINQ - XML belgeleri. Tipik satın alma siparişi
dosyasıdır.

PurchaseOrder.xml
<?xml version="1.0"?>
<PurchaseOrder PurchaseOrderNumber="99503" OrderDate="1999-10-20">
<Address Type="Shipping">
<Name>Ellen Adams</Name>
<Street>123 Maple Street</Street>
<City>Mill Valley</City>
<State>CA</State>
<Zip>10999</Zip>
<Country>USA</Country>
</Address>
<Address Type="Billing">
<Name>Tai Yee</Name>
<Street>8 Oak Avenue</Street>
<City>Old Town</City>
<State>PA</State>
<Zip>95819</Zip>
<Country>USA</Country>
</Address>
<DeliveryNotes>Please leave packages in shed by driveway.</DeliveryNotes>
<Items>
<Item PartNumber="872-AA">
<ProductName>Lawnmower</ProductName>
<Quantity>1</Quantity>
<USPrice>148.95</USPrice>
<Comment>Confirm this is electric</Comment>
</Item>
<Item PartNumber="926-AA">
<ProductName>Baby Monitor</ProductName>
<Quantity>2</Quantity>
<USPrice>39.98</USPrice>
<ShipDate>1999-05-21</ShipDate>
</Item>
</Items>
</PurchaseOrder>
Örnek XML Dosyası: Bir Ad Alanında Tipik Satın
Alma Siparişi
23.10.2019 • 2 minutes to read • Edit Online

Aşağıdaki XML dosyası LINQ - XML belgelerindeki çeşitli örneklerde kullanılır. Bu dosya tipik bir satın alma
siparişi. XML bir ad alanıdır.

PurchaseOrderInNamespace. xml
<?xml version="1.0"?>
<aw:PurchaseOrder
aw:PurchaseOrderNumber="99503"
aw:OrderDate="1999-10-20"
xmlns:aw="http://www.adventure-works.com">
<aw:Address aw:Type="Shipping">
<aw:Name>Ellen Adams</aw:Name>
<aw:Street>123 Maple Street</aw:Street>
<aw:City>Mill Valley</aw:City>
<aw:State>CA</aw:State>
<aw:Zip>10999</aw:Zip>
<aw:Country>USA</aw:Country>
</aw:Address>
<aw:Address aw:Type="Billing">
<aw:Name>Tai Yee</aw:Name>
<aw:Street>8 Oak Avenue</aw:Street>
<aw:City>Old Town</aw:City>
<aw:State>PA</aw:State>
<aw:Zip>95819</aw:Zip>
<aw:Country>USA</aw:Country>
</aw:Address>
<aw:DeliveryNotes>Please leave packages in shed by driveway.</aw:DeliveryNotes>
<aw:Items>
<aw:Item aw:PartNumber="872-AA">
<aw:ProductName>Lawnmower</aw:ProductName>
<aw:Quantity>1</aw:Quantity>
<aw:USPrice>148.95</aw:USPrice>
<aw:Comment>Confirm this is electric</aw:Comment>
</aw:Item>
<aw:Item aw:PartNumber="926-AA">
<aw:ProductName>Baby Monitor</aw:ProductName>
<aw:Quantity>2</aw:Quantity>
<aw:USPrice>39.98</aw:USPrice>
<aw:ShipDate>1999-05-21</aw:ShipDate>
</aw:Item>
</aw:Items>
</aw:PurchaseOrder>
Örnek XML Dosyası: Birden Fazla Satın Alma
Siparişi (LINQ to XML)
23.10.2019 • 2 minutes to read • Edit Online

Aşağıdaki XML dosyasını çeşitli örneklerde kullanılan LINQ - XML belgeleri. Bu dosya, çeşitli satın alma
siparişleri içerir.

PurchaseOrders.xml
<?xml version="1.0"?>
<PurchaseOrders>
<PurchaseOrder PurchaseOrderNumber="99503" OrderDate="1999-10-20">
<Address Type="Shipping">
<Name>Ellen Adams</Name>
<Street>123 Maple Street</Street>
<City>Mill Valley</City>
<State>CA</State>
<Zip>10999</Zip>
<Country>USA</Country>
</Address>
<Address Type="Billing">
<Name>Tai Yee</Name>
<Street>8 Oak Avenue</Street>
<City>Old Town</City>
<State>PA</State>
<Zip>95819</Zip>
<Country>USA</Country>
</Address>
<DeliveryNotes>Please leave packages in shed by driveway.</DeliveryNotes>
<Items>
<Item PartNumber="872-AA">
<ProductName>Lawnmower</ProductName>
<Quantity>1</Quantity>
<USPrice>148.95</USPrice>
<Comment>Confirm this is electric</Comment>
</Item>
<Item PartNumber="926-AA">
<ProductName>Baby Monitor</ProductName>
<Quantity>2</Quantity>
<USPrice>39.98</USPrice>
<ShipDate>1999-05-21</ShipDate>
</Item>
</Items>
</PurchaseOrder>
<PurchaseOrder PurchaseOrderNumber="99505" OrderDate="1999-10-22">
<Address Type="Shipping">
<Name>Cristian Osorio</Name>
<Street>456 Main Street</Street>
<City>Buffalo</City>
<State>NY</State>
<Zip>98112</Zip>
<Country>USA</Country>
</Address>
<Address Type="Billing">
<Name>Cristian Osorio</Name>
<Street>456 Main Street</Street>
<City>Buffalo</City>
<State>NY</State>
<Zip>98112</Zip>
<Country>USA</Country>
<Country>USA</Country>
</Address>
<DeliveryNotes>Please notify me before shipping.</DeliveryNotes>
<Items>
<Item PartNumber="456-NM">
<ProductName>Power Supply</ProductName>
<Quantity>1</Quantity>
<USPrice>45.99</USPrice>
</Item>
</Items>
</PurchaseOrder>
<PurchaseOrder PurchaseOrderNumber="99504" OrderDate="1999-10-22">
<Address Type="Shipping">
<Name>Jessica Arnold</Name>
<Street>4055 Madison Ave</Street>
<City>Seattle</City>
<State>WA</State>
<Zip>98112</Zip>
<Country>USA</Country>
</Address>
<Address Type="Billing">
<Name>Jessica Arnold</Name>
<Street>4055 Madison Ave</Street>
<City>Buffalo</City>
<State>NY</State>
<Zip>98112</Zip>
<Country>USA</Country>
</Address>
<Items>
<Item PartNumber="898-AZ">
<ProductName>Computer Keyboard</ProductName>
<Quantity>1</Quantity>
<USPrice>29.99</USPrice>
</Item>
<Item PartNumber="898-AM">
<ProductName>Wireless Mouse</ProductName>
<Quantity>1</Quantity>
<USPrice>14.99</USPrice>
</Item>
</Items>
</PurchaseOrder>
</PurchaseOrders>
Örnek XML Dosyası: Bir Ad Alanında Birden Fazla
Satın Alma Siparişi
23.10.2019 • 2 minutes to read • Edit Online

Aşağıdaki XML dosyasını çeşitli örneklerde kullanılan LINQ - XML belgeleri. Bu dosya, çeşitli satın alma siparişleri
içerir. Bir ad alanında XML'dir.

PurchaseOrdersInNamespace.xml
<?xml version="1.0" encoding="utf-8"?>
<aw:PurchaseOrders xmlns:aw="http://www.adventure-works.com">
<aw:PurchaseOrder aw:PurchaseOrderNumber="99503" aw:OrderDate="1999-10-20">
<aw:Address aw:Type="Shipping">
<aw:Name>Ellen Adams</aw:Name>
<aw:Street>123 Maple Street</aw:Street>
<aw:City>Mill Valley</aw:City>
<aw:State>CA</aw:State>
<aw:Zip>10999</aw:Zip>
<aw:Country>USA</aw:Country>
</aw:Address>
<aw:Address aw:Type="Billing">
<aw:Name>Tai Yee</aw:Name>
<aw:Street>8 Oak Avenue</aw:Street>
<aw:City>Old Town</aw:City>
<aw:State>PA</aw:State>
<aw:Zip>95819</aw:Zip>
<aw:Country>USA</aw:Country>
</aw:Address>
<aw:DeliveryNotes>Please leave packages in shed by driveway.</aw:DeliveryNotes>
<aw:Items>
<aw:Item aw:PartNumber="872-AA">
<aw:ProductName>Lawnmower</aw:ProductName>
<aw:Quantity>1</aw:Quantity>
<aw:USPrice>148.95</aw:USPrice>
<aw:Comment>Confirm this is electric</aw:Comment>
</aw:Item>
<aw:Item aw:PartNumber="926-AA">
<aw:ProductName>Baby Monitor</aw:ProductName>
<aw:Quantity>2</aw:Quantity>
<aw:USPrice>39.98</aw:USPrice>
<aw:ShipDate>1999-05-21</aw:ShipDate>
</aw:Item>
</aw:Items>
</aw:PurchaseOrder>
<aw:PurchaseOrder aw:PurchaseOrderNumber="99505" aw:OrderDate="1999-10-22">
<aw:Address aw:Type="Shipping">
<aw:Name>Cristian Osorio</aw:Name>
<aw:Street>456 Main Street</aw:Street>
<aw:City>Buffalo</aw:City>
<aw:State>NY</aw:State>
<aw:Zip>98112</aw:Zip>
<aw:Country>USA</aw:Country>
</aw:Address>
<aw:Address aw:Type="Billing">
<aw:Name>Cristian Osorio</aw:Name>
<aw:Street>456 Main Street</aw:Street>
<aw:City>Buffalo</aw:City>
<aw:State>NY</aw:State>
<aw:Zip>98112</aw:Zip>
<aw:Country>USA</aw:Country>
<aw:Country>USA</aw:Country>
</aw:Address>
<aw:DeliveryNotes>Please notify me before shipping.</aw:DeliveryNotes>
<aw:Items>
<aw:Item aw:PartNumber="456-NM">
<aw:ProductName>Power Supply</aw:ProductName>
<aw:Quantity>1</aw:Quantity>
<aw:USPrice>45.99</aw:USPrice>
</aw:Item>
</aw:Items>
</aw:PurchaseOrder>
<aw:PurchaseOrder aw:PurchaseOrderNumber="99504" aw:OrderDate="1999-10-22">
<aw:Address aw:Type="Shipping">
<aw:Name>Jessica Arnold</aw:Name>
<aw:Street>4055 Madison Ave</aw:Street>
<aw:City>Seattle</aw:City>
<aw:State>WA</aw:State>
<aw:Zip>98112</aw:Zip>
<aw:Country>USA</aw:Country>
</aw:Address>
<aw:Address aw:Type="Billing">
<aw:Name>Jessica Arnold</aw:Name>
<aw:Street>4055 Madison Ave</aw:Street>
<aw:City>Buffalo</aw:City>
<aw:State>NY</aw:State>
<aw:Zip>98112</aw:Zip>
<aw:Country>USA</aw:Country>
</aw:Address>
<aw:Items>
<aw:Item aw:PartNumber="898-AZ">
<aw:ProductName>Computer Keyboard</aw:ProductName>
<aw:Quantity>1</aw:Quantity>
<aw:USPrice>29.99</aw:USPrice>
</aw:Item>
<aw:Item aw:PartNumber="898-AM">
<aw:ProductName>Wireless Mouse</aw:ProductName>
<aw:Quantity>1</aw:Quantity>
<aw:USPrice>14.99</aw:USPrice>
</aw:Item>
</aw:Items>
</aw:PurchaseOrder>
</aw:PurchaseOrders>
Örnek XML Dosyası: Test Yapılandırması (LINQ to
XML)
23.10.2019 • 2 minutes to read • Edit Online

Aşağıdaki XML dosyasını çeşitli örneklerde kullanılan LINQ - XML belgeleri. Bu bir test yapılandırma dosyasıdır.

TestConfig.xml
<?xml version="1.0"?>
<Tests>
<Test TestId="0001" TestType="CMD">
<Name>Convert number to string</Name>
<CommandLine>Examp1.EXE</CommandLine>
<Input>1</Input>
<Output>One</Output>
</Test>
<Test TestId="0002" TestType="CMD">
<Name>Find succeeding characters</Name>
<CommandLine>Examp2.EXE</CommandLine>
<Input>abc</Input>
<Output>def</Output>
</Test>
<Test TestId="0003" TestType="GUI">
<Name>Convert multiple numbers to strings</Name>
<CommandLine>Examp2.EXE /Verbose</CommandLine>
<Input>123</Input>
<Output>One Two Three</Output>
</Test>
<Test TestId="0004" TestType="GUI">
<Name>Find correlated key</Name>
<CommandLine>Examp3.EXE</CommandLine>
<Input>a1</Input>
<Output>b1</Output>
</Test>
<Test TestId="0005" TestType="GUI">
<Name>Count characters</Name>
<CommandLine>FinalExamp.EXE</CommandLine>
<Input>This is a test</Input>
<Output>14</Output>
</Test>
<Test TestId="0006" TestType="GUI">
<Name>Another Test</Name>
<CommandLine>Examp2.EXE</CommandLine>
<Input>Test Input</Input>
<Output>10</Output>
</Test>
</Tests>
Örnek XML Dosyası: Bir Ad Alanında Test
Yapılandırması
23.10.2019 • 2 minutes to read • Edit Online

Aşağıdaki XML dosyası LINQ - XML belgelerindeki çeşitli örneklerde kullanılır. Bu bir test yapılandırma dosyasıdır.
XML bir ad alanıdır.

Testconfigınnamespace. xml
<?xml version="1.0"?>
<Tests xmlns="http://www.adatum.com">
<Test TestId="0001" TestType="CMD">
<Name>Convert number to string</Name>
<CommandLine>Examp1.EXE</CommandLine>
<Input>1</Input>
<Output>One</Output>
</Test>
<Test TestId="0002" TestType="CMD">
<Name>Find succeeding characters</Name>
<CommandLine>Examp2.EXE</CommandLine>
<Input>abc</Input>
<Output>def</Output>
</Test>
<Test TestId="0003" TestType="GUI">
<Name>Convert multiple numbers to strings</Name>
<CommandLine>Examp2.EXE /Verbose</CommandLine>
<Input>123</Input>
<Output>One Two Three</Output>
</Test>
<Test TestId="0004" TestType="GUI">
<Name>Find correlated key</Name>
<CommandLine>Examp3.EXE</CommandLine>
<Input>a1</Input>
<Output>b1</Output>
</Test>
<Test TestId="0005" TestType="GUI">
<Name>Count characters</Name>
<CommandLine>FinalExamp.EXE</CommandLine>
<Input>This is a test</Input>
<Output>14</Output>
</Test>
<Test TestId="0006" TestType="GUI">
<Name>Another Test</Name>
<CommandLine>Examp2.EXE</CommandLine>
<Input>Test Input</Input>
<Output>10</Output>
</Test>
</Tests>
Örnek XML Dosyası: Müşteriler ve Siparişler (LINQ
to XML)
23.10.2019 • 4 minutes to read • Edit Online

Aşağıdaki XML dosyası LINQ - XML belgelerindeki çeşitli örneklerde kullanılır. Bu dosya müşteriler ve
siparişler içerir.
Örnek örnek xsd dosyası: Müşteriler ve siparişler , bu belgeyi doğrulamak için kullanılabilecek bir xsd içerir.
xs:key CustomerID xs:keyref Öğeözniteliğinin biranahtar CustomerID olduğunu ve her Order öğe ve
içindeki öğe arasında bir ilişki oluşturmasını sağlamak için xsd 'nin ve özelliklerini kullanır. Customer
CustomerID her Customer öğe için özniteliği.

Join Yan tümcesini kullanarak bu ilişkiden faydalanan LINQ sorguları yazma örneği için bkz . nasıl yapılır:
Iki koleksiyona (LINQ to XML ) (C#)birleştirin.

CustomersOrders. xml
<?xml version="1.0" encoding="utf-8"?>
<Root>
<Customers>
<Customer CustomerID="GREAL">
<CompanyName>Great Lakes Food Market</CompanyName>
<ContactName>Howard Snyder</ContactName>
<ContactTitle>Marketing Manager</ContactTitle>
<Phone>(503) 555-7555</Phone>
<FullAddress>
<Address>2732 Baker Blvd.</Address>
<City>Eugene</City>
<Region>OR</Region>
<PostalCode>97403</PostalCode>
<Country>USA</Country>
</FullAddress>
</Customer>
<Customer CustomerID="HUNGC">
<CompanyName>Hungry Coyote Import Store</CompanyName>
<ContactName>Yoshi Latimer</ContactName>
<ContactTitle>Sales Representative</ContactTitle>
<Phone>(503) 555-6874</Phone>
<Fax>(503) 555-2376</Fax>
<FullAddress>
<Address>City Center Plaza 516 Main St.</Address>
<City>Elgin</City>
<Region>OR</Region>
<PostalCode>97827</PostalCode>
<Country>USA</Country>
</FullAddress>
</Customer>
<Customer CustomerID="LAZYK">
<CompanyName>Lazy K Kountry Store</CompanyName>
<ContactName>John Steel</ContactName>
<ContactTitle>Marketing Manager</ContactTitle>
<Phone>(509) 555-7969</Phone>
<Fax>(509) 555-6221</Fax>
<FullAddress>
<Address>12 Orchestra Terrace</Address>
<City>Walla Walla</City>
<Region>WA</Region>
<PostalCode>99362</PostalCode>
<Country>USA</Country>
</FullAddress>
</Customer>
<Customer CustomerID="LETSS">
<CompanyName>Let's Stop N Shop</CompanyName>
<ContactName>Jaime Yorres</ContactName>
<ContactTitle>Owner</ContactTitle>
<Phone>(415) 555-5938</Phone>
<FullAddress>
<Address>87 Polk St. Suite 5</Address>
<City>San Francisco</City>
<Region>CA</Region>
<PostalCode>94117</PostalCode>
<Country>USA</Country>
</FullAddress>
</Customer>
</Customers>
<Orders>
<Order>
<CustomerID>GREAL</CustomerID>
<EmployeeID>6</EmployeeID>
<OrderDate>1997-05-06T00:00:00</OrderDate>
<RequiredDate>1997-05-20T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1997-05-09T00:00:00">
<ShipVia>2</ShipVia>
<Freight>3.35</Freight>
<ShipName>Great Lakes Food Market</ShipName>
<ShipAddress>2732 Baker Blvd.</ShipAddress>
<ShipCity>Eugene</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97403</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>GREAL</CustomerID>
<EmployeeID>8</EmployeeID>
<OrderDate>1997-07-04T00:00:00</OrderDate>
<RequiredDate>1997-08-01T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1997-07-14T00:00:00">
<ShipVia>2</ShipVia>
<Freight>4.42</Freight>
<ShipName>Great Lakes Food Market</ShipName>
<ShipAddress>2732 Baker Blvd.</ShipAddress>
<ShipCity>Eugene</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97403</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>GREAL</CustomerID>
<EmployeeID>1</EmployeeID>
<OrderDate>1997-07-31T00:00:00</OrderDate>
<RequiredDate>1997-08-28T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1997-08-05T00:00:00">
<ShipVia>2</ShipVia>
<Freight>116.53</Freight>
<ShipName>Great Lakes Food Market</ShipName>
<ShipAddress>2732 Baker Blvd.</ShipAddress>
<ShipCity>Eugene</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97403</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>GREAL</CustomerID>
<EmployeeID>4</EmployeeID>
<EmployeeID>4</EmployeeID>
<OrderDate>1997-07-31T00:00:00</OrderDate>
<RequiredDate>1997-08-28T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1997-08-04T00:00:00">
<ShipVia>2</ShipVia>
<Freight>18.53</Freight>
<ShipName>Great Lakes Food Market</ShipName>
<ShipAddress>2732 Baker Blvd.</ShipAddress>
<ShipCity>Eugene</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97403</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>GREAL</CustomerID>
<EmployeeID>6</EmployeeID>
<OrderDate>1997-09-04T00:00:00</OrderDate>
<RequiredDate>1997-10-02T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1997-09-10T00:00:00">
<ShipVia>1</ShipVia>
<Freight>57.15</Freight>
<ShipName>Great Lakes Food Market</ShipName>
<ShipAddress>2732 Baker Blvd.</ShipAddress>
<ShipCity>Eugene</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97403</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>GREAL</CustomerID>
<EmployeeID>3</EmployeeID>
<OrderDate>1997-09-25T00:00:00</OrderDate>
<RequiredDate>1997-10-23T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1997-09-30T00:00:00">
<ShipVia>3</ShipVia>
<Freight>76.13</Freight>
<ShipName>Great Lakes Food Market</ShipName>
<ShipAddress>2732 Baker Blvd.</ShipAddress>
<ShipCity>Eugene</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97403</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>GREAL</CustomerID>
<EmployeeID>4</EmployeeID>
<OrderDate>1998-01-06T00:00:00</OrderDate>
<RequiredDate>1998-02-03T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1998-02-04T00:00:00">
<ShipVia>2</ShipVia>
<Freight>719.78</Freight>
<ShipName>Great Lakes Food Market</ShipName>
<ShipAddress>2732 Baker Blvd.</ShipAddress>
<ShipCity>Eugene</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97403</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>GREAL</CustomerID>
<EmployeeID>3</EmployeeID>
<OrderDate>1998-03-09T00:00:00</OrderDate>
<RequiredDate>1998-04-06T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1998-03-18T00:00:00">
<ShipVia>2</ShipVia>
<Freight>33.68</Freight>
<Freight>33.68</Freight>
<ShipName>Great Lakes Food Market</ShipName>
<ShipAddress>2732 Baker Blvd.</ShipAddress>
<ShipCity>Eugene</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97403</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>GREAL</CustomerID>
<EmployeeID>3</EmployeeID>
<OrderDate>1998-04-07T00:00:00</OrderDate>
<RequiredDate>1998-05-05T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1998-04-15T00:00:00">
<ShipVia>2</ShipVia>
<Freight>25.19</Freight>
<ShipName>Great Lakes Food Market</ShipName>
<ShipAddress>2732 Baker Blvd.</ShipAddress>
<ShipCity>Eugene</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97403</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>GREAL</CustomerID>
<EmployeeID>4</EmployeeID>
<OrderDate>1998-04-22T00:00:00</OrderDate>
<RequiredDate>1998-05-20T00:00:00</RequiredDate>
<ShipInfo>
<ShipVia>3</ShipVia>
<Freight>18.84</Freight>
<ShipName>Great Lakes Food Market</ShipName>
<ShipAddress>2732 Baker Blvd.</ShipAddress>
<ShipCity>Eugene</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97403</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>GREAL</CustomerID>
<EmployeeID>4</EmployeeID>
<OrderDate>1998-04-30T00:00:00</OrderDate>
<RequiredDate>1998-06-11T00:00:00</RequiredDate>
<ShipInfo>
<ShipVia>3</ShipVia>
<Freight>14.01</Freight>
<ShipName>Great Lakes Food Market</ShipName>
<ShipAddress>2732 Baker Blvd.</ShipAddress>
<ShipCity>Eugene</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97403</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>HUNGC</CustomerID>
<EmployeeID>3</EmployeeID>
<OrderDate>1996-12-06T00:00:00</OrderDate>
<RequiredDate>1997-01-03T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1996-12-09T00:00:00">
<ShipVia>2</ShipVia>
<Freight>20.12</Freight>
<ShipName>Hungry Coyote Import Store</ShipName>
<ShipAddress>City Center Plaza 516 Main St.</ShipAddress>
<ShipCity>Elgin</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97827</ShipPostalCode>
<ShipPostalCode>97827</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>HUNGC</CustomerID>
<EmployeeID>1</EmployeeID>
<OrderDate>1996-12-25T00:00:00</OrderDate>
<RequiredDate>1997-01-22T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1997-01-03T00:00:00">
<ShipVia>3</ShipVia>
<Freight>30.34</Freight>
<ShipName>Hungry Coyote Import Store</ShipName>
<ShipAddress>City Center Plaza 516 Main St.</ShipAddress>
<ShipCity>Elgin</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97827</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>HUNGC</CustomerID>
<EmployeeID>3</EmployeeID>
<OrderDate>1997-01-15T00:00:00</OrderDate>
<RequiredDate>1997-02-12T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1997-01-24T00:00:00">
<ShipVia>1</ShipVia>
<Freight>0.2</Freight>
<ShipName>Hungry Coyote Import Store</ShipName>
<ShipAddress>City Center Plaza 516 Main St.</ShipAddress>
<ShipCity>Elgin</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97827</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>HUNGC</CustomerID>
<EmployeeID>4</EmployeeID>
<OrderDate>1997-07-16T00:00:00</OrderDate>
<RequiredDate>1997-08-13T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1997-07-21T00:00:00">
<ShipVia>1</ShipVia>
<Freight>45.13</Freight>
<ShipName>Hungry Coyote Import Store</ShipName>
<ShipAddress>City Center Plaza 516 Main St.</ShipAddress>
<ShipCity>Elgin</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97827</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>HUNGC</CustomerID>
<EmployeeID>8</EmployeeID>
<OrderDate>1997-09-08T00:00:00</OrderDate>
<RequiredDate>1997-10-06T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1997-10-15T00:00:00">
<ShipVia>1</ShipVia>
<Freight>111.29</Freight>
<ShipName>Hungry Coyote Import Store</ShipName>
<ShipAddress>City Center Plaza 516 Main St.</ShipAddress>
<ShipCity>Elgin</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97827</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>LAZYK</CustomerID>
<CustomerID>LAZYK</CustomerID>
<EmployeeID>1</EmployeeID>
<OrderDate>1997-03-21T00:00:00</OrderDate>
<RequiredDate>1997-04-18T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1997-04-10T00:00:00">
<ShipVia>3</ShipVia>
<Freight>7.48</Freight>
<ShipName>Lazy K Kountry Store</ShipName>
<ShipAddress>12 Orchestra Terrace</ShipAddress>
<ShipCity>Walla Walla</ShipCity>
<ShipRegion>WA</ShipRegion>
<ShipPostalCode>99362</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>LAZYK</CustomerID>
<EmployeeID>8</EmployeeID>
<OrderDate>1997-05-22T00:00:00</OrderDate>
<RequiredDate>1997-06-19T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1997-06-26T00:00:00">
<ShipVia>2</ShipVia>
<Freight>11.92</Freight>
<ShipName>Lazy K Kountry Store</ShipName>
<ShipAddress>12 Orchestra Terrace</ShipAddress>
<ShipCity>Walla Walla</ShipCity>
<ShipRegion>WA</ShipRegion>
<ShipPostalCode>99362</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>LETSS</CustomerID>
<EmployeeID>1</EmployeeID>
<OrderDate>1997-06-25T00:00:00</OrderDate>
<RequiredDate>1997-07-23T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1997-07-04T00:00:00">
<ShipVia>2</ShipVia>
<Freight>13.73</Freight>
<ShipName>Let's Stop N Shop</ShipName>
<ShipAddress>87 Polk St. Suite 5</ShipAddress>
<ShipCity>San Francisco</ShipCity>
<ShipRegion>CA</ShipRegion>
<ShipPostalCode>94117</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>LETSS</CustomerID>
<EmployeeID>8</EmployeeID>
<OrderDate>1997-10-27T00:00:00</OrderDate>
<RequiredDate>1997-11-24T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1997-11-05T00:00:00">
<ShipVia>2</ShipVia>
<Freight>51.44</Freight>
<ShipName>Let's Stop N Shop</ShipName>
<ShipAddress>87 Polk St. Suite 5</ShipAddress>
<ShipCity>San Francisco</ShipCity>
<ShipRegion>CA</ShipRegion>
<ShipPostalCode>94117</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>LETSS</CustomerID>
<EmployeeID>6</EmployeeID>
<OrderDate>1997-11-10T00:00:00</OrderDate>
<RequiredDate>1997-12-08T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1997-11-21T00:00:00">
<ShipVia>2</ShipVia>
<ShipVia>2</ShipVia>
<Freight>45.97</Freight>
<ShipName>Let's Stop N Shop</ShipName>
<ShipAddress>87 Polk St. Suite 5</ShipAddress>
<ShipCity>San Francisco</ShipCity>
<ShipRegion>CA</ShipRegion>
<ShipPostalCode>94117</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>LETSS</CustomerID>
<EmployeeID>4</EmployeeID>
<OrderDate>1998-02-12T00:00:00</OrderDate>
<RequiredDate>1998-03-12T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1998-02-13T00:00:00">
<ShipVia>2</ShipVia>
<Freight>90.97</Freight>
<ShipName>Let's Stop N Shop</ShipName>
<ShipAddress>87 Polk St. Suite 5</ShipAddress>
<ShipCity>San Francisco</ShipCity>
<ShipRegion>CA</ShipRegion>
<ShipPostalCode>94117</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
</Orders>
</Root>
Örnek XSD Dosyası: Müşteriler ve Siparişler
23.10.2019 • 2 minutes to read • Edit Online

Aşağıdaki xsd dosyası LINQ - XML belgelerindeki çeşitli örneklerde kullanılır. Bu dosya, örnek xml dosyası için
bir şema tanımı içerir: Müşteriler ve siparişler (LINQ to XML ). Şema xs:key , CustomerID xs:keyref
öğeözniteliğininbiranahtar CustomerID olduğunu ve her Order bir öğedeki öğe arasında bir ilişki kurmayı
oluşturmak için xsd 'nin ve özelliklerini kullanır ve Customer CustomerID her Customer öğe için özniteliği.
Join Yan tümcesini kullanarak bu ilişkiden faydalanan LINQ sorguları yazma örneği için bkz . nasıl yapılır: Iki
koleksiyona (LINQ to XML ) (C#)birleştirin.

Müştermicders. xsd
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name='Root'>
<xs:complexType>
<xs:sequence>
<xs:element name='Customers'>
<xs:complexType>
<xs:sequence>
<xs:element name='Customer' type='CustomerType' minOccurs='0' maxOccurs='unbounded' />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name='Orders'>
<xs:complexType>
<xs:sequence>
<xs:element name='Order' type='OrderType' minOccurs='0' maxOccurs='unbounded' />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:key name='CustomerIDKey'>
<xs:selector xpath='Customers/Customer'/>
<xs:field xpath='@CustomerID'/>
</xs:key>
<xs:keyref name='CustomerIDKeyRef' refer='CustomerIDKey'>
<xs:selector xpath='Orders/Order'/>
<xs:field xpath='CustomerID'/>
</xs:keyref>
</xs:element>
<xs:complexType name='CustomerType'>
<xs:sequence>
<xs:element name='CompanyName' type='xs:string'/>
<xs:element name='ContactName' type='xs:string'/>
<xs:element name='ContactTitle' type='xs:string'/>
<xs:element name='Phone' type='xs:string'/>
<xs:element name='Fax' minOccurs='0' type='xs:string'/>
<xs:element name='FullAddress' type='AddressType'/>
</xs:sequence>
<xs:attribute name='CustomerID' type='xs:token'/>
</xs:complexType>
<xs:complexType name='AddressType'>
<xs:sequence>
<xs:element name='Address' type='xs:string'/>
<xs:element name='City' type='xs:string'/>
<xs:element name='Region' type='xs:string'/>
<xs:element name='PostalCode' type='xs:string' />
<xs:element name='PostalCode' type='xs:string' />
<xs:element name='Country' type='xs:string'/>
</xs:sequence>
<xs:attribute name='CustomerID' type='xs:token'/>
</xs:complexType>
<xs:complexType name='OrderType'>
<xs:sequence>
<xs:element name='CustomerID' type='xs:token'/>
<xs:element name='EmployeeID' type='xs:token'/>
<xs:element name='OrderDate' type='xs:dateTime'/>
<xs:element name='RequiredDate' type='xs:dateTime'/>
<xs:element name='ShipInfo' type='ShipInfoType'/>
</xs:sequence>
</xs:complexType>
<xs:complexType name='ShipInfoType'>
<xs:sequence>
<xs:element name='ShipVia' type='xs:integer'/>
<xs:element name='Freight' type='xs:decimal'/>
<xs:element name='ShipName' type='xs:string'/>
<xs:element name='ShipAddress' type='xs:string'/>
<xs:element name='ShipCity' type='xs:string'/>
<xs:element name='ShipRegion' type='xs:string'/>
<xs:element name='ShipPostalCode' type='xs:string'/>
<xs:element name='ShipCountry' type='xs:string'/>
</xs:sequence>
<xs:attribute name='ShippedDate' type='xs:dateTime'/>
</xs:complexType>
</xs:schema>
Örnek XML Dosyası: Bir Ad Alanında Müşteriler ve
Siparişler
23.10.2019 • 3 minutes to read • Edit Online

Aşağıdaki XML dosyasını çeşitli örneklerde kullanılan LINQ - XML belgeleri. Bu dosya, müşteriler ve siparişler
içerir. Bir ad alanında XML'dir.

CustomersOrdersInNamespace.xml
<?xml version="1.0" encoding="utf-8"?>
<Root xmlns="http://www.adventure-works.com">
<Customers>
<Customer CustomerID="GREAL">
<CompanyName>Great Lakes Food Market</CompanyName>
<ContactName>Howard Snyder</ContactName>
<ContactTitle>Marketing Manager</ContactTitle>
<Phone>(503) 555-7555</Phone>
<FullAddress>
<Address>2732 Baker Blvd.</Address>
<City>Eugene</City>
<Region>OR</Region>
<PostalCode>97403</PostalCode>
<Country>USA</Country>
</FullAddress>
</Customer>
<Customer CustomerID="HUNGC">
<CompanyName>Hungry Coyote Import Store</CompanyName>
<ContactName>Yoshi Latimer</ContactName>
<ContactTitle>Sales Representative</ContactTitle>
<Phone>(503) 555-6874</Phone>
<Fax>(503) 555-2376</Fax>
<FullAddress>
<Address>City Center Plaza 516 Main St.</Address>
<City>Elgin</City>
<Region>OR</Region>
<PostalCode>97827</PostalCode>
<Country>USA</Country>
</FullAddress>
</Customer>
<Customer CustomerID="LAZYK">
<CompanyName>Lazy K Kountry Store</CompanyName>
<ContactName>John Steel</ContactName>
<ContactTitle>Marketing Manager</ContactTitle>
<Phone>(509) 555-7969</Phone>
<Fax>(509) 555-6221</Fax>
<FullAddress>
<Address>12 Orchestra Terrace</Address>
<City>Walla Walla</City>
<Region>WA</Region>
<PostalCode>99362</PostalCode>
<Country>USA</Country>
</FullAddress>
</Customer>
<Customer CustomerID="LETSS">
<CompanyName>Let's Stop N Shop</CompanyName>
<ContactName>Jaime Yorres</ContactName>
<ContactTitle>Owner</ContactTitle>
<Phone>(415) 555-5938</Phone>
<FullAddress>
<Address>87 Polk St. Suite 5</Address>
<Address>87 Polk St. Suite 5</Address>
<City>San Francisco</City>
<Region>CA</Region>
<PostalCode>94117</PostalCode>
<Country>USA</Country>
</FullAddress>
</Customer>
</Customers>
<Orders>
<Order>
<CustomerID>GREAL</CustomerID>
<EmployeeID>6</EmployeeID>
<OrderDate>1997-05-06T00:00:00</OrderDate>
<RequiredDate>1997-05-20T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1997-05-09T00:00:00">
<ShipVia>2</ShipVia>
<Freight>3.35</Freight>
<ShipName>Great Lakes Food Market</ShipName>
<ShipAddress>2732 Baker Blvd.</ShipAddress>
<ShipCity>Eugene</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97403</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>GREAL</CustomerID>
<EmployeeID>8</EmployeeID>
<OrderDate>1997-07-04T00:00:00</OrderDate>
<RequiredDate>1997-08-01T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1997-07-14T00:00:00">
<ShipVia>2</ShipVia>
<Freight>4.42</Freight>
<ShipName>Great Lakes Food Market</ShipName>
<ShipAddress>2732 Baker Blvd.</ShipAddress>
<ShipCity>Eugene</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97403</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>GREAL</CustomerID>
<EmployeeID>1</EmployeeID>
<OrderDate>1997-07-31T00:00:00</OrderDate>
<RequiredDate>1997-08-28T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1997-08-05T00:00:00">
<ShipVia>2</ShipVia>
<Freight>116.53</Freight>
<ShipName>Great Lakes Food Market</ShipName>
<ShipAddress>2732 Baker Blvd.</ShipAddress>
<ShipCity>Eugene</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97403</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>GREAL</CustomerID>
<EmployeeID>4</EmployeeID>
<OrderDate>1997-07-31T00:00:00</OrderDate>
<RequiredDate>1997-08-28T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1997-08-04T00:00:00">
<ShipVia>2</ShipVia>
<Freight>18.53</Freight>
<ShipName>Great Lakes Food Market</ShipName>
<ShipAddress>2732 Baker Blvd.</ShipAddress>
<ShipCity>Eugene</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97403</ShipPostalCode>
<ShipPostalCode>97403</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>GREAL</CustomerID>
<EmployeeID>6</EmployeeID>
<OrderDate>1997-09-04T00:00:00</OrderDate>
<RequiredDate>1997-10-02T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1997-09-10T00:00:00">
<ShipVia>1</ShipVia>
<Freight>57.15</Freight>
<ShipName>Great Lakes Food Market</ShipName>
<ShipAddress>2732 Baker Blvd.</ShipAddress>
<ShipCity>Eugene</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97403</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>GREAL</CustomerID>
<EmployeeID>3</EmployeeID>
<OrderDate>1997-09-25T00:00:00</OrderDate>
<RequiredDate>1997-10-23T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1997-09-30T00:00:00">
<ShipVia>3</ShipVia>
<Freight>76.13</Freight>
<ShipName>Great Lakes Food Market</ShipName>
<ShipAddress>2732 Baker Blvd.</ShipAddress>
<ShipCity>Eugene</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97403</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>GREAL</CustomerID>
<EmployeeID>4</EmployeeID>
<OrderDate>1998-01-06T00:00:00</OrderDate>
<RequiredDate>1998-02-03T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1998-02-04T00:00:00">
<ShipVia>2</ShipVia>
<Freight>719.78</Freight>
<ShipName>Great Lakes Food Market</ShipName>
<ShipAddress>2732 Baker Blvd.</ShipAddress>
<ShipCity>Eugene</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97403</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>GREAL</CustomerID>
<EmployeeID>3</EmployeeID>
<OrderDate>1998-03-09T00:00:00</OrderDate>
<RequiredDate>1998-04-06T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1998-03-18T00:00:00">
<ShipVia>2</ShipVia>
<Freight>33.68</Freight>
<ShipName>Great Lakes Food Market</ShipName>
<ShipAddress>2732 Baker Blvd.</ShipAddress>
<ShipCity>Eugene</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97403</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>GREAL</CustomerID>
<CustomerID>GREAL</CustomerID>
<EmployeeID>3</EmployeeID>
<OrderDate>1998-04-07T00:00:00</OrderDate>
<RequiredDate>1998-05-05T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1998-04-15T00:00:00">
<ShipVia>2</ShipVia>
<Freight>25.19</Freight>
<ShipName>Great Lakes Food Market</ShipName>
<ShipAddress>2732 Baker Blvd.</ShipAddress>
<ShipCity>Eugene</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97403</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>GREAL</CustomerID>
<EmployeeID>4</EmployeeID>
<OrderDate>1998-04-22T00:00:00</OrderDate>
<RequiredDate>1998-05-20T00:00:00</RequiredDate>
<ShipInfo>
<ShipVia>3</ShipVia>
<Freight>18.84</Freight>
<ShipName>Great Lakes Food Market</ShipName>
<ShipAddress>2732 Baker Blvd.</ShipAddress>
<ShipCity>Eugene</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97403</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>GREAL</CustomerID>
<EmployeeID>4</EmployeeID>
<OrderDate>1998-04-30T00:00:00</OrderDate>
<RequiredDate>1998-06-11T00:00:00</RequiredDate>
<ShipInfo>
<ShipVia>3</ShipVia>
<Freight>14.01</Freight>
<ShipName>Great Lakes Food Market</ShipName>
<ShipAddress>2732 Baker Blvd.</ShipAddress>
<ShipCity>Eugene</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97403</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>HUNGC</CustomerID>
<EmployeeID>3</EmployeeID>
<OrderDate>1996-12-06T00:00:00</OrderDate>
<RequiredDate>1997-01-03T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1996-12-09T00:00:00">
<ShipVia>2</ShipVia>
<Freight>20.12</Freight>
<ShipName>Hungry Coyote Import Store</ShipName>
<ShipAddress>City Center Plaza 516 Main St.</ShipAddress>
<ShipCity>Elgin</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97827</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>HUNGC</CustomerID>
<EmployeeID>1</EmployeeID>
<OrderDate>1996-12-25T00:00:00</OrderDate>
<RequiredDate>1997-01-22T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1997-01-03T00:00:00">
<ShipVia>3</ShipVia>
<Freight>30.34</Freight>
<ShipName>Hungry Coyote Import Store</ShipName>
<ShipAddress>City Center Plaza 516 Main St.</ShipAddress>
<ShipCity>Elgin</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97827</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>HUNGC</CustomerID>
<EmployeeID>3</EmployeeID>
<OrderDate>1997-01-15T00:00:00</OrderDate>
<RequiredDate>1997-02-12T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1997-01-24T00:00:00">
<ShipVia>1</ShipVia>
<Freight>0.2</Freight>
<ShipName>Hungry Coyote Import Store</ShipName>
<ShipAddress>City Center Plaza 516 Main St.</ShipAddress>
<ShipCity>Elgin</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97827</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>HUNGC</CustomerID>
<EmployeeID>4</EmployeeID>
<OrderDate>1997-07-16T00:00:00</OrderDate>
<RequiredDate>1997-08-13T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1997-07-21T00:00:00">
<ShipVia>1</ShipVia>
<Freight>45.13</Freight>
<ShipName>Hungry Coyote Import Store</ShipName>
<ShipAddress>City Center Plaza 516 Main St.</ShipAddress>
<ShipCity>Elgin</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97827</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>HUNGC</CustomerID>
<EmployeeID>8</EmployeeID>
<OrderDate>1997-09-08T00:00:00</OrderDate>
<RequiredDate>1997-10-06T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1997-10-15T00:00:00">
<ShipVia>1</ShipVia>
<Freight>111.29</Freight>
<ShipName>Hungry Coyote Import Store</ShipName>
<ShipAddress>City Center Plaza 516 Main St.</ShipAddress>
<ShipCity>Elgin</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97827</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>LAZYK</CustomerID>
<EmployeeID>1</EmployeeID>
<OrderDate>1997-03-21T00:00:00</OrderDate>
<RequiredDate>1997-04-18T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1997-04-10T00:00:00">
<ShipVia>3</ShipVia>
<Freight>7.48</Freight>
<ShipName>Lazy K Kountry Store</ShipName>
<ShipAddress>12 Orchestra Terrace</ShipAddress>
<ShipCity>Walla Walla</ShipCity>
<ShipRegion>WA</ShipRegion>
<ShipPostalCode>99362</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>LAZYK</CustomerID>
<EmployeeID>8</EmployeeID>
<OrderDate>1997-05-22T00:00:00</OrderDate>
<RequiredDate>1997-06-19T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1997-06-26T00:00:00">
<ShipVia>2</ShipVia>
<Freight>11.92</Freight>
<ShipName>Lazy K Kountry Store</ShipName>
<ShipAddress>12 Orchestra Terrace</ShipAddress>
<ShipCity>Walla Walla</ShipCity>
<ShipRegion>WA</ShipRegion>
<ShipPostalCode>99362</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>LETSS</CustomerID>
<EmployeeID>1</EmployeeID>
<OrderDate>1997-06-25T00:00:00</OrderDate>
<RequiredDate>1997-07-23T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1997-07-04T00:00:00">
<ShipVia>2</ShipVia>
<Freight>13.73</Freight>
<ShipName>Let's Stop N Shop</ShipName>
<ShipAddress>87 Polk St. Suite 5</ShipAddress>
<ShipCity>San Francisco</ShipCity>
<ShipRegion>CA</ShipRegion>
<ShipPostalCode>94117</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>LETSS</CustomerID>
<EmployeeID>8</EmployeeID>
<OrderDate>1997-10-27T00:00:00</OrderDate>
<RequiredDate>1997-11-24T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1997-11-05T00:00:00">
<ShipVia>2</ShipVia>
<Freight>51.44</Freight>
<ShipName>Let's Stop N Shop</ShipName>
<ShipAddress>87 Polk St. Suite 5</ShipAddress>
<ShipCity>San Francisco</ShipCity>
<ShipRegion>CA</ShipRegion>
<ShipPostalCode>94117</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>LETSS</CustomerID>
<EmployeeID>6</EmployeeID>
<OrderDate>1997-11-10T00:00:00</OrderDate>
<RequiredDate>1997-12-08T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1997-11-21T00:00:00">
<ShipVia>2</ShipVia>
<Freight>45.97</Freight>
<ShipName>Let's Stop N Shop</ShipName>
<ShipAddress>87 Polk St. Suite 5</ShipAddress>
<ShipCity>San Francisco</ShipCity>
<ShipRegion>CA</ShipRegion>
<ShipPostalCode>94117</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
</Order>
<Order>
<CustomerID>LETSS</CustomerID>
<EmployeeID>4</EmployeeID>
<OrderDate>1998-02-12T00:00:00</OrderDate>
<RequiredDate>1998-03-12T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1998-02-13T00:00:00">
<ShipVia>2</ShipVia>
<Freight>90.97</Freight>
<ShipName>Let's Stop N Shop</ShipName>
<ShipAddress>87 Polk St. Suite 5</ShipAddress>
<ShipCity>San Francisco</ShipCity>
<ShipRegion>CA</ShipRegion>
<ShipPostalCode>94117</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
</Orders>
</Root>
Örnek XML Dosyası: Sayısal Veriler (LINQ to XML)
23.10.2019 • 2 minutes to read • Edit Online

Aşağıdaki XML dosyasını çeşitli örneklerde kullanılan LINQ - XML belgeleri. Bu dosya, birleşimi, ortalama ve
Gruplama için sayısal veriler içerir.

Data.xml
<Root>
<TaxRate>7.25</TaxRate>
<Data>
<Category>A</Category>
<Quantity>3</Quantity>
<Price>24.50</Price>
</Data>
<Data>
<Category>B</Category>
<Quantity>1</Quantity>
<Price>89.99</Price>
</Data>
<Data>
<Category>A</Category>
<Quantity>5</Quantity>
<Price>4.95</Price>
</Data>
<Data>
<Category>A</Category>
<Quantity>3</Quantity>
<Price>66.00</Price>
</Data>
<Data>
<Category>B</Category>
<Quantity>10</Quantity>
<Price>.99</Price>
</Data>
<Data>
<Category>A</Category>
<Quantity>15</Quantity>
<Price>29.00</Price>
</Data>
<Data>
<Category>B</Category>
<Quantity>8</Quantity>
<Price>6.99</Price>
</Data>
</Root>
Örnek XML Dosyası: Bir Ad Alanında Sayısal Veriler
23.10.2019 • 2 minutes to read • Edit Online

Aşağıdaki XML dosyasını çeşitli örneklerde kullanılan LINQ - XML belgeleri. Bu dosya, birleşimi, ortalama ve
Gruplama için sayısal veriler içerir. Bir ad alanında XML'dir.

Veri
<Root xmlns='http://www.adatum.com'>
<TaxRate>7.25</TaxRate>
<Data>
<Category>A</Category>
<Quantity>3</Quantity>
<Price>24.50</Price>
</Data>
<Data>
<Category>B</Category>
<Quantity>1</Quantity>
<Price>89.99</Price>
</Data>
<Data>
<Category>A</Category>
<Quantity>5</Quantity>
<Price>4.95</Price>
</Data>
<Data>
<Category>A</Category>
<Quantity>3</Quantity>
<Price>66.00</Price>
</Data>
<Data>
<Category>B</Category>
<Quantity>10</Quantity>
<Price>.99</Price>
</Data>
<Data>
<Category>A</Category>
<Quantity>15</Quantity>
<Price>29.00</Price>
</Data>
<Data>
<Category>B</Category>
<Quantity>8</Quantity>
<Price>6.99</Price>
</Data>
</Root>
Örnek XML Dosyası: Kitaplar (LINQ to XML)
23.10.2019 • 2 minutes to read • Edit Online

Aşağıdaki XML dosyasını çeşitli örneklerde kullanılan LINQ - XML belgeleri. Dosya kitapları hakkında bilgi içerir.

Books.XML
<?xml version="1.0"?>
<Catalog>
<Book id="bk101">
<Author>Garghentini, Davide</Author>
<Title>XML Developer's Guide</Title>
<Genre>Computer</Genre>
<Price>44.95</Price>
<PublishDate>2000-10-01</PublishDate>
<Description>An in-depth look at creating applications
with XML.</Description>
</Book>
<Book id="bk102">
<Author>Garcia, Debra</Author>
<Title>Midnight Rain</Title>
<Genre>Fantasy</Genre>
<Price>5.95</Price>
<PublishDate>2000-12-16</PublishDate>
<Description>A former architect battles corporate zombies,
an evil sorceress, and her own childhood to become queen
of the world.</Description>
</Book>
</Catalog>
Örnek XML Dosyası: Birleştirilmiş Satın Alma
Siparişleri
23.10.2019 • 2 minutes to read • Edit Online

Aşağıdaki XML dosyasını çeşitli örneklerde kullanılan LINQ - XML belgeleri. Bu dosyayı, birden çok şirketlerin
farklı şekiller ile satın alma siparişleri kümesidir. Her bir şirketten satın alma siparişleri ayrı ad alanlarında ' dir.

ConsolidatedPurchaseOrders.xml
<?xml version="1.0"?>
<PurchaseOrders xmlns="www.contoso.com">
<PurchaseOrder
PurchaseOrderNumber="99503"
OrderDate="1999-10-20">
<Address Type="Shipping">
<Name>Ellen Adams</Name>
<Street>123 Maple Street</Street>
<City>Mill Valley</City>
<State>CA</State>
<Zip>10999</Zip>
<Country>USA</Country>
</Address>
<Address Type="Billing">
<Name>Tai Yee</Name>
<Street>8 Oak Avenue</Street>
<City>Old Town</City>
<State>PA</State>
<Zip>95819</Zip>
<Country>USA</Country>
</Address>
<DeliveryNotes>Please leave packages in shed by driveway.</DeliveryNotes>
<Items>
<Item PartNumber="872-AA">
<ProductName>Lawnmower</ProductName>
<Quantity>1</Quantity>
<USPrice>148.95</USPrice>
<Comment>Confirm this is electric</Comment>
</Item>
<Item PartNumber="926-AA">
<ProductName>Baby Monitor</ProductName>
<Quantity>2</Quantity>
<USPrice>39.98</USPrice>
<ShipDate>1999-05-21</ShipDate>
</Item>
</Items>
</PurchaseOrder>
<PurchaseOrder PurchaseOrderNumber="99505" OrderDate="1999-10-22">
<Address Type="Shipping">
<Name>Cristian Osorio</Name>
<Street>456 Main Street</Street>
<City>Buffalo</City>
<State>NY</State>
<Zip>98112</Zip>
<Country>USA</Country>
</Address>
<Address Type="Billing">
<Name>Cristian Osorio</Name>
<Street>456 Main Street</Street>
<City>Buffalo</City>
<State>NY</State>
<State>NY</State>
<Zip>98112</Zip>
<Country>USA</Country>
</Address>
<DeliveryNotes>Please notify by email before shipping.</DeliveryNotes>
<Items>
<Item PartNumber="456-NM">
<ProductName>Power Supply</ProductName>
<Quantity>1</Quantity>
<USPrice>45.99</USPrice>
</Item>
</Items>
</PurchaseOrder>
<PurchaseOrder PurchaseOrderNumber="99504" OrderDate="1999-10-22">
<Address Type="Shipping">
<Name>Jessica Arnold</Name>
<Street>4055 Madison Ave</Street>
<City>Seattle</City>
<State>WA</State>
<Zip>98112</Zip>
<Country>USA</Country>
</Address>
<Address Type="Billing">
<Name>Jessica Arnold</Name>
<Street>4055 Madison Ave</Street>
<City>Buffalo</City>
<State>NY</State>
<Zip>98112</Zip>
<Country>USA</Country>
</Address>
<DeliveryNotes>Please do not deliver on Saturday.</DeliveryNotes>
<Items>
<Item PartNumber="898-AZ">
<ProductName>Computer Keyboard</ProductName>
<Quantity>1</Quantity>
<USPrice>29.99</USPrice>
</Item>
<Item PartNumber="898-AM">
<ProductName>Wireless Mouse</ProductName>
<Quantity>1</Quantity>
<USPrice>14.99</USPrice>
</Item>
</Items>
</PurchaseOrder>
<aw:PurchaseOrder
PONumber="11223"
Date="2000-01-15"
xmlns:aw="http://www.adventure-works.com">
<aw:ShippingAddress>
<aw:Name>Chris Preston</aw:Name>
<aw:Street>123 Main St.</aw:Street>
<aw:City>Seattle</aw:City>
<aw:State>WA</aw:State>
<aw:Zip>98113</aw:Zip>
<aw:Country>USA</aw:Country>
</aw:ShippingAddress>
<aw:BillingAddress>
<aw:Name>Chris Preston</aw:Name>
<aw:Street>123 Main St.</aw:Street>
<aw:City>Seattle</aw:City>
<aw:State>WA</aw:State>
<aw:Zip>98113</aw:Zip>
<aw:Country>USA</aw:Country>
</aw:BillingAddress>
<aw:DeliveryInstructions>Ship only complete order.</aw:DeliveryInstructions>
<aw:Item PartNum="LIT-01">
<aw:ProductID>Litware Networking Card</aw:ProductID>
<aw:Qty>1</aw:Qty>
<aw:Price>20.99</aw:Price>
</aw:Item>
</aw:Item>
<aw:Item PartNum="LIT-25">
<aw:ProductID>Litware 17in LCD Monitor</aw:ProductID>
<aw:Qty>1</aw:Qty>
<aw:Price>199.99</aw:Price>
</aw:Item>
</aw:PurchaseOrder>
</PurchaseOrders>
Başvuru (LINQ to XML)
23.10.2019 • 2 minutes to read • Edit Online

Bu konu, LINQ to XML başvuru konularına bağlantılar içerir.

Bu Bölümde
LINQ to XML sınıfları için başvuru belgeleri için bkz System.Xml.Linq.
XML ağaçlarını bir XSD dosyasına karşı doğrulamanıza yardımcı olan uzantı yöntemlerine ilişkin başvuru belgeleri
için, bkz System.Xml.Schema.Extensions.
Bir XML ağacındaki XPath sorgularını değerlendirmenizi sağlayan uzantı yöntemlerine ilişkin başvuru belgeleri
için, bkz System.Xml.XPath.Extensions.

Ayrıca bkz.
LINQ to XML (C#)
ADO.NET'e LINQ (Portal Sayfası)
23.10.2019 • 3 minutes to read • Edit Online

LINQ to ADO.net, Dil ile Tümleşik Sorgu (LINQ ) programlama modelini kullanarak ADO.NET içinde herhangi bir
numaralandırılabilir nesneyi sorgulamanızı sağlar.

NOTE
LINQ to ADO.NET belgeleri .NET Framework SDK 'sının ADO.NET bölümünde bulunur: LINQ ve ADO.net.

Üç ayrı ADO.net Dil ile Tümleşik Sorgu (LINQ ) teknolojisi vardır: LINQ to DataSet, LINQ - SQLve LINQ to
Entities. LINQ to DataSet üzerinde DataSetdaha zengin, iyileştirilmiş sorgulama sağlar, LINQ - SQL SQL Server
veritabanı şemalarını doğrudan sorgulayabilir ve LINQ to Entities varlık veri modeli sorgulamanızı sağlar.

LINQ - DataSet
, DataSet ADO.net ' deki en yaygın olarak kullanılan bileşenlerden biridir ve ADO.net 'in üzerinde oluşturulduğu,
bağlantısı kesilen programlama modelinin temel öğesidir. Ancak, bu kadar belirgin olsa da, DataSet sınırlı sorgu
yeteneklerine sahiptir.
LINQ to DataSet, diğer birçok veri kaynağı için kullanılabilen aynı DataSet sorgu işlevini kullanarak ' ye daha
zengin sorgu özellikleri oluşturmanızı sağlar.
Daha fazla bilgi için LINQ to DataSet.

LINQ - SQL
LINQ - SQLilişkisel verileri nesne olarak yönetmeye yönelik bir çalışma zamanı altyapısı sağlar. ' LINQ - SQLDe,
bir ilişkisel veritabanının veri modeli, geliştiricinin programlama dilinde ifade edilen bir nesne modeliyle eşleştirilir.
Uygulamayı yürüttüğünüzde, LINQ - SQL nesne modelindeki dil ile tümleşik sorguları SQL 'e çevirir ve yürütmek
üzere veritabanına gönderir. Veritabanı sonuçları döndürdüğünde, LINQ - SQL bunları işleyebileceğiniz nesnelere
geri çevirir.
LINQ - SQL, veritabanında saklı yordamlar ve Kullanıcı tanımlı işlevler ve nesne modelinde devralma için destek
içerir.
Daha fazla bilgi için bkz. LINQ to SQL.

LINQ - Varlıklar
Varlık Veri Modeli, ilişkisel veriler .NET ortamında nesneler olarak sunulur. Bu, nesne katmanını destek için LINQ
ideal bir hedef haline getirir ve geliştiricilerin iş mantığını oluşturmak için kullanılan dilden sorguları veritabanına
göre formüllemesini sağlar. Bu yetenek LINQ to Entities olarak bilinir. Daha fazla bilgi için bkz. LINQ to Entities .

Ayrıca bkz.
LINQ ve ADO.NET
Dil ile tümleşik sorgu (LINQ ) (C#)
LINQ Sorgusu için Veri Kaynağı Etkinleştirme
23.10.2019 • 5 minutes to read • Edit Online

Herhangi bir veri kaynağının, LINQ LINQ düzende sorgulanmasını sağlamak için genişlemenin çeşitli yolları vardır.
Veri kaynağı örneğin bir veri yapısı, Web hizmeti, dosya sistemi veya veritabanı olabilir. Bu model, sorgunun
sözdizimi ve deseninin değişmediği LINQ için, istemcilerin sorgulama etkinleştirildiği bir veri kaynağını
sorgulamasını kolaylaştırır. LINQ Bu veri kaynaklarına genişletilebilen LINQ yollar şunlardır:
Bu türün sorgulanmasına olanak tanımak LINQ için arabirimbirtüriçindeuygulama.IEnumerable<T>
Bu türün özel Where Select sorgulanmasınıetkinleştirmekiçinvegibibirtürügenişletenstandartsorguLINQ
işleci yöntemleri oluşturma.
IQueryable<T> Arabirimi uygulayan veri kaynağınız için bir sağlayıcı oluşturma. Bu arabirimi uygulayan bir
sağlayıcı, sorguları LINQ , örneğin Uzaktan özel bir şekilde yürütebileceği ifade ağaçları biçiminde alır.
Veri kaynağınız için mevcut LINQ bir teknolojinin avantajlarından yararlanan bir sağlayıcı oluşturma. Böyle
bir sağlayıcı, yalnızca sorgulamayı etkinleştirmez, aynı zamanda kullanıcı tanımlı türlere yönelik işlemleri ve
eşleştirmeyi de ekler, güncelleştirir ve siler.
Bu konuda, bu seçenekler açıklanmaktadır.

Veri Kaynağınızın LINQ Sorgulamasını Etkinleştirme


Bellek İçi Veriler
Bellek içi verilerin sorgulanmasını mümkün kılmak LINQ için iki yol vardır. Veri, uygulayan IEnumerable<T>bir tür
ise, nesneleri kullanarak LINQ verileri sorgulayabilirsiniz. IEnumerable<T> Arabirimi uygulayarak, yazdığınız
türden numaralandırmayı etkinleştirmek mantıklı değilse, bu türde standart sorgu işleci yöntemleri tanımlayabilir
LINQ veya türü genişleten standart sorgu işleci yöntemleri oluşturabilirsiniz LINQ . Standart sorgu işleçlerinin özel
uygulamaları, sonuçları döndürmek için ertelenmiş yürütme kullanmalıdır.
Uzak Veriler
Uzak bir veri kaynağının sorgulanmasını etkinleştirmek LINQ için en iyi seçenek, IQueryable<T> arabirimini
uygulamaktır. Ancak, bu, bir veri kaynağı için gibi LINQ - SQL bir sağlayıcının genişlemesiyle farklılık gösterir.
Visual Studio 2008 ' de LINQ LINQ - SQL, diğer veri kaynağı türlerine gibi mevcut teknolojileri genişletmek için
hiçbir sağlayıcı modeli mevcuttur.

IQueryable LINQ Sağlayıcıları


LINQuygulayan IQueryable<T> sağlayıcılar, karmaşıklığının büyük ölçüde farklılık gösterebilir. Bu bölümde, farklı
karmaşıklık düzeyleri açıklanmaktadır.
Daha az karmaşık IQueryable bir sağlayıcı, Web hizmeti 'nin tek bir yöntemiyle arabirim alabilir. Bu türden bir
sağlayıcı, işlediği sorgularda belirli bilgiler beklediği için çok özeldir. Muhtemelen tek bir sonuç türü ortaya çıkaran
kapalı bir tür sistemi vardır. Sorgunun çoğu yürütme, örneğin standart sorgu işleçleri Enumerable uygulamaları
kullanılarak yerel olarak gerçekleşir. Daha az karmaşık olan bir sağlayıcı, sorguyu temsil eden ifade ağacında
yalnızca bir yöntem çağrısı ifadesi inceleyebilir ve kalan sorgu mantığının başka bir yerde işlenmesine izin verebilir.
Orta düzeyde karmaşıklığa sahip bir sağlayıcı,kısmenifadeedenbirsorgudilinesahipbirverikaynağınıhedefleyebilir.
IQueryable Bir Web hizmetini hedefliyorsa, Web hizmetinin birden fazla yöntemiyle arabirim oluşturabilir ve
sorgunun sorduğu soruya göre bir çağrı yöntemi seçebilir. Orta düzeyde karmaşıklığa sahip bir sağlayıcının basit
bir sağlayıcıya göre daha zengin bir tür sistemi vardır, ancak yine de sabit bir tür sistemidir. Örneğin, sağlayıcı ters
çevrilebilen bire çok ilişkilerine sahip türleri kullanabilir, ancak kullanıcı tanımlı türler için eşleştirme teknolojisi
sağlamaz.
Sağlayıcı gibi IQueryable karmaşık bir sağlayıcı LINQ , tüm sorguları SQL gibi bir ifade eden sorgu diline
çevirebilir. LINQ - SQL Karmaşık bir sağlayıcı, sorguda çok çeşitli soruları işleyebileceği için daha az karmaşık olan
bir sağlayıcıya göre daha geneldir. Ayrıca, açık bir tür sistemine de sahiptir ve bu nedenle kullanıcı tanımlı türleri
eşleştirmek için kapsamlı bir altyapı içermelidir. Karmaşık bir sağlayıcının geliştirilmesi için önemli ölçüde çaba
gerekir.

Ayrıca bkz.
IQueryable<T>
IEnumerable<T>
Enumerable
Standart sorgu Işleçlerine genelC#bakış ()
LINQ to Objects (C#)
Visual Studio IDE ve LINQ için Araçlar desteği (C#)
23.10.2019 • 2 minutes to read • Edit Online

Visual Studio tümleşik geliştirme ortamı (IDE ), LINQ uygulama geliştirmeyi destekleyen aşağıdaki özellikleri
sağlar:

Object Relational Designer


Nesne İlişkisel Tasarımcısı, temel bir veritabanındaki ilişkisel verileri temsil eden içinde C# sınıflar oluşturmak için
LINQ to SQL uygulamalarda kullanabileceğiniz bir görsel tasarım aracıdır. Daha fazla bilgi için bkz. Visual Studio
'da LINQ to SQL araçları.

SQLMetal komut satırı aracı


SQLMetal, LINQ to SQL uygulamalarında kullanılmak üzere mevcut veritabanlarından sınıflar oluşturmak için
derleme işlemlerinde kullanılabilen bir komut satırı aracıdır. Daha fazla bilgi için bkz. SqlMetal. exe (kod üretme
aracı).

LINQ duyarlı kod Düzenleyicisi


Kod C# Düzenleyicisi, IntelliSense ve biçimlendirme ÖZELLIKLERINE sahip LINQ 'i destekler.

Visual Studio hata ayıklayıcısı desteği


Visual Studio hata ayıklayıcısı sorgu ifadelerinin hatalarını ayıklamayı destekler. Daha fazla bilgi için bkz. LINQ hata
ayıklama.

Ayrıca bkz.
Dil ile tümleşik sorgu (LINQ ) (C#)
Nesne odaklı programlama (C#)
4.12.2019 • 16 minutes to read • Edit Online

C#Kapsülleme, devralma ve çok biçimlilik dahil olmak üzere nesne odaklı programlama için tam destek sağlar.
Kapsülleme , ilişkili özellikler, Yöntemler ve diğer üyelerin bir grubunun tek bir birim veya nesne olarak kabul
edildiği anlamına gelir.
Devralma , mevcut bir sınıfı temel alan yeni sınıflar oluşturma özelliğini açıklar.
Çok biçimlilik , her bir sınıf farklı yollarla aynı özellikleri veya yöntemleri uyguladığından bile, birbirinin yerine
kullanılabilecek birden fazla sınıfa sahip olabileceği anlamına gelir.
Bu bölümde aşağıdaki kavramlar açıklanmaktadır:
Sınıflar ve nesneler
Sınıf üyeleri
Özellikler ve alanlar
Yöntemler
Oluşturucular
Sonlandırıcılar
Olaylar
İç içe geçmiş sınıflar
Erişim değiştiricileri ve erişim düzeyleri
Sınıfları örnekleme
Statik sınıflar ve Üyeler
Anonim Tipler
Devralma
Üyeleri geçersiz kılma
Arabirimler
Genel Türler
Temsilciler

Sınıflar ve nesneler
Terimler sınıfı ve nesne bazen birbirinin yerine kullanılır, ancak aslında nesneler sınıfların kullanılabilir örnekleri
olduğunda sınıflar nesne türünü betimler. Bu nedenle, bir nesne oluşturma konusuna örnekoluşturma denir. Şema
benzerleme vurguladı kullanarak bir sınıf şeması bir şema, bir nesne ise bu şema tarafından oluşturulan bir
derleme.
Bir sınıf tanımlamak için:
class SampleClass
{
}

C#Ayrıca, büyük bir nesne dizisi oluşturmanız gerektiğinde ve bunun için çok fazla bellek kullanmak
istemediğinizde yararlı olan yapılar adlı sınıfların hafif bir sürümünü de sağlar.
Bir yapı tanımlamak için:

struct SampleStruct
{
}

Daha fazla bilgi için bkz.


class
struct
Sınıf üyeleri
Her sınıf, sınıf verilerini tanımlayan özellikleri, sınıf davranışını tanımlayan yöntemleri ve farklı sınıflar ve nesneler
arasında iletişim sağlayan olayları içeren farklı sınıf üyelerine sahip olabilir.
Özellikler ve alanlar
Alanlar ve özellikler bir nesnenin içerdiği bilgileri temsil eder. Alanlar, okunabilir veya doğrudan
ayarlanabileceğinden, değişkenlere benzer.
Bir alan tanımlamak için:

class SampleClass
{
public string sampleField;
}

Özellikler, değerlerin nasıl ayarlandığı veya döndürüldüğü hakkında daha fazla denetim sağlayan alma ve
ayarlama yordamlarına sahiptir.
C#Özellik değerini depolamak için özel bir alan oluşturmanıza veya bu alanı arka planda otomatik olarak oluşturan
otomatik uygulanan özellikler olarak adlandırılan ve özellik yordamları için temel mantığı sağlayan bir özel alan
oluşturmanızı sağlar.
Otomatik uygulanan bir özellik tanımlamak için:

class SampleClass
{
public int SampleProperty { get; set; }
}

Özellik değerini okumak ve yazmak için bazı ek işlemler gerçekleştirmeniz gerekiyorsa, özellik değerini depolamak
için bir alan tanımlayın ve bunu depolamak ve almak için temel mantığı sağlayın:
class SampleClass
{
private int _sample;
public int Sample
{
// Return the value stored in a field.
get { return _sample; }
// Store the value in the field.
set { _sample = value; }
}
}

Çoğu özelliğin, özellik değerini ayarlamak ve almak için yöntemleri ya da yordamları vardır. Ancak, bunları
değiştirilmesini veya okumayı kısıtlamak için salt okunurdur veya salt yazılır özellikler oluşturabilirsiniz. İçinde C#,
get veya set özellik yöntemini atlayabilirsiniz. Ancak otomatik olarak uygulanan özellikler salt okunurdur veya
salt yazılır olamaz.
Daha fazla bilgi için bkz.
get
set
Yöntem
Bir Yöntem , bir nesnenin gerçekleştirebileceği bir eylemdir.
Bir sınıfın yöntemini tanımlamak için:

class SampleClass
{
public int sampleMethod(string sampleParam)
{
// Insert code here
}
}

Bir sınıf, parametrelerin veya parametre türlerinin sayısında farklı olan aynı yöntemin çeşitli uygulamalarına veya
aşırıyüküne sahip olabilir.
Bir yöntemi aşırı yüklemek için:

public int sampleMethod(string sampleParam) {}


public int sampleMethod(int sampleParam) {}

Çoğu durumda, bir sınıf tanımı içinde bir yöntemi bildirirsiniz. Ancak, C# sınıfının gerçek tanımının dışında mevcut
bir sınıfa Yöntemler eklemenize olanak tanıyan genişletme yöntemlerini de destekler.
Daha fazla bilgi için bkz.
Yöntemler
Genişletme Yöntemleri
Kurucu
Oluşturucular, belirli bir türden bir nesne oluşturulduğunda otomatik olarak yürütülen sınıf yöntemleridir.
Oluşturucular genellikle yeni nesnenin veri üyelerini başlatır. Bir Oluşturucu, bir sınıf oluşturulduğunda yalnızca bir
kez çalıştırılabilir. Ayrıca, kurucudaki kod her zaman bir sınıftaki diğer koddan önce çalışır. Ancak, başka bir
yöntemle aynı şekilde birden çok Oluşturucu aşırı yüklemesi oluşturabilirsiniz.
Bir sınıf için bir Oluşturucu tanımlamak için:

public class SampleClass


{
public SampleClass()
{
// Add code here
}
}

Daha fazla bilgi için bkz. oluşturucular.


Sonlandırıcılar
Sonlandırıcılar sınıfların örneklerini deketmek için kullanılır. .NET Framework, çöp toplayıcı uygulamanızdaki
yönetilen nesneler için bellek ayırmayı ve serbest bırakma işlemini otomatik olarak yönetir. Ancak, uygulamanızın
oluşturduğu yönetilmeyen kaynakları temizlemek için sonlandırıcılardan yine de ihtiyacınız olabilir. Bir sınıf için
yalnızca bir sonlandırıcılar olabilir.
.NET Framework sonlandırıcılar ve çöp toplama hakkında daha fazla bilgi için bkz. çöp toplama.
Olayları
Olaylar, bir sınıf ya da nesnenin, ilgi çekici bir şeyler gerçekleştiğinde diğer sınıflara veya nesnelere bildirilmesini
sağlar. Olayı gönderen (veya Başlatan) sınıf Yayımcı olarak adlandırılır ve olayı alan (veya işleyen) sınıflar
abonelerolarak adlandırılır. Olaylar, nasıl oluşturulur ve işlenir hakkında daha fazla bilgi için bkz. Olaylar.
Bir sınıfında bir olay bildirmek için Event anahtar sözcüğünü kullanın.
Bir olayı yükseltmek için olay temsilcisini çağırın.
Bir olaya abone olmak için += işlecini kullanın; bir olayın aboneliğini kaldırmak için -= işlecini kullanın.
İç içe geçmiş sınıflar
Başka bir sınıf içinde tanımlı bir sınıf iç içeçağırılır. Varsayılan olarak, iç içe yerleştirilmiş sınıf özeldir.

class Container
{
class Nested
{
// Add code here.
}
}

İç içe yerleştirilmiş sınıfın bir örneğini oluşturmak için, container sınıfının adını ve ardından nokta ve ardından iç içe
geçmiş sınıfın adını kullanın:

Container.Nested nestedInstance = new Container.Nested()

Erişim değiştiricileri ve erişim düzeyleri


Tüm sınıflar ve sınıf üyeleri, erişim değiştiricilerinikullanarak diğer sınıflara hangi erişim düzeyini sundukları
belirler.
Aşağıdaki erişim değiştiriciler kullanılabilir:

C#İCISI TANIM

public Türe veya üyeye aynı derlemedeki veya buna başvuran başka
bir derlemede bir veya daha fazla kod tarafından erişilebilir.
C#İCISI TANIM

private Türe veya üyeye yalnızca aynı sınıftaki kodla erişilebilir.

protected Türe veya üyeye yalnızca aynı sınıftaki veya türetilmiş bir
sınıftaki kodla erişilebilir.

internal Türe veya üyeye aynı derlemedeki kod tarafından erişilebilir,


ancak başka bir derlemeden erişilebilir.

protected internal Türe veya üyeye aynı derlemedeki herhangi bir kod ya da
başka bir derlemedeki türetilmiş bir sınıf tarafından erişilebilir.

private protected Türe veya üyeye aynı sınıftaki veya temel sınıf derlemesi
içindeki türetilmiş bir sınıftaki kodla erişilebilir.

Daha fazla bilgi için bkz. erişim değiştiricileri.


Sınıfları örnekleme
Bir nesne oluşturmak için bir sınıf örneği oluşturmanız veya bir sınıf örneği oluşturmanız gerekir.

SampleClass sampleObject = new SampleClass();

Bir sınıfı örnekledikten sonra, örneğin özelliklerine ve alanlarına değerler atayabilir ve sınıf yöntemlerini
çağırabilirsiniz.

// Set a property value.


sampleObject.sampleProperty = "Sample String";
// Call a method.
sampleObject.sampleMethod();

Sınıf örnek oluşturma işlemi sırasında özelliklere değer atamak için, nesne başlatıcıları kullanın:

// Set a property value.


SampleClass sampleObject = new SampleClass
{ FirstProperty = "A", SecondProperty = "B" };

Daha fazla bilgi için bkz.


new İşleci
Nesne ve Koleksiyon Başlatıcıları
Statik sınıflar ve Üyeler
Sınıfının statik üyesi, bir sınıfın tüm örnekleri tarafından paylaşılan bir özellik, yordam veya alandır.
Statik üye tanımlamak için:

static class SampleClass


{
public static string SampleString = "Sample String";
}

Statik üyeye erişmek için, sınıfın adını bu sınıfın bir nesnesi oluşturmadan kullanın:
Console.WriteLine(SampleClass.SampleString);

İçindeki C# statik sınıfların yalnızca statik üyeleri vardır ve örneklenemez. Statik Üyeler ayrıca statik olmayan
özelliklere, alanlara veya yöntemlere erişemez
Daha fazla bilgi için bkz: static.
Anonim türler
Anonim türler, veri türü için bir sınıf tanımı yazmadan nesneler oluşturmanızı sağlar.Bunun yerine, derleyici sizin
için bir sınıf oluşturur. Sınıfın kullanılabilir adı yok ve nesneyi bildirirken belirttiğiniz özellikleri içerir.
Anonim türün bir örneğini oluşturmak için:

// sampleObject is an instance of a simple anonymous type.


var sampleObject =
new { FirstProperty = "A", SecondProperty = "B" };

Daha fazla bilgi için bkz: anonim türler.

Devralmayı
Devralma, başka bir sınıfta tanımlanan davranışı yeniden kullanan, genişleten ve değiştiren yeni bir sınıf
oluşturmanıza olanak sağlar. Üyeleri devralınmış olan sınıfa temel sınıfdenir ve bu üyeleri devralan sınıfa türetilmiş
sınıfdenir. Ancak, içindeki C# tüm sınıflar, .NET sınıf hiyerarşisini destekleyen Object sınıfından dolaylı olarak
devralınır ve tüm sınıflara alt düzey hizmetler sağlar.

NOTE
C#birden çok devralmayı desteklemez. Diğer bir deyişle, türetilmiş bir sınıf için yalnızca bir temel sınıf belirtebilirsiniz.

Temel sınıftan devralması için:

class DerivedClass:BaseClass {}

Varsayılan olarak, tüm sınıflar devralınabilir. Ancak, bir sınıfın temel sınıf olarak kullanılması gerekip gerekmediğini
belirtebilir veya yalnızca temel sınıf olarak kullanılabilecek bir sınıf oluşturmanız gerekir.
Bir sınıfın temel sınıf olarak kullanılamayacağını belirtmek için:

public sealed class A { }

Bir sınıfın yalnızca temel sınıf olarak kullanılabileceğini ve örneklenemez olduğunu belirtmek için:

public abstract class B { }

Daha fazla bilgi için bkz.


sealed
abstract
Üyeleri geçersiz kılma
Varsayılan olarak, türetilmiş bir sınıf kendi temel sınıfından tüm üyeleri devralır. Devralınan üyenin davranışını
değiştirmek istiyorsanız, onu geçersiz kılmanız gerekir. Diğer bir deyişle, türetilmiş sınıfta yöntemin, özelliğin veya
olayın yeni bir uygulamasını tanımlayabilirsiniz.
Özelliklerin ve yöntemlerin nasıl geçersiz kılınabileceğini denetlemek için aşağıdaki değiştiriciler kullanılır:

C#İCISI TANIM

virtual Bir sınıf üyesinin türetilmiş bir sınıfta geçersiz kılınmasına izin
verir.

override Temel sınıfta tanımlanan bir sanal (geçersiz kılınabilir) üyeyi


geçersiz kılar.

abstract Türetilmiş sınıfta bir sınıf üyesinin geçersiz kılınmasını gerektirir.

new Değiştiricisi Temel sınıftan devralınan bir üyeyi gizler

Arabirimlerdeki
Sınıflar gibi arabirimler, özellikler, Yöntemler ve olaylar kümesi tanımlar.Ancak sınıfların aksine arabirimler
uygulama sağlamaz. Sınıflar tarafından uygulanır ve sınıflardan ayrı varlıklar olarak tanımlanır. Arabirim, bir
arabirimi uygulayan bir sınıfın, bu arabirimin her yönünü tam olarak tanımlandığı gibi uygulaması gerektiğini
belirten bir sözleşmeyi temsil eder.
Bir arabirim tanımlamak için:

interface ISampleInterface
{
void doSomething();
}

Bir sınıfa bir arabirim uygulamak için:

class SampleClass : ISampleInterface


{
void ISampleInterface.doSomething()
{
// Method implementation.
}
}

Daha fazla bilgi için bkz.


Arabirimler
interface

Tür
.NET Framework sınıflar, yapılar, arabirimler ve Yöntemler, depolayabilecekleri veya kullanabileceği nesne türlerini
tanımlayan tür parametreleri içerebilir. En yaygın genel türler örneği, bir koleksiyonda depolanacak nesne türlerini
belirtebileceğiniz bir koleksiyondur.
Genel bir sınıf tanımlamak için:
public class SampleGeneric<T>
{
public T Field;
}

Genel sınıfın bir örneğini oluşturmak için:

SampleGeneric<string> sampleObject = new SampleGeneric<string>();


sampleObject.Field = "Sample string";

Daha fazla bilgi için bkz.


Genel Türler
Genel Türler

İlerin
Temsilci , yöntem imzasını tanımlayan bir türdür ve uyumlu imzaya sahip herhangi bir yönteme başvuru
sağlayabilir. Yöntemi temsilci aracılığıyla çağırabilir (veya çağırabilirsiniz). Temsilciler, yöntemleri bağımsız
değişkenler olarak diğer yöntemlere geçirmek için kullanılır.

NOTE
Olay işleyicileri, temsilciler aracılığıyla çağrılan yöntemlerden başka bir şey değildir. Olay İşlemede temsilciler kullanma
hakkında daha fazla bilgi için bkz. Olaylar.

Bir temsilci oluşturmak için:

public delegate void SampleDelegate(string str);

Temsilci tarafından belirtilen imzayla eşleşen bir yönteme başvuru oluşturmak için:

class SampleClass
{
// Method that matches the SampleDelegate signature.
public static void sampleMethod(string message)
{
// Add code here.
}
// Method that instantiates the delegate.
void SampleDelegate()
{
SampleDelegate sd = sampleMethod;
sd("Sample string");
}
}

Daha fazla bilgi için bkz.


Temsilciler
delegate

Ayrıca bkz.
C# Programlama Kılavuzu
Yansıma (C#)
4.12.2019 • 2 minutes to read • Edit Online

Yansıma derlemeleri, modülleri ve türleri tanımlayan nesneler (Typetüründe) sağlar. Bir türün örneğini dinamik
olarak oluşturmak, türü var olan bir nesneye bağlamak veya var olan bir nesneden türü almak ya da onun
yöntemlerini çağırmak ya da alanları ve özelliklerine erişmek için yansıma kullanabilirsiniz. Kodunuzda
öznitelikler kullanıyorsanız, yansıma bunlara erişmenizi sağlar. Daha fazla bilgi için bkz. öznitelikler.
Bir değişkenin türünü almak için Object temel sınıfından tüm türler tarafından devralınan GetType() yöntemi
kullanılarak oluşan basit bir yansıma örneğidir:

NOTE
. Cs dosyanızın üst kısmına using System; ve using System.Reflection; eklediğinizden emin olun.

// Using GetType to obtain type information:


int i = 42;
Type type = i.GetType();
Console.WriteLine(type);

Çıktı: System.Int32 .
Aşağıdaki örnek, yüklü derlemenin tam adını almak için yansıma kullanır.

// Using Reflection to get information of an Assembly:


Assembly info = typeof(int).Assembly;
Console.WriteLine(info);

Çıktı: System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e .

NOTE
protected C# ve internal anahtar kelimelerinde hiçbir anlamı yoktur ve yansıma API 'lerinde kullanılmaz. Il 'deki ilgili
terimler Aile ve derlemedir. Yansıma kullanarak bir internal yöntemi tanımlamak için IsAssembly özelliğini kullanın.
protected internal yöntemi tanımlamak için IsFamilyOrAssemblykullanın.

Yansımaya genel bakış


Aşağıdaki durumlarda yansıma yararlı olur:
Programınızın meta verilerindeki özniteliklere erişmeniz gerektiğinde. Daha fazla bilgi için bkz. özniteliklerde
depolanan bilgileri alma.
Bir derlemedeki türleri İnceleme ve örnekleme için.
Çalışma zamanında yeni türler oluşturmak için. System.Reflection.Emitsınıfları kullanın.
Geç bağlama gerçekleştirmek için çalışma zamanında oluşturulan türler üzerindeki yöntemlere erişme.
Türleri dinamik olarak yükleme ve kullanmakonusuna bakın.

İlgili bölümler
Daha fazla bilgi için:
Yansıma
Tür Bilgilerini Görüntüleme
Yansıma ve Genel Türler
System.Reflection.Emit
Özniteliklerde Depolanan Bilgileri Alma

Ayrıca bkz.
C# Programlama Kılavuzu
.NET’te bütünleştirilmiş kodlar
Serileştirme (C# )
23.10.2019 • 6 minutes to read • Edit Online

Serileştirme bir nesneyi depolamak veya bellek, bir veritabanı veya dosya aktarmak için bayt akışı bir nesne
dönüştürme işlemidir. Ana amacı, gerektiğinde yeniden oluşturmak için bir nesnenin durumu kaydetmektir. Seri
durumundan çıkarma ters işlem çağrılır.

Seri hale getirme nasıl çalışır?


Bu örnekte genel seri hale getirme işlemini gösterir:

Yalnızca veri ancak nesnenin türü, sürüm, kültür ve derleme adı gibi bilgileri izleme bir akışa nesne seri hale
getirilir. Bu akıştan, bir veritabanı, dosya veya bellek içinde saklanabilir.
Serileştirme kullanımları
Seri hale getirme geliştiricinin bir nesne durumunu kaydetmek ve gerektiğinde depolama nesneleri ve bunun yanı
sıra veri değişimi sağlama yeniden sağlar. Serileştirme bir geliştirici nesnesi aracılığıyla bir Web hizmeti uzak bir
uygulamaya gönderme, bir etki alanından bir nesne geçirme, nesnenin bir güvenlik duvarı üzerinden bir XML
dizesi olarak geçirme veya güvenliğini sağlama gibi eylemleri gerçekleştirebilirsiniz veya uygulamalar arasında
kullanıcıya özgü bilgileri.
Bir nesne seri hale getirilebilir yapma
Nesne seri hale için gereken bir nesneyi serileştirmek için bir akış serileştirilmiş nesne içerecek ve bir Formatter.
System.Runtime.Serialization seri hale getirme ve seri kaldırma nesneler için gerekli olan sınıflar içerir.
Uygulama SerializableAttribute özniteliği bu türün örneğini serileştirilmiş göstermek için bir tür. Seri hale getirmek
çalışır, ancak türüne sahip bir özel durum SerializableAttribute özniteliği.
Seri hale getirilebilir olması için sınıf alana istemiyorsanız, uygulama NonSerializedAttribute özniteliği. Bir işaretçi,
tanıtıcı veya belirli bir ortama özgü bazı başka veri yapısına serializable bir tür alanı içeren ve alan
atayamayacağına farklı bir ortamda yeniden oluşturulur olamaz, nonserializable yapmak isteyebilirsiniz.
Serileştirilmiş sınıf işaretlenen diğer sınıfların nesnelere başvurular içeriyorsa SerializableAttribute, bu nesneleri
ayrıca seri hale.

İkili ve XML serileştirme


İkili veya XML serileştirme kullanabilirsiniz. İkili seri hale getirme, tüm üyeleri, salt okunur bile üyeleri seri hale
getirilmiş ve performans geliştirilir. XML serileştirme daha okunabilir bir kod ve nesneyi paylaşmak ve birlikte
çalışabilirlik amacıyla kullanım daha fazla esneklik sağlar.
İkili seri hale getirme
İkili kodlama ikili serileştirme depolama veya ağ yuva tabanlı akışları gibi kullanımlar için compact serileştirme
üretmek için kullanır.
XML serileştirme
XML serileştirme ortak alanları ve bir nesne veya özelliklerini parametre ve dönüş değerleri yöntemleri, belirli bir
XML Şeması Tanım Dili (XSD ) belge uyan bir XML akışı olarak serileştirir. XML serileştirme sonuçlarında
sınıflarıyla ortak özellikler ve XML için dönüştürülür alanları kesin. System.Xml.Serialization seri hale getirme ve
XML seri durumdan çıkarmak için gereken sınıfların içerir.
Öznitelikleri için sınıflar ve sınıf üyeleri denetlenmesine uygulamak XmlSerializer serileştiren veya sınıfının bir
örneği seri durumdan çıkarır.

Temel ve özel seri hale getirme


İki yolla temel ve özel serileştirme gerçekleştirilebilir. Temel serileştirme otomatik olarak nesneyi serileştirmek için
.NET Framework'ü kullanır.
Temel serileştirme
Nesne sahip temel serileştirme sırasında tek gereksinim olmasıdır SerializableAttribute özniteliği uygulandı.
NonSerializedAttribute Serileştirilmekte olan belirli alanları tutmak için kullanılabilir.
Temel serileştirme kullandığınızda, sürüm oluşturma nesnelerin sorunlara neden olabilir. Sürüm oluşturma
sorunları önemli olduğunda, özel serileştirme kullanırsınız. Temel serileştirme serileştirme gerçekleştirmek için en
kolay yoludur ancak kadar denetim işlemi üzerinde sağlamaz.
Özel serileştirme
Özel serileştirme, tam olarak hangi nesnelerin serileştirilmiş ve nasıl yapılacağıyla belirtebilirsiniz. Sınıf
işaretlenmelidir SerializableAttribute ve uygulama ISerializable arabirimi.
Bir özel biçimde seri durumdan nesnenizin istiyorsanız özel bir oluşturucu kullanmanız gerekir.

Tasarımcı serileştirme
Tasarımcı serileştirme özel bir geliştirme araçları ile ilişkili nesne Kalıcılık türü içeren serileştirme biçimidir.
Tasarımcı serileştirme bir nesne grafiğinin daha sonra nesne grafiğini kurtarmak için kullanılabilir bir kaynak
dosyasına dönüştürme işlemidir. Bir kaynak dosyası, kod, biçimlendirme veya hatta SQL tablo bilgileri içerebilir.

İlgili Konular ve örnekler


İzlenecek yol: Visual Studio'da bir nesneyi kalıcı kılma (C#)
Bir nesnenin veri değerleri depolamak ve bunları nesnesi örneği başlatıldığında almanıza imkan sağlayan,
örnekleri arasında kalıcı hale getirmek için serileştirme'nın nasıl kullanılabileceğini gösterir.
Nasıl yapılır: Nesne verilerini bir XML dosyasından okuma (C#)
Bir XML dosyası kullanmayı önceden yazılmış nesne verilerini okuma işlemini gösterir XmlSerializer sınıfı.
Nasıl yapılır: Nesne verilerini bir XML dosyasına yazma (C#)
Nesne öğesinden bir sınıf bir XML kullanarak dosyaya yazma işlemi gösterilmektedir XmlSerializer sınıfı.
Nasıl yapılır: Nesne verilerini bir XML dosyasına
yazma (C#)
23.10.2019 • 2 minutes to read • Edit Online

Bu örnek, XmlSerializer sınıfını kullanarak bir sınıftan bir XML dosyasına nesne yazar.

Örnek
public class XMLWrite
{

static void Main(string[] args)


{
WriteXML();
}

public class Book


{
public String title;
}

public static void WriteXML()


{
Book overview = new Book();
overview.title = "Serialization Overview";
System.Xml.Serialization.XmlSerializer writer =
new System.Xml.Serialization.XmlSerializer(typeof(Book));

var path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) +


"//SerializationOverview.xml";
System.IO.FileStream file = System.IO.File.Create(path);

writer.Serialize(file, overview);
file.Close();
}
}

Kod Derleniyor
Seri hale getirilen sınıfın parametre içermeyen bir ortak Oluşturucusu olmalıdır.

Güçlü Programlama
Aşağıdaki koşullar özel bir duruma neden olabilir:
Seri hale getirilen sınıfın ortak, parametresiz bir oluşturucusu yok.
Dosya var ve salt okunurdur (IOException).
Yol çok uzun (PathTooLongException).
Disk dolu (IOException).

.NET Framework Güvenliği


Bu örnek, dosya zaten yoksa yeni bir dosya oluşturur. Uygulamanın bir dosya oluşturması gerekiyorsa, bu
uygulamanın klasöre erişmesi gerekir Create . Dosya zaten mevcutsa, uygulamanın yalnızca Write daha az bir
ayrıcalığa erişmesi gerekir. Mümkün olduğunda, dağıtım sırasında dosyanın oluşturulması daha güvenlidir ve bir
klasör için Read Create erişim yerine yalnızca tek bir dosyaya erişim izni verir.

Ayrıca bkz.
StreamWriter
Nasıl yapılır: XML dosyasından (C#) nesne verilerini okuma
Serileştirme (C#)
Nasıl yapılır: XML dosyasından (C#) nesne verilerini
okuma
23.10.2019 • 2 minutes to read • Edit Online

Bu örnek, XmlSerializer daha önce sınıfını kullanarak bir XML dosyasına yazılmış nesne verilerini okur.

Örnek
public class Book
{
public String title;
}

public void ReadXML()


{
// First write something so that there is something to read ...
var b = new Book { title = "Serialization Overview" };
var writer = new System.Xml.Serialization.XmlSerializer(typeof(Book));
var wfile = new System.IO.StreamWriter(@"c:\temp\SerializationOverview.xml");
writer.Serialize(wfile, b);
wfile.Close();

// Now we can read the serialized book ...


System.Xml.Serialization.XmlSerializer reader =
new System.Xml.Serialization.XmlSerializer(typeof(Book));
System.IO.StreamReader file = new System.IO.StreamReader(
@"c:\temp\SerializationOverview.xml");
Book overview = (Book)reader.Deserialize(file);
file.Close();

Console.WriteLine(overview.title);

Kod Derleniyor
"C:\temp\SerializationOverview.xml" dosya adını seri hale getirilen verileri içeren dosyanın adıyla değiştirin.
Verileri seri hale getirme hakkında daha fazla bilgi için bkz. nasıl yapılır: Nesne verilerini bir XML dosyasına
(C#)yazın.
Sınıfın parametresiz ortak bir oluşturucusu olmalıdır.
Yalnızca ortak özellikler ve alanların serisi kaldırılır.

Güçlü Programlama
Aşağıdaki koşullar özel bir duruma neden olabilir:
Seri hale getirilen sınıfın ortak, parametresiz bir oluşturucusu yok.
Dosyadaki veriler, seri durumdan çıkarılacak sınıftan verileri temsil etmez.
Dosya yok (IOException).
.NET Framework Güvenliği
Girişleri her zaman doğrulayın ve güvenilmeyen bir kaynaktaki verileri hiçbir zaman serisini kaldırma. Yeniden
oluşturulan nesne, yerel bir bilgisayarda, serisi kaldırılan kodun izinleriyle çalışır. Verileri uygulamanızda
kullanmadan önce tüm girişleri doğrulayın.

Ayrıca bkz.
StreamWriter
Nasıl yapılır: Nesne verilerini bir XML dosyasına yazma (C#)
Serileştirme (C#)
C# Programlama Kılavuzu
İzlenecek yol: C kullanarak bir nesneyi kalıcı hale
getirme#
23.10.2019 • 7 minutes to read • Edit Online

Nesneleri, değerleri depolamanızı ve nesnenin bir sonraki açılışında bunları almanızı sağlayan örnekler arasında bir
nesnenin verilerini kalıcı hale getirmek için serileştirme kullanabilirsiniz.
Bu kılavuzda, temel Loan bir nesne oluşturacak ve verilerini bir dosyaya kalıcı hale getirilecektir. Daha sonra
nesneyi yeniden oluşturduğunuzda dosyadaki verileri buradan alırsınız.

IMPORTANT
Bu örnek, dosya henüz yoksa yeni bir dosya oluşturur. Bir uygulamanın bir dosya oluşturması gerekiyorsa, bu uygulamanın
klasör için izni Create olması gerekir. İzinler, erişim denetim listeleri kullanılarak ayarlanır. Dosya zaten varsa, uygulamanın
daha az izne sahip yalnızca Write izne ihtiyacı vardır. Mümkün olduğunda, dağıtım sırasında dosyayı oluşturmak ve yalnızca
tek bir dosyaya (bir klasör için Read izinler oluşturmak yerine) izin vermek daha güvenlidir. Ayrıca, Kullanıcı klasörlerine veri
yazmak, kök klasör veya Program Files klasöründen daha güvenlidir.

IMPORTANT
Bu örnek, verileri bir ikili biçim dosyasında depolar. Bu biçimler, parolalar veya kredi kartı bilgileri gibi hassas veriler için
kullanılmamalıdır.

Önkoşullar
Derlemek ve çalıştırmak için .NET Core SDK' yi çalıştırın.
Henüz yapmadıysanız, en sevdiğiniz kod düzenleyicinizi yükleyebilirsiniz.

TIP
Bir kod Düzenleyicisi yüklemeniz mı gerekiyor? Visual Studio 'yudeneyin!

Örnek 7,3 gerektirir C# . Bkz . C# dil sürümünü seçme


Örnek kodu, .NET örnekleri GitHub deposundaçevrimiçi olarak inceleyebilirsiniz.

Kredi nesnesi oluşturma


İlk adım, sınıfını kullanan bir Loan sınıf ve konsol uygulaması oluşturmaktır:
1. Yeni bir uygulama oluşturun. dotnet new console -o serialization Adlı serialization bir alt dizinde yeni bir
konsol uygulaması oluşturmak için yazın.
2. Düzenleyicinizde uygulamayı açın ve adlı Loan.cs yeni bir sınıf ekleyin.
3. Sınıfınıza Loan aşağıdaki kodu ekleyin:
public class Loan : INotifyPropertyChanged
{
public double LoanAmount { get; set; }
public double InterestRatePercent { get; set; }

[field:NonSerialized()]
public DateTime TimeLastLoaded { get; set; }

public int Term { get; set; }

private string customer;


public string Customer
{
get { return customer; }
set
{
customer = value;
PropertyChanged?.Invoke(this,
new PropertyChangedEventArgs(nameof(Customer)));
}
}

[field: NonSerialized()]
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

public Loan(double loanAmount,


double interestRate,
int term,
string customer)
{
this.LoanAmount = loanAmount;
this.InterestRatePercent = interestRate;
this.Term = term;
this.customer = customer;
}

Ayrıca, Loan sınıfını kullanan bir uygulama da oluşturmanız gerekecektir.

Kredi nesnesini seri hale getirme


1. Açık Program.cs . Aşağıdaki kodu ekleyin:

Loan TestLoan = new Loan(10000.0, 7.5, 36, "Neil Black");

PropertyChanged Olay için bir olay işleyicisi ve Loan nesneyi değiştirmek ve değişiklikleri göstermek için birkaç
satır ekleyin. Eklemeleri aşağıdaki kodda görebilirsiniz:

TestLoan.PropertyChanged += (_, __) => Console.WriteLine($"New customer value: {TestLoan.Customer}");

TestLoan.Customer = "Henry Clay";


Console.WriteLine(TestLoan.InterestRatePercent);
TestLoan.InterestRatePercent = 7.1;
Console.WriteLine(TestLoan.InterestRatePercent);

Bu noktada, kodu çalıştırabilir ve geçerli çıktıyı görebilirsiniz:


New customer value: Henry Clay
7.5
7.1

Bu uygulamayı sürekli olarak çalıştırmak her zaman aynı değerleri yazar. Programı her çalıştırdığınızda yeni bir
kredi nesnesi oluşturulur. Gerçek dünyada, faiz oranları düzenli aralıklarla değişir, ancak uygulama her
çalıştırıldığında her zaman gerekli değildir. Serileştirme kodu, uygulamanın örnekleri arasındaki en son faiz oranını
koruduğunuzdan anlamına gelir. Bir sonraki adımda, yalnızca kredi sınıfına serileştirme ekleyerek bunu
yapacaksınız.

Nesneyi kalıcı hale getirmek için serileştirme kullanma


Kredi sınıfının değerlerini kalıcı hale getirmek için, önce sınıfı Serializable özniteliğiyle işaretlemeniz gerekir.
Aşağıdaki kodu ödünç verme sınıfı tanımının üzerine ekleyin:

[Serializable()]

, SerializableAttribute Derleyiciye sınıftaki her şeyin bir dosyaya kalıcı olarak devam edebilir olduğunu söyler.
PropertyChanged Olay, nesne grafiğinin depolanması gereken parçasını temsil etmediğinden, serileştirilmemelidir.
Bunun yapılması, bu olaya eklenmiş tüm nesneleri serileştirilir. Olay PropertyChanged işleyicisi için alan
NonSerializedAttribute bildirimine ekleyebilirsiniz.

[field: NonSerialized()]
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

7,3 ' C# den başlayarak, field hedef değeri kullanarak otomatik uygulanan bir özelliğin yedekleme alanına
öznitelikler ekleyebilirsiniz. Aşağıdaki kod bir TimeLastLoaded özellik ekler ve onu seri hale getirilebilir değil olarak
işaretler:

[field:NonSerialized()]
public DateTime TimeLastLoaded { get; set; }

Sonraki adım, ödünç uygulama uygulamasına serileştirme kodu eklemektir. Sınıfını seri hale getirmek ve bir
dosyaya yazmak için, System.IO ve System.Runtime.Serialization.Formatters.Binary ad alanlarını kullanırsınız. Tam
nitelikli adları yazmayı önlemek için, aşağıdaki kodda gösterildiği gibi gerekli ad alanlarına başvurular
ekleyebilirsiniz:

using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

Sonraki adım, nesne oluşturulduğunda nesnenin serisini kaldırmak için kod eklemektir. Aşağıdaki kodda
gösterildiği gibi serileştirilmiş verilerin dosya adı sınıfına bir sabit ekleyin:

const string FileName = @"../../../SavedLoan.bin";

Sonra, TestLoan nesneyi oluşturan satırdan sonra aşağıdaki kodu ekleyin:


if (File.Exists(FileName))
{
Console.WriteLine("Reading saved file");
Stream openFileStream = File.OpenRead(FileName);
BinaryFormatter deserializer = new BinaryFormatter();
TestLoan = (Loan)deserializer.Deserialize(openFileStream);
TestLoan.TimeLastLoaded = DateTime.Now;
openFileStream.Close();
}

Önce dosyanın var olduğunu denetlemeniz gerekir. Varsa, ikili dosyayı okumak için Stream bir sınıf ve dosyayı
çevirecek bir BinaryFormatter sınıf oluşturun. Akış türünden kredi nesne türüne de dönüştürmeniz gerekir.
Daha sonra, sınıfı bir dosyaya seri hale getirmek için kod eklemeniz gerekir. Main Yöntemdeki mevcut koddan
sonra aşağıdaki kodu ekleyin:

Stream SaveFileStream = File.Create(FileName);


BinaryFormatter serializer = new BinaryFormatter();
serializer.Serialize(SaveFileStream, TestLoan);
SaveFileStream.Close();

Bu noktada, uygulamayı derleyip çalıştırabilirsiniz. İlk kez çalıştırıldığında, faiz oranlarının 7,5 ' de başlayacağını ve
sonra 7,1 olarak değiştiğine dikkat edin. Uygulamayı kapatın ve sonra yeniden çalıştırın. Artık uygulama,
kaydedilen dosyayı okudığı iletiyi yazdırır ve faiz oranı, kodu değiştiren koddan önce bile 7,1 olur.

Ayrıca bkz.
Serileştirme (C#)
C# Programlama Kılavuzu
Deyimler, İfadeler ve İşleçler (C# Programlama
Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Bir C# uygulamayı kapsayan kod, anahtar sözcüklerden, ifadelerden ve işleçlerden oluşan ifadelerden oluşur. Bu
bölüm, bir C# programın bu temel öğeleriyle ilgili bilgiler içerir.
Daha fazla bilgi için bkz.:
Deyimler
İfadeler
İfade gövdeli üyeler
Anonim İşlevler
Eşitlik Karşılaştırmaları

C# Dil Belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir kaynaktır.

Ayrıca bkz.
C# Programlama Kılavuzu
Tür Değiştirme ve Tür Dönüştürmeler
Deyimler (C# Programlama Kılavuzu)
23.10.2019 • 9 minutes to read • Edit Online

Bir programın aldığı eylemler deyimler bölümünde ifade edilir. Yaygın eylemler, belirli bir koşula bağlı olarak
değişkenleri bildirme, değer atama, yöntemleri çağırma, koleksiyonlar aracılığıyla döngü oluşturma ve bir veya
başka bir kod bloğuna dallandırma içerir. Bir programda deyimlerin yürütülme sırası, denetim akışı veya yürütme
akışı olarak adlandırılır. Programın çalışma zamanında aldığı girişe nasıl davrandığına bağlı olarak, denetim akışı,
programın her çalıştırılışında farklılık gösterebilir.
Bir deyim, noktalı virgül veya bir blokta bir dizi tek satırlık deyimlerle biten tek satırlık koddan oluşabilir. Bir ifade
bloğu {} köşeli ayraç içine alınır ve iç içe bloklar içerebilir. Aşağıdaki kod, tek satırlık deyimlerin iki örneğini ve çok
satırlı bir deyim bloğunu göstermektedir:

static void Main()


{
// Declaration statement.
int counter;

// Assignment statement.
counter = 1;

// Error! This is an expression, not an expression statement.


// counter + 1;

// Declaration statements with initializers are functionally


// equivalent to declaration statement followed by assignment statement:
int[] radii = { 15, 32, 108, 74, 9 }; // Declare and initialize an array.
const double pi = 3.14159; // Declare and initialize constant.

// foreach statement block that contains multiple statements.


foreach (int radius in radii)
{
// Declaration statement with initializer.
double circumference = pi * (2 * radius);

// Expression statement (method invocation). A single-line


// statement can span multiple text lines because line breaks
// are treated as white space, which is ignored by the compiler.
System.Console.WriteLine("Radius of circle #{0} is {1}. Circumference = {2:N2}",
counter, radius, circumference);

// Expression statement (postfix increment).


counter++;

} // End of foreach statement block


} // End of Main method body.
} // End of SimpleStatements class.
/*
Output:
Radius of circle #1 = 15. Circumference = 94.25
Radius of circle #2 = 32. Circumference = 201.06
Radius of circle #3 = 108. Circumference = 678.58
Radius of circle #4 = 74. Circumference = 464.96
Radius of circle #5 = 9. Circumference = 56.55
*/

Deyim türleri
Aşağıdaki tabloda, içindeki C# çeşitli deyim türleri ve ilgili anahtar kelimeleri, daha fazla bilgi içeren konuların
bağlantılarıyla listelenmektedir:

KATEGORI C#ANAHTAR SÖZCÜKLER/NOTLAR

Bildirim deyimleri Bir bildirim bildirimi yeni bir değişken veya sabit tanıtır.
Değişken bildirimi, isteğe bağlı olarak değişkenine bir değer
atayabilir. Sabit bildiriminde atama gereklidir.

İfade deyimleri Bir değeri hesaplayan ifade deyimleri değeri bir değişkende
depoalmalıdır. Daha fazla bilgi için bkz. Expression deyimleri.

Seçim deyimleri Seçim deyimleri, belirtilen bir veya daha fazla koşula bağlı
olarak farklı kod bölümlerine dallandırmayı sağlar. Daha fazla
bilgi için aşağıdaki konulara bakın:

Eğer, Else, anahtar, büyük/küçük harf

Yineleme deyimleri Yineleme deyimleri, diziler gibi koleksiyonlar aracılığıyla döngü


gerçekleştirmenizi veya belirli bir koşul karşılanana kadar aynı
deyim kümesini sürekli olarak gerçekleştirmenizi sağlar. Daha
fazla bilgi için aşağıdaki konulara bakın:

Do, for, foreach, in, ,,

Atlama deyimleri Atdeyimlerini, kodun başka bir bölümüne aktarma denetimi.


Daha fazla bilgi için aşağıdaki konulara bakın:

Kes, devam, varsayılan, goto, Return, yield

Özel durum işleme deyimleri Özel durum işleme deyimleri, çalışma zamanında oluşan
olağanüstü koşullardan sorunsuz bir şekilde kurtarmanızı
sağlar. Daha fazla bilgi için aşağıdaki konulara bakın:

throw, try-catch, try-finally, try-catch-finally

Checked ve unchecked Checked ve unchecked deyimleri, sonuçta elde edilen değeri


tutmak için çok küçük bir değişkende depolandığında sayısal
işlemlere taşma olmasına izin verilip verilmeyeceğini
belirtmenizi sağlar. Daha fazla bilgi için bkz. Checked ve
unchecked.

await İfade Zaman uyumsuz değiştiriciyle bir yöntemi işaretlerseniz,


yönteminde await işlecini kullanabilirsiniz. Denetim zaman
uyumsuz yöntemde await bir ifadeye ulaştığında denetim
çağırana döner ve beklenen görev tamamlanana kadar
yöntem içindeki ilerleme durumu askıya alınır. Görev
tamamlandığında, yürütme yöntemi içinde çalışmaya çalışabilir.

Basit bir örnek için, yöntemlerin"zaman uyumsuz metotlar"


bölümüne bakın. Daha fazla bilgi için bkz. Async ve await Ile
zaman uyumsuz programlama.
KATEGORI C#ANAHTAR SÖZCÜKLER/NOTLAR

yield return İfade Yineleyici, bir koleksiyon üzerinde liste veya dizi gibi özel bir
yineleme gerçekleştirir. Bir yineleyici, her öğeyi birer birer
döndürmek için yield return ifadesini kullanır. Bir
yield return ifadeye ulaşıldığında, koddaki geçerli konum
hatırlanır. Yineleyici bir sonraki sefer çağrıldığında, yürütme o
konumdan yeniden başlatılır.

Daha fazla bilgi için bkz. yineleyiciler.

fixed İfade Fixed deyimleri, çöp toplayıcısının taşınabilir bir değişkenin


yerini değiştirmesini engeller. Daha fazla bilgi için bkz.
düzeltildi.

lock İfade Lock deyimleri tek seferde yalnızca bir iş parçacığına kod
bloklarına erişimi sınırlamanıza olanak sağlar. Daha fazla bilgi
için bkz. Lock.

Etiketli deyimler Bir deyime bir etiket verebilir ve sonra etiketli ifadeye geçmek
için goto anahtar sözcüğünü kullanabilirsiniz. (Aşağıdaki
satırdaki örneğe bakın.)

Boş ifade Boş ifade tek bir noktalı virgülden oluşur. Hiçbir şey yapmaz ve
bir deyimin gerekli olduğu, ancak herhangi bir eylemin
gerçekleştirilmesi gereken yerlerde kullanılabilir.

Bildirim deyimleri
Aşağıdaki kod, bir başlangıç ataması ve, gerekli başlatmaya sahip sabit bir bildirime sahip ve olmayan değişken
bildirimlerinin örneklerini gösterir.

// Variable declaration statements.


double area;
double radius = 2;

// Constant declaration statement.


const double pi = 3.14159;

İfade deyimleri
Aşağıdaki kod, atama, atamayla nesne oluşturma ve yöntem çağırma dahil olmak üzere ifade deyimlerinin
örneklerini gösterir.

// Expression statement (assignment).


area = 3.14 * (radius * radius);

// Error. Not statement because no assignment:


//circ * 2;

// Expression statement (method invocation).


System.Console.WriteLine();

// Expression statement (new object creation).


System.Collections.Generic.List<string> strings =
new System.Collections.Generic.List<string>();
Boş ifade
Aşağıdaki örneklerde boş bir deyimin iki kullanımı gösterilmektedir:

void ProcessMessages()
{
while (ProcessMessage())
; // Statement needed here.
}

void F()
{
//...
if (done) goto exit;
//...
exit:
; // Statement needed here.
}

Gömülü deyimler
Do, while, forve foreachdahil bazı deyimler, her zaman bunları izleyen bir katıştırılmış ifadeye sahiptir. Bu
katıştırılmış deyim tek bir deyim veya deyim bloğunda {} köşeli ayraç içine alınmış birden çok deyim olabilir. Hatta,
tek satırlı katıştırılmış deyimler, aşağıdaki örnekte gösterildiği {} gibi köşeli ayraç içine alınabilir:

// Recommended style. Embedded statement in block.


foreach (string s in System.IO.Directory.GetDirectories(
System.Environment.CurrentDirectory))
{
System.Console.WriteLine(s);
}

// Not recommended.
foreach (string s in System.IO.Directory.GetDirectories(
System.Environment.CurrentDirectory))
System.Console.WriteLine(s);

{} Köşeli ayraçlar içine alınmış gömülü bir ifade, bir bildirim bildirimi veya etiketli bir ifade olamaz. Bu, aşağıdaki
örnekte gösterilmiştir:

if(pointB == true)
//Error CS1023:
int radius = 5;

Hatayı onarmak için katıştırılmış ifadeyi bir bloğa yerleştirin:

if (b == true)
{
// OK:
System.DateTime d = System.DateTime.Now;
System.Console.WriteLine(d.ToLongDateString());
}

İç içe geçmiş Ifade blokları


Aşağıdaki kodda gösterildiği gibi, ekstre blokları iç içe olabilir:
foreach (string s in System.IO.Directory.GetDirectories(
System.Environment.CurrentDirectory))
{
if (s.StartsWith("CSharp"))
{
if (s.EndsWith("TempFolder"))
{
return s;
}
}

}
return "Not found.";

Erişilemeyen deyimler
Derleyici, denetim akışının herhangi bir koşullarda belirli bir deyime hiçbir şekilde ulaşamayacağını belirlerse,
aşağıdaki örnekte gösterildiği gibi, uyarı CS0162 oluşturacaktır:

// An over-simplified example of unreachable code.


const int val = 5;
if (val < 4)
{
System.Console.WriteLine("I'll never write anything."); //CS0162
}

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin deyimler bölümüne bakın.

Ayrıca bkz.
C# Programlama Kılavuzu
İfade anahtar sözcükleri
İfadeler
İfadeler (C# Programlama Kılavuzu)
4.11.2019 • 7 minutes to read • Edit Online

Bir ifade bir veya daha fazla işlenenin dizisi ve tek bir değer, nesne, yöntem veya ad alanı olarak
değerlendirilebilen sıfır veya daha fazla işleçlerdir . İfadeler, bir değişmez değer, bir yöntem çağırma, bir işleç ve
işlenenleri ya da basit bir adiçerebilir. Basit adlar bir değişkenin adı, tür üyesi, yöntem parametresi, ad alanı veya
tür olabilir.
İfadeler, diğer ifadeleri parametre olarak kullanan işleçler veya parametreleri diğer Yöntem çağrılarını çağıran
Yöntem çağrılarını kullanabilir, böylece ifadeler basit ve çok karmaşık olabilir. Aşağıdaki iki ifade örneğidir:

((x < 10) && ( x > 5)) || ((x > 20) && (x < 25));

System.Convert.ToInt32("35");

İfade değerleri
İfadelerin çoğunda, örneğin deyimlerde veya yöntem parametrelerinde kullanıldığında, ifadenin bazı değerler
değerlendirmesi beklenir. X ve y tamsayılar ise, ifade x + y sayısal bir değer olarak değerlendirilir. İfade
new MyClass() , bir MyClass sınıfının yeni bir örneğine başvuru olarak değerlendirilir. İfade myClass.ToString() ,
yöntemin dönüş türü olduğundan bir dize olarak değerlendirilir. Ancak, bir ad alanı adı bir ifade olarak
sınıflandırılabilse de, bir değer olarak değerlendirilmez ve bu nedenle hiçbir ifadenin nihai sonucu olmaz. Bir ad
alanı adını yöntem parametresine geçiremez veya yeni bir ifadede kullanamaz veya bir değişkene atayabilirsiniz.
Daha büyük bir ifadede yalnızca alt ifade olarak kullanabilirsiniz. Aynı şekilde türler (System.Type nesnelerden
farklı olarak), Yöntem grubu adları (belirli metotlardan farklı olarak) ve olay ekleme ve kaldırma erişimcileri için de
geçerlidir.
Her değerin ilişkili bir türü vardır. Örneğin, x ve y int tür değişkenleridir, x + y ifade değeri de int olarak
yazılır. Değer farklı türde bir değişkene atanırsa veya x ve y farklı türse, tür dönüştürme kuralları uygulanır. Bu
dönüşümlerin nasıl çalıştığı hakkında daha fazla bilgi için bkz. atama ve tür dönüştürmeleri.

Taştığında
Değer değerin türünün en büyük değerinden daha büyükse sayısal ifadeler taşmaya neden olabilir. Daha fazla
bilgi için, bkz. Checked ve unchecked ve yerleşik sayısal dönüşümler makalesindeki Açık sayısal dönüştürmeler
bölümü.

İşleç önceliği ve ilişkilendirilebilirlik


Bir ifadenin değerlendirilme şekli, birleşim ve işleç önceliği kurallarına tabidir. Daha fazla bilgi için bkz. işleçler.
Atama ifadeleri ve yöntem çağırma ifadeleri hariç olmak üzere çoğu ifadenin bir deyime katıştırılması gerekir.
Daha fazla bilgi için bkz. deyimler.

Değişmez değerler ve basit adlar


İki basit ifade türü değişmez değer ve basit adlardır. Sabit değer, adı olmayan bir sabit değerdir.Örneğin, aşağıdaki
kod örneğinde, hem 5 hem de "Hello World" değişmez değerlerdir:
// Expression statements.
int i = 5;
string s = "Hello World";

Değişmez değerler hakkında daha fazla bilgi için bkz. türler.


Yukarıdaki örnekte, hem i hem de s yerel değişkenleri tanımlayan basit adlardır. Bu değişkenler bir ifadede
kullanıldığında, değişken adı, şu anda, değişkenin bellekteki konumunda depolanan değeri değerlendirir. Bu,
aşağıdaki örnekte gösterilmiştir:

int num = 5;
System.Console.WriteLine(num); // Output: 5
num = 6;
System.Console.WriteLine(num); // Output: 6

Çağırma ifadeleri
Aşağıdaki kod örneğinde, DoWork çağrısı bir çağırma deyimidir.

DoWork();

Bir yöntem çağrısı, önceki örnekteki gibi bir ad olarak veya başka bir ifadenin sonucu olarak, parantez ve herhangi
bir yöntem parametresi olarak yöntemin adını gerektirir. Daha fazla bilgi için bkz. Yöntemler. Bir temsilci çağrısı,
parantez içinde bir temsilci ve yöntem parametrelerinin adını kullanır. Daha fazla bilgi için bkz. Temsilciler. Yöntem
etkinleştirmeleri ve temsilci etkinleştirmeleri, yöntemi bir değer döndürürse yöntemin dönüş değeri olarak
değerlendirilir. Void döndüren yöntemler bir ifadede bir değer yerine kullanılamaz.

Sorgu ifadeleri
Genel içindeki ifadelerle ilgili kuralların aynı kuralları sorgu ifadeleri için de geçerlidir. Daha fazla bilgi için bkz.
LINQ.

Lambda ifadeleri
Lambda ifadeleri, adı olmayan ancak giriş parametreleri ve birden çok deyim içeren "satır içi yöntemleri" temsil
eder. Bağımsız değişkenleri yöntemlere geçirmek için LINQ 'ta kapsamlı olarak kullanılırlar. Lambda ifadeleri,
kullanıldıkları içeriğe bağlı olarak temsilciler ya da ifade ağaçları için derlenir. Daha fazla bilgi için bkz. lambda
ifadeleri.

İfade ağaçları
İfade ağaçları, ifadelerin veri yapıları olarak temsil olmasını sağlar. Sorgu ifadelerini, SQL veritabanı gibi başka bir
bağlamda anlamlı koda dönüştürmek için, LINQ sağlayıcıları tarafından kapsamlı olarak kullanılır. Daha fazla bilgi
için bkz. Ifade ağaçlarıC#().

İfade gövdesi tanımları


C#Yöntemler, oluşturucular, sonlandırıcılar, Özellikler ve Dizin oluşturucular için kısa ifade gövdesi açıklaması
sunmanıza olanak tanıyan Expression-Bodied üyelerinidestekler. Daha fazla bilgi için bkz. Expression-Bodied
Üyeler.

Açıklamalar
Bir ifadeden bir değişken, nesne özelliği veya nesne Dizin Oluşturucu erişimi tanımlandığında, bu öğenin değeri
ifadenin değeri olarak kullanılır. İfade, son olarak gereken türü değerlendiren C# sürece bir değer veya nesnenin
gerektiği yerde yerleştirilebilecek.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin ifadeler bölümüne bakın.

Ayrıca bkz.
C# Programlama Kılavuzu
işleçler
Yöntemler
Temsilciler
Türler
LINQ
İfade-Bodied Üyeler (C# Programlama Kılavuzu)
31.10.2019 • 5 minutes to read • Edit Online

İfade gövdesi tanımları, üyenin uygulamasını çok kısa, okunabilir bir biçimde sağlamanıza olanak tanır. Bir
yöntem veya özellik gibi desteklenen herhangi bir üyenin mantığı tek bir ifadeden oluşuyorsa, bir ifade gövdesi
tanımı kullanabilirsiniz. Bir ifade gövdesi tanımında aşağıdaki genel sözdizimi vardır:

member => expression;

Burada ifadesi geçerli bir ifadedir.


6 ' C# da Yöntemler ve salt okunurdur özellikler için ifade gövdesi tanımları desteği sunuldu ve 7,0 ' de C#
genişletildi. İfade gövdesi tanımları, aşağıdaki tabloda listelenen tür üyeleri ile birlikte kullanılabilir:

ÜYE İTIBARIYLE DESTEKLENIYOR...

Yöntemidir C# 6

Salt okunurdur özelliği C# 6

Özelliði C# 7.0

Constructor C# 7.0

Sonlandırıcı C# 7.0

Dizinleyic C# 7.0

Yöntemler
İfade-Bodied yöntemi, türü yöntemin dönüş türüyle eşleşen bir değer döndüren tek bir ifadeden oluşur veya
void döndüren yöntemler için bazı işlemleri gerçekleştirir. Örneğin, ToString yöntemini geçersiz kılan türler,
genellikle geçerli nesnenin dize gösterimini döndüren tek bir ifade içerir.
Aşağıdaki örnek, bir ifade gövdesi tanımıyla ToString yöntemini geçersiz kılan bir Person sınıfını tanımlar. Ayrıca,
konsola bir ad görüntüleyen bir DisplayName yöntemi tanımlar. return anahtar sözcüğünün ToString ifadesi
gövde tanımında kullanılmadığını unutmayın.
using System;

public class Person


{
public Person(string firstName, string lastName)
{
fname = firstName;
lname = lastName;
}

private string fname;


private string lname;

public override string ToString() => $"{fname} {lname}".Trim();


public void DisplayName() => Console.WriteLine(ToString());
}

class Example
{
static void Main()
{
Person p = new Person("Mandy", "Dejesus");
Console.WriteLine(p);
p.DisplayName();
}
}

Daha fazla bilgi için bkz. YöntemlerC# (Programlama Kılavuzu).

Salt okunurdur özellikleri


C# 6 ' dan itibaren, salt okunurdur bir özellik uygulamak için ifade gövdesi tanımı kullanabilirsiniz. Bunu yapmak
için aşağıdaki sözdizimini kullanın:

PropertyType PropertyName => expression;

Aşağıdaki örnek, salt okunurdur Name özelliği özel locationName alanının değerini döndüren bir ifade gövdesi
tanımı olarak uygulanan bir Location sınıfını tanımlar:

public class Location


{
private string locationName;

public Location(string name)


{
locationName = name;
}

public string Name => locationName;


}

Özellikler hakkında daha fazla bilgi için bkz. ÖzelliklerC# (Programlama Kılavuzu).

Özellikler
7,0 ' C# den başlayarak, özellik get ve set erişimcileri uygulamak için ifade gövdesi tanımlarını kullanabilirsiniz.
Aşağıdaki örnek bunun nasıl yapılacağını göstermektedir:
public class Location
{
private string locationName;

public Location(string name) => Name = name;

public string Name


{
get => locationName;
set => locationName = value;
}
}

Özellikler hakkında daha fazla bilgi için bkz. ÖzelliklerC# (Programlama Kılavuzu).

Oluşturucular
Bir oluşturucunun ifade gövdesi tanımı genellikle tek bir atama ifadesi veya oluşturucunun bağımsız
değişkenlerini işleyen veya örnek durumunu Başlatan bir yöntem çağrısından oluşur.
Aşağıdaki örnek, oluşturucusunun adıadlı tek bir dize parametresine sahip bir Location sınıfını tanımlar. İfade
gövdesi tanımı, bağımsız değişkeni Name özelliğine atar.

public class Location


{
private string locationName;

public Location(string name) => Name = name;

public string Name


{
get => locationName;
set => locationName = value;
}
}

Daha fazla bilgi için bkz. oluşturucularC# (Programlama Kılavuzu).

Sonlandırıcılar
Sonlandırıcı için bir ifade gövdesi tanımı tipik olarak, yönetilmeyen kaynakları serbest bırakma deyimleri gibi
temizleme deyimlerini içerir.
Aşağıdaki örnek, sonlandırıcının çağrıldığını göstermek için bir ifade gövde tanımı kullanan sonlandırıcıyı
tanımlar.

using System;

public class Destroyer


{
public override string ToString() => GetType().Name;

~Destroyer() => Console.WriteLine($"The {ToString()} destructor is executing.");


}

Daha fazla bilgi için bkz. sonlandırıcılarC# (Programlama Kılavuzu).

Dizin Oluşturucular
Özellikler ile benzer şekilde, get erişimci bir değer döndüren tek bir ifadeden oluşuyorsa veya set erişimcisi
basit bir atama gerçekleştirdiğinden, Dizin Oluşturucu get ve set erişimcileri ifade gövdesi tanımlarından
oluşur.
Aşağıdaki örnek, bir dizi spor adını içeren bir iç String dizisi içeren Sports adlı bir sınıfı tanımlar. Dizin
Oluşturucu get ve set erişimcileri, ifade gövdesi tanımları olarak uygulanır.

using System;
using System.Collections.Generic;

public class Sports


{
private string[] types = { "Baseball", "Basketball", "Football",
"Hockey", "Soccer", "Tennis",
"Volleyball" };

public string this[int i]


{
get => types[i];
set => types[i] = value;
}
}

Daha fazla bilgi için bkz. DizinC# oluşturucular (Programlama Kılavuzu).


Anonim işlevler (C# Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Anonim bir işlev, bir temsilci türünün beklendiği her yerde kullanılabilecek bir "satır içi" deyim veya ifadedir.
Adlandırılmış bir temsilciyi başlatmak veya bir yöntem parametresi olarak adlandırılmış bir temsilci türü yerine
bunu geçirmek için kullanabilirsiniz.
Anonim bir işlev oluşturmak için bir lambda ifadesi veya anonim yöntem kullanabilirsiniz. Satır içi kod yazmak
için daha kısa ve açıklayıcı bir yol sağlayan lambda ifadeleri kullanmanızı öneririz. Anonim yöntemlerin aksine,
bazı lambda ifadesi türleri ifade ağacı türlerine dönüştürülebilir.

C 'deki temsilcilerin evrimi#


1,0 C# ' de, bir temsilci örneğini kodun başka bir yerinde tanımlanmış bir yöntemle açıkça başlatarak
oluşturdunuz. C#2,0, anonim yöntemler kavramını bir temsilci çağrısında yürütülebilecek adlandırılmamış satır içi
deyimler yazmak için bir yol olarak sunmuştur. C#3,0, anonim yöntemlere kavram olarak benzeyen, ancak daha
açıklayıcı ve kısa olan lambda ifadeleri sunmuştur. Bu iki özellik topluca Anonim işlevlerolarak bilinir. Genel
olarak, .NET Framework sürüm 3,5 ve üstünü hedefleyen uygulamalar Lambda ifadelerini kullanmalıdır.
Aşağıdaki örnek 1,0 ile C# C# 3,0 arasında temsilci oluşturma gelişini göstermektedir:
class Test
{
delegate void TestDelegate(string s);
static void M(string s)
{
Console.WriteLine(s);
}

static void Main(string[] args)


{
// Original delegate syntax required
// initialization with a named method.
TestDelegate testDelA = new TestDelegate(M);

// C# 2.0: A delegate can be initialized with


// inline code, called an "anonymous method." This
// method takes a string as an input parameter.
TestDelegate testDelB = delegate(string s) { Console.WriteLine(s); };

// C# 3.0. A delegate can be initialized with


// a lambda expression. The lambda also takes a string
// as an input parameter (x). The type of x is inferred by the compiler.
TestDelegate testDelC = (x) => { Console.WriteLine(x); };

// Invoke the delegates.


testDelA("Hello. My name is M and I write lines.");
testDelB("That's nothing. I'm anonymous and ");
testDelC("I'm a famous author.");

// Keep console window open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* Output:
Hello. My name is M and I write lines.
That's nothing. I'm anonymous and
I'm a famous author.
Press any key to exit.
*/

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin anonim işlev ifadeleri bölümüne bakın.

Ayrıca bkz.
Deyimler, İfadeler ve İşleçler
Lambda İfadeleri
Temsilciler
İfade ağaçları (C#)
Lambda ifadeleri (C# Programlama Kılavuzu)
4.11.2019 • 17 minutes to read • Edit Online

Lambda ifadesi aşağıdaki iki formdan herhangi birinin bir ifadesidir:


Gövdesi olarak bir ifadeye sahip olan ifade lambda :

(input-parameters) => expression

Gövdesi olarak bir ifade bloğuna sahip olan ifade lambda :

(input-parameters) => { <sequence-of-statements> }

Lambda parametre listesini gövdesinden ayırmak için => lambda bildirimi işlecini kullanın. Lambda
ifadesi oluşturmak için, lambda işlecinin sol tarafında (varsa) giriş parametrelerini ve diğer tarafta bir
ifade ya da deyim bloğunu belirtirsiniz.
Herhangi bir lambda ifadesi, bir temsilci türüne dönüştürülebilir. Lambda ifadesinin dönüştürülebileceği
temsilci türü, parametrelerinin ve dönüş değerinin türlerine göre tanımlanır. Lambda ifadesi bir değer
döndürmezse, Action temsilci türlerinden birine dönüştürülebilir; Aksi takdirde, Func temsilci
türlerinden birine dönüştürülebilir. Örneğin, iki parametresi olan ve değer döndüren bir lambda ifadesi
bir Action<T1,T2> temsilcisine dönüştürülemez. Bir parametreye sahip olan ve bir değer döndüren bir
lambda ifadesi Func<T,TResult> temsilciye dönüştürülebilir. Aşağıdaki örnekte, x adlı bir parametreyi
belirten x => x * x lambda ifadesi, bir temsilci türü değişkenine atanmış x kare değeri döndürür:

Func<int, int> square = x => x * x;


Console.WriteLine(square(5));
// Output:
// 25

Aşağıdaki örnekte gösterildiği gibi ifade lambdaları da ifade ağacı türlerine dönüştürülebilir:

System.Linq.Expressions.Expression<Func<int, int>> e = x => x * x;


Console.WriteLine(e);
// Output:
// x => (x * x)

Lambda ifadelerini, örneğin, arka planda yürütülmesi gereken kodu geçirmek için Task.Run(Action)
yöntemine bir bağımsız değişken olarak temsilci türleri veya ifade ağaçları örnekleri gerektiren herhangi
bir kodda kullanabilirsiniz. Aşağıdaki örnekte gösterildiği gibi, LINQ ' de C# yazdığınızda Lambda
ifadelerini de kullanabilirsiniz:

int[] numbers = { 2, 3, 4, 5 };
var squaredNumbers = numbers.Select(x => x * x);
Console.WriteLine(string.Join(" ", squaredNumbers));
// Output:
// 4 9 16 25

System.Linq.Enumerable sınıfında Enumerable.Select yöntemini çağırmak için yöntem tabanlı sözdizimi


kullandığınızda (örneğin, LINQ to Objects ve LINQ to XML, parametre bir temsilci türüdür
System.Func<T,TResult>. System.Linq.Queryable sınıfında Queryable.Select yöntemini çağırdığınızda,
örneğin LINQ to SQL, parametre türü bir ifade ağacı türüdür Expression<Func<TSource,TResult>> . Her iki
durumda da, parametre değerini belirtmek için aynı lambda ifadesini kullanabilirsiniz. Bu, Lambdalar
tarafından oluşturulan nesnelerin türü farklı olsa da, iki Select benzer görünmesini sağlar.

İfade lambdaları
=> işlecinin sağ tarafında bir ifade olan bir lambda ifadesine bir ifade lambdaadı verilir. İfade lambdaları
ifade ağaçlarınınyapımını yaygın olarak kullanır. Bir lambda ifadesi, ifadenin sonucunu verir ve aşağıdaki
temel biçimi alır:

(input-parameters) => expression

Parantezler yalnızca lambdanın bir çıktı parametresi varsa isteğe bağlıdır; aksi takdirde bunlar gereklidir.
Boş ayraçlarla sıfır giriş parametrelerini belirtin:

Action line = () => Console.WriteLine();

İki veya daha fazla giriş parametresi, ayraç içinde virgülle ayrılır:

Func<int, int, bool> testForEquality = (x, y) => x == y;

Bazen derleyicinin giriş türlerini çıkarması olanaksızdır. Aşağıdaki örnekte gösterildiği gibi türleri açıkça
belirtebilirsiniz:

Func<int, string, bool> isTooLong = (int x, string s) => s.Length > x;

Giriş parametresi türleri tamamen açık veya tümü örtük olmalıdır; Aksi halde, bir CS0748 derleyici hatası
oluşur.
Lambda ifadesinin gövdesi bir yöntem çağrısından oluşabilir. Ancak, SQL Server gibi .NET ortak dil
çalışma zamanının bağlamı dışında değerlendirilen ifade ağaçları oluşturuyorsanız, Lambda ifadelerinde
Yöntem çağrılarını kullanmamalısınız. Yöntemler .NET ortak dil çalışma zamanı bağlamının dışında
anlamlı olmayacaktır.

İfade lambdaları
Ayraçlar arasındaki deyimler hariç statement lambda, expression lambda'ya benzer:

(input-parameters) => { <sequence-of-statements> }

Bir lambda deyiminin gövdesi herhangi bir sayıda deyimden oluşabilir; ancak, uygulamada genellikle iki
veya üçten fazla değildir.
Action<string> greet = name =>
{
string greeting = $"Hello {name}!";
Console.WriteLine(greeting);
};
greet("World");
// Output:
// Hello World!

Deyim lambdaları ifade ağaçları oluşturmak için kullanılamaz.

Zaman uyumsuz Lambdalar


Async ve await anahtar sözcüklerini kullanarak zaman uyumsuz işleme içeren lambda ifadeleri ve
deyimlerini kolayca oluşturabilirsiniz. Örneğin, aşağıdaki Windows Forms örnek, zaman uyumsuz bir
yöntemi çağıran ve bekleden bir olay işleyicisi içerir, ExampleMethodAsync .

public partial class Form1 : Form


{
public Form1()
{
InitializeComponent();
button1.Click += button1_Click;
}

private async void button1_Click(object sender, EventArgs e)


{
await ExampleMethodAsync();
textBox1.Text += "\r\nControl returned to Click event handler.\n";
}

private async Task ExampleMethodAsync()


{
// The following line simulates a task-returning asynchronous process.
await Task.Delay(1000);
}
}

Zaman uyumsuz lambda kullanarak aynı olay işleyicisini ekleyebilirsiniz. Bu işleyiciyi eklemek için
aşağıdaki örnekte gösterildiği gibi Lambda parametre listesinden önce bir async değiştiricisi ekleyin:

public partial class Form1 : Form


{
public Form1()
{
InitializeComponent();
button1.Click += async (sender, e) =>
{
await ExampleMethodAsync();
textBox1.Text += "\r\nControl returned to Click event handler.\n";
};
}

private async Task ExampleMethodAsync()


{
// The following line simulates a task-returning asynchronous process.
await Task.Delay(1000);
}
}

Zaman uyumsuz yöntemlerin nasıl oluşturulacağı ve kullanılacağı hakkında daha fazla bilgi için bkz.
Async ve await Ile zaman uyumsuz programlama.

Lambda ifadeleri ve tanımlama grupları


Dil, C# 7,0 ile başlayarak, Tanımlama gruplarıiçin yerleşik destek sağlar. C# Bir lambda ifadesine bağımsız
değişken olarak bir tanımlama grubu sağlayabilirsiniz ve lambda ifadeniz de bir tanımlama grubu
döndürebilir. Bazı durumlarda, C# derleyici demet bileşenleri türlerini belirlemekte tür çıkarımı kullanır.
Bir tanımlama grubu, bileşenlerinin virgülle ayrılmış bir listesini parantez içine alarak tanımlarsınız.
Aşağıdaki örnek, her bir değeri iki katına çıkarır ve çarpma 'un sonucunu içeren üç bileşeni olan bir
tanımlama grubu döndüren bir lambda ifadesine bir dizi sayıyı geçirmek için üç bileşeni olan tanımlama
grubunu kullanır.

Func<(int, int, int), (int, int, int)> doubleThem = ns => (2 * ns.Item1, 2 * ns.Item2, 2 * ns.Item3);
var numbers = (2, 3, 4);
var doubledNumbers = doubleThem(numbers);
Console.WriteLine($"The set {numbers} doubled: {doubledNumbers}");
// Output:
// The set (2, 3, 4) doubled: (4, 6, 8)

Normalde, bir tanımlama grubu alanları Item1 , Item2 vb. olarak adlandırılır. Ancak, aşağıdaki örnekte
olduğu gibi adlandırılmış bileşenlerle bir tanımlama grubu tanımlayabilirsiniz.

Func<(int n1, int n2, int n3), (int, int, int)> doubleThem = ns => (2 * ns.n1, 2 * ns.n2, 2 * ns.n3);
var numbers = (2, 3, 4);
var doubledNumbers = doubleThem(numbers);
Console.WriteLine($"The set {numbers} doubled: {doubledNumbers}");

Tanımlama grupları hakkında C# daha fazla bilgi için bkz C# . demet türleri.

Standart sorgu işleçleri ile Lambdalar


Diğer uygulamalar arasında LINQ to Objects, türü genel temsilcilerin Func<TResult> ailesinden olan bir
giriş parametresine sahiptir. Bu temsilciler, giriş parametrelerinin sayısını ve türünü ve temsilcinin dönüş
türünü tanımlamak için tür parametreleri kullanır. Func temsilciler, bir kaynak veri kümesindeki her
öğeye uygulanan Kullanıcı tanımlı ifadeleri kapsüllemek için çok yararlıdır. Örneğin, Func<T,TResult>
temsilci türünü göz önünde bulundurun:

public delegate TResult Func<in T, out TResult>(T arg)

Temsilci, int bir giriş parametresi olduğu ve döndürülen değer bool Func<int, bool> bir örnek olarak
oluşturulabilir. Dönüş değeri her zaman son tür parametresinde belirtilir. Örneğin,
Func<int, string, bool> iki giriş parametresi olan bir temsilciyi, int ve string ve bool dönüş türünü
tanımlar. Aşağıdaki Func temsilci çağrıldığında, giriş parametresinin beş ' a eşit olup olmadığını belirten
Boole değeri döndürür:

Func<int, bool> equalsFive = x => x == 5;


bool result = equalsFive(4);
Console.WriteLine(result); // False

Bağımsız değişken türü bir Expression<TDelegate>olduğunda bir lambda ifadesi de sağlayabilirsiniz,


örneğin, Queryable türünde tanımlanan standart sorgu işleçleri. Bir Expression<TDelegate> bağımsız
değişkeni belirttiğinizde, lambda bir ifade ağacına derlenir.
Aşağıdaki örnek Count standart sorgu işlecini kullanır:

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
int oddNumbers = numbers.Count(n => n % 2 == 1);
Console.WriteLine($"There are {oddNumbers} odd numbers in {string.Join(" ", numbers)}");

Derleyici giriş parametresinin türünü çıkarabilir veya bunu açıkça belirtebilirsiniz. Bu belirli lambda
ifadesi, ikiye bölünen 1 ' in geri kalanı olduğunda bu tamsayıları ( n ) sayar.
Aşağıdaki örnek, koşulu karşılamayan dizideki ilk sayı olduğundan, 9 ' dan önce gelen numbers
dizisindeki tüm öğeleri içeren bir dizi üretir:

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
var firstNumbersLessThanSix = numbers.TakeWhile(n => n < 6);
Console.WriteLine(string.Join(" ", firstNumbersLessThanSix));
// Output:
// 5 4 1 3

Aşağıdaki örnek, birden çok giriş parametresini parantez içine alarak belirtir. Yöntemi, değeri dizideki sıra
konumundan daha az olan bir sayıyla karşılaşana kadar numbers dizisindeki tüm öğeleri döndürür:

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
var firstSmallNumbers = numbers.TakeWhile((n, index) => n >= index);
Console.WriteLine(string.Join(" ", firstSmallNumbers));
// Output:
// 5 4

Lambda ifadelerinde tür çıkarımı


Lambda yazarken genellikle giriş parametreleri için bir tür belirtmeniz gerekmez, derleyici lambda
gövdesine, parametre türlerine ve C# dil belirtiminde açıklanan diğer etkenlere göre türü çıkarsabilir.
Standart sorgu işleçlerinin çoğunda ilk giriş kaynak dizisindeki öğelerin türüdür. Bir
IEnumerable<Customer> sorguladıktan sonra, giriş değişkeni bir Customer nesnesi olarak algılanır ve bu,
yöntemlerine ve özelliklerine erişiminiz olduğu anlamına gelir:

customers.Where(c => c.City == "London");

Lambdalar için tür çıkarımı için genel kurallar aşağıdaki gibidir:


Lambda temsilci türüyle aynı sayıda parametre içermelidir.
Lambdadaki her giriş parametresi, denk gelen temsilci parametresine dolaylı olarak
dönüştürülebilir olmalıdır.
Lambdanın (varsa) dönüş değeri örtük olarak temsilcinin dönüş türüne dönüştürülebilir olmalıdır.
Ortak tür sisteminin hiçbir "lambda ifadesi" kavramı olmadığından, lambda ifadelerinin bir tür olmadığını
unutmayın. Ancak, bazen bir lambda ifadesinin "tür" i resmi olarak konuşmak yararlı olabilir. Bu
durumlarda tür, lambda ifadesinin dönüştürüldüğü temsilci türüne veya Expression türüne başvurur.

Lambda ifadelerinde dış değişkenlerin ve değişken kapsamının


yakalanması
Lambdalar, dış değişkenlerebaşvurabilir. Bunlar, lambda ifadesini tanımlayan yöntemde veya lambda
ifadesini içeren türde kapsamda kapsam içinde olan değişkenlerdir. Bu şekilde tutulan değişkenler, aksi
halde kapsam dışına çıkacak ve çöp olarak toplanacak olsalar dahi kullanılmak üzere lambda ifadesinde
saklanır. Bir lambda ifadesinde tüketilebilmesi için öncelikle mutlaka bir harici değişken tayin edilmelidir.
Aşağıdaki örnek bu kuralları gösterir:

public static class VariableScopeWithLambdas


{
public class VariableCaptureGame
{
internal Action<int> updateCapturedLocalVariable;
internal Func<int, bool> isEqualToCapturedLocalVariable;

public void Run(int input)


{
int j = 0;

updateCapturedLocalVariable = x =>
{
j = x;
bool result = j > input;
Console.WriteLine($"{j} is greater than {input}: {result}");
};

isEqualToCapturedLocalVariable = x => x == j;

Console.WriteLine($"Local variable before lambda invocation: {j}");


updateCapturedLocalVariable(10);
Console.WriteLine($"Local variable after lambda invocation: {j}");
}
}

public static void Main()


{
var game = new VariableCaptureGame();

int gameInput = 5;
game.Run(gameInput);

int jTry = 10;


bool result = game.isEqualToCapturedLocalVariable(jTry);
Console.WriteLine($"Captured local variable is equal to {jTry}: {result}");

int anotherJ = 3;
game.updateCapturedLocalVariable(anotherJ);

bool equalToAnother = game.isEqualToCapturedLocalVariable(anotherJ);


Console.WriteLine($"Another lambda observes a new value of captured variable:
{equalToAnother}");
}
// Output:
// Local variable before lambda invocation: 0
// 10 is greater than 5: True
// Local variable after lambda invocation: 10
// Captured local variable is equal to 10: True
// 3 is greater than 5: False
// Another lambda observes a new value of captured variable: True
}

Lambda ifadelerindeki değişken kapsam için aşağıdaki kurallar geçerlidir:


Tutulan bir değişkenin kullandığı bellek, ona başvuran temsilcinin kullandığı bellek geri
kazanılmaya hazır hale gelinceye kadar geri kazanılmaz.
Bir lambda ifadesi içinde tanıtılan değişkenler kapsayan yöntemde görünmez.
Lambda ifadesi kapsayan yöntemden bir ın, refveya Out parametresini doğrudan yakalayamaz.
Lambda ifadesindeki bir dönüş deyimi kapsayan metodun dönüşmesine neden olmaz.
Bir lambda ifadesi, bu sıçrama deyiminin hedefi lambda ifade bloğunun dışındaysa bir goto,
Breakveya Continue deyimi içeremez. Ayrıca, hedef bloğun içindeyse lambda ifade bloğunun
dışında bir sıçrama deyimine sahip olmak için bir hatadır.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin anonim işlev ifadeleri bölümüne bakın.

öne çıkan kitap bölümü


3,0 tanımlama kitabı, üçüncü sürüm 'de Temsilciler, olaylar ve lambda ifadeleri C# : 3,0 programcılar için
C# 250 ' den fazla çözüm

Ayrıca bkz.
C# Programlama Kılavuzu
LINQ (dil ile tümleşik sorgu)
İfade Ağaçları
Yerel işlevler lambda ifadeleriyle karşılaştırılır
Örtük olarak yazılan lambda ifadeleri
Visual Studio 2008 C# örnekleri (bkz. LINQ örnek sorguları dosyaları ve XQuery programı)
Özyinelemeli lambda ifadeleri
Nasıl yapılır: Sorguda Lambda İfadeleri Kullanma (C#
Programlama Kılavuzu)
4.11.2019 • 3 minutes to read • Edit Online

Lambda ifadelerini doğrudan sorgu sözdiziminde kullanamazsınız, ancak bunları yöntem çağrılarında kullanın ve
sorgu ifadeleri Yöntem çağrıları içerebilir. Aslında, bazı sorgu işlemleri yalnızca yöntem sözdiziminde ifade
edilebilir. Sorgu sözdizimi ve Yöntem sözdizimi arasındaki fark hakkında daha fazla bilgi için bkz. LINQ 'Te sorgu
sözdizimi ve Yöntem sözdizimi.

Örnek
Aşağıdaki örnek, Enumerable.Where standart sorgu işlecini kullanarak bir lambda ifadesinin Yöntem tabanlı bir
sorguda nasıl kullanılacağını göstermektedir. Bu örnekteki Where yönteminin, temsilci türü Func<T,TResult> bir
giriş parametresine sahip olduğunu ve bu temsilcinin girdi olarak bir tamsayı aldığını ve bir Boolean
döndürdüğünden emin olduğunu unutmayın. Lambda ifadesi bu temsilciye dönüştürülebilir. Bu, Queryable.Where
yöntemini kullanan LINQ - SQL bir sorgudaysa, parametre türü bir Expression<Func<int,bool>> olur ancak
lambda ifadesi tamamen aynı şekilde görünür. Ifade türü hakkında daha fazla bilgi için bkz.
System.Linq.Expressions.Expression.

class SimpleLambda
{
static void Main()
{

// Data source.
int[] scores = { 90, 71, 82, 93, 75, 82 };

// The call to Count forces iteration of the source


int highScoreCount = scores.Where(n => n > 80).Count();

Console.WriteLine("{0} scores are greater than 80", highScoreCount);

// Outputs: 4 scores are greater than 80


}
}

Örnek
Aşağıdaki örnek, bir sorgu ifadesinin Yöntem çağrısında bir lambda ifadesinin nasıl kullanılacağını göstermektedir.
Lambda gereklidir çünkü Sum standart sorgu işleci sorgu sözdizimi kullanılarak çağrılamaz.
Sorgu ilk olarak öğrencileri, GradeLevel numaralandırmasında tanımlanan şekilde kendi sınıf düzeylerine göre
gruplandırır. Ardından her bir grup için her öğrenci için toplam puanları ekler. Bunun için iki Sum işlemi gerekir. İç
Sum her öğrencinin toplam Puanını hesaplar ve dış Sum , gruptaki tüm öğrenciler için çalışan ve Birleşik toplamı
tutar.
private static void TotalsByGradeLevel()
{
// This query retrieves the total scores for First Year students, Second Years, and so on.
// The outer Sum method uses a lambda in order to specify which numbers to add together.
var categories =
from student in students
group student by student.Year into studentGroup
select new { GradeLevel = studentGroup.Key, TotalScore = studentGroup.Sum(s => s.ExamScores.Sum()) };

// Execute the query.


foreach (var cat in categories)
{
Console.WriteLine("Key = {0} Sum = {1}", cat.GradeLevel, cat.TotalScore);
}
}
/*
Outputs:
Key = SecondYear Sum = 1014
Key = ThirdYear Sum = 964
Key = FirstYear Sum = 1058
Key = FourthYear Sum = 974
*/

Kod Derleniyor
Bu kodu çalıştırmak için, metodu kopyalayıp nasıl yapılır: bir nesne koleksiyonunu sorgulama ve Main
yönteminden çağırma bölümünde sunulan StudentClass yapıştırın.

Ayrıca bkz.
Lambda İfadeleri
İfade ağaçları (C#)
Eşitlik karşılaştırmaları (C# Programlama Kılavuzu)
29.11.2019 • 5 minutes to read • Edit Online

Her zaman eşitlik için iki değeri karşılaştırmak gereklidir. Bazı durumlarda denklikolarak da bilinen değer eşitlikiçin
test edersiniz, bu da iki değişken tarafından içerilen değerlerin eşit olduğu anlamına gelir. Diğer durumlarda, iki
değişkenin bellekteki aynı temel nesneye başvurmadığını belirlemelisiniz. Bu tür bir eşitlik, başvuru eşitlikveya
kimlikolarak adlandırılır. Bu konu, bu iki tür eşitliği açıklar ve daha fazla bilgi için diğer konulara bağlantılar sağlar.

Başvuru eşitliği
Başvuru eşitliği, iki nesne başvurusunun aynı temel nesneye başvurduğu anlamına gelir. Bu durum, aşağıdaki
örnekte gösterildiği gibi basit atama aracılığıyla gerçekleşebilir.

using System;
class Test
{
public int Num { get; set; }
public string Str { get; set; }

static void Main()


{
Test a = new Test() { Num = 1, Str = "Hi" };
Test b = new Test() { Num = 1, Str = "Hi" };

bool areEqual = System.Object.ReferenceEquals(a, b);


// False:
System.Console.WriteLine("ReferenceEquals(a, b) = {0}", areEqual);

// Assign b to a.
b = a;

// Repeat calls with different results.


areEqual = System.Object.ReferenceEquals(a, b);
// True:
System.Console.WriteLine("ReferenceEquals(a, b) = {0}", areEqual);

// Keep the console open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}

Bu kodda, iki nesne oluşturulur, ancak atama ifadesinden sonra, her iki başvuru da aynı nesneye başvurur.Bu
nedenle, başvuru eşitliği vardır. İki başvuruyu aynı nesneye başvurmadığını öğrenmek için ReferenceEquals
yöntemini kullanın.
Başvuru eşitliği kavramı yalnızca başvuru türleri için geçerlidir. Değer türünün bir örneği bir değişkene
atandığında, değerin bir kopyası yapıldığında değer türü nesnelerinin başvuru eşitliği olamaz. Bu nedenle, bellekte
aynı konuma başvuran iki kutulanmış yapı olamaz. Ayrıca, iki değer türünü karşılaştırmak için ReferenceEquals
kullanırsanız, nesnelerde yer alan değerler aynı olsa bile sonuç her zaman false olur. Bunun nedeni, her
değişkenin ayrı bir nesne örneğinde paketlenme örneğidir. Daha fazla bilgi için bkz. nasıl yapılır: başvuru eşitliği
testi (kimlik).

Değer eşitlik
Değer eşitliği iki nesnenin aynı değer veya değerleri içerdiği anlamına gelir. İnt veya boolgibi temel değer türleri
için, değer eşitlik için testler basittir. Aşağıdaki örnekte gösterildiği gibi == işlecini kullanabilirsiniz.

int a = GetOriginalValue();
int b = GetCurrentValue();

// Test for value equality.


if( b == a)
{
// The two integers are equal.
}

Çoğu diğer tür için, değer eşitlik testi, türün onu nasıl tanımladığını anladığından emin olmanızı gerektirdiğinden
daha karmaşıktır. Birden çok alanı veya özelliği olan sınıflar ve yapılar için, değer eşitlik genellikle tüm alanların
veya özelliklerin aynı değere sahip olduğu anlamına gelir. Örneğin, pointA. X, pointB. X ve pointA. Y ' ye eşitse, iki
Point nesne eşdeğer olacak şekilde tanımlanabilir. y öğesine eşittir.

Ancak, bir tür içindeki tüm alanları temel alan denklik gereksinimi yoktur. Bir alt kümeyi temel alabilir. Sahip
olmadığınız türleri karşılaştırdığınızda, bu tür için denkliğin nasıl tanımlandığını anladığınızdan emin olmalısınız.
Kendi sınıflarınızda ve yapılarda değer eşitliğini tanımlama hakkında daha fazla bilgi için bkz. nasıl yapılır: tür Için
değer eşitliği tanımlama.
Kayan nokta değerleri için değer eşitliği
Kayan nokta değerlerinin (Double ve float) eşitlik karşılaştırmaları, ikili bilgisayarlarda kayan nokta aritmetiği
noktasında kesinlik eksikliği nedeniyle sorunlu bir sorunlardır. Daha fazla bilgi için System.Doublekonusunun
açıklamalara bakın.

İlgili konular
BAŞLIK AÇIKLAMA

Nasıl yapılır: Başvuru Eşitliği Testi (Kimlik) İki değişkenin başvuru eşitlik içerip içermediğini nasıl
belirleyebileceğinizi açıklar.

Nasıl yapılır: Tür için Değer Eşitliği Tanımlama Bir tür için bir özel değer eşitlik tanımı sağlamayı açıklar.

C# Programlama Kılavuzu .NET Framework C# C# aracılığıyla kullanılabilecek önemli dil


özellikleri ve özellikleri hakkında ayrıntılı bilgi için bağlantılar
sağlar.

Türler C# Tür sistemi ve ek bilgilerin bağlantıları hakkında bilgi sağlar.

Ayrıca bkz.
C# Programlama Kılavuzu
Nasıl yapılır: bir tür için değer eşitliği tanımlama (C#
Programlama Kılavuzu)
23.10.2019 • 10 minutes to read • Edit Online

Tanımladığınız bir sınıf veya yapı zamanı türü için değer eşitliği (veya eşdeğer) özel bir tanımı oluşturmak için
mantıklı olup olmadığını belirleyin. Genellikle, değer eşitliği çeşit bir koleksiyona eklenmesi olması beklenen
nesne türü veya alanlar ve özellikler kümesi saklamak için birincil amaçları olduğunda uygulayın. Tüm alanlar ve
Özellikler türü karşılaştırması, değer eşitliği tanımınız temel alabilir veya tanımı bir alt kümesi üzerinde temel
alabilir. Ancak, her iki durumda da ve sınıflar ve yapılar, uygulamanız beş garantileri denkliğin izlemelidir:
1. x.Equals(x) döndürür true . Bu yansıma özelliğin çağırılır.
2. x.Equals(y) aynı değeri döndürür y.Equals(x) . Bu simetrik özelliğin çağırılır.
3. Varsa (x.Equals(y) && y.Equals(z)) döndürür true , ardından x.Equals(z) döndürür true . Bu geçişli
özelliğin çağırılır.
4. Art arda gelen çağrıları x.Equals(y) nesneleri başvurulan x ve y değiştirilmez sürece aynı değeri döndürür.
5. x.Equals(null) döndürür false . Ancak, null.Equals(null) ; aykırı Yukarıdaki iki kural numara uymaz.
Önceden tanımladığınız herhangi bir yapının devraldığı değer eşitliği varsayılan bir uygulama sahip
System.ValueType , geçersiz kılma Object.Equals(Object) yöntemi. Bu uygulama, tüm alanları ve tür özellikleri
incelemek için yansıtma kullanır. Bu uygulama doğru sonuçlar ürettiğinden olsa da, bu özellikle tür için yazdığınız
özel bir uygulama ile karşılaştırıldığında yavaştır.
Uygulama ayrıntıları için değer eşitliği, sınıflar ve yapılar için farklıdır. Ancak, sınıflar ve yapılar aynı temel adımları
eşitlik uygulamak için gerektirir:
1. Geçersiz kılma sanal Object.Equals(Object) yöntemi. Çoğu durumda, uygulamanıza
bool Equals( object obj ) türe özgü yalnızca çağırmalıdır Equals uygulamasıdır yöntemi
System.IEquatable<T> arabirimi. (2. adıma bakın.)
2. Uygulama System.IEquatable<T> türe özgü sağlayarak arabirimi Equals yöntemi. Gerçek denklik
karşılaştırması gerçekleştirildiği budur. Örneğin, yalnızca bir veya iki alanları türünüz karşılaştırarak eşitliği
tanımlama karar verebilirsiniz. Özel durumlar oluşturmayın Equals . Yalnızca sınıflar için: Bu yöntem,
sınıfta bildirilen alanları incelemeniz gerekir. Çağırmalıdır base.Equals temel sınıfta olan alanlar incelemek
için. (Tür doğrudan öğesinden devralıyorsa bunu Object, çünkü Object uygulaması Object.Equals(Object)
başvuru eşitliği denetimi gerçekleştirir.)
3. İsteğe bağlı ancak önerilir: Aşırı yükleme == ve ! = işleçleri.
4. Geçersiz kılma Object.GetHashCode böylece aynı üretmek değer eşitliğine sahip iki nesnenin karma kodu.
5. İsteğe bağlı: "Büyük" veya "az" tanımlarında desteklemek için uygulama IComparable<T> arabirim
türünüz için ve ayrıca aşırı <= ve >= işleçleri.
İlk örnekte, bir sınıf uygulamasını gösterir. İkinci örnek, bir yapı uygulamasını gösterir.

Örnek
Aşağıdaki örnek, bir sınıfta (başvuru türü) değer eşitliği uygulamak gösterilmektedir.
namespace ValueEquality
{
using System;
class TwoDPoint : IEquatable<TwoDPoint>
{
// Readonly auto-implemented properties.
public int X { get; private set; }
public int Y { get; private set; }

// Set the properties in the constructor.


public TwoDPoint(int x, int y)
{
if ((x < 1) || (x > 2000) || (y < 1) || (y > 2000))
{
throw new System.ArgumentException("Point must be in range 1 - 2000");
}
this.X = x;
this.Y = y;
}

public override bool Equals(object obj)


{
return this.Equals(obj as TwoDPoint);
}

public bool Equals(TwoDPoint p)


{
// If parameter is null, return false.
if (Object.ReferenceEquals(p, null))
{
return false;
}

// Optimization for a common success case.


if (Object.ReferenceEquals(this, p))
{
return true;
}

// If run-time types are not exactly the same, return false.


if (this.GetType() != p.GetType())
{
return false;
}

// Return true if the fields match.


// Note that the base class is not invoked because it is
// System.Object, which defines Equals as reference equality.
return (X == p.X) && (Y == p.Y);
}

public override int GetHashCode()


{
return X * 0x00010000 + Y;
}

public static bool operator ==(TwoDPoint lhs, TwoDPoint rhs)


{
// Check for null on left side.
if (Object.ReferenceEquals(lhs, null))
{
if (Object.ReferenceEquals(rhs, null))
{
// null == null = true.
return true;
}

// Only the left side is null.


return false;
}
// Equals handles case of null on right side.
return lhs.Equals(rhs);
}

public static bool operator !=(TwoDPoint lhs, TwoDPoint rhs)


{
return !(lhs == rhs);
}
}

// For the sake of simplicity, assume a ThreeDPoint IS a TwoDPoint.


class ThreeDPoint : TwoDPoint, IEquatable<ThreeDPoint>
{
public int Z { get; private set; }

public ThreeDPoint(int x, int y, int z)


: base(x, y)
{
if ((z < 1) || (z > 2000))
{
throw new System.ArgumentException("Point must be in range 1 - 2000");
}
this.Z = z;
}

public override bool Equals(object obj)


{
return this.Equals(obj as ThreeDPoint);
}

public bool Equals(ThreeDPoint p)


{
// If parameter is null, return false.
if (Object.ReferenceEquals(p, null))
{
return false;
}

// Optimization for a common success case.


if (Object.ReferenceEquals(this, p))
{
return true;
}

// Check properties that this class declares.


if (Z == p.Z)
{
// Let base class check its own fields
// and do the run-time type comparison.
return base.Equals((TwoDPoint)p);
}
else
{
return false;
}
}

public override int GetHashCode()


{
return (X * 0x100000) + (Y * 0x1000) + Z;
}

public static bool operator ==(ThreeDPoint lhs, ThreeDPoint rhs)


{
// Check for null.
if (Object.ReferenceEquals(lhs, null))
{
if (Object.ReferenceEquals(rhs, null))
if (Object.ReferenceEquals(rhs, null))
{
// null == null = true.
return true;
}

// Only the left side is null.


return false;
}
// Equals handles the case of null on right side.
return lhs.Equals(rhs);
}

public static bool operator !=(ThreeDPoint lhs, ThreeDPoint rhs)


{
return !(lhs == rhs);
}
}

class Program
{
static void Main(string[] args)
{
ThreeDPoint pointA = new ThreeDPoint(3, 4, 5);
ThreeDPoint pointB = new ThreeDPoint(3, 4, 5);
ThreeDPoint pointC = null;
int i = 5;

Console.WriteLine("pointA.Equals(pointB) = {0}", pointA.Equals(pointB));


Console.WriteLine("pointA == pointB = {0}", pointA == pointB);
Console.WriteLine("null comparison = {0}", pointA.Equals(pointC));
Console.WriteLine("Compare to some other type = {0}", pointA.Equals(i));

TwoDPoint pointD = null;


TwoDPoint pointE = null;

Console.WriteLine("Two null TwoDPoints are equal: {0}", pointD == pointE);

pointE = new TwoDPoint(3, 4);


Console.WriteLine("(pointE == pointA) = {0}", pointE == pointA);
Console.WriteLine("(pointA == pointE) = {0}", pointA == pointE);
Console.WriteLine("(pointA != pointE) = {0}", pointA != pointE);

System.Collections.ArrayList list = new System.Collections.ArrayList();


list.Add(new ThreeDPoint(3, 4, 5));
Console.WriteLine("pointE.Equals(list[0]): {0}", pointE.Equals(list[0]));

// Keep the console window open in debug mode.


System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
}

/* Output:
pointA.Equals(pointB) = True
pointA == pointB = True
null comparison = False
Compare to some other type = False
Two null TwoDPoints are equal: True
(pointE == pointA) = False
(pointA == pointE) = False
(pointA != pointE) = True
pointE.Equals(list[0]): False
*/
}
Sınıflar (başvuru türleri) üzerinde hem de varsayılan uygulamasını Object.Equals(Object) yöntemleri değeri eşitlik
kontrolüne başvuru bir eşitlik karşılaştırması gerçekleştirir. Bir uygulayan sanal yöntemi geçersiz kıldığında, amacı,
değer eşitliği anlamları vermektir.
== Ve != işleçleri sınıfı bunları aşırı değil olsa bile sınıfları ile kullanılabilir. Ancak, bir başvuru eşitliği denetimi
gerçekleştirmek için varsayılan davranış şeklindedir. İşlecini aşırı yüklediyseniz bir sınıftaki Equals yöntemini aşırı
== ve != işleçleri, ancak gerekli değildir.

Örnek
Aşağıdaki örnek, bir yapı (değer türü) değer eşitliği uygulamak gösterilmektedir:

struct TwoDPoint : IEquatable<TwoDPoint>


{
// Read/write auto-implemented properties.
public int X { get; private set; }
public int Y { get; private set; }

public TwoDPoint(int x, int y)


: this()
{
X = x;
Y = x;
}

public override bool Equals(object obj)


{
if (obj is TwoDPoint)
{
return this.Equals((TwoDPoint)obj);
}
return false;
}

public bool Equals(TwoDPoint p)


{
return (X == p.X) && (Y == p.Y);
}

public override int GetHashCode()


{
return X ^ Y;
}

public static bool operator ==(TwoDPoint lhs, TwoDPoint rhs)


{
return lhs.Equals(rhs);
}

public static bool operator !=(TwoDPoint lhs, TwoDPoint rhs)


{
return !(lhs.Equals(rhs));
}
}

class Program
{
static void Main(string[] args)
{
TwoDPoint pointA = new TwoDPoint(3, 4);
TwoDPoint pointB = new TwoDPoint(3, 4);
int i = 5;

// Compare using virtual Equals, static Equals, and == and != operators.


// True:
// True:
Console.WriteLine("pointA.Equals(pointB) = {0}", pointA.Equals(pointB));
// True:
Console.WriteLine("pointA == pointB = {0}", pointA == pointB);
// True:
Console.WriteLine("Object.Equals(pointA, pointB) = {0}", Object.Equals(pointA, pointB));
// False:
Console.WriteLine("pointA.Equals(null) = {0}", pointA.Equals(null));
// False:
Console.WriteLine("(pointA == null) = {0}", pointA == null);
// True:
Console.WriteLine("(pointA != null) = {0}", pointA != null);
// False:
Console.WriteLine("pointA.Equals(i) = {0}", pointA.Equals(i));
// CS0019:
// Console.WriteLine("pointA == i = {0}", pointA == i);

// Compare unboxed to boxed.


System.Collections.ArrayList list = new System.Collections.ArrayList();
list.Add(new TwoDPoint(3, 4));
// True:
Console.WriteLine("pointE.Equals(list[0]): {0}", pointA.Equals(list[0]));

// Compare nullable to nullable and to non-nullable.


TwoDPoint? pointC = null;
TwoDPoint? pointD = null;
// False:
Console.WriteLine("pointA == (pointC = null) = {0}", pointA == pointC);
// True:
Console.WriteLine("pointC == pointD = {0}", pointC == pointD);

TwoDPoint temp = new TwoDPoint(3, 4);


pointC = temp;
// True:
Console.WriteLine("pointA == (pointC = 3,4) = {0}", pointA == pointC);

pointD = temp;
// True:
Console.WriteLine("pointD == (pointC = 3,4) = {0}", pointD == pointC);

// Keep the console window open in debug mode.


System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
}

/* Output:
pointA.Equals(pointB) = True
pointA == pointB = True
Object.Equals(pointA, pointB) = True
pointA.Equals(null) = False
(pointA == null) = False
(pointA != null) = True
pointA.Equals(i) = False
pointE.Equals(list[0]): True
pointA == (pointC = null) = False
pointC == pointD = True
pointA == (pointC = 3,4) = True
pointD == (pointC = 3,4) = True
*/
}

Yapılar, varsayılan uygulaması için Object.Equals(Object) (geçersiz kılınan sürümünde olduğu System.ValueType)
türündeki her alanın değeri karşılaştırmak için yansıma kullanarak bir değer eşitliği denetimi gerçekleştirir. Ne
zaman bir uygulayan geçersiz kılan sanal Equals yöntemi bir yapı içinde amaçlı olduğundan değeri eşitlik
kontrolüne gerçekleştirmenin daha verimli bir yöntem sağlar ve isteğe bağlı olarak bazı alt kümesinde yapının
alan veya özellik karşılaştırma taban.
== Ve ! = işleçleri struct açıkça bunları aşırı sürece yapı üzerinde çalışamaz.

Ayrıca bkz.
Eşitlik karşılaştırmaları
C# Programlama Kılavuzu
Nasıl yapılır: Başvuru eşitlik için test (kimlik) (C#
Programlama Kılavuzu)
23.10.2019 • 4 minutes to read • Edit Online

Türlerinizin başvuru eşitlik karşılaştırmalarını desteklemek için herhangi bir özel mantık uygulamanız gerekmez.
Bu işlev, statik Object.ReferenceEquals yönteme göre tüm türler için sağlanır.
Aşağıdaki örnek, iki değişkenin başvuru eşitliğiolup olmadığını nasıl belirleyeceğini gösterir. Bu, bellekteki aynı
nesneye başvurdukları anlamına gelir.
Örnek ayrıca neden Object.ReferenceEquals her zaman değer türleri false için döndüğünü ve ReferenceEquals
neden dize eşitliğini belirlemede kullanmamalısınız gerektiğini gösterir.

Örnek
namespace TestReferenceEquality
{
struct TestStruct
{
public int Num { get; private set; }
public string Name { get; private set; }

public TestStruct(int i, string s) : this()


{
Num = i;
Name = s;
}
}

class TestClass
{
public int Num { get; set; }
public string Name { get; set; }
}

class Program
{
static void Main()
{
// Demonstrate reference equality with reference types.
#region ReferenceTypes

// Create two reference type instances that have identical values.


TestClass tcA = new TestClass() { Num = 1, Name = "New TestClass" };
TestClass tcB = new TestClass() { Num = 1, Name = "New TestClass" };

Console.WriteLine("ReferenceEquals(tcA, tcB) = {0}",


Object.ReferenceEquals(tcA, tcB)); // false

// After assignment, tcB and tcA refer to the same object.


// They now have reference equality.
tcB = tcA;
Console.WriteLine("After asignment: ReferenceEquals(tcA, tcB) = {0}",
Object.ReferenceEquals(tcA, tcB)); // true

// Changes made to tcA are reflected in tcB. Therefore, objects


// that have reference equality also have value equality.
tcA.Num = 42;
tcA.Name = "TestClass 42";
tcA.Name = "TestClass 42";
Console.WriteLine("tcB.Name = {0} tcB.Num: {1}", tcB.Name, tcB.Num);
#endregion

// Demonstrate that two value type instances never have reference equality.
#region ValueTypes

TestStruct tsC = new TestStruct( 1, "TestStruct 1");

// Value types are copied on assignment. tsD and tsC have


// the same values but are not the same object.
TestStruct tsD = tsC;
Console.WriteLine("After asignment: ReferenceEquals(tsC, tsD) = {0}",
Object.ReferenceEquals(tsC, tsD)); // false
#endregion

#region stringRefEquality
// Constant strings within the same assembly are always interned by the runtime.
// This means they are stored in the same location in memory. Therefore,
// the two strings have reference equality although no assignment takes place.
string strA = "Hello world!";
string strB = "Hello world!";
Console.WriteLine("ReferenceEquals(strA, strB) = {0}",
Object.ReferenceEquals(strA, strB)); // true

// After a new string is assigned to strA, strA and strB


// are no longer interned and no longer have reference equality.
strA = "Goodbye world!";
Console.WriteLine("strA = \"{0}\" strB = \"{1}\"", strA, strB);

Console.WriteLine("After strA changes, ReferenceEquals(strA, strB) = {0}",


Object.ReferenceEquals(strA, strB)); // false

// A string that is created at runtime cannot be interned.


StringBuilder sb = new StringBuilder("Hello world!");
string stringC = sb.ToString();
// False:
Console.WriteLine("ReferenceEquals(stringC, strB) = {0}",
Object.ReferenceEquals(stringC, strB));

// The string class overloads the == operator to perform an equality comparison.


Console.WriteLine("stringC == strB = {0}", stringC == strB); // true

#endregion

// Keep the console open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
}

/* Output:
ReferenceEquals(tcA, tcB) = False
After asignment: ReferenceEquals(tcA, tcB) = True
tcB.Name = TestClass 42 tcB.Num: 42
After asignment: ReferenceEquals(tsC, tsD) = False
ReferenceEquals(strA, strB) = True
strA = "Goodbye world!" strB = "Hello world!"
After strA changes, ReferenceEquals(strA, strB) = False
*/

Evrensel temel sınıftaki Equals uygulamasının uygulanması de bir başvuru eşitlik denetimi gerçekleştirir, ancak
bunu kullanmak en iyisidir çünkü yöntemi geçersiz kılmak için bir sınıf olduğunda, sonuçlar beklediğiniz gibi
olmayabilir. System.Object Aynı, == ve != işleçleri için de geçerlidir. Başvuru türleri üzerinde çalıştıklarında,
varsayılan davranışı == ve != başvuru eşitlik denetimi gerçekleştirmek için kullanılır. Ancak, türetilmiş sınıflar bir
değer eşitlik denetimi gerçekleştirmek için işlecini aşırı yükleyebilir. Hata olasılığını en aza indirmek için, iki
nesnenin başvuru eşitlik içerip içermediğini ReferenceEquals belirlemekte her zaman en iyi şekilde kullanılır.
Aynı derleme içindeki sabit dizeler her zaman çalışma zamanı tarafından dağıtılır. Diğer bir deyişle, her benzersiz
sabit değer dizesinin yalnızca bir örneği korunur. Ancak çalışma zamanı, çalışma zamanında oluşturulan dizelerin
birbirine bağlı olduğunu veya farklı derlemelerdeki iki eşit Sabit dizenin birbirine bağlı olduğunu garanti etmez.

Ayrıca bkz.
Eşitlik Karşılaştırmaları
Türler (C# Programlama Kılavuzu)
29.11.2019 • 19 minutes to read • Edit Online

Türler, değişkenler ve değerler


C#türü kesin belirlenmiş bir dildir. Her değişken ve sabitin, bir değeri değerlendiren her ifadeyi olduğu gibi bir
türü vardır. Her yöntem imzası her giriş parametresi ve dönüş değeri için bir tür belirtir. .NET sınıf kitaplığı, dosya
sistemi, ağ bağlantıları, koleksiyon ve nesne dizileri ve tarihler gibi çok çeşitli mantıksal yapıları temsil eden daha
karmaşık türler ve yerleşik sayısal türlerin bir kümesini tanımlar. Tipik C# bir program, sınıf kitaplığından türleri
ve programın sorunlu etki alanına özgü kavramları modelleyebilir Kullanıcı tanımlı türleri kullanır.
Bir tür içinde depolanan bilgiler şunları içerebilir:
Türün bir değişkeninin gerektirdiği depolama alanı.
Temsil ettiği maksimum ve en düşük değerler.
İçerdiği Üyeler (Yöntemler, alanlar, olaylar vb.).
Devraldığı temel tür.
Değişkenlere yönelik belleğin çalışma zamanında ayrılabileceği konum.
İzin verilen işlem türleri.
Derleyici, kodunuzda gerçekleştirilen tüm işlemlerin tür açısından güvenliolduğundan emin olmak için tür
bilgilerini kullanır. Örneğin, inttüründe bir değişken bildirirseniz, derleyici değişkeni toplama ve çıkarma
işlemlerinde kullanmanıza izin verir. Booltüründe bir değişkende aynı işlemleri gerçekleştirmeye çalışırsanız,
derleyici aşağıdaki örnekte gösterildiği gibi bir hata oluşturur:

int a = 5;
int b = a + 2; //OK

bool test = true;

// Error. Operator '+' cannot be applied to operands of type 'int' and 'bool'.
int c = a + test;

NOTE
C ve C++ geliştiricilerle, bool 'un C# int'e dönüştürülebilir olmadığına dikkat edin.

Derleyici, tür bilgilerini yürütülebilir dosyaya meta veriler olarak katıştırır. Ortak dil çalışma zamanı (CLR ), bellek
ayırdığı ve geri kazanır daha fazla güvence altına almak için çalışma zamanında bu meta verileri kullanır.
Değişken bildirimlerinde türleri belirtme
Bir programda bir değişken veya sabit belirttiğinizde, onun türünü belirtmeniz veya var anahtar sözcüğünü
kullanarak derleyicinin türü saymasına izin vermelisiniz. Aşağıdaki örnek, hem yerleşik sayısal türler hem de
Kullanıcı tanımlı karmaşık türler kullanan bazı değişken bildirimlerini gösterir:
// Declaration only:
float temperature;
string name;
MyClass myClass;

// Declaration with initializers (four examples):


char firstLetter = 'C';
var limit = 3;
int[] source = { 0, 1, 2, 3, 4, 5 };
var query = from item in source
where item <= limit
select item;

Yöntem parametrelerinin türleri ve dönüş değerleri Yöntem imzasında belirtilmiştir. Aşağıdaki imza, giriş
bağımsız değişkeni olarak bir int gerektiren ve bir dize döndüren bir yöntemi gösterir:

public string GetName(int ID)


{
if (ID < names.Length)
return names[ID];
else
return String.Empty;
}
private string[] names = { "Spencer", "Sally", "Doug" };

Bir değişken oluşturulduktan sonra, yeni bir türle yeniden bildirilemez ve belirtilen türle uyumlu olmayan bir
değer atanamaz. Örneğin, bir int bildiremez ve bunu bir true Boolean değeri atayabilirsiniz. Ancak, değerler
başka türlere dönüştürülebilir (örneğin, yeni değişkenlere atandığında veya yöntem bağımsız değişkenleri olarak
geçirildiğinde). Veri kaybına neden olmayan bir tür dönüştürmesi , derleyici tarafından otomatik olarak
gerçekleştirilir. Veri kaybına neden olabilecek bir dönüştürme, kaynak kodda bir tür dönüştürme gerektirir.
Daha fazla bilgi için bkz. atama ve tür dönüştürmeleri.

Yerleşik türler
C#tamsayılar, kayan nokta değerleri, Boole ifadeleri, metin karakterleri, ondalık değerler ve diğer veri türlerini
temsil etmek için standart bir yerleşik sayısal türler kümesi sağlar. Ayrıca, yerleşik string ve object türleri
vardır. Bunlar, herhangi bir C# programda kullanabilmeniz için kullanılabilir. Yerleşik türler hakkında daha fazla
bilgi için bkz. Yerleşik türler Için başvuru tabloları.

Özel türler
Kendi özel türlerinizi oluşturmak için struct, Class, Interfaceve enum yapılarını kullanırsınız. .NET sınıf kitaplığı,
Microsoft tarafından kendi uygulamalarınızda kullanabileceğiniz özel türlerin bir koleksiyonudur. Varsayılan
olarak, sınıf kitaplığındaki en sık kullanılan türler her C# programda kullanılabilir. Diğerleri yalnızca
tanımlandıkları derlemeye açıkça bir proje başvurusu eklediğinizde kullanılabilir hale gelir. Derleyicinin
derlemeye bir başvurusu olduktan sonra, kaynak kodda o derlemede belirtilen türlerin değişkenlerini (ve
sabitleri) bildirebilirsiniz. Daha fazla bilgi için bkz. .NET sınıf kitaplığı.

Ortak tür sistemi


.NET 'teki tür sistemi hakkında iki temel noktayı anlamak önemlidir:
Devralma ilkesini destekler. Türler, temel türlerolarak adlandırılan diğer türlerden türetilebilir. Türetilmiş
tür, yöntemleri, özellikleri ve temel türün diğer üyelerini devralır (bazı kısıtlamalarla). Temel tür başka bir
türden türetebilir, bu durumda türetilmiş tür, devralma hiyerarşisindeki her iki temel türün üyelerini
devralır. System.Int32 (C# anahtar sözcük: int) gibi yerleşik sayısal türler dahil olmak üzere tüm türler,
sonunda System.Object (C# anahtar sözcük: nesne) olan tek bir temel türden türetilir. Bu Birleşik tür
hiyerarşisine ortak tür sistemi (Cts) denir. ' De C#devralma hakkında daha fazla bilgi için bkz. Devralma.
CTS içindeki her tür, bir değer türü veya bir başvuru türüolarak tanımlanır. Bu, .NET sınıf kitaplığı 'ndaki
tüm özel türleri ve ayrıca kendi Kullanıcı tanımlı türlerinizi içerir. Struct anahtar sözcüğünü kullanarak
tanımladığınız türler değer türleridir; Tüm yerleşik sayısal türler structs . Sınıf anahtar sözcüğünü
kullanarak tanımladığınız türler başvuru türleridir. Başvuru türleri ve değer türlerinde farklı derleme
zamanı kuralları ve farklı çalışma zamanı davranışları vardır.
Aşağıdaki çizimde, CTS 'deki değer türleri ve başvuru türleri arasındaki ilişki gösterilmektedir.
Aşağıdaki görüntüde, CTS 'deki değer türleri ve başvuru türleri gösterilmektedir:

NOTE
En yaygın olarak kullanılan türlerin System ad alanında düzenlendiğini görebilirsiniz. Ancak, bir türün bulunduğu ad
alanının, bir değer türü veya başvuru türü olup olmadığı bir ilişkisi yoktur.

Değer türleri
Değer türleri, System.Objecttüretilen System.ValueTypetüretilir. System.ValueType türetilen türlerin CLR 'de özel
davranışı vardır. Değer türü değişkenleri doğrudan değerlerini içerir, bu da belleğin, değişkenin bildirildiği
bağlamda satır içi olarak ayrıldığı anlamına gelir. Değer türü değişkenler için ayrı bir yığın ayırma veya çöp
toplama ek yükü yoktur.
Değer türlerinin iki kategorisi vardır: struct ve enum.
Yerleşik sayısal türler yapı birimleridir ve erişebileceğiniz özelliklere ve yöntemlere sahiptirler:

// Static method on type byte.


byte b = byte.MaxValue;

Ancak bunları, basit olmayan türler gibi bu değerlere bildirir ve bunlara atanır:
byte num = 0xA;
int i = 5;
char c = 'Z';

Değer türleri korumalıdır, yani örneğin, bir türü System.Int32türetemezsiniz ve Kullanıcı tanımlı herhangi bir
sınıftan veya yapıdan devralacak bir struct tanımlayamazsınız, çünkü bir struct yalnızca
System.ValueTypedevralabilir. Ancak, bir struct bir veya daha fazla arabirim uygulayabilir. Yapı türünü, uygulayan
herhangi bir arabirim türüne çevirebilirsiniz; Bu, bir kutulama işleminin yapıyı yönetilen yığında bir başvuru türü
nesnesinin içine sarmasına neden olur. Kutulama işlemleri, bir System.Object veya herhangi bir arabirim türünü
giriş parametresi olarak alan bir yönteme bir değer türü geçirdiğinizde oluşur. Daha fazla bilgi için bkz. kutulama
ve kutudançıkarma.
Kendi özel değer türlerinizi oluşturmak için struct anahtar sözcüğünü kullanırsınız. Genellikle, bir yapı aşağıdaki
örnekte gösterildiği gibi küçük bir ilgili değişkenler kümesi için kapsayıcı olarak kullanılır:

public struct Coords


{
public int x, y;

public Coords(int p1, int p2)


{
x = p1;
y = p2;
}
}

Yapılar hakkında daha fazla bilgi için bkz. yapılar. .NET 'teki değer türleri hakkında daha fazla bilgi için bkz. değer
türleri.
Değer türlerinin diğer kategorisi sabit listesi' dir. Enum, adlandırılmış integral sabitleri kümesini tanımlar.
Örneğin, .NET sınıf kitaplığındaki System.IO.FileMode numaralandırması, bir dosyanın nasıl açılacağını belirten
adlandırılmış sabit tamsayılar kümesi içerir. Aşağıdaki örnekte gösterildiği gibi tanımlanmıştır:

public enum FileMode


{
CreateNew = 1,
Create = 2,
Open = 3,
OpenOrCreate = 4,
Truncate = 5,
Append = 6,
}

System.IO.FileMode.Create sabiti 2 değerine sahiptir. Ancak ad, kaynak kodu okuyan insanlar için çok daha
anlamlı olur ve bu nedenle sabit değişmez sayılar yerine Numaralandırmaların kullanılması daha iyidir. Daha
fazla bilgi için bkz. System.IO.FileMode.
Tüm numaralandırmalar System.ValueTypedevralan System.Enumdevralır. Yapılar için uygulanan tüm kurallar,
numaralandırmalar için de geçerlidir. Numaralandırmalar hakkında daha fazla bilgi için bkz. numaralandırma
türleri.
Başvuru türleri
Class, Delegate, array veya Interface olarak tanımlanan bir tür, bir başvuru türüdür. Çalışma zamanında, bir
başvuru türünde bir değişken bildirdiğinizde, New işlecini kullanarak açıkça bir nesne oluşturana veya başka bir
new yerde oluşturulmuş bir nesne (örneğin, ' de gösterildiği gibi) Aşağıdaki örnek:
MyClass mc = new MyClass();
MyClass mc2 = mc;

Bir arabirim, kendisini uygulayan bir sınıf nesnesiyle birlikte başlatılmalıdır. MyClass IMyInterface uygularsa,
aşağıdaki örnekte gösterildiği gibi bir IMyInterface örneği oluşturursunuz:

IMyInterface iface = new MyClass();

Nesne oluşturulduğunda, bellek yönetilen yığında ayrılır ve değişken yalnızca nesnenin konumuna bir başvuru
içerir. Yönetilen yığında bulunan türler, her ikisi de ayrıldıklarında ve çöp toplamaolarak bilinen clr 'nin otomatik
bellek yönetimi işlevselliği tarafından geri kazanıyorsa ek yük gerektirir. Ancak çöp toplama da yüksek oranda
iyileştirilmiştir ve çoğu senaryoda bir performans sorunu oluşturmaz. Çöp toplama hakkında daha fazla bilgi için
bkz. Otomatik bellek yönetimi.
Tüm diziler, öğeleri değer türleri olsa bile başvuru türlerdir.Diziler, System.Array sınıfından dolaylı olarak türetilir,
ancak aşağıdaki örnekte gösterildiği gibi bunları tarafından C#verilen Basitleştirilmiş sözdizimi ile bildirir ve
kullanabilirsiniz:

// Declare and initialize an array of integers.


int[] nums = { 1, 2, 3, 4, 5 };

// Access an instance property of System.Array.


int len = nums.Length;

Başvuru türleri devralmayı tamamen destekler. Bir sınıf oluşturduğunuzda, korumalıolarak tanımlanmayan diğer
bir arabirim veya sınıftan kalıtımla alabilir ve diğer sınıflar sınıfınızdan devralınabilir ve sanal yöntemlerinizi
geçersiz kılabilir. Kendi sınıflarınızı oluşturma hakkında daha fazla bilgi için bkz. sınıflar ve yapılar. Devralma ve
sanal yöntemler hakkında daha fazla bilgi için bkz. Devralma.

Değişmez değer türleri


' C#De, değişmez değerler derleyicisinden bir tür alır. Sayının sonuna bir harf ekleyerek sayısal bir sabit değerin
nasıl yazılması gerektiğini belirtebilirsiniz. Örneğin, 4,56 değerinin bir float olarak değerlendirilip
değerlendirilmeyeceğini belirtmek için, sayının sonuna bir "f" veya "F" ekleyin: 4.56f . Hiçbir harf eklenyoksa,
derleyici değişmez değer için bir tür çıkarması olur. Hangi türlerin harf sonekleriyle belirtibileceği hakkında daha
fazla bilgi için bkz. değer türlerindebağımsız türler için başvuru sayfaları.
Değişmez değerler yazıldığı ve tüm türler System.Objectsonunda sonuç olarak türettiğinden, aşağıdaki gibi bir
kod yazabilir ve derleyebilirsiniz:

string s = "The answer is " + 5.ToString();


// Outputs: "The answer is 5"
Console.WriteLine(s);

Type type = 12345.GetType();


// Outputs: "System.Int32"
Console.WriteLine(type);

Genel türler
Bir tür, istemci kodunun türün bir örneğini oluşturduğunda sağladığı gerçek tür ( somut tür) için yer tutucu
olarak görev yapan bir veya daha fazla tür parametresiyle bildirilemez. Bu tür türler Genel türlerolarak
adlandırılır. Örneğin, System.Collections.Generic.List<T> .NET türü, kuralına göre bir tür parametresine sahiptir.
Türün bir örneğini oluşturduğunuzda, listenin içereceği nesnelerin türünü (örneğin, dize) belirtirsiniz:

List<string> stringList = new List<string>();


stringList.Add("String example");
// compile time error adding a type other than a string:
stringList.Add(4);

Tür parametresinin kullanımı, her öğeyi nesneyedönüştürmek zorunda kalmadan her türlü öğe türünü tutmak
için aynı sınıfı yeniden kullanmayı mümkün kılar. Derleyici, koleksiyon öğelerinin belirli türünü bildiğinden ve
derleme zamanında bir hata tetikleyebildiğinden, genel koleksiyon sınıfları kesin türü belirtilmiş koleksiyonlar
olarak adlandırılır. stringList Örneğin, önceki örnek. Daha fazla bilgi için bkz. Genel türler.

Örtük türler, anonim türler ve null yapılabilir değer türleri


Daha önce belirtildiği gibi, var anahtar sözcüğünü kullanarak yerel bir değişkeni (sınıf üyelerini değil) örtük
olarak yazabilirsiniz. Değişken hala derleme zamanında bir tür alır, ancak tür derleyici tarafından sağlanır.Daha
fazla bilgi için bkz. örtülü olarak yazılan yerel değişkenler.
Bazı durumlarda, yöntem sınırlarını depolamayı veya geçişi istemediğiniz ilgili değerlerin basit kümeleri için
adlandırılmış bir tür oluşturmak uygun değildir. Bu amaçla anonim türler oluşturabilirsiniz. Daha fazla bilgi için
bkz. anonim türler.
Sıradan değer türlerinin değeri nullolamaz. Ancak, türden sonra bir ? ekleyerek null yapılabilir değer türleri
oluşturabilirsiniz. Örneğin int? , nulldeğeri de olan bir int türüdür. Null yapılabilir değer türleri
System.Nullable<T>genel yapı türü örnekleridir. Null olabilen değer türleri, genellikle sayısal değerlerin null
olabileceği veritabanlarına ve veritabanlarından veri geçirirken faydalıdır. Daha fazla bilgi için bkz. Nullable değer
türleri.

İlgili bölümler
Daha fazla bilgi için aşağıdaki konulara bakın:
Tür Değiştirme ve Tür Dönüştürmeler
Kutulama ve Kutudan Çıkarma
Tür dinamiği kullanma
Değer Türleri
Başvuru Türleri
Sınıflar ve Yapılar
Anonim Tipler
Genel Türler

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir kaynaktır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
XML Veri Türlerini Dönüştürme
Integral türleri
Atama ve tür dönüşümleri (C# Programlama
Kılavuzu)
25.11.2019 • 8 minutes to read • Edit Online

C# , Derleme zamanında statik olarak yazıldığı için, bir değişken oluşturulduktan sonra yeniden bildirilemez
veya tür değişken türüne örtük olarak dönüştürülemediği takdirde başka bir türde bir değer atanamaz.
Örneğin, string örtülü olarak int dönüştürülemez. Bu nedenle, i int olarak bildirdikten sonra, aşağıdaki
kodda gösterildiği gibi, "Merhaba" dizesini buna atayamazsınız:

int i;
i = "Hello"; // error CS0029: Cannot implicitly convert type 'string' to 'int'

Ancak bazen bir değeri başka bir türün değişken veya yöntem parametresine kopyalamanız gerekebilir.
Örneğin, parametresi double olarak yazılan bir yönteme geçirmeniz gereken bir tamsayı değişkenine sahip
olabilirsiniz. Ya da bir arabirim türü değişkenine bir sınıf değişkeni atamanız gerekebilir. Bu tür işlemlere tür
dönüştürmeleridenir. ' C#De, aşağıdaki tür dönüştürmeleri gerçekleştirebilirsiniz:
Örtük dönüştürmeler: dönüştürme türü güvenli olduğundan ve hiçbir veri kaybolacağı için özel bir
sözdizimi gerekli değildir. Örnekler, daha küçük integral türlerine ve türetilmiş sınıflardan taban sınıflara
Dönüştürmelere dönüşümler içerir.
Açık dönüşümler (yayınlar) : açık dönüşümler () atama işleci gerektirir. Dönüştürme işlemi,
dönüştürmede bilgiler kaybediliyorsa veya dönüştürme işleminin diğer nedenlerle başarısız olabileceği
durumlarda gereklidir. Tipik örneklerde, daha az duyarlık veya daha küçük bir aralığa sahip olan bir türe
sayısal dönüştürme ve bir temel sınıf örneğinin türetilmiş bir sınıfa dönüştürülmesi sayılabilir.
Kullanıcı tanımlı dönüştürmeler: Kullanıcı tanımlı dönüştürmeler, temel sınıf ile türetilmiş sınıf
ilişkisine sahip olmayan özel türler arasında açık ve örtük dönüştürmeleri etkinleştirmek için
tanımlayabileceğiniz özel yöntemler tarafından gerçekleştirilir. Daha fazla bilgi için bkz. Kullanıcı tanımlı
dönüştürme işleçleri.
Yardımcı sınıflarla dönüşümler: tamsayılar ve System.DateTime nesneleri ya da onaltılı dizeler ve bayt
dizileri gibi uyumlu olmayan türler arasında dönüştürme yapmak için System.BitConverter sınıfını,
System.Convert sınıfını ve Int32.Parsegibi yerleşik sayısal türlerin Parse yöntemlerini kullanabilirsiniz.
Daha fazla bilgi için bkz. nasıl yapılır: Byte dizisini int 'e dönüştürme, nasıl yapılır: bir dizeyi sayıya
dönüştürmeve nasıl yapılır: onaltılık dizeler ve sayısal türler arasında dönüştürme.

Örtük dönüştürmeler
Yerleşik sayısal türler için, saklanacak değer kesilmeden veya yuvarlanmadan değişkene sığmayacak olan örtük
bir dönüştürme yapılabilir. İntegral türleri için bu, kaynak türü aralığının hedef tür için uygun bir alt küme
olduğu anlamına gelir. Örneğin, Long (64-bit tamsayı) türünde bir değişken, bir int (32 bit tamsayı)
depolayabileceği herhangi bir değeri depolayabilirler. Aşağıdaki örnekte, derleyici bigNum atamak için, sağdaki
num değerini örtülü olarak bir tür long dönüştürür.

// Implicit conversion. A long can


// hold any value an int can hold, and more!
int num = 2147483647;
long bigNum = num;
Tüm örtük sayısal dönüştürmelerin tam listesi için, yerleşik sayısal dönüşümler makalesinin Örtük Sayısal
Dönüşümler bölümüne bakın.
Başvuru türleri için, örtük bir dönüştürme her zaman bir sınıftan doğrudan veya dolaylı temel sınıflarından veya
arabirimlerinden herhangi birine bulunur. Türetilmiş bir sınıf her zaman bir temel sınıfın tüm üyelerini
içerdiğinden özel bir sözdizimi gerekli değildir.

Derived d = new Derived();


Base b = d; // Always OK.

Açık dönüşümler
Ancak, bilgileri kaybetme riski olmadan bir dönüştürme gerçekleştirilemez, derleyici bir dönüştürme
olarakadlandırılan açık bir dönüştürme gerçekleştirmenizi gerektirir. Bir atama, dönüştürmeyi yapmayı
düşündüğünüz ve veri kaybını fark ettiğini farkında olabileceğiniz derleyicisini açıkça bildiren bir yoldur. Bir tür
dönüştürme gerçekleştirmek için, dönüştürülecek değeri veya değişkeni önünde parantez içinde içine,
dönüştürmekte olduğunuz türü belirtin. Aşağıdaki program bir Double öğesine bir Double yayınlar . Program,
atama olmadan derlenmeyecektir.

class Test
{
static void Main()
{
double x = 1234.7;
int a;
// Cast double to int.
a = (int)x;
System.Console.WriteLine(a);
}
}
// Output: 1234

Desteklenen açık sayısal dönüştürmelerin tam listesi için yerleşik sayısal dönüşümler konusunun Açık Sayısal
Dönüşümler bölümüne bakın.
Başvuru türleri için bir temel türden türetilmiş bir türe dönüştürmeniz gerekiyorsa açık bir atama gerekir:

// Create a new derived type.


Giraffe g = new Giraffe();

// Implicit conversion to base type is safe.


Animal a = g;

// Explicit conversion is required to cast back


// to derived type. Note: This will compile but will
// throw an exception at run time if the right-side
// object is not in fact a Giraffe.
Giraffe g2 = (Giraffe) a;

Başvuru türleri arasındaki bir atama işlemi, temel alınan nesnenin çalışma zamanı türünü değiştirmez; yalnızca
bu nesneye başvuru olarak kullanılan değerin türünü değiştirir. Daha fazla bilgi için bkz. çok biçimlilik.

Çalışma zamanında dönüştürme özel durumlarını yazın


Bazı başvuru türü dönüştürmelerinde, derleyici bir dönüştürmenin geçerli olup olmayacağını belirleyemez.
Çalışma zamanında düzgün şekilde derlenen bir atama işlemi mümkündür. Aşağıdaki örnekte gösterildiği gibi,
çalışma zamanında başarısız olan bir tür dönüştürme bir InvalidCastException oluşturulmasına neden olur.
using System;

class Animal
{
public void Eat() { Console.WriteLine("Eating."); }
public override string ToString()
{
return "I am an animal.";
}
}
class Reptile : Animal { }
class Mammal : Animal { }

class UnSafeCast
{
static void Main()
{
Test(new Mammal());

// Keep the console window open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}

static void Test(Animal a)


{
// Cause InvalidCastException at run time
// because Mammal is not convertible to Reptile.
Reptile r = (Reptile)a;
}

C#, gerçekten bir dönüştürme yapmadan önce uyumluluğu test etmeniz için , . işlecini sağlar. Daha fazla bilgi
için bkz. model eşleştirme ve as ve işleç işleçlerini kullanarak güvenle atama.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin dönüşümler bölümüne bakın.

Ayrıca bkz.
C# Programlama Kılavuzu
Türler
() Cast işleci
Kullanıcı tanımlı dönüştürme işleçleri
Genelleştirilmiş tür dönüştürmesi
Nasıl yapılır: Bir Dizeyi Sayıya Dönüştürme
Kutulama ve Kutudan Çıkarma (C# Programlama
Kılavuzu)
23.10.2019 • 8 minutes to read • Edit Online

Kutulama, bir değer türünü türüne object veya bu değer türü tarafından uygulanan herhangi bir arabirim
türüne dönüştürme işlemidir. CLR bir değer türüne sahip olduğunda, değeri bir System.Object örnek içinde
sarmalar ve yönetilen yığında depolar. Kutudan çıkarma, nesneden değer türünü ayıklar. Paketleme örtük;
kutudan çıkarma açıktır. Kutulama ve kutudan çıkarma kavramı, herhangi bir türdeki C# değerin bir nesne olarak
değerlendiribileceği tür sisteminin Birleşik görünümünü içermez.
Aşağıdaki örnekte, tamsayı değişkeni i paketlenmelidir ve nesnesine o atanır.

int i = 123;
// The following line boxes i.
object o = i;

Nesne o daha sonra kutulanabilir ve tamsayı değişkenine i atanabilir:

o = 123;
i = (int)o; // unboxing

Aşağıdaki örnekler, kutulamayı ' de C#nasıl kullanıldığını gösterir.

// String.Concat example.
// String.Concat has many versions. Rest the mouse pointer on
// Concat in the following statement to verify that the version
// that is used here takes three object arguments. Both 42 and
// true must be boxed.
Console.WriteLine(String.Concat("Answer", 42, true));

// List example.
// Create a list of objects to hold a heterogeneous collection
// of elements.
List<object> mixedList = new List<object>();

// Add a string element to the list.


mixedList.Add("First Group:");

// Add some integers to the list.


for (int j = 1; j < 5; j++)
{
// Rest the mouse pointer over j to verify that you are adding
// an int to a list of objects. Each element j is boxed when
// you add j to mixedList.
mixedList.Add(j);
}

// Add another string and more integers.


mixedList.Add("Second Group:");
for (int j = 5; j < 10; j++)
{
mixedList.Add(j);
}

// Display the elements in the list. Declare the loop variable by


// Display the elements in the list. Declare the loop variable by
// using var, so that the compiler assigns its type.
foreach (var item in mixedList)
{
// Rest the mouse pointer over item to verify that the elements
// of mixedList are objects.
Console.WriteLine(item);
}

// The following loop sums the squares of the first group of boxed
// integers in mixedList. The list elements are objects, and cannot
// be multiplied or added to the sum until they are unboxed. The
// unboxing must be done explicitly.
var sum = 0;
for (var j = 1; j < 5; j++)
{
// The following statement causes a compiler error: Operator
// '*' cannot be applied to operands of type 'object' and
// 'object'.
//sum += mixedList[j] * mixedList[j]);

// After the list elements are unboxed, the computation does


// not cause a compiler error.
sum += (int)mixedList[j] * (int)mixedList[j];
}

// The sum displayed is 30, the sum of 1 + 4 + 9 + 16.


Console.WriteLine("Sum: " + sum);

// Output:
// Answer42True
// First Group:
// 1
// 2
// 3
// 4
// Second Group:
// 5
// 6
// 7
// 8
// 9
// Sum: 30

Performans
Basit atamalara göre, kutulama ve kutudan çıkarma, pahalı maliyetli işlemlerdir. Bir değer türü
paketlenayarlandığında, yeni bir nesne ayrılmalıdır ve oluşturulmalıdır. Daha düşük bir dereceye kadar, kutudan
çıkarma için gereken atama da pahalı bir hesaplama olur. Daha fazla bilgi için bkz. performans.

Kutulama
Paketleme, değer türlerini atık toplanmış yığında depolamak için kullanılır. Kutulama, bir değer türünün türüne
object veya bu değer türü tarafından uygulanan herhangi bir arabirim türüne örtük olarak dönüştürülmedir.
Değer türünü kutulama yığında bir nesne örneği ayırır ve değeri yeni nesneye kopyalar.
Bir değer türü değişkeninin aşağıdaki bildirimini göz önünde bulundurun:

int i = 123;

Aşağıdaki ifade, değişkende i kutulama işlemini örtülü olarak uygular:


// Boxing copies the value of i into object o.
object o = i;

Bu deyimin sonucu, yığında, yığında tür o int değerine başvuran bir nesne başvurusu oluşturuyor. Bu değer,
değişkene i atanan değer türü değerinin bir kopyasıdır. İki değişken i arasındaki fark, ve o aşağıdaki
kutulama dönüştürme görüntüsünde gösterilmektedir:

Kutulamayı aşağıdaki örnekte olduğu gibi açıkça gerçekleştirmek de mümkündür, ancak açık kutulama hiçbir
şekilde gerekli değildir:

int i = 123;
object o = (object)i; // explicit boxing

Açıklama
Bu örnek, kutulama kullanarak bir i tamsayı değişkenini nesnesine o dönüştürür. Ardından, değişkeninde i
depolanan değer ' 456 dan 123 ' a değiştirilir. Örnek, özgün değer türü ve kutulanmış nesnenin ayrı bellek
konumları kullandığı ve bu nedenle farklı değerleri depolayabileceği gösterilmektedir.

Örnek
class TestBoxing
{
static void Main()
{
int i = 123;

// Boxing copies the value of i into object o.


object o = i;

// Change the value of i.


i = 456;

// The change in i doesn't affect the value stored in o.


System.Console.WriteLine("The value-type value = {0}", i);
System.Console.WriteLine("The object-type value = {0}", o);
}
}
/* Output:
The value-type value = 456
The object-type value = 123
*/

Çıkarma
Kutudan çıkarma, türden object bir değer türüne veya arabirim türünden arabirimi uygulayan bir değer türüne
açık bir dönüşümtür. Kutudan çıkarma işlemi aşağıdakilerden oluşur:
Verilen değer türünün paketlenmiş bir değeri olduğundan emin olmak için nesne örneği denetleniyor.
Değer, örnekten değer türü değişkenine kopyalanıyor.
Aşağıdaki deyimler, kutulama ve kutudan çıkarma işlemlerini gösterir:

int i = 123; // a value type


object o = i; // boxing
int j = (int)o; // unboxing

Aşağıdaki şekilde, önceki ifadelerin sonucu gösterilmektedir:

Değer türlerinin serbest bırakılmasının çalışma zamanında başarılı olması için, kutudan çıkarılmış olan öğe, bu
değer türünün bir örneğini kutulama tarafından daha önce oluşturulmuş bir nesneye başvuru olmalıdır. Bir
kaldırma null girişimi bir NullReferenceExceptionolur. Uyumsuz bir değer türüne başvurunun kaldırılması
denenmeye neden olur InvalidCastException.

Örnek
Aşağıdaki örnek, geçersiz kutudan çıkarma ve sonuç olarak ortaya çıkan InvalidCastException bir durumu
gösterir. try Ve catch kullanarak, hata oluştuğunda bir hata mesajı görüntülenir.

class TestUnboxing
{
static void Main()
{
int i = 123;
object o = i; // implicit boxing

try
{
int j = (short)o; // attempt to unbox

System.Console.WriteLine("Unboxing OK.");
}
catch (System.InvalidCastException e)
{
System.Console.WriteLine("{0} Error: Incorrect unboxing.", e.Message);
}
}
}

Bu program çıkışlar:
Specified cast is not valid. Error: Incorrect unboxing.

İfadesini değiştirirseniz:

int j = (short) o;
Yeni değer:

int j = (int) o;

dönüştürme gerçekleştirilecek ve şu çıktıyı alacaksınız:


Unboxing OK.

C# Dil Belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir kaynaktır.

İlgili Bölümler
Daha fazla bilgi için:
Başvuru Türleri
Değer Türleri

Ayrıca bkz.
C# Programlama Kılavuzu
Nasıl yapılır: byte Dizisini int'e Dönüştürme (C#
Programlama Kılavuzu)
31.10.2019 • 2 minutes to read • Edit Online

Bu örnek, bir bayt dizisini bir int 'e ve bir bayt dizisine geri dönüştürmek için BitConverter sınıfının nasıl
kullanılacağını gösterir. Örneğin, ağ dışı baytları okuduktan sonra bayttan bir yerleşik veri türüne dönüştürmeniz
gerekebilir. Örnekteki ToInt32 (byte[], Int32) yöntemine ek olarak, aşağıdaki tablo, baytları (bayt dizisinden bir
diziden) diğer yerleşik türlere dönüştüren BitConverter sınıfındaki yöntemleri listelemektedir.

DÖNDÜRÜLEN TÜR YÖNTEM

bool ToBoolean (Byte[], Int32)

char ToChar (bayt[], Int32)

double ToDouble (bayt[], Int32)

short Toınt16 (Byte[], Int32)

int Toınt32 (Byte[], Int32)

long Toınt64 (Byte[], Int32)

float ToSingle (Byte[], Int32)

ushort Touınt16 (Byte[], Int32)

uint Touınt32 (Byte[], Int32)

ulong Touınt64 (Byte[], Int32)

Örnek
Bu örnek, bir bayt dizisini başlatır, bilgisayar mimarisi az endian ise diziyi tersine çevirir (yani, ilk olarak en az
önemli bayt depolanır) ve ardından dört baytı dönüştürmek için ToInt32 (byte[], Int32) yöntemini çağırır dizide
int . Toınt32 için ikinci bağımsız değişken ( Byte[], Int32 ) bayt dizisinin başlangıç dizinini belirtir.

NOTE
Çıktı, bilgisayarınızın mimarisinin bitiliğine bağlı olarak farklılık gösterebilir.
byte[] bytes = { 0, 0, 0, 25 };

// If the system architecture is little-endian (that is, little end first),


// reverse the byte array.
if (BitConverter.IsLittleEndian)
Array.Reverse(bytes);

int i = BitConverter.ToInt32(bytes, 0);


Console.WriteLine("int: {0}", i);
// Output: int: 25

Örnek
Bu örnekte, bir int bayt dizisine dönüştürmek için BitConverter sınıfının GetBytes(Int32) yöntemi çağırılır.

NOTE
Çıktı, bilgisayarınızın mimarisinin bitiliğine bağlı olarak farklılık gösterebilir.

byte[] bytes = BitConverter.GetBytes(201805978);


Console.WriteLine("byte array: " + BitConverter.ToString(bytes));
// Output: byte array: 9A-50-07-0C

Ayrıca bkz.
BitConverter
IsLittleEndian
Türler
Nasıl yapılır: Bir Dizeyi Sayıya Dönüştürme (C#
Programlama Kılavuzu)
29.11.2019 • 6 minutes to read • Edit Online

Çeşitli sayısal türlerde ( int , long , double , vb.) bulunan Parse veya TryParse yöntemini çağırarak veya
System.Convert sınıfındaki yöntemleri kullanarak bir dizeyi sayıya dönüştürebilirsiniz.
Bir dizeniz varsa, bir yöntemi (örneğin, int.TryParse("11", out number) ) veya Parse yöntemi (örneğin,
TryParse
var number = int.Parse("11") ) çağırmak biraz daha etkilidir ve kolaydır. Convert yöntemi kullanmak,
IConvertibleuygulayan genel nesneler için daha yararlıdır.
System.Int32 türü gibi, dizeyi içeren sayısal türde Parse veya TryParse yöntemlerini kullanabilirsiniz.
Convert.ToInt32 yöntemi dahili olarak Parse kullanır. Parse yöntemi, dönüştürülmüş sayıyı döndürür; TryParse
yöntemi, dönüştürmenin başarılı olup olmadığını belirten bir Boolean değeri döndürür ve bir out
parametresindekidönüştürülmüş sayıyı döndürür. Dize geçerli bir biçimde değilse, Parse bir özel durum
oluşturur, ancak TryParse false döndürür. Bir Parse yöntemi çağrılırken, ayrıştırma işleminin başarısız olduğu
olayda bir FormatException yakalamak için her zaman özel durum işlemeyi kullanmanız gerekir.

Parse ve Trypari yöntemlerini çağırma


Parse ve TryParse yöntemleri, dizenin başındaki ve sonundaki boşlukları yoksayar, ancak diğer tüm karakterler
uygun sayısal türü ( int , long , ulong , float ) biçimli karakterler olmalıdır. , decimal vb.). Dizeyi oluşturan dize
içindeki tüm boşluklar hataya neden olur. Örneğin, "10", "10,3" veya "10" öğesini ayrıştırmak için
decimal.TryParse kullanabilirsiniz, ancak bu yöntemi, "10X", "1 0" (katıştırılmış alanı notta), "10 .3" (katıştırılmış
alanı), "10E1" ( float.TryParse burada), vb. ayrıştırarak kullanamazsınız. Ayrıca, değeri null olan bir dize veya
String.Empty başarıyla ayrıştırılamadı. String.IsNullOrEmpty metodunu çağırarak, ayrıştırmayı denemeden önce
null veya boş bir dize kontrol edebilirsiniz.
Aşağıdaki örnek, Parse ve TryParse için hem başarılı hem de başarısız çağrıları gösterir.
using System;

public class StringConversion


{
public static void Main()
{
string input = String.Empty;
try
{
int result = Int32.Parse(input);
Console.WriteLine(result);
}
catch (FormatException)
{
Console.WriteLine($"Unable to parse '{input}'");
}
// Output: Unable to parse ''

try
{
int numVal = Int32.Parse("-105");
Console.WriteLine(numVal);
}
catch (FormatException e)
{
Console.WriteLine(e.Message);
}
// Output: -105

if (Int32.TryParse("-105", out int j))


Console.WriteLine(j);
else
Console.WriteLine("String could not be parsed.");
// Output: -105

try
{
int m = Int32.Parse("abc");
}
catch (FormatException e)
{
Console.WriteLine(e.Message);
}
// Output: Input string was not in a correct format.

string inputString = "abc";


if (Int32.TryParse(inputString, out int numValue))
Console.WriteLine(inputString);
else
Console.WriteLine($"Int32.TryParse could not parse '{inputString}' to an int.");
// Output: Int32.TryParse could not parse 'abc' to an int.
}
}

Aşağıdaki örnekte, baştaki sayısal karakterler (onaltılık karakterler dahil) ve sondaki sayısal olmayan karakterler
içermesi beklenen bir dizeyi ayrıştırmak için bir yaklaşım gösterilmektedir. TryParse yöntemi çağrılmadan önce bir
dizenin başından yeni bir dizeye geçerli karakterler atar. Ayrıştırılacak dizeler az sayıda karakter içerdiğinden,
örnek yeni bir dizeye geçerli karakterler atamak için String.Concat yöntemini çağırır. Daha büyük bir dize için
bunun yerine StringBuilder sınıfı kullanılabilir.
using System;

public class StringConversion


{
public static void Main()
{
var str = " 10FFxxx";
string numericString = String.Empty;
foreach (var c in str)
{
// Check for numeric characters (hex in this case) or leading or trailing spaces.
if ((c >= '0' && c <= '9') || (Char.ToUpperInvariant(c) >= 'A' && Char.ToUpperInvariant(c) <=
'F') || c == ' ') {
numericString = String.Concat(numericString, c.ToString());
}
else
{
break;
}
}
if (int.TryParse(numericString, System.Globalization.NumberStyles.HexNumber, null, out int i))
Console.WriteLine($"'{str}' --> '{numericString}' --> {i}");
// Output: ' 10FFxxx' --> ' 10FF' --> 4351

str = " -10FFXXX";


numericString = "";
foreach (char c in str) {
// Check for numeric characters (0-9), a negative sign, or leading or trailing spaces.
if ((c >= '0' && c <= '9') || c == ' ' || c == '-')
{
numericString = String.Concat(numericString, c);
} else
break;
}
if (int.TryParse(numericString, out int j))
Console.WriteLine($"'{str}' --> '{numericString}' --> {j}");
// Output: ' -10FFXXX' --> ' -10' --> -10
}
}

Convert yöntemlerini çağırma


Aşağıdaki tabloda, bir dizeyi sayıya dönüştürmek için kullanabileceğiniz Convert sınıfından bazı yöntemler
listelenmiştir.

SAYISAL TÜR YÖNTEM

decimal ToDecimal(String)

float ToSingle(String)

double ToDouble(String)

short ToInt16(String)

int ToInt32(String)

long ToInt64(String)
SAYISAL TÜR YÖNTEM

ushort ToUInt16(String)

uint ToUInt32(String)

ulong ToUInt64(String)

Aşağıdaki örnek, bir giriş dizesini int'e dönüştürmek için Convert.ToInt32(String) yöntemini çağırır. Örnek, bu
yöntemle oluşturulabilecek en yaygın iki özel durumu yakalar, FormatException ve OverflowException. Elde edilen
sayı Int32.MaxValueaşmadan arttırılabiliyorsa, örnek sonuca 1 ekler ve çıktıyı görüntüler.
using System;

public class ConvertStringExample1


{
static void Main(string[] args)
{
int numVal = -1;
bool repeat = true;

while (repeat)
{
Console.Write("Enter a number between −2,147,483,648 and +2,147,483,647 (inclusive): ");

string input = Console.ReadLine();

// ToInt32 can throw FormatException or OverflowException.


try
{
numVal = Convert.ToInt32(input);
if (numVal < Int32.MaxValue)
{
Console.WriteLine("The new value is {0}", ++numVal);
}
else
{
Console.WriteLine("numVal cannot be incremented beyond its current value");
}
}
catch (FormatException)
{
Console.WriteLine("Input string is not a sequence of digits.");
}
catch (OverflowException)
{
Console.WriteLine("The number cannot fit in an Int32.");
}

Console.Write("Go again? Y/N: ");


string go = Console.ReadLine();
if (go.ToUpper() != "Y")
{
repeat = false;
}
}
}
}
// Sample Output:
// Enter a number between -2,147,483,648 and +2,147,483,647 (inclusive): 473
// The new value is 474
// Go again? Y/N: y
// Enter a number between -2,147,483,648 and +2,147,483,647 (inclusive): 2147483647
// numVal cannot be incremented beyond its current value
// Go again? Y/N: y
// Enter a number between -2,147,483,648 and +2,147,483,647 (inclusive): -1000
// The new value is -999
// Go again? Y/N: n

Ayrıca bkz.
Türler
Nasıl yapılır: Bir Dizenin Sayısal bir Değeri Temsil Edip Etmediğini Belirleme
Örnek: .NET Core WinForms biçimlendirme yardımcı programıC#()
Nasıl yapılır: Onaltılık Dizeler ve Sayısal Türler
Arasında Dönüştürme (C# Programlama Kılavuzu)
27.11.2019 • 4 minutes to read • Edit Online

Bu örneklerde aşağıdaki görevlerin nasıl gerçekleştirileceği gösterilmektedir:


Dizedekiher karakterin onaltılık değerini elde edin.
Onaltılık dizedeki her değere karşılık gelen char 'ı alın.
Bir onaltılı string bir int'e dönüştürün.
Onaltılı string bir floatöğesine dönüştürün.
Bir bayt dizisini onaltılık string dönüştürür.

Örnek
Bu örnek, string her karakterin onaltılık değerini verir. İlk olarak string bir karakter dizisine ayrıştırır. Sonra
sayısal değerini elde etmek için her bir karakter ToInt32(Char) çağırır. Son olarak, sayıyı string onaltılık temsili
olarak biçimlendirir.

string input = "Hello World!";


char[] values = input.ToCharArray();
foreach (char letter in values)
{
// Get the integral value of the character.
int value = Convert.ToInt32(letter);
// Convert the integer value to a hexadecimal value in string form.
Console.WriteLine($"Hexadecimal value of {letter} is {value:X}");
}
/* Output:
Hexadecimal value of H is 48
Hexadecimal value of e is 65
Hexadecimal value of l is 6C
Hexadecimal value of l is 6C
Hexadecimal value of o is 6F
Hexadecimal value of is 20
Hexadecimal value of W is 57
Hexadecimal value of o is 6F
Hexadecimal value of r is 72
Hexadecimal value of l is 6C
Hexadecimal value of d is 64
Hexadecimal value of ! is 21
*/

Örnek
Bu örnek, onaltılı değerlerin bir string ayrıştırır ve her bir onaltılık değere karşılık gelen karakteri verir. İlk olarak,
her onaltılı değeri bir dizide tek bir string olarak almak için Split (Char[]) yöntemini çağırır. Sonra onaltılık değeri
tamsayıolarak temsil edilen bir ondalık değere dönüştürmek için ToInt32(String, Int32) çağırır. Bu karakter koduna
karşılık gelen karakteri almanın iki farklı yolunu gösterir. İlk teknik, bir string olarak tamsayı bağımsız
değişkenine karşılık gelen karakteri döndüren ConvertFromUtf32(Int32)kullanır. İkinci teknik, int açıkça bir
char'a yayınlar.
string hexValues = "48 65 6C 6C 6F 20 57 6F 72 6C 64 21";
string[] hexValuesSplit = hexValues.Split(' ');
foreach (string hex in hexValuesSplit)
{
// Convert the number expressed in base-16 to an integer.
int value = Convert.ToInt32(hex, 16);
// Get the character corresponding to the integral value.
string stringValue = Char.ConvertFromUtf32(value);
char charValue = (char)value;
Console.WriteLine("hexadecimal value = {0}, int value = {1}, char value = {2} or {3}",
hex, value, stringValue, charValue);
}
/* Output:
hexadecimal value = 48, int value = 72, char value = H or H
hexadecimal value = 65, int value = 101, char value = e or e
hexadecimal value = 6C, int value = 108, char value = l or l
hexadecimal value = 6C, int value = 108, char value = l or l
hexadecimal value = 6F, int value = 111, char value = o or o
hexadecimal value = 20, int value = 32, char value = or
hexadecimal value = 57, int value = 87, char value = W or W
hexadecimal value = 6F, int value = 111, char value = o or o
hexadecimal value = 72, int value = 114, char value = r or r
hexadecimal value = 6C, int value = 108, char value = l or l
hexadecimal value = 64, int value = 100, char value = d or d
hexadecimal value = 21, int value = 33, char value = ! or !
*/

Örnek
Bu örnek, Parse(String, NumberStyles) yöntemini çağırarak bir onaltılı string tamsayıya dönüştürmenin başka
bir yolunu gösterir.

string hexString = "8E2";


int num = Int32.Parse(hexString, System.Globalization.NumberStyles.HexNumber);
Console.WriteLine(num);
//Output: 2274

Örnek
Aşağıdaki örnek, System.BitConverter sınıfı ve UInt32.Parse yöntemi kullanılarak bir onaltılı string bir float
öğesine nasıl dönüştürüleceğini gösterir.

string hexString = "43480170";


uint num = uint.Parse(hexString, System.Globalization.NumberStyles.AllowHexSpecifier);

byte[] floatVals = BitConverter.GetBytes(num);


float f = BitConverter.ToSingle(floatVals, 0);
Console.WriteLine("float convert = {0}", f);

// Output: 200.0056

Örnek
Aşağıdaki örnek, System.BitConverter sınıfını kullanarak bir bayt dizisinin onaltılık dizeye nasıl dönüştürüleceğini
gösterir.
byte[] vals = { 0x01, 0xAA, 0xB1, 0xDC, 0x10, 0xDD };

string str = BitConverter.ToString(vals);


Console.WriteLine(str);

str = BitConverter.ToString(vals).Replace("-", "");


Console.WriteLine(str);

/*Output:
01-AA-B1-DC-10-DD
01AAB1DC10DD
*/

Ayrıca bkz.
Standart Sayısal Biçim Dizeleri
Türler
Nasıl yapılır: Bir Dizenin Sayısal bir Değeri Temsil Edip Etmediğini Belirleme
Dinamik tür kullanımı (C# Programlama Kılavuzu)
4.11.2019 • 8 minutes to read • Edit Online

C#4 dynamic yeni bir tür tanıtır. Tür statik bir türdür, ancak dynamic türünde bir nesne statik tür denetimini atlar.
Çoğu durumda, bu işlev object tür gibidir. Derleme zamanında, dynamic olarak yazılan bir öğe, herhangi bir
işlemi desteklemeye yönelik olarak kabul edilir. Bu nedenle, nesnenin değerini bir COM API 'sinden, IronPython
gibi dinamik bir dilden, HTML Belge Nesne Modeli (DOM ), yansımasından veya programdaki herhangi bir
yerden alıp ulaşmamasından endişe etmeniz gerekmez. Ancak, kod geçerli değilse, hatalar çalışma zamanında
yakalanmalıdır.
Örneğin, aşağıdaki kodda exampleMethod1 örnek yönteminin yalnızca bir parametresi varsa, derleyici iki bağımsız
değişken içerdiğinden, ec.exampleMethod1(10, 4) yöntemine yapılan ilk çağrının geçerli olmadığını algılar. Çağrı,
bir derleyici hatasına neden olur. dynamic_ec türü dynamic olduğundan, dynamic_ec.exampleMethod1(10, 4)
metoduna yapılan ikinci çağrı derleyici tarafından denetlenmez. Bu nedenle, hiçbir derleyici hatası bildirilmemiştir.
Ancak, hata süresiz olarak çıkış yapmaz. Çalışma zamanında yakalanır ve bir çalışma zamanı özel durumuna
neden olur.

static void Main(string[] args)


{
ExampleClass ec = new ExampleClass();
// The following call to exampleMethod1 causes a compiler error
// if exampleMethod1 has only one parameter. Uncomment the line
// to see the error.
//ec.exampleMethod1(10, 4);

dynamic dynamic_ec = new ExampleClass();


// The following line is not identified as an error by the
// compiler, but it causes a run-time exception.
dynamic_ec.exampleMethod1(10, 4);

// The following calls also do not cause compiler errors, whether


// appropriate methods exist or not.
dynamic_ec.someMethod("some argument", 7, null);
dynamic_ec.nonexistentMethod();
}

class ExampleClass
{
public ExampleClass() { }
public ExampleClass(int v) { }

public void exampleMethod1(int i) { }

public void exampleMethod2(string str) { }


}

Bu örneklerde derleyicinin rolü, her bir deyimin dynamic olarak yazılan nesne veya ifade için hangi amaçla
önerdikleridir hakkındaki bilgileri birlikte paketlemenize olanak sağlar. Çalışma zamanında, depolanan bilgiler
incelenir ve geçerli olmayan herhangi bir ifade çalışma zamanı özel durumuna neden olur.
Çoğu dinamik işlemin sonucu dynamic . Örneğin, aşağıdaki örnekte fare işaretçisini testSum kullanımı üzerine
getirdiğinizde, IntelliSense türü (yerel değişken) dinamik testSum' ı görüntüler.
dynamic d = 1;
var testSum = d + 3;
// Rest the mouse pointer over testSum in the following statement.
System.Console.WriteLine(testSum);

Sonucun dynamic dahil olmadığı işlemler şunlardır:


dynamic dönüştürme işlemleri başka bir türe.
dynamic türünde bağımsız değişkenler içeren Oluşturucu çağrıları.

Örneğin, aşağıdaki bildirimde testInstance türü dynamic değil ExampleClass .

var testInstance = new ExampleClass(d);

Dönüştürme örnekleri aşağıdaki "Dönüşümler" bölümünde gösterilmiştir.

Dönüşümler
Dinamik nesneler ve diğer türler arasındaki dönüştürmeler kolaydır. Bu, geliştiricinin dinamik ve dinamik
olmayan davranış arasında geçiş yapmasına olanak sağlar.
Aşağıdaki örneklerde gösterildiği gibi, herhangi bir nesne dinamik türe örtük olarak dönüştürülebilir.

dynamic d1 = 7;
dynamic d2 = "a string";
dynamic d3 = System.DateTime.Today;
dynamic d4 = System.Diagnostics.Process.GetProcesses();

Buna karşılık, örtük bir dönüştürme dynamic türünde herhangi bir ifadeye dinamik olarak uygulanabilir.

int i = d1;
string str = d2;
DateTime dt = d3;
System.Diagnostics.Process[] procs = d4;

Dinamik türdeki bağımsız değişkenlerle aşırı yükleme çözümlemesi


Bir yöntem çağrısındaki bir veya daha fazla bağımsız değişken dynamic , ya da yöntem çağrısının alıcısı dynamic
türünde ise, aşırı yükleme çözümlemesi, derleme zamanı yerine çalışma zamanında gerçekleşir. Aşağıdaki
örnekte, tek bir dize bağımsız değişkeni almak için yalnızca erişilebilir exampleMethod2 yöntemi tanımlanırsa,
bağımsız değişken olarak d1 gönderme bir derleyici hatasına neden olmaz, ancak çalışma zamanı özel
durumuna neden olur. d1 çalışma zamanı türü int olduğundan ve exampleMethod2 bir dize gerektirdiğinden
aşırı yükleme çözümlemesi çalışma zamanında başarısız olur.

// Valid.
ec.exampleMethod2("a string");

// The following statement does not cause a compiler error, even though ec is not
// dynamic. A run-time exception is raised because the run-time type of d1 is int.
ec.exampleMethod2(d1);
// The following statement does cause a compiler error.
//ec.exampleMethod2(7);
Dinamik dil çalışma zamanı
Dinamik dil çalışma zamanı (DLR ) .NET Framework 4 ' te yeni bir API 'dir. İçinde C# dynamic türünü destekleyen
altyapıyı ve ayrıca IronPython ve IronRuby gibi dinamik programlama dillerinin uygulanmasını sağlar. DLR
hakkında daha fazla bilgi için bkz. dinamik dil çalışma zamanına genel bakış.

COM birlikte çalışma


C#4, Office Otomasyonu API 'leri gibi COM API 'lerle birlikte çalışma deneyimini geliştiren çeşitli özellikler içerir.
Geliştirmeler arasında dynamic türünün ve adlandırılmış ve isteğe bağlı bağımsız değişkenlerinkullanımı vardır.
Birçok COM yöntemi, türleri object olarak tanımlayarak bağımsız değişken türlerinde ve dönüş türünde
değişimler için izin verir. Bu, ' deki kesin olarak belirlenmiş değişkenlerle koordine etmek için değerlerin açık bir
şekilde C#çevrim kümesini gerektiren bir -Link (C# derleyici seçenekleri) seçeneğini kullanarak derlerseniz
dynamic türünün kullanıma sunulması, com imzalarındaki object tekrarlamalarını dynamic türü gibi kabul
etmenizi ve dolayısıyla çok sayıda atama yapılmasını önlemenize olanak sağlar. Örneğin, aşağıdaki deyimler
Microsoft Office Excel elektronik tablosundaki bir hücreye dynamic türü ve dynamic türü olmadan nasıl
erişirsiniz.

// Before the introduction of dynamic.


((Excel.Range)excelApp.Cells[1, 1]).Value2 = "Name";
Excel.Range range2008 = (Excel.Range)excelApp.Cells[1, 1];

// After the introduction of dynamic, the access to the Value property and
// the conversion to Excel.Range are handled by the run-time COM binder.
excelApp.Cells[1, 1].Value = "Name";
Excel.Range range2010 = excelApp.Cells[1, 1];

İlgili konular
BAŞLIK AÇIKLAMA

dynamic dynamic anahtar sözcüğünün kullanımını açıklar.

Dinamik Dil Çalışma Zamanına Genel Bakış Ortak dil çalışma zamanına (CLR) dinamik diller için bir hizmet
kümesi ekleyen bir çalışma zamanı ortamı olan DLR 'ye genel
bir bakış sağlar.

İzlenecek yol: dinamik nesneler oluşturma ve kullanma Özel dinamik nesne oluşturmaya ve bir IronPython
kitaplığına erişen bir proje oluşturmaya yönelik adım adım
yönergeler sağlar.

Nasıl yapılır: Visual C# Özelliklerini Kullanarak Office Birlikte Adlandırılmış ve isteğe bağlı bağımsız değişkenler, dynamic
Çalışma Nesnelerine Erişim türü ve Office API nesnelerine erişimi kolaylaştıran diğer
geliştirmeleri kullanan bir projenin nasıl oluşturulacağını
gösterir.
İzlenecek yol: Dinamik Nesneler Oluşturma ve
Kullanma (C# and Visual Basic)
4.11.2019 • 17 minutes to read • Edit Online

Dinamik nesneler, derleme zamanında değil, çalışma zamanında Özellikler ve yöntemler gibi üyeleri kullanıma
sunar. Bu, statik bir tür veya biçimle eşleşmeyen yapılarla çalışacak nesneler oluşturmanızı sağlar. Örneğin, geçerli
HTML biçimlendirme öğelerinin ve özniteliklerin herhangi bir birleşimini içerebilen HTML Belge Nesne Modeli
(DOM ) başvurmak için dinamik bir nesne kullanabilirsiniz. Her HTML belgesi benzersiz olduğundan, belirli bir
HTML belgesi üyeleri çalışma zamanında belirlenir. HTML öğesinin bir özniteliğine başvurmak için ortak bir
yöntem, özniteliğin adını öğesinin GetProperty metoduna geçirmektir. HTML öğesi <div id="Div1">``id
özniteliğine başvurmak için, önce <div> öğesine bir başvuru alın ve ardından divElement.GetProperty("id")
kullanın. Dinamik bir nesne kullanıyorsanız, divElement.id olarak id özniteliğine başvurabilirsiniz.
Dinamik nesneler IronPython ve IronRuby gibi dinamik dillere de kolay erişim sağlar. Çalışma zamanında
yorumlanan dinamik bir betiğe başvurmak için dinamik bir nesne kullanabilirsiniz.
Geç bağlamayı kullanarak dinamik bir nesneye başvurabilirsiniz. İçinde C#, bir geç bağlantılı nesnenin türünü
dynamic olarak belirtirsiniz. Visual Basic, bir geç bağlantılı nesnenin türünü Object olarak belirtirsiniz. Daha fazla
bilgi için bkz. dinamik ve erken ve geç bağlama.
System.Dynamic ad alanındaki sınıfları kullanarak özel dinamik nesneler oluşturabilirsiniz. Örneğin, bir
ExpandoObject oluşturabilir ve çalışma zamanında o nesnenin üyelerini belirtebilirsiniz. Ayrıca, DynamicObject
sınıfını devralan kendi türünü de oluşturabilirsiniz. Sonra, çalışma zamanı dinamik işlevselliği sağlamak için
DynamicObject sınıfının üyelerini geçersiz kılabilirsiniz.
Bu kılavuzda, aşağıdaki görevleri yerine getirmeniz gerekir:
Bir metin dosyasının içeriğini dinamik olarak bir nesnenin özellikleri olarak sunan özel bir nesne oluşturun.
IronPython kitaplığı kullanan bir proje oluşturun.

Prerequisites
Bu izlenecek yolu tamamlamak için .NET için IronPython gerekir. En son sürümü edinmek için indirme sayfasına
gidin.

NOTE
Bilgisayarınız, aşağıdaki yönergelerde yer alan Visual Studio kullanıcı arabirimi öğelerinden bazıları için farklı adlar veya
konumlar gösterebilir. Sahip olduğunuz Visual Studio sürümü ve kullandığınız ayarlar bu öğeleri belirler. Daha fazla bilgi için
IDE'yi kişiselleştirme.

Özel dinamik nesne oluşturma


Bu izlenecek yolda oluşturduğunuz ilk proje, bir metin dosyasının içeriğini arayan özel bir dinamik nesne tanımlar.
Aranacak metin, dinamik bir özelliğin adı ile belirtilir. Örneğin, kod çağırma dynamicFile.Sample belirtiyorsa,
dinamik sınıf, dosyadaki "Sample" ile başlayan tüm satırları içeren bir dize genel listesini döndürür. Arama
büyük/küçük harfe duyarlıdır. Dinamik sınıf Ayrıca iki isteğe bağlı bağımsız değişkeni destekler. İlk bağımsız
değişken, dinamik sınıfın satır başlangıcında, satırın sonunda veya satırdaki herhangi bir yerde eşleşmelerin
aranması gerektiğini belirten bir arama seçeneği enum değeridir. İkinci bağımsız değişken, dinamik sınıfın,
aramadan önce her satırdaki baştaki ve sondaki boşlukları kırpmalıdır. Örneğin, kod çağırma
dynamicFile.Sample(StringSearchOption.Contains) belirtiyorsa dinamik sınıf, "Sample" öğesini bir satırda herhangi
bir yerde arar. Kod çağırma dynamicFile.Sample(StringSearchOption.StartsWith, false) belirtiyorsa, dinamik sınıf
her satırın başlangıcında "Sample" arar ve baştaki ve sondaki boşlukları kaldırmaz. Dinamik sınıfın varsayılan
davranışı, her satırın başlangıcında bir eşleşme aramak ve baştaki ve sondaki boşlukları kaldırmak içindir.
Özel bir dinamik sınıf oluşturmak için
1. Visual Studio 'Yu başlatın.
2. Dosya menüsünde, Yeni ' nin üzerine gelin ve ardından Proje' ye tıklayın.
3. Yeni proje iletişim kutusunda, Proje türleri bölmesinde Windows ' un seçili olduğundan emin olun.
Şablonlar bölmesinde konsol uygulaması ' nı seçin. Ad kutusuna DynamicSample yazın ve ardından
Tamam' a tıklayın. Yeni proje oluşturulur.
4. DynamicSample projesine sağ tıklayın ve Ekle' nin üzerine gelin ve ardından sınıf' a tıklayın. Ad kutusuna
ReadOnlyFile yazın ve ardından Tamam' a tıklayın. ReadOnlyFile sınıfını içeren yeni bir dosya eklenir.

5. ReadOnlyFile.cs veya ReadOnlyFile. vb dosyasının en üstünde, System.IO ve System.Dynamic ad alanlarını


içeri aktarmak için aşağıdaki kodu ekleyin.

using System.IO;
using System.Dynamic;

Imports System.IO
Imports System.Dynamic

6. Özel dinamik nesne, arama ölçütlerini bulmak için bir sabit listesi kullanır. Class ifadesinden önce aşağıdaki
sabit listesi tanımını ekleyin.

public enum StringSearchOption


{
StartsWith,
Contains,
EndsWith
}

Public Enum StringSearchOption


StartsWith
Contains
EndsWith
End Enum

7. Aşağıdaki kod örneğinde gösterildiği gibi, sınıf ifadesini DynamicObject sınıfını devralacak şekilde
güncelleştirin.

class ReadOnlyFile : DynamicObject

Public Class ReadOnlyFile


Inherits DynamicObject

8. Dosya yolu için bir özel alan ve ReadOnlyFile sınıfı için bir Oluşturucu tanımlamak üzere ReadOnlyFile
sınıfına aşağıdaki kodu ekleyin.
// Store the path to the file and the initial line count value.
private string p_filePath;

// Public constructor. Verify that file exists and store the path in
// the private variable.
public ReadOnlyFile(string filePath)
{
if (!File.Exists(filePath))
{
throw new Exception("File path does not exist.");
}

p_filePath = filePath;
}

' Store the path to the file and the initial line count value.
Private p_filePath As String

' Public constructor. Verify that file exists and store the path in
' the private variable.
Public Sub New(ByVal filePath As String)
If Not File.Exists(filePath) Then
Throw New Exception("File path does not exist.")
End If

p_filePath = filePath
End Sub

9. Aşağıdaki GetPropertyValue yöntemini ReadOnlyFile sınıfına ekleyin. GetPropertyValue yöntemi giriş,


arama ölçütü olarak alır ve bu arama ölçütleriyle eşleşen bir metin dosyasındaki satırları döndürür.
ReadOnlyFile sınıfı tarafından sunulan dinamik yöntemler, ilgili sonuçlarını almak için GetPropertyValue
yöntemini çağırır.
public List<string> GetPropertyValue(string propertyName,
StringSearchOption StringSearchOption =
StringSearchOption.StartsWith,
bool trimSpaces = true)
{
StreamReader sr = null;
List<string> results = new List<string>();
string line = "";
string testLine = "";

try
{
sr = new StreamReader(p_filePath);

while (!sr.EndOfStream)
{
line = sr.ReadLine();

// Perform a case-insensitive search by using the specified search options.


testLine = line.ToUpper();
if (trimSpaces) { testLine = testLine.Trim(); }

switch (StringSearchOption)
{
case StringSearchOption.StartsWith:
if (testLine.StartsWith(propertyName.ToUpper())) { results.Add(line); }
break;
case StringSearchOption.Contains:
if (testLine.Contains(propertyName.ToUpper())) { results.Add(line); }
break;
case StringSearchOption.EndsWith:
if (testLine.EndsWith(propertyName.ToUpper())) { results.Add(line); }
break;
}
}
}
catch
{
// Trap any exception that occurs in reading the file and return null.
results = null;
}
finally
{
if (sr != null) {sr.Close();}
}

return results;
}
Public Function GetPropertyValue(ByVal propertyName As String,
Optional ByVal StringSearchOption As StringSearchOption =
StringSearchOption.StartsWith,
Optional ByVal trimSpaces As Boolean = True) As List(Of String)

Dim sr As StreamReader = Nothing


Dim results As New List(Of String)
Dim line = ""
Dim testLine = ""

Try
sr = New StreamReader(p_filePath)

While Not sr.EndOfStream


line = sr.ReadLine()

' Perform a case-insensitive search by using the specified search options.


testLine = UCase(line)
If trimSpaces Then testLine = Trim(testLine)

Select Case StringSearchOption


Case StringSearchOption.StartsWith
If testLine.StartsWith(UCase(propertyName)) Then results.Add(line)
Case StringSearchOption.Contains
If testLine.Contains(UCase(propertyName)) Then results.Add(line)
Case StringSearchOption.EndsWith
If testLine.EndsWith(UCase(propertyName)) Then results.Add(line)
End Select
End While
Catch
' Trap any exception that occurs in reading the file and return Nothing.
results = Nothing
Finally
If sr IsNot Nothing Then sr.Close()
End Try

Return results
End Function

10. GetPropertyValue yönteminden sonra, DynamicObject sınıfının TryGetMember metodunu geçersiz kılmak
için aşağıdaki kodu ekleyin. TryGetMember yöntemi, dinamik bir sınıfın bir üyesi istendiğinde ve hiçbir
bağımsız değişken belirtilmediğinde çağrılır. binder bağımsız değişkeni, başvurulan üye hakkında bilgi
içerir ve result bağımsız değişkeni belirtilen üye için döndürülen sonuca başvurur. TryGetMember
yöntemi, istenen üye varsa true döndüren bir Boolean değer döndürür; Aksi takdirde false döndürür.

// Implement the TryGetMember method of the DynamicObject class for dynamic member calls.
public override bool TryGetMember(GetMemberBinder binder,
out object result)
{
result = GetPropertyValue(binder.Name);
return result == null ? false : true;
}

' Implement the TryGetMember method of the DynamicObject class for dynamic member calls.
Public Overrides Function TryGetMember(ByVal binder As GetMemberBinder,
ByRef result As Object) As Boolean
result = GetPropertyValue(binder.Name)
Return If(result Is Nothing, False, True)
End Function

11. TryGetMember yönteminden sonra, DynamicObject sınıfının TryInvokeMember metodunu geçersiz kılmak
için aşağıdaki kodu ekleyin. Bağımsız değişkenlerle bir dinamik sınıfın üyesi istendiğinde TryInvokeMember
yöntemi çağrılır. binder bağımsız değişkeni, başvurulan üye hakkında bilgi içerir ve result bağımsız
değişkeni belirtilen üye için döndürülen sonuca başvurur. args bağımsız değişkeni, üyeye geçirilen
bağımsız değişkenlerin bir dizisini içerir. TryInvokeMember yöntemi, istenen üye varsa true döndüren bir
Boolean değer döndürür; Aksi takdirde false döndürür.
TryInvokeMember yönteminin özel sürümü, ilk bağımsız değişkenin önceki adımda tanımladığınız
StringSearchOption numaralandırmasından bir değer olmasını bekler. TryInvokeMember yöntemi ikinci
bağımsız değişkenin bir Boole değeri olmasını bekler. Bağımsız değişkenlerden biri veya her ikisi de geçerli
değerlerdir, sonuçları almak için GetPropertyValue yöntemine geçirilir.

// Implement the TryInvokeMember method of the DynamicObject class for


// dynamic member calls that have arguments.
public override bool TryInvokeMember(InvokeMemberBinder binder,
object[] args,
out object result)
{
StringSearchOption StringSearchOption = StringSearchOption.StartsWith;
bool trimSpaces = true;

try
{
if (args.Length > 0) { StringSearchOption = (StringSearchOption)args[0]; }
}
catch
{
throw new ArgumentException("StringSearchOption argument must be a StringSearchOption enum
value.");
}

try
{
if (args.Length > 1) { trimSpaces = (bool)args[1]; }
}
catch
{
throw new ArgumentException("trimSpaces argument must be a Boolean value.");
}

result = GetPropertyValue(binder.Name, StringSearchOption, trimSpaces);

return result == null ? false : true;


}
' Implement the TryInvokeMember method of the DynamicObject class for
' dynamic member calls that have arguments.
Public Overrides Function TryInvokeMember(ByVal binder As InvokeMemberBinder,
ByVal args() As Object,
ByRef result As Object) As Boolean

Dim StringSearchOption As StringSearchOption = StringSearchOption.StartsWith


Dim trimSpaces = True

Try
If args.Length > 0 Then StringSearchOption = CType(args(0), StringSearchOption)
Catch
Throw New ArgumentException("StringSearchOption argument must be a StringSearchOption enum
value.")
End Try

Try
If args.Length > 1 Then trimSpaces = CType(args(1), Boolean)
Catch
Throw New ArgumentException("trimSpaces argument must be a Boolean value.")
End Try

result = GetPropertyValue(binder.Name, StringSearchOption, trimSpaces)

Return If(result Is Nothing, False, True)


End Function

12. Dosyayı kaydedin ve kapatın.


Örnek metin dosyası oluşturmak için
1. DynamicSample projesine sağ tıklayın ve Ekle' nin üzerine gelin ve ardından Yeni öğe' ye tıklayın. Yüklü
şablonlar bölmesinde, genel' i seçin ve sonra metin dosyası şablonunu seçin. Ad kutusunda TextFile1. txt
varsayılan adını bırakın ve Ekle' ye tıklayın. Projeye yeni bir metin dosyası eklenir.
2. Aşağıdaki metni TextFile1. txt dosyasına kopyalayın.

List of customers and suppliers

Supplier: Lucerne Publishing (https://www.lucernepublishing.com/)


Customer: Preston, Chris
Customer: Hines, Patrick
Customer: Cameron, Maria
Supplier: Graphic Design Institute (https://www.graphicdesigninstitute.com/)
Supplier: Fabrikam, Inc. (https://www.fabrikam.com/)
Customer: Seubert, Roxanne
Supplier: Proseware, Inc. (http://www.proseware.com/)
Customer: Adolphi, Stephan
Customer: Koch, Paul

3. Dosyayı kaydedin ve kapatın.


Özel dinamik nesneyi kullanan bir örnek uygulama oluşturmak için
1. Çözüm Gezgini, Visual C#kullanıyorsanız Visual Basic veya program.cs dosyasını kullanıyorsanız
Module1. vb dosyasını çift tıklayın.
2. TextFile1. txt dosyasının ReadOnlyFile sınıfının bir örneğini oluşturmak için aşağıdaki kodu ana yordama
ekleyin. Kod, dinamik üyeleri çağırmak ve "Customer" dizesini içeren metnin satırlarını almak için geç
bağlamayı kullanır.
dynamic rFile = new ReadOnlyFile(@"..\..\TextFile1.txt");
foreach (string line in rFile.Customer)
{
Console.WriteLine(line);
}
Console.WriteLine("----------------------------");
foreach (string line in rFile.Customer(StringSearchOption.Contains, true))
{
Console.WriteLine(line);
}

Dim rFile As Object = New ReadOnlyFile("..\..\TextFile1.txt")


For Each line In rFile.Customer
Console.WriteLine(line)
Next
Console.WriteLine("----------------------------")
For Each line In rFile.Customer(StringSearchOption.Contains, True)
Console.WriteLine(line)
Next

3. Dosyayı kaydedin ve uygulamayı derlemek ve çalıştırmak için CTRL + F5 tuşlarına basın.

Dinamik dil kitaplığı çağırma


Bu kılavuzda oluşturduğunuz sonraki proje, IronPython dinamik dilinde yazılmış bir kitaplığa erişir.
Özel bir dinamik sınıf oluşturmak için
1. Visual Studio 'da, Dosya menüsünde, Yeni ' nin üzerine gelin ve ardından Proje' ye tıklayın.
2. Yeni proje iletişim kutusunda, Proje türleri bölmesinde Windows ' un seçili olduğundan emin olun.
Şablonlar bölmesinde konsol uygulaması ' nı seçin. Ad kutusuna DynamicIronPythonSample yazın ve
ardından Tamam' a tıklayın. Yeni proje oluşturulur.
3. Visual Basic kullanıyorsanız, DynamicIronPythonSample projesine sağ tıklayın ve ardından Özellikler' e
tıklayın. Başvurular sekmesine tıklayın. Ekle düğmesine tıklayın. Görsel C#kullanıyorsanız, Çözüm
Gezgini' de Başvurular klasörüne sağ tıklayın ve ardından Başvuru Ekle' ye tıklayın.
4. Araştır sekmesinde, IronPython kitaplıklarının yüklendiği klasöre gidin. Örneğin, .NET 4,0 için C:\Program
Files\ıronpython 2,6. IronPython. dll, IronPython. Modules. dll, Microsoft. Scripting. dllve Microsoft.
Dynamic. dll kitaplıklarını seçin. Tamam'a tıklayın.
5. Visual Basic kullanıyorsanız, Module1. vb dosyasını düzenleyin. Görsel C#kullanıyorsanız, program.cs
dosyasını düzenleyin.
6. Dosyanın en üstüne, Microsoft.Scripting.Hosting ve IronPython.Hosting ad alanlarını IronPython
kitaplıklarından içeri aktarmak için aşağıdaki kodu ekleyin.

using Microsoft.Scripting.Hosting;
using IronPython.Hosting;

Imports Microsoft.Scripting.Hosting
Imports IronPython.Hosting

7. Ana yöntemde, IronPython kitaplıklarını barındırmak üzere yeni bir


Microsoft.Scripting.Hosting.ScriptRuntime nesnesi oluşturmak için aşağıdaki kodu ekleyin. ScriptRuntime
nesnesi IronPython kitaplığı modülünü random.py yükler.
// Set the current directory to the IronPython libraries.
System.IO.Directory.SetCurrentDirectory(
Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) +
@"\IronPython 2.6 for .NET 4.0\Lib");

// Create an instance of the random.py IronPython library.


Console.WriteLine("Loading random.py");
ScriptRuntime py = Python.CreateRuntime();
dynamic random = py.UseFile("random.py");
Console.WriteLine("random.py loaded.");

' Set the current directory to the IronPython libraries.


My.Computer.FileSystem.CurrentDirectory =
My.Computer.FileSystem.SpecialDirectories.ProgramFiles &
"\IronPython 2.6 for .NET 4.0\Lib"

' Create an instance of the random.py IronPython library.


Console.WriteLine("Loading random.py")
Dim py = Python.CreateRuntime()
Dim random As Object = py.UseFile("random.py")
Console.WriteLine("random.py loaded.")

8. Random.py modülünü yüklemeye yönelik koddan sonra, bir tamsayılar dizisi oluşturmak için aşağıdaki
kodu ekleyin. Dizi, dizideki değerleri rastgele sıralayan random.py modülünün shuffle yöntemine geçirilir.

// Initialize an enumerable set of integers.


int[] items = Enumerable.Range(1, 7).ToArray();

// Randomly shuffle the array of integers by using IronPython.


for (int i = 0; i < 5; i++)
{
random.shuffle(items);
foreach (int item in items)
{
Console.WriteLine(item);
}
Console.WriteLine("-------------------");
}

' Initialize an enumerable set of integers.


Dim items = Enumerable.Range(1, 7).ToArray()

' Randomly shuffle the array of integers by using IronPython.


For i = 0 To 4
random.shuffle(items)
For Each item In items
Console.WriteLine(item)
Next
Console.WriteLine("-------------------")
Next

9. Dosyayı kaydedin ve uygulamayı derlemek ve çalıştırmak için CTRL + F5 tuşlarına basın.

Ayrıca bkz.
System.Dynamic
System.Dynamic.DynamicObject
Tür dinamiği kullanma
Erken ve Geç Bağlama
dynamic
Dinamik arabirimleri uygulama (Microsoft TechNet 'ten indirilebilir PDF )
Sınıflar ve Yapılar (C# Programlama Kılavuzu)
23.10.2019 • 10 minutes to read • Edit Online

Sınıflar ve yapılar, .NET Framework ortak tür sisteminin temel yapılarıdır. Her biri, mantıksal birim olarak
birbirine ait bir veri kümesini ve davranışları kapsülleyen bir veri yapısıdır. Veri ve davranışlar, sınıfın veya
yapının üyeleridir ve bu konuda daha sonra listelendiği gibi yöntemleri, özellikleri ve olayları gibi, vb. içerir.
Sınıf veya yapı bildirimi, çalışma zamanında örnek veya nesne oluşturmak için kullanılan bir şema gibidir. Adlı
Person bir sınıf veya yapı tanımlarsanız, Person türün adıdır. p Person Türünde
birdeğişkenbildirirsenizvebaşladıysanızbirnesneveyaörneğiolarakifadeedilir. Person p Aynı Person türde
birden çok örnek oluşturulabilir ve her bir örnek, özelliklerinde ve alanlarında farklı değerlere sahip olabilir.
Sınıf bir başvuru türüdür. Sınıfın bir nesnesi oluşturulduğunda, nesnenin atandığı değişken yalnızca o belleğe
yönelik bir başvuru barındırır. Nesne başvurusu yeni bir değişkene atandığında, yeni değişken özgün nesneye
başvurur. Her ikisi de aynı verilere başvurduğundan, bir değişken aracılığıyla yapılan değişiklikler diğer
değişkene yansıtılır.
Struct bir değer türüdür. Bir struct oluşturulduğunda, yapının atandığı değişken yapının gerçek verilerini
barındırır. Yapı yeni bir değişkene atandığında, kopyalanır. Bu nedenle, yeni değişken ve özgün değişken aynı
verilerin iki ayrı kopyasını içerir. Bir kopyada yapılan değişiklikler diğer kopyayı etkilemez.
Genel olarak, sınıflar daha karmaşık davranışı modellemek veya bir sınıf nesnesi oluşturulduktan sonra
değiştirilmesi amaçlanan veriler için kullanılır. Yapılar, öncelikle yapı oluşturulduktan sonra değiştirilmesi
amaçlanmayan verileri içeren küçük veri yapıları için idealdir.
Daha fazla bilgi için bkz. sınıflar, nesnelerve yapılar.

Örnek
Aşağıdaki CustomClass örnekte, ProgrammingGuide ad alanındaki üç üye vardır: örnek Oluşturucu, adlı
Number bir özellik ve adlı Multiply bir yöntem. Sınıfındaki yöntemi ,bir CustomClass örneği (nesne) oluşturur
ve nesnenin yöntemi ile özelliğine nokta gösterimi kullanılarak erişilir. Main Program
using System;

namespace ProgrammingGuide
{
// Class definition.
public class CustomClass
{
// Class members.
//
// Property.
public int Number { get; set; }

// Method.
public int Multiply(int num)
{
return num * Number;
}

// Instance Constructor.
public CustomClass()
{
Number = 0;
}
}

// Another class definition that contains Main, the program entry point.
class Program
{
static void Main(string[] args)
{
// Create an object of type CustomClass.
CustomClass custClass = new CustomClass();

// Set the value of the public property.


custClass.Number = 27;

// Call the public method.


int result = custClass.Multiply(4);
Console.WriteLine($"The result is {result}.");
}
}
}
// The example displays the following output:
// The result is 108.

Kapsül
Kapsülleme bazen nesne odaklı programlamanın ilk ve prensibi olarak adlandırılır. Kapsülleme ilkelerine göre,
bir sınıf veya yapı, üyelerinin her birinin ne şekilde erişilebilir olduğunu belirtebilir sınıfın veya yapının dışında
kod alma. Sınıf veya derleme dışından kullanılması amaçlanmayan Yöntemler ve değişkenler, kodlama
hataları veya kötü amaçlı yazılımlar için potansiyelini sınırlamak üzere gizlenebilir.
Sınıflar hakkında daha fazla bilgi için bkz. sınıflar ve nesneler.
Üyeler
Tüm Yöntemler, alanlar, sabitler, Özellikler ve olaylar bir tür içinde bildirilmelidir; Bunlara tür üyeleri denir.
İçinde C#, bazı dillerde olduğu gibi genel değişkenler veya yöntemler yoktur. Bir programın giriş noktası
Main bile, yöntemi bir sınıf veya yapı içinde bildirilmelidir. Aşağıdaki liste, bir sınıfta veya yapıda
bildirilebilecek çeşitli üye türlerini içerir.
Alanlar
Sabitler
Özellikler
Yöntemler
Oluşturucular
Olaylar
Sonlandırıcılar
Dizin Oluşturucular
İşleçler
İç içe Geçmiş Türler
Erişilebilirlik
Bazı yöntemler ve özellikler, sınıf veya yapı birimi dışında, istemci koduolarak bilinen koddan çağrılmalıdır
veya erişilmek üzere tasarlanmıştır. Diğer yöntemler ve özellikler yalnızca sınıfta veya yapıda kullanım için
olabilir. Yalnızca amaçlanan istemci kodunun ulaşabilmesi için kodunuzun erişilebilirliğini sınırlandırmamak
önemlidir. Türlerinizin ve üyelerinin istemci koduna ne kadar erişilebilir olduğunu, genel, korunan, dahili,
korunan iç, özel ve özel korumalıerişim değiştiricilerini kullanarak belirtirsiniz. Varsayılan Erişilebilirlik ' dir
private . Daha fazla bilgi için bkz. erişim değiştiricileri.

Devralma
Sınıflar (ancak yapılar değil) devralma kavramını destekler. Başka bir sınıftan ( temel sınıf) türetilen bir sınıf,
oluşturucular ve sonlandırıcılar hariç temel sınıfın tüm genel, korunan ve dahili üyelerini otomatik olarak
içerir. Daha fazla bilgi için bkz. Devralma ve çok biçimlilik.
Sınıflar Özetolarak, bir veya daha fazla yönteminin bir uygulama olmadığı anlamına gelir. Soyut sınıflar
doğrudan örneklenemez, ancak eksik uygulamayı sağlayan diğer sınıflar için temel sınıf olarak görev yapabilir.
Sınıflar, diğer sınıfların bunlardan devralmasını engellemek için Sealed olarak da bildirilemez. Daha fazla bilgi
için bkz. soyut ve korumalı sınıflar ve sınıf üyeleri.
Arabirimler
Sınıflar ve yapılar birden çok arabirimi kalýtýmla alabilir. Bir arabirimden devralması için, türün arabirimde
tanımlanmış tüm yöntemleri uyguladığı anlamına gelir. Daha fazla bilgi için bkz. arabirimler.
Genel Türler
Sınıflar ve yapılar, bir veya daha fazla tür parametresiyle tanımlanabilir.İstemci kodu, türün bir örneğini
oluşturduğunda türü sağlar. Örneğin List<T> , System.Collections.Generic ad alanındaki sınıfı bir tür
parametresiyle tanımlanmıştır. İstemci kodu, listenin tutacağız türü List<string> belirtmek List<int> için
bir veya örneği oluşturur. Daha fazla bilgi için bkz. Genel türler.
Statik türler
Sınıflar (ancak yapılar için değil) statikolarak bildirilemez. Statik bir sınıf yalnızca statik üyeler içerebilir ve yeni
anahtar sözcüğüyle başlatılamaz. Program yüklendiğinde sınıfın bir kopyası belleğe yüklenir ve onun
üyelerine sınıf adından erişilir. Sınıfların ve yapıların her ikisi de statik üye içerebilir. Daha fazla bilgi için bkz.
statik sınıflar ve statik sınıf üyeleri.
İç içe Geçmiş Türler
Bir sınıf veya yapı, başka bir sınıf veya yapı içinde iç içe olabilir. Daha fazla bilgi için bkz. Iç Içe türler.
Kısmi türler
Bir sınıf, yapı veya yöntemin bir parçasını bir kod dosyasında ve farklı bir kod dosyasındaki başka bir bölüme
tanımlayabilirsiniz. Daha fazla bilgi için bkz. kısmi sınıflar ve Yöntemler.
Nesne başlatıcıları
Yapıcısını açıkça çağırmadan sınıf veya yapı nesneleri ve nesne koleksiyonları oluşturabilir ve başlatabilir.
Daha fazla bilgi için bkz. nesne ve koleksiyon başlatıcıları.
Anonim Türler
Adlandırılmış bir sınıf oluşturmak için uygun veya gerekli olmadığı durumlarda (örneğin, bir listeyi kalıcı hale
getirmek veya başka bir yönteme geçirmek zorunda değilsiniz veri yapıları içeren bir liste doldururken),
anonim türler kullanırsınız. Daha fazla bilgi için bkz. anonim türler.
Genişletme Yöntemleri
Metotları özgün türe ait gibi çağrılabilecek ayrı bir tür oluşturarak, türetilmiş sınıf oluşturmadan bir sınıfı
"genişletebilirsiniz". Daha fazla bilgi için bkz. Uzantı yöntemleri.
Örtülü Olarak Yazılan Yerel Değişkenler
Bir sınıf veya yapı yönteminde, derleyicinin derleme zamanında doğru türü belirlemesini söylemek için örtük
yazma kullanabilirsiniz. Daha fazla bilgi için bkz. örtülü olarak yazılan yerel değişkenler.

C# Dil Belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
C# Programlama Kılavuzu
Sınıflar (C# Programlama Kılavuzu)
23.10.2019 • 8 minutes to read • Edit Online

Başvuru türleri
Sınıf olarak tanımlanan bir tür, başvuru türüdür. Çalışma zamanında, bir başvuru türünde bir değişken
bildirdiğinizde, New işlecini kullanarak sınıfın bir örneğini açıkça oluşturana veya onu oluşturulmuş bir
uyumlu türdeki nesne atayan sürece değişken null değerini içerir diğer bir yerde, aşağıdaki örnekte
gösterildiği gibi:

//Declaring an object of type MyClass.


MyClass mc = new MyClass();

//Declaring another object of the same type, assigning it the value of the first object.
MyClass mc2 = mc;

Nesne oluşturulduğunda, söz konusu nesne için yönetilen yığında yeterli bellek ayrılır ve değişken yalnızca
belirtilen nesnenin konumuna bir başvuru içerir. Yönetilen yığında bulunan türler, her ikisi de ayrıldıklarında ve
çöp toplamaolarak bilinen clr 'nin otomatik bellek yönetimi işlevselliği tarafından geri kazanıyorsa ek yük
gerektirir. Ancak çöp toplama da yüksek oranda iyileştirilmiştir ve çoğu senaryoda bir performans sorunu
oluşturmaz. Çöp toplama hakkında daha fazla bilgi için bkz. Otomatik bellek yönetimi ve çöp toplama.

Sınıfları Bildirme
Sınıflar, aşağıdaki örnekte gösterildiği gibi, Class anahtar sözcüğü ve ardından benzersiz bir tanımlayıcı
kullanılarak bildirilenler:

//[access modifier] - [class] - [identifier]


public class Customer
{
// Fields, properties, methods and events go here...
}

class Anahtar sözcüğü öncesinde erişim düzeyidir. Bu durumda genel kullanıldığından, herkes bu sınıfın
örneklerini oluşturabilir. Sınıfın adı class anahtar sözcüğünü izler. Sınıfın adı geçerli C# bir tanımlayıcı
adıolmalıdır. Tanımın geri kalanı, davranışın ve verilerin tanımlandığı sınıf gövdesidir. Bir sınıftaki alanlar,
özellikler, Yöntemler ve olaylar topluca sınıf üyeleriolarak adlandırılır.

Nesneler oluşturma
Bazen birbirinin yerine kullanıldıkları halde bir sınıf ve bir nesne farklı şeylerdir. Bir sınıf nesne türünü tanımlar,
ancak nesnenin kendisi değildir. Bir nesne, bir sınıfı temel alan somut bir varlıktır ve bazen bir sınıfın örneği
olarak adlandırılır.
Nesneler Yeni anahtar sözcüğü kullanılarak, ardından nesnenin temel aldığı sınıfın adı tarafından
oluşturulabilir ve şöyle olur:

Customer object1 = new Customer();

Bir sınıfın bir örneği oluşturulduğunda, nesnesine bir başvuru, programcıya geri geçirilir. Önceki örnekte,
object1 temel alan Customer bir nesnesine başvurudur. Bu başvuru yeni nesneye başvurur ancak nesne
verilerinin kendisini içermez. Aslında, herhangi bir nesne oluşturmadan bir nesne başvurusu oluşturabilirsiniz:

Customer object2;

Bir nesneye başvurmayan bu gibi nesne başvuruları oluşturmanızı önermeyiz, çünkü bu başvuru, bu tür bir
başvuruya erişim denemesi çalışma zamanında başarısız olur. Ancak, bu tür bir başvuru, yeni bir nesne
oluşturarak ya da bunun gibi var olan bir nesneye atanarak bir nesneye başvurmak için kullanılabilir:

Customer object3 = new Customer();


Customer object4 = object3;

Bu kod, her ikisi de aynı nesneye başvuran iki nesne başvurusu oluşturur. Bu nedenle, nesne üzerinde yapılan
object3 tüm değişiklikler sonraki object4 kullanımlarda yansıtılır. Sınıfları temel alan nesneler başvuruya
göre başvurulduğu için sınıflar başvuru türleri olarak bilinir.

Sınıf devralma
Sınıflar, nesne odaklı programlamanın temel bir özelliği olan devralmayıtamamen destekler. Bir sınıf
oluşturduğunuzda, korumalıolarak tanımlanmayan diğer bir arabirim veya sınıftan kalıtımla alabilir ve diğer
sınıflar sınıfınızdan devralınabilir ve sınıf sanal yöntemlerini geçersiz kılabilir.
Devralma bir türetmekullanılarak gerçekleştirilir. Bu, bir sınıfın veri ve davranış devraldığı temel sınıf
kullanılarak bildirildiği anlamına gelir. Bir temel sınıf, bir iki nokta üst üste eklenerek ve türetilmiş sınıf adından
sonra temel sınıfın adı aşağıdaki gibi olarak belirtilir:

public class Manager : Employee


{
// Employee fields, properties, methods and events are inherited
// New Manager fields, properties, methods and events go here...
}

Bir sınıf bir temel sınıf bildiriyorsa, oluşturucular hariç, taban sınıfın tüm üyelerini devralır. Daha fazla bilgi için
bkz. Devralma.
Aksine C++, içindeki C# bir sınıf yalnızca bir temel sınıftan doğrudan devralınabilir. Ancak, bir temel sınıfın
kendisi başka bir sınıftan devraldığı için, bir sınıf dolaylı olarak birden fazla temel sınıfı devralınabilir. Ayrıca, bir
sınıf doğrudan birden fazla arabirim uygulayabilir. Daha fazla bilgi için bkz. arabirimler.
Bir sınıf, soyutolarak bildirilemez. Soyut bir sınıf imza tanımına sahip ancak uygulamaya sahip olmayan soyut
yöntemler içerir. Soyut sınıfların örneği oluşturulamıyor. Yalnızca soyut yöntemleri uygulayan türetilmiş sınıflar
aracılığıyla kullanılabilir. Buna karşılık, korumalı bir sınıf diğer sınıfların bundan türemesine izin vermez. Daha
fazla bilgi için bkz. soyut ve korumalı sınıflar ve sınıf üyeleri.
Sınıf tanımları, farklı kaynak dosyalar arasında bölünebilir. Daha fazla bilgi için bkz. kısmi sınıflar ve Yöntemler.

Örnek
Aşağıdaki örnek, bir Otomatik uygulanan özellik, bir yöntem ve Oluşturucu olarak adlandırılan özel bir
yöntem içeren bir ortak sınıf tanımlar. Daha fazla bilgi için bkz. Özellikler, Yöntemlerve oluşturucular konuları.
Daha sonra sınıfının örnekleri new anahtar sözcüğüyle oluşturulur.
using System;

public class Person


{
// Constructor that takes no arguments:
public Person()
{
Name = "unknown";
}

// Constructor that takes one argument:


public Person(string name)
{
Name = name;
}

// Auto-implemented readonly property:


public string Name { get; }

// Method that overrides the base class (System.Object) implementation.


public override string ToString()
{
return Name;
}
}
class TestPerson
{
static void Main()
{
// Call the constructor that has no parameters.
var person1 = new Person();
Console.WriteLine(person1.Name);

// Call the constructor that has one parameter.


var person2 = new Person("Sarah Jones");
Console.WriteLine(person2.Name);
// Get the string representation of the person2 instance.
Console.WriteLine(person2);

Console.WriteLine("Press any key to exit.");


Console.ReadKey();
}
}
// Output:
// unknown
// Sarah Jones
// Sarah Jones

C# Dil Belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
C# Programlama Kılavuzu
Nesne Odaklı Programlama
Çok biçimlilik
Tanımlayıcı adları
Üyeler
Yöntemler
Oluşturucular
Sonlandırıcılar
Nesneler
Nesneler (C# Programlama Kılavuzu)
4.11.2019 • 8 minutes to read • Edit Online

Sınıf veya yapı tanımı, türün ne yapabileceğini belirten bir şema gibidir. Bir nesne temelde, Blueprint 'e göre
ayrılan ve yapılandırılan bir bellek bloğudur. Bir program aynı sınıftan birçok nesne oluşturabilir. Nesneler de
örnekler olarak adlandırılır ve adlandırılmış bir değişkende veya bir dizi ya da koleksiyonda depolanabilir. İstemci
kodu, yöntemleri çağırmak ve nesnenin ortak özelliklerine erişmek için bu değişkenleri kullanan koddur. Gibi
nesne yönelimli bir dilde C#, tipik bir program dinamik olarak etkileşimde bulunan birden çok nesneden oluşur.

NOTE
Statik türler burada açıklananla farklı davranır. Daha fazla bilgi için bkz. statik sınıflar ve statik sınıf üyeleri.

Struct örnekleri ve sınıf örnekleri


Sınıflar başvuru türleri olduğundan, sınıf nesnesinin bir değişkeni yönetilen yığında nesnenin adresine bir
başvuru içerir. Aynı türde ikinci bir nesne ilk nesnesine atanırsa, her iki değişken de o adresteki nesneye başvurur.
Bu nokta, bu konunun ilerleyen kısımlarında daha ayrıntılı bir şekilde ele alınmıştır.
Sınıfların örnekleri, New işlecikullanılarak oluşturulur. Aşağıdaki örnekte, Person tür ve person1 ve bu türdeki
person 2 örnekler ya da nesnelerdir.
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public Person(string name, int age)
{
Name = name;
Age = age;
}
// Other properties, methods, events...
}

class Program
{
static void Main()
{
Person person1 = new Person("Leopold", 6);
Console.WriteLine("person1 Name = {0} Age = {1}", person1.Name, person1.Age);

// Declare new person, assign person1 to it.


Person person2 = person1;

// Change the name of person2, and person1 also changes.


person2.Name = "Molly";
person2.Age = 16;

Console.WriteLine("person2 Name = {0} Age = {1}", person2.Name, person2.Age);


Console.WriteLine("person1 Name = {0} Age = {1}", person1.Name, person1.Age);

// Keep the console open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();

}
}
/*
Output:
person1 Name = Leopold Age = 6
person2 Name = Molly Age = 16
person1 Name = Molly Age = 16
*/

Yapılar değer türleri olduğundan, bir struct nesnesinin değişkeni tüm nesnenin bir kopyasını tutar. Yapı örnekleri,
new işleci kullanılarak da oluşturulabilir, ancak aşağıdaki örnekte gösterildiği gibi bu gerekli değildir:
public struct Person
{
public string Name;
public int Age;
public Person(string name, int age)
{
Name = name;
Age = age;
}
}

public class Application


{
static void Main()
{
// Create struct instance and initialize by using "new".
// Memory is allocated on thread stack.
Person p1 = new Person("Alex", 9);
Console.WriteLine("p1 Name = {0} Age = {1}", p1.Name, p1.Age);

// Create new struct object. Note that struct can be initialized


// without using "new".
Person p2 = p1;

// Assign values to p2 members.


p2.Name = "Spencer";
p2.Age = 7;
Console.WriteLine("p2 Name = {0} Age = {1}", p2.Name, p2.Age);

// p1 values remain unchanged because p2 is copy.


Console.WriteLine("p1 Name = {0} Age = {1}", p1.Name, p1.Age);

// Keep the console open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/*
Output:
p1 Name = Alex Age = 9
p2 Name = Spencer Age = 7
p1 Name = Alex Age = 9
*/

Hem p1 hem de p2 için bellek, iş parçacığı yığınında ayrılır. Bu bellek, bildirildiği tür veya yöntem ile birlikte
geri kazanılır. Bu, yapıların atama sırasında kopyalanmasının bir nedenidir. Buna karşılık, bir sınıf örneği için
ayrılan bellek, nesneye yapılan tüm başvurular kapsam dışına çıkış yaparken ortak dil çalışma zamanı tarafından
otomatik olarak geri kazanılır (çöp toplamıştır). İçinde C++yaptığınız gibi bir sınıf nesnesini kesin şekilde yok
etmek mümkün değildir. .NET Framework çöp toplama hakkında daha fazla bilgi için bkz. çöp toplama.

NOTE
Yönetilen yığında bellek ayırma ve ayırmayı kaldırma işlemi, ortak dil çalışma zamanında son derece iyileştirilmiştir. Çoğu
durumda, yığında bir sınıf örneği ayırmanın performans maliyetinde önemli bir fark yoktur.

Nesne kimliği ve değer eşitlik karşılaştırması


İki nesneyi eşitlik için karşılaştırdığınızda, ilk olarak iki değişkenin bellekte aynı nesneyi temsil ettiğini veya bir ya
da daha fazla alanının değerlerinin eşdeğer olup olmadığını ayırt etmeniz gerekir. Değerleri karşılaştırmak
istiyorsanız, nesnelerin değer türleri (yapılar) veya başvuru türleri (sınıflar, temsilciler, diziler) örnekleri olup
olmadığını göz önünde bulundurmanız gerekir.
İki sınıf örneğinin bellekteki aynı konuma (aynı kimliğesahip oldukları anlamına gelir) başvuruda bulunup
bulunmadığını anlamak için, statik Equals yöntemini kullanın. (System.Object, Kullanıcı tanımlı yapılar ve
sınıflar da dahil olmak üzere tüm değer türleri ve başvuru türleri için örtülü temel sınıftır.)
İki yapı örneğindeki örnek alanlarının aynı değerlere sahip olup olmadığını anlamak için ValueType.Equals
yöntemini kullanın. Tüm yapılar System.ValueTypeörtük olarak devraldığı için, aşağıdaki örnekte
gösterildiği gibi yöntemi doğrudan nesneniz üzerinde çağırın:

// Person is defined in the previous example.

//public struct Person


//{
// public string Name;
// public int Age;
// public Person(string name, int age)
// {
// Name = name;
// Age = age;
// }
//}

Person p1 = new Person("Wallace", 75);


Person p2;
p2.Name = "Wallace";
p2.Age = 75;

if (p2.Equals(p1))
Console.WriteLine("p2 and p1 have the same values.");

// Output: p2 and p1 have the same values.

Equals System.ValueType uygulanması, alanların herhangi bir yapıda olduğunu belirleyebilmesi gerektiği için
yansıma kullanır. Kendi yapı birimlerinizi oluştururken, türüne özgü etkili bir eşitlik algoritması sağlamak için
Equals yöntemini geçersiz kılın.

İki sınıf örneklerindeki alanların değerlerinin eşit olup olmadığını anlamak için Equals yöntemini veya = =
işlecinikullanabilirsiniz. Ancak, yalnızca sınıf geçersiz kılınmışsa veya bu tür nesneler için "eşitlik" anlamına
gelen özel bir tanım sağlamak için bunları aşırı yüklediyseniz kullanın. Sınıfı, IEquatable<T> arabirimini veya
IEqualityComparer<T> arabirimini de uygulayabilir. Her iki arabirim de değer eşitliğini test etmek için
kullanılabilecek yöntemler sağlar. Equals geçersiz kılan kendi sınıflarınızı tasarlarken, nasıl yapılır: tür Için
değer eşitliği tanımlama ve Object.Equals(Object)için belirtilen yönergeleri izlediğinizden emin olun.

İlgili Bölümler
Daha fazla bilgi için:
Sınıflar
Yapılar
Oluşturucular
Sonlandırıcılar
Olaylar

Ayrıca bkz.
C# Programlama Kılavuzu
object
Devralma
class
struct
new İşleci
Ortak Tür Sistemi
Yapılar (C# Programlama Kılavuzu)
25.11.2019 • 2 minutes to read • Edit Online

Yapılar struct anahtar sözcüğü kullanılarak tanımlanır, örneğin:

public struct PostalAddress


{
// Fields, properties, methods and events go here...
}

Yapılar, aynı sözdiziminin büyük bir kısmını sınıflarla paylaşır. Yapının adı geçerli C# bir tanımlayıcı adıolmalıdır.
Yapılar aşağıdaki yollarla sınıflardan daha sınırlıdır:
Bir struct bildiriminde, alanlar const veya static olarak bildirilmeyen sürece başlatılamaz.
Struct parametresiz bir Oluşturucu (parametresiz bir Oluşturucu) veya sonlandırıcısı bildiremez.
Yapılar atamaya kopyalanır. Bir yapı yeni bir değişkene atandığında, tüm veriler kopyalanır ve yeni kopyada
yapılan değişiklikler özgün kopyanın verilerini değiştirmez. Bu, Dictionary<string, myStruct> gibi değer
türlerinin koleksiyonlarıyla çalışırken unutmamak önemlidir.
Yapılar, başvuru türleri olan sınıfların aksine değer türlerdir.
Sınıfların aksine, yapılar new işleci kullanılmadan oluşturulabilir.
Yapılar, parametreleri olan oluşturucular bildirebilir.
Yapı, başka bir struct veya sınıftan devralınabilir ve bir sınıfın temeli olamaz. Tüm yapılar, Objectdevralan
ValueTypedoğrudan devralır.
Bir struct, arabirimler uygulayabilir.
Bir struct null olamaz ve değişken null değer türü olarak bildirildiği sürece bir struct değişkeni null
atanamaz.

Ayrıca bkz.
C# Programlama Kılavuzu
Sınıflar ve Yapılar
Sınıflar
Null yapılabilir değer türleri
Tanımlayıcı adları
Yapıları Kullanma
Bir struct geçirme ve bir yönteme sınıf başvurusu geçirme arasındaki farkı nasıl anlarsınız
Yapıları kullanma (C# Programlama Kılavuzu)
27.11.2019 • 5 minutes to read • Edit Online

struct türü Point , Rectangle ve Color gibi hafif nesneleri temsil etmek için uygundur. Bir noktayı Otomatik
uygulanmış özelliklerlebir sınıf olarak temsil etmek uygun olsa da, bazı senaryolarda bir Yapı daha verimli olabilir.
Örneğin, 1000 Point nesnelerden oluşan bir dizi bildirirseniz, her bir nesneye başvurmak için ek bellek
ayırabilirsiniz; Bu durumda, bir yapı daha pahalı olur. .NET zaten Pointadlı bir nesne içerdiğinden, bu örnekteki
yapı bunun yerine Coords olarak adlandırılmıştır.

public struct Coords


{
public int x, y;

public Coords(int p1, int p2)


{
x = p1;
y = p2;
}
}

Bir struct için parametresiz bir Oluşturucu tanımlamak hatadır. Bir yapı gövdesinde örnek alanı başlatmak da bir
hatadır. Yalnızca parametreli bir oluşturucuyu, örtük, parametresiz oluşturucuyu, nesne başlatıcısınıkullanarak veya
yapı oluşturulduktan sonra üyelere ayrı ayrı erişerek, dışarıdan erişilebilen yapı üyelerini başlatabilirsiniz.
Herhangi bir özel veya başka şekilde erişilemeyen üye, oluşturucuların yalnızca kullanımını gerektirir.
New işlecini kullanarak bir struct nesnesi oluşturduğunuzda, oluşturulur ve uygun Oluşturucu oluşturucunun
imzasınagöre çağırılır. Sınıfların aksine, yapılar new işleci kullanılmadan örneklenebilir. Böyle bir durumda, bir
Oluşturucu çağrısı yoktur ve bu da ayırmayı daha verimli hale getirir. Ancak alanlar atanmamış olarak kalır ve tüm
alanlar başlatılana kadar nesne kullanılamaz. Bu, özellikler aracılığıyla değerleri almak veya ayarlamak için bir
değer içerir.
Parametresiz oluşturucuyu kullanarak bir yapı nesnesi örneği oluşturursanız, tüm Üyeler varsayılan
değerlerinegöre atanır.
Bir yapı için parametrelere sahip bir Oluşturucu yazarken, tüm üyeleri açık olarak başlatmalısınız; Aksi takdirde bir
veya daha fazla üye atanmamış olarak kalır ve yapı birimi CS0171, derleyici hatası üretirken kullanılamaz.
Sınıflar için olduğu gibi yapılar için devralma yoktur. Yapı, başka bir struct veya sınıftan devralınabilir ve bir sınıfın
temeli olamaz. Ancak yapılar, temel sınıftan devralınır Object. Bir struct, arabirimler uygulayabilir ve tam olarak
sınıfların yaptığı şekilde yapılır.
Anahtar sözcüğünü kullanarak bir sınıf bildiremezsiniz struct . İçinde C#, sınıflar ve yapılar anlamsal olarak
farklıdır. Yapı bir değer türüdür, ancak bir sınıf bir başvuru türüdür.Daha fazla bilgi için bkz. değer türleri ve
başvuru türleri.
Başvuru türü semantiklerine ihtiyacınız yoksa, bunun yerine bir yapı olarak bildirirseniz küçük bir sınıf sistem
tarafından daha verimli bir şekilde işlenebilir.

Örnek 1
Bu örnekte, hem parametresiz hem de parametreli oluşturucular kullanılarak struct başlatma gösterilmektedir.
public struct Coords
{
public int x, y;

public Coords(int p1, int p2)


{
x = p1;
y = p2;
}
}

// Declare and initialize struct objects.


class TestCoords
{
static void Main()
{
// Initialize.
var coords1 = new Coords();
var coords2 = new Coords(10, 10);

// Display results.
Console.Write("Coords 1: ");
Console.WriteLine($"x = {coords1.x}, y = {coords1.y}");

Console.Write("Coords 2: ");
Console.WriteLine($"x = {coords2.x}, y = {coords2.y}");

// Keep the console window open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* Output:
Coords 1: x = 0, y = 0
Coords 2: x = 10, y = 10
*/

Örnek 2
Bu örnek, yapılar için benzersiz olan bir özelliği gösterir. new işlecini kullanmadan bir CoOrds nesnesi oluşturur.
Word struct sözcüğünü class Word ile değiştirirseniz, program derlenmez.

public struct Coords


{
public int x, y;

public Coords(int p1, int p2)


{
x = p1;
y = p2;
}
}
// Declare a struct object without "new".
class TestCoordsNoNew
{
static void Main()
{
// Declare an object.
Coords coords1;

// Initialize.
coords1.x = 10;
coords1.y = 20;

// Display results.
Console.Write("Coords 1: ");
Console.WriteLine($"x = {coords1.x}, y = {coords1.y}");

// Keep the console window open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
// Output: Coords 1: x = 10, y = 20

Ayrıca bkz.
C# Programlama Kılavuzu
Sınıflar ve Yapılar
Yapılar
Devralma (C# Programlama Kılavuzu)
23.10.2019 • 10 minutes to read • Edit Online

Kapsülleme ve çok biçimlilik ile birlikte devralma, nesne odaklı programlamanın üç birincil özelliklerinden
biridir. Devralma, diğer sınıflarda tanımlanan davranışı yeniden kullanan, genişleten ve değiştiren yeni
sınıflar oluşturmanıza olanak sağlar. Üyeleri devralınmış olan sınıfa temel sınıfdenir ve bu üyeleri devralan
sınıfa türetilmiş sınıfdenir. Türetilmiş bir sınıfın yalnızca bir doğrudan temel sınıfı olabilir. Ancak, devralma
geçişlidir. ClassC, ClassB 'den türetildiyse ve ClassB, ClassA 'dan türetilirse ClassC, ClassB ve ClassA 'da
belirtilen üyeleri devralır.

NOTE
Yapılar devralmayı desteklemez, ancak arabirimler uygulayabilir. Daha fazla bilgi için bkz. arabirimler.

Kavramsal olarak, türetilmiş bir sınıf temel sınıfın bir özelleştirmesi olur. Örneğin, bir taban sınıfınız Animal
varsa adlı bir türetilmiş sınıfa Mammal ve adında Reptile başka bir türetilmiş sınıfa sahip olabilirsiniz. , Bir,
Reptile ve bir olur ,ancakhertüretilmişsınıftemelsınıfınfarklıözelleştirmelerinitemsileder. Animal Mammal
Animal

Başka bir sınıftan türetmek için bir sınıf tanımladığınızda, türetilmiş sınıf, oluşturucular ve sonlandırıcılar
hariç, temel sınıfın tüm üyelerini dolaylı olarak kazanıyor. Türetilmiş sınıf bundan sonra kodu yeniden
uygulamak zorunda kalmadan temel sınıfta yeniden kullanabilir. Türetilmiş sınıfta daha fazla üye
ekleyebilirsiniz. Bu şekilde, türetilmiş sınıf temel sınıfın işlevselliğini genişletir.
Aşağıdaki çizimde, bazı iş sürecindeki WorkItem bir iş öğesini temsil eden bir sınıf gösterilmektedir. Tüm
sınıflar gibi, öğesinden System.Object türetilir ve tüm yöntemlerini devralır. WorkItem kendisine ait beş
üyeyi ekler. Bunlar bir Oluşturucu içerir, çünkü oluşturucular devralınmaz. Sınıf ChangeRequest öğesinden
WorkItem devralır ve belirli bir iş öğesi türünü temsil eder. ChangeRequest devralınan WorkItem üyelere ve
kaynağından Objectdaha fazla üye ekler. Kendi oluşturucusunu eklemesi ve ayrıca eklemesi
originalItemID gerekir. Özelliği originalItemID , ChangeRequest Örneğin değişiklik isteğinin uygulandığı
orijinalle WorkItem ilişkilendirilmesini sağlar.

Aşağıdaki örnek, önceki çizimde gösterilen sınıf ilişkilerinin ' de C#nasıl ifade edildiği gösterilmektedir.
WorkItem Örnek ayrıca sanal yöntemin Object.ToStringnasıl geçersiz kılındığını ve ChangeRequest sınıfın
yöntem WorkItem uygulamasını nasıl devraldığını gösterir.
// WorkItem implicitly inherits from the Object class.
public class WorkItem
{
// Static field currentID stores the job ID of the last WorkItem that
// has been created.
private static int currentID;

//Properties.
protected int ID { get; set; }
protected string Title { get; set; }
protected string Description { get; set; }
protected TimeSpan jobLength { get; set; }

// Default constructor. If a derived class does not invoke a base-


// class constructor explicitly, the default constructor is called
// implicitly.
public WorkItem()
{
ID = 0;
Title = "Default title";
Description = "Default description.";
jobLength = new TimeSpan();
}

// Instance constructor that has three parameters.


public WorkItem(string title, string desc, TimeSpan joblen)
{
this.ID = GetNextID();
this.Title = title;
this.Description = desc;
this.jobLength = joblen;
}

// Static constructor to initialize the static member, currentID. This


// constructor is called one time, automatically, before any instance
// of WorkItem or ChangeRequest is created, or currentID is referenced.
static WorkItem()
{
currentID = 0;
}

protected int GetNextID()


{
// currentID is a static field. It is incremented each time a new
// instance of WorkItem is created.
return ++currentID;
}

// Method Update enables you to update the title and job length of an
// existing WorkItem object.
public void Update(string title, TimeSpan joblen)
{
this.Title = title;
this.jobLength = joblen;
}

// Virtual method override of the ToString method that is inherited


// from System.Object.
public override string ToString()
{
return $"{this.ID} - {this.Title}";
}
}

// ChangeRequest derives from WorkItem and adds a property (originalItemID)


// and two constructors.
public class ChangeRequest : WorkItem
{
{
protected int originalItemID { get; set; }

// Constructors. Because neither constructor calls a base-class


// constructor explicitly, the default constructor in the base class
// is called implicitly. The base class must contain a default
// constructor.

// Default constructor for the derived class.


public ChangeRequest() { }

// Instance constructor that has four parameters.


public ChangeRequest(string title, string desc, TimeSpan jobLen,
int originalID)
{
// The following properties and the GetNexID method are inherited
// from WorkItem.
this.ID = GetNextID();
this.Title = title;
this.Description = desc;
this.jobLength = jobLen;

// Property originalItemId is a member of ChangeRequest, but not


// of WorkItem.
this.originalItemID = originalID;
}
}

class Program
{
static void Main()
{
// Create an instance of WorkItem by using the constructor in the
// base class that takes three arguments.
WorkItem item = new WorkItem("Fix Bugs",
"Fix all bugs in my code branch",
new TimeSpan(3, 4, 0, 0));

// Create an instance of ChangeRequest by using the constructor in


// the derived class that takes four arguments.
ChangeRequest change = new ChangeRequest("Change Base Class Design",
"Add members to the class",
new TimeSpan(4, 0, 0),
1);

// Use the ToString method defined in WorkItem.


Console.WriteLine(item.ToString());

// Use the inherited Update method to change the title of the


// ChangeRequest object.
change.Update("Change the Design of the Base Class",
new TimeSpan(4, 0, 0));

// ChangeRequest inherits WorkItem's override of ToString.


Console.WriteLine(change.ToString());

// Keep the console open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* Output:
1 - Fix Bugs
2 - Change the Design of the Base Class
*/
Soyut ve sanal yöntemler
Bir temel sınıf bir yöntemi sanalolarak bildiriyorsa, türetilmiş bir sınıf yöntemi kendi uygulamasıyla
geçersiz kılabilir . Bir temel sınıf bir üyeyi soyutolarak bildiriyorsa, bu yöntemin doğrudan bu sınıftan
devralan Özet olmayan herhangi bir sınıfta geçersiz kılınmalıdır. Türetilmiş bir sınıf kendi soyut ise, soyut
üyeleri Uygulamasız devralır. Soyut ve sanal üyeler, nesne odaklı programlamanın ikinci birincil özelliği
olan çok biçimlilik için temeldir. Daha fazla bilgi için bkz. çok biçimlilik.

Soyut temel sınıflar


New işlecini kullanarak doğrudan örnek oluşturmayı engellemek istiyorsanız, bir sınıfı soyut olarak
bildirebilirsiniz. Bunu yaparsanız, sınıfı yalnızca yeni bir sınıf ondan türetilirse kullanılabilir. Soyut bir sınıf,
kendilerine soyut olarak bildirildiği bir veya daha fazla yöntem imzası içerebilir. Bu imzalar parametreleri ve
dönüş değerini belirtir, ancak hiçbir uygulamaya (Yöntem gövdesi) sahip olmaz. Soyut bir sınıfın soyut
Üyeler içermesi gerekmez; Ancak, bir sınıf soyut üye içeriyorsa, sınıfın kendisi Özet olarak bildirilmelidir.
Soyut olmayan türetilmiş sınıfların, soyut bir temel sınıftan herhangi bir soyut Yöntem için uygulama
sağlaması gerekir. Daha fazla bilgi için bkz. soyut ve korumalı sınıflar ve sınıf üyeleri.

Arabirimler
Arabirim , yalnızca soyut üyelerden oluşan soyut temel sınıfa benzer bir başvuru türüdür. Bir sınıf bir
arabirim uygularsa, arabirimin tüm üyeleri için bir uygulama sağlamalıdır. Bir sınıf, yalnızca tek bir
doğrudan taban sınıftan türeyebilse de birden çok arabirim uygulayabilir.
Arabirimler, "bir" a "ilişkisine sahip olmayan sınıflar için belirli özellikleri tanımlamak üzere kullanılır.
Örneğin, System.IEquatable<T> arabirim, tür iki nesnenin eşdeğer olup olmadığını belirlemesi için istemci
kodunu etkinleştirmek zorunda olan herhangi bir sınıf veya yapı tarafından uygulanabilir (ancak tür denklik
tanımlar). IEquatable<T>, bir temel sınıf ve türetilmiş bir sınıf (örneğin, a Mammal Animal ) arasında
bulunan aynı "bir" ilişki türünü göstermez. Daha fazla bilgi için bkz. arabirimler.

Daha fazla türetme engelleniyor


Bir sınıf, kendisini veya üyeyi korumalıolarak bildirerek diğer sınıfların bunlardan veya üyelerinden birinden
devralmasını önleyebilir. Daha fazla bilgi için bkz. soyut ve korumalı sınıflar ve sınıf üyeleri.

Temel sınıf üyelerinin türetilmiş sınıf gizlemesi


Türetilmiş bir sınıf, aynı ada ve imzaya sahip üyeleri bildirerek, temel sınıf üyelerini gizleyebilir. Yeni
değiştirici, üyenin temel üyenin geçersiz kılınmasına yönelik amaçlanmadığını açıkça belirtmek için
kullanılabilir. Yeni kullanımı gerekli değildir, ancak Yeni kullanılmazsa derleyici uyarısı oluşturulacaktır. Daha
fazla bilgi için bkz. geçersiz kılma ve Yeni anahtar sözcüklerle sürüm oluşturma ve geçersiz kılma ve yeni
anahtar sözcüklerin ne zaman kullanılacağını bilme.

Ayrıca bkz.
C# Programlama Kılavuzu
Sınıflar ve Yapılar
class
struct
Çok Biçimlilik (C# Programlama Kılavuzu)
25.11.2019 • 12 minutes to read • Edit Online

Çok biçimlilik, kapsülleme ve devralma sonrasında nesne odaklı programlama için genellikle üçüncü olarak
adlandırılır. Çok biçimlilik, "çoktan şekillendirilmiş" anlamına gelen ve iki ayrı yönü bulunan bir Yunan
kelimedir:
Çalışma zamanında, türetilmiş bir sınıfın nesneleri Yöntem parametreleri ve koleksiyonlar ya da diziler
gibi yerlerde bir temel sınıfın nesneleri olarak kabul edilebilir. Bu gerçekleştiğinde, nesnenin bildirildiği
tür artık çalışma zamanı türüyle aynı değildir.
Temel sınıflar sanal yöntemleritanımlayabilir ve uygulayabilir ve türetilmiş sınıflar bunları geçersiz
kılabilir , bu da kendi tanım ve uygulamasını sağlar. Çalışma zamanında, istemci kodu yöntemi
çağırdığında, CLR nesnenin çalışma zamanı türünü arar ve sanal yöntemin geçersiz kılmasını çağırır. Bu
nedenle, kaynak kodunuzda bir yöntemi temel sınıf üzerinde çağırabilir ve türetilmiş sınıfın yönteminin
yürütülmesine neden olabilirsiniz.
Sanal yöntemler, ilişkili nesneler gruplarıyla tek bir şekilde çalışmanıza olanak sağlar.Örneğin, bir kullanıcının
çizim yüzeyinde çeşitli şekil türlerini oluşturmalarına olanak tanıyan bir çizim uygulamanız olduğunu
varsayalım. Kullanıcı tarafından oluşturulacak belirli şekil türlerini derleme sırasında bilemezsiniz. Bununla
birlikte, uygulamanın oluşturulan çeşitli şekil türlerini izlemesi gerekir ve Kullanıcı fare eylemlerine yanıt olarak
onları güncelleştirmek zorunda olur. Bu sorunu çözmek için iki temel adımda çok biçimlilik kullanabilirsiniz:
1. Her belirli şekil sınıfının ortak bir temel sınıftan türetildiği bir sınıf hiyerarşisi oluşturun.
2. Temel sınıf yöntemine tek bir çağrı aracılığıyla herhangi bir türetilmiş sınıfta uygun yöntemi çağırmak
için bir sanal yöntem kullanın.
İlk olarak, Shape adlı bir temel sınıf ve Rectangle , Circle ve Triangle gibi türetilmiş sınıflar oluşturun. Shape
sınıfına Draw adlı sanal bir yöntem verin ve sınıfın temsil ettiği belirli şekli çizmek için her türetilmiş sınıfta bunu
geçersiz kılın. List<Shape> nesne oluşturun ve buna bir daire, üçgen ve dikdörtgen ekleyin. Çizim yüzeyini
güncelleştirmek için, listeyi yinelemek ve listedeki her bir Shape nesnesinde Draw yöntemini çağırmak için bir
foreach döngüsü kullanın. Listedeki her bir nesne, belirtilen Shape türüne sahip olsa da, çağrılacak çalışma
zamanı türüdür (her türetilmiş sınıfta yönteminin geçersiz kılınan sürümü).

using System;
using System.Collections.Generic;

public class Shape


{
// A few example members
public int X { get; private set; }
public int Y { get; private set; }
public int Height { get; set; }
public int Width { get; set; }

// Virtual method
public virtual void Draw()
{
Console.WriteLine("Performing base class drawing tasks");
}
}

class Circle : Shape


{
public override void Draw()
public override void Draw()
{
// Code to draw a circle...
Console.WriteLine("Drawing a circle");
base.Draw();
}
}
class Rectangle : Shape
{
public override void Draw()
{
// Code to draw a rectangle...
Console.WriteLine("Drawing a rectangle");
base.Draw();
}
}
class Triangle : Shape
{
public override void Draw()
{
// Code to draw a triangle...
Console.WriteLine("Drawing a triangle");
base.Draw();
}
}

class Program
{
static void Main(string[] args)
{
// Polymorphism at work #1: a Rectangle, Triangle and Circle
// can all be used whereever a Shape is expected. No cast is
// required because an implicit conversion exists from a derived
// class to its base class.
var shapes = new List<Shape>
{
new Rectangle(),
new Triangle(),
new Circle()
};

// Polymorphism at work #2: the virtual method Draw is


// invoked on each of the derived classes, not the base class.
foreach (var shape in shapes)
{
shape.Draw();
}

// Keep the console open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}

/* Output:
Drawing a rectangle
Performing base class drawing tasks
Drawing a triangle
Performing base class drawing tasks
Drawing a circle
Performing base class drawing tasks
*/

' C#De, Kullanıcı tanımlı türler dahil olmak üzere tüm türler Object' den devraldığı için her tür polimorfik olur.

Çok biçimlilik genel bakış


Sanal Üyeler
Türetilmiş bir sınıf temel sınıftan devraldığında, temel sınıfın tüm yöntemlerini, alanlarını, özelliklerini ve
olaylarını alır. Türetilmiş sınıfın Tasarımcısı şunları yapıp oluşturulmayacağını seçebilir
taban sınıftaki sanal üyeleri geçersiz kıl,
En yakın temel sınıf yöntemini geçersiz kılmadan devralma
temel sınıf uygulamalarını gizleyen bu üyelerin sanal olmayan yeni uygulamasını tanımlayın
Türetilmiş bir sınıf, yalnızca temel sınıf üyesi sanal veya soyutolarak bildirilirse bir temel sınıf üyesini geçersiz
kılabilir. Türetilmiş üye, metodun sanal çağrıya katılmayı amaçladığı kesin olarak belirtmek için override anahtar
sözcüğünü kullanmalıdır. Aşağıdaki kod bir örnek sağlar:

public class BaseClass


{
public virtual void DoWork() { }
public virtual int WorkProperty
{
get { return 0; }
}
}
public class DerivedClass : BaseClass
{
public override void DoWork() { }
public override int WorkProperty
{
get { return 0; }
}
}

Alanlar sanal olamaz; yalnızca Yöntemler, özellikler, olaylar ve Dizin oluşturucular sanal olabilir.Türetilmiş bir
sınıf sanal üyeyi geçersiz kıldığında, bu üye, bu sınıfın bir örneği temel sınıfın bir örneği olarak erişildiği zaman
bile çağırılır. Aşağıdaki kod bir örnek sağlar:

DerivedClass B = new DerivedClass();


B.DoWork(); // Calls the new method.

BaseClass A = (BaseClass)B;
A.DoWork(); // Also calls the new method.

Sanal yöntemler ve özellikler, türetilmiş sınıfların bir yöntemin temel sınıf uygulamasını kullanmaya gerek
kalmadan bir temel sınıfı genişletmesine imkan tanır. Daha fazla bilgi için bkz. geçersiz kılma ve yeni anahtar
sözcüklerle sürüm oluşturma. Bir arabirim, bir yöntemi veya uygulamasının türetilmiş sınıflara ayrılmakta
olduğu yöntemler kümesini tanımlamak için başka bir yol sağlar. Daha fazla bilgi için bkz. arabirimler.
Temel sınıf üyelerini yeni üyelerle gizleme
Türetilmiş üyenin bir temel sınıftaki üye ile aynı ada sahip olmasını istiyorsanız, ancak sanal çağrıya katılmasını
istemiyorsanız, New anahtar sözcüğünü kullanabilirsiniz. new anahtar sözcüğü, değiştirilmekte olan bir sınıf
üyesinin dönüş türünden önce konur. Aşağıdaki kod bir örnek sağlar:
public class BaseClass
{
public void DoWork() { WorkField++; }
public int WorkField;
public int WorkProperty
{
get { return 0; }
}
}

public class DerivedClass : BaseClass


{
public new void DoWork() { WorkField++; }
public new int WorkField;
public new int WorkProperty
{
get { return 0; }
}
}

Gizli temel sınıf üyelerine, türetilmiş sınıfın örneğini bir temel sınıfın örneğine aktararak istemci kodundan de
erişilebilir. Örneğin:

DerivedClass B = new DerivedClass();


B.DoWork(); // Calls the new method.

BaseClass A = (BaseClass)B;
A.DoWork(); // Calls the old method.

Türetilmiş sınıfların sanal üyeleri geçersiz kılmasını önler


Sanal üyeler ve ilk olarak onu tanımlayan sınıf arasında kaç sınıf bildirildiği bağımsız olarak sanal Üyeler sanal
olarak kalır. Sınıf A bir sanal üye bildirirse ve B sınıfı bir ' dan türetilir ve C sınıfı B 'den türetilmişse, C sınıfı
sanal üyeyi devralır ve B sınıfı bu üye için bir geçersiz kılma bildirdiğine bakılmaksızın onu geçersiz kılma
seçeneğine sahiptir. Aşağıdaki kod bir örnek sağlar:

public class A
{
public virtual void DoWork() { }
}
public class B : A
{
public override void DoWork() { }
}

Türetilmiş bir sınıf, bir geçersiz kılma korumalıolarak bildirerek sanal devralmayı durdurabilir. Bu, sınıf üye
bildiriminde override anahtar sözcüğünden önce sealed anahtar sözcüğünü yerleştirmeyi gerektirir.
Aşağıdaki kod bir örnek sağlar:

public class C : B
{
public sealed override void DoWork() { }
}

Önceki örnekte, yöntem DoWork artık C 'den türetilmiş hiçbir sınıfta sanal değildir. B türüne veya tür A 'ya
dönüştürülseler bile, C örnekleri için hala sanal bir. Sealed yöntemleri, aşağıdaki örnekte gösterildiği gibi, new
anahtar sözcüğü kullanılarak türetilmiş sınıflar tarafından değiştirilebilir:
public class D : C
{
public new void DoWork() { }
}

Bu durumda, d üzerinde DoWork , D türünde bir değişken kullanılarak çağrılırsa, yeni DoWork çağırılır. C, B veya
A türündeki bir değişken D örneğine erişmek için kullanılırsa, DoWork çağrısı, sanal devralma kurallarını
izleyerek bu çağrıları C sınıfında DoWork uygulamasına yönlendirirsiniz.
Türetilmiş sınıflardan temel sınıf sanal üyelerine erişme
Bir yöntemi veya özelliği değiştirilmiş veya geçersiz kılan türetilmiş bir sınıf, base anahtar sözcüğünü
kullanarak temel sınıftaki yönteme veya özelliğe erişmeye devam edebilir. Aşağıdaki kod bir örnek sağlar:

public class Base


{
public virtual void DoWork() {/*...*/ }
}
public class Derived : Base
{
public override void DoWork()
{
//Perform Derived's work here
//...
// Call DoWork on base class
base.DoWork();
}
}

Daha fazla bilgi için bkz. Base.

NOTE
Sanal üyelerin, kendi uygulamalarında bu üyenin temel sınıf uygulamasını çağırmak için base kullanması önerilir. Temel
sınıf davranışının oluşmasına izin vermek, türetilmiş sınıfın türetilmiş sınıfa özgü davranış uygulamaya odaklanmalarını
sağlar. Temel sınıf uygulama çağrılıp, davranışını temel sınıfın davranışıyla uyumlu hale getirmek için türetilmiş sınıfa kadar
olur.

Bu Bölümde
Geçersiz Kılma ve Yeni Anahtar Sözcüklerle Sürüm Oluşturma
Geçersiz Kılmanın ve Yeni Anahtar Sözcüklerin Ne Zaman Kullanılacağını Bilme
ToString yöntemini geçersiz kılma

Ayrıca bkz.
C# Programlama Kılavuzu
Devralma
Soyut ve Korumalı Sınıflar ve Sınıf Üyeleri
Yöntemler
Olaylar
Veri Erişimi
Dizin Oluşturucular
Türler
Geçersiz Kılma ve Yeni Anahtar Sözcüklerle Sürüm
Oluşturma (C# Programlama Kılavuzu)
1.11.2019 • 8 minutes to read • Edit Online

Dil C# , farklı kitaplıklarda temel ve türetilmiş sınıflar arasında sürüm oluşturmanın, geriye dönük uyumluluğu
geliştirebilir ve bakımını yapabilmesi için tasarlanmıştır. Bu, örneğin, türetilmiş bir sınıftaki üye ile aynı ada sahip
bir temel sınıfta yeni bir üyenin giriş tarafından C# tamamen desteklendiği ve beklenmeyen davranışlara neden
olmadığı anlamına gelir. Ayrıca, bir yöntemin devralınan bir yöntemi geçersiz kılmak için bir yöntemin açıkça veya
bir yöntemin devralınmış bir adlandırılmış yöntemi gizleyen yeni bir yöntem olup olmadığı anlamına gelir.
' C#De, türetilmiş sınıflar temel sınıf yöntemleriyle aynı ada sahip yöntemler içerebilir.
Temel sınıf yöntemi tanımlanmış bir sanalolmalıdır.
Türetilmiş sınıftaki yöntemin önünde New veya override anahtar sözcükleri yoksa, derleyici bir uyarı
verecek ve Yöntem new anahtar sözcüğü var gibi davranır.
Türetilmiş sınıftaki yöntemi öncesinde new anahtar kelimesiyle, yöntemi temel sınıftaki yönteminden
bağımsız olarak tanımlanır.
Türetilmiş sınıftaki yöntemin önünde override anahtar sözcüğü varsa, türetilen sınıfın nesneleri temel
sınıf yöntemi yerine bu yöntemi çağırır.
Temel sınıf yöntemi, base anahtar sözcüğü kullanılarak türetilmiş sınıfın içinden çağrılabilir.
override , virtual ve new anahtar sözcükleri özellikler, Dizin oluşturucular ve olaylar için de
uygulanabilir.
Varsayılan olarak, C# metotlar sanal değildir. Bir yöntem sanal olarak bildirilirse, yöntemi devralan herhangi bir
sınıf kendi sürümünü uygulayabilir. Bir yöntemi sanal yapmak için, taban sınıfının yöntem bildiriminde virtual
değiştiricisi kullanılır. Türetilmiş sınıf daha sonra, override anahtar sözcüğünü kullanarak temel sanal yöntemi
geçersiz kılabilir veya new anahtar sözcüğünü kullanarak temel sınıftaki sanal yöntemi gizleyebilirsiniz.
override anahtar sözcüğünün ne de new anahtar sözcüğü belirtilmemişse, derleyici bir uyarı vermez ve
türetilmiş sınıftaki yöntem temel sınıftaki yöntemi gizler.
Bu uygulamada bunu göstermek için, Şirket A 'nın programınızın kullandığı GraphicsClass adlı bir sınıf
oluşturduğunu varsayalım. GraphicsClass aşağıda verilmiştir:

class GraphicsClass
{
public virtual void DrawLine() { }
public virtual void DrawPoint() { }
}

Şirketiniz bu sınıfı kullanır ve yeni bir yöntem ekleyerek kendi sınıfınızı türetmeniz için kullanın:

class YourDerivedGraphicsClass : GraphicsClass


{
public void DrawRectangle() { }
}

Uygulamanız sorunlar olmadan kullanılır, Şirket A GraphicsClass yeni bir sürümünü yayınlar, bu da aşağıdaki
koda benzer:

class GraphicsClass
{
public virtual void DrawLine() { }
public virtual void DrawPoint() { }
public virtual void DrawRectangle() { }
}

GraphicsClass yeni sürümü artık DrawRectangle adlı bir yöntemi içerir. Başlangıçta, hiçbir şey gerçekleşmez. Yeni
sürüm hala eski sürümle uyumlu. Dağıttığınız tüm yazılımlar, yeni sınıf bu bilgisayar sistemlerine yüklense bile
çalışmaya devam eder. DrawRectangle yönteme yapılan tüm çağrılar, türetilmiş sınıfınıza sürümünüze
başvurmasına devam edecektir.
Ancak, GraphicsClass yeni sürümünü kullanarak uygulamanızı yeniden derleydükten sonra, CS0108
derleyicisinden bir uyarı alırsınız. Bu uyarı, DrawRectangle yönteminizin uygulamanızda nasıl davranmasını
istediğinizi dikkate almanız gerektiğini bildirir.
Yönteminizin yeni temel sınıf yöntemini geçersiz kılmasını istiyorsanız override anahtar sözcüğünü kullanın:

class YourDerivedGraphicsClass : GraphicsClass


{
public override void DrawRectangle() { }
}

override anahtar sözcüğü, YourDerivedGraphicsClass türetilmiş tüm nesnelerin DrawRectangle türetilmiş sınıf
sürümünü kullanmasını sağlar. YourDerivedGraphicsClass türetilen nesneler, temel anahtar sözcüğünü kullanarak
DrawRectangle temel sınıf sürümüne erişmeye devam edebilir:

base.DrawRectangle();

Yönteminizin yeni temel sınıf yöntemini geçersiz kılmasını istemiyorsanız, aşağıdaki noktalar geçerlidir. İki
yöntem arasında karışıklık oluşmasını önlemek için yönteminizi yeniden adlandırabilirsiniz. Bu, zaman alan ve
hataya açık olabilir ve bazı durumlarda pratik değildir. Ancak, projeniz nispeten küçükse, yöntemi yeniden
adlandırmak için Visual Studio 'nun yeniden düzenleme seçeneklerini kullanabilirsiniz. Daha fazla bilgi için bkz.
yeniden düzenleme sınıfları ve türleri (sınıf Tasarımcısı).
Alternatif olarak, türetilmiş sınıf tanımınızda new anahtar sözcüğünü kullanarak uyarıyı engelleyebilirsiniz:

class YourDerivedGraphicsClass : GraphicsClass


{
public new void DrawRectangle() { }
}

new anahtar sözcüğünü kullanmak derleyiciye, tanımınızın taban sınıfta bulunan tanımı gizlediğini belirtir. Bu,
varsayılan davranıştır.

Geçersiz kılma ve Yöntem seçimi


Bir yöntem bir sınıfta adlandırıldığında, C# derleyici, aynı ada sahip iki yöntem olduğunda ve geçilen parametre
ile uyumlu olan parametreler gibi, çağrı ile uyumlu olduğunda çağırmak için en iyi yöntemi seçer. Aşağıdaki
yöntemler uyumlu olacaktır:
public class Derived : Base
{
public override void DoWork(int param) { }
public void DoWork(double param) { }
}

DoWork bir Derived örneğinde çağrıldığında, C# derleyici ilk olarak çağrıyı Derived üzerinde ilk olarak belirtilen
DoWork sürümleriyle uyumlu hale getirmek üzere çalışır. Geçersiz kılma yöntemleri bir sınıfta bildirildiği gibi
düşünülmez, bir temel sınıfta belirtilen metodun yeni uygulamalarıdır. Yalnızca C# derleyici, Derived üzerindeki
bir özgün yönteme yönelik yöntem çağrısını eşleşemez, geçersiz kılınan bir yönteme yapılan çağrıyı aynı ada ve
uyumlu parametrelere eşleştirmeye çalışır. Örneğin:

int val = 5;
Derived d = new Derived();
d.DoWork(val); // Calls DoWork(double).

val değişkeni bir Double öğesine örtük olarak dönüştürülebildiğinden, C# derleyici DoWork(int) yerine
DoWork(double) çağırır. Bunu önlemenin iki yolu vardır. İlk olarak, sanal yöntemlerle aynı ada sahip yeni
yöntemler bildirmemeye özen gösterin. İkinci olarak, Derived örneğini Base C# kaldırarak temel sınıf Yöntem
listesinde arama yaparak derleyiciye sanal yöntemi çağırabilmeniz için talimat verebilirsiniz. Yöntem sanal olduğu
için, Derived üzerindeki DoWork(int) uygulanması çağrılacaktır. Örneğin:

((Base)d).DoWork(val); // Calls DoWork(int) on Derived.

new ve override daha fazla örnek için bkz. override ve New anahtar sözcüklerini ne zaman kullanacağınızı
bilme.

Ayrıca bkz.
C# Programlama Kılavuzu
Sınıflar ve Yapılar
Yöntemler
Devralma
Geçersiz Kılmanın ve Yeni Anahtar Sözcüklerin Ne
Zaman Kullanılacağını Bilme (C# Programlama
Kılavuzu)
23.10.2019 • 14 minutes to read • Edit Online

İçinde C#, türetilmiş bir sınıftaki bir yöntem, temel sınıftaki bir yöntemle aynı ada sahip olabilir. Yöntemlerinin
New ve override anahtar sözcüklerini kullanarak nasıl etkileşime gireceğini belirtebilirsiniz. virtual new
Değiştirici, temel sınıf yöntemini genişletir ve değiştirici, erişilebilir bir temel sınıf yöntemini gizler. override Fark,
bu konudaki örneklerde gösterilmiştir.
Konsol uygulamasında, aşağıdaki iki sınıfı BaseClass bildirin ve. DerivedClass DerivedClass öğesinden
BaseClass devralır.

class BaseClass
{
public void Method1()
{
Console.WriteLine("Base - Method1");
}
}

class DerivedClass : BaseClass


{
public void Method2()
{
Console.WriteLine("Derived - Method2");
}
}

Yönteminde, ve bc değişkenlerinibildirin. bcdc dc Main

bc türündedir BaseClass ve değeri türündedir BaseClass .


dc türündedir DerivedClass ve değeri türündedir DerivedClass .
bcdc türündedir BaseClass ve değeri türündedir DerivedClass . Bu, dikkat edilmesi gereken değişkendir.
Ve bc türüolduğundan BaseClass , atama kullanmadığınız müddetçe yalnızca doğrudan erişim Method1
sağlayabilir. bcdc Değişken dc , Method1 ve ' Method2 a erişebilir. Bu ilişkiler aşağıdaki kodda gösterilmiştir.
class Program
{
static void Main(string[] args)
{
BaseClass bc = new BaseClass();
DerivedClass dc = new DerivedClass();
BaseClass bcdc = new DerivedClass();

bc.Method1();
dc.Method1();
dc.Method2();
bcdc.Method1();
}
// Output:
// Base - Method1
// Base - Method1
// Derived - Method2
// Base - Method1
}

Ardından, aşağıdaki Method2 yöntemi öğesine BaseClass ekleyin. Bu yöntemin imzası içindeki Method2
DerivedClass yönteminin imzasıyla eşleşir.

public void Method2()


{
Console.WriteLine("Base - Method2");
}

Artık BaseClass bir BaseClass bc bcdc yöntemi olduğundan, aşağıdaki kodda gösterildiği gibi, değişkenler için
ikinci bir çağırma açıklaması eklenebilir. Method2

bc.Method1();
bc.Method2();
dc.Method1();
dc.Method2();
bcdc.Method1();
bcdc.Method2();

Projeyi derlediğinizde, içinde Method2 BaseClass yönteminin eklenmesi bir uyarıya neden olur. Uyarı, içindeki
DerivedClass yönteminin içindeki Method2 Method2 yöntemigizlediğinibelirtir BaseClass . Bu sonuca neden
olmak istiyorsanız, new Method2 tanımda anahtar sözcüğünü kullanmanız önerilir. Alternatif olarak, uyarıyı
çözümlemek için Method2 yöntemlerden birini yeniden adlandırabilirsiniz, ancak her zaman pratik değildir.
Eklemeden new önce, ek çağırma deyimleri tarafından üretilen çıktıyı görmek için programı çalıştırın. Aşağıdaki
sonuçlar görüntülenir.

// Output:
// Base - Method1
// Base - Method2
// Base - Method1
// Derived - Method2
// Base - Method1
// Base - Method2

new Anahtar sözcüğü, bu çıktıyı üreten ilişkileri korur, ancak uyarıyı bastırır.Türüne BaseClass sahip değişkenler
BaseClass , üyelerine erişmeye devam eder ve türüne DerivedClass sahip olan değişken ilk olarak DerivedClass
üyelere erişmeye devam eder ve öğesinden BaseClass devralınan üyeleri göz önünde bulundurun.
Uyarıyı bastırmak için, aşağıdaki kodda gösterildiği new gibi değiştiricisini Method2 içindeki DerivedClass
tanımına ekleyin. Değiştirici veya public daha önce eklenebilir.

public new void Method2()


{
Console.WriteLine("Derived - Method2");
}

Çıktının değiştirilmediğini doğrulamak için programı yeniden çalıştırın. Ayrıca uyarının artık göründüğünü
doğrulayın. Kullanarak new , değiştirdiği üyenin, temel sınıftan devralınan bir üyeyi gizlediğini fark edersiniz.
Devralma yoluyla ad gizleme hakkında daha fazla bilgi için bkz. Yeni değiştirici.
Bu davranışı kullanmanın override etkilerine karşı tersine geçmek için aşağıdaki yöntemi öğesine DerivedClass
ekleyin. Değiştirici veya daha önce eklenebilir. public override

public override void Method1()


{
Console.WriteLine("Derived - Method1");
}

virtual Değiştiricisini Method1 içindeki tanımına BaseClass ekleyin. Değiştirici veya daha önce eklenebilir.
public virtual

public virtual void Method1()


{
Console.WriteLine("Base - Method1");
}

Projeyi yeniden çalıştırın. Özellikle aşağıdaki Çıktının son iki satırını görürsünüz.

// Output:
// Base - Method1
// Base - Method2
// Derived - Method1
// Derived - Method2
// Derived - Method1
// Base - Method2

override Değiştiricinin kullanımı, içinde bcdc Method1 tanımlanan DerivedClass yönteme erişim sağlar.
Genellikle, devralma hiyerarşilerindeki istenen davranıştır. Türetilmiş sınıftan oluşturulan değerlere sahip
nesnelerin türetilmiş sınıfta tanımlanan yöntemleri kullanmasını istiyorsunuz. Temel sınıf yöntemini genişletmek
için bu override davranışı kullanarak elde edersiniz.
Aşağıdaki kod tam örneği içerir.
using System;
using System.Text;

namespace OverrideAndNew
{
class Program
{
static void Main(string[] args)
{
BaseClass bc = new BaseClass();
DerivedClass dc = new DerivedClass();
BaseClass bcdc = new DerivedClass();

// The following two calls do what you would expect. They call
// the methods that are defined in BaseClass.
bc.Method1();
bc.Method2();
// Output:
// Base - Method1
// Base - Method2

// The following two calls do what you would expect. They call
// the methods that are defined in DerivedClass.
dc.Method1();
dc.Method2();
// Output:
// Derived - Method1
// Derived - Method2

// The following two calls produce different results, depending


// on whether override (Method1) or new (Method2) is used.
bcdc.Method1();
bcdc.Method2();
// Output:
// Derived - Method1
// Base - Method2
}
}

class BaseClass
{
public virtual void Method1()
{
Console.WriteLine("Base - Method1");
}

public virtual void Method2()


{
Console.WriteLine("Base - Method2");
}
}

class DerivedClass : BaseClass


{
public override void Method1()
{
Console.WriteLine("Derived - Method1");
}

public new void Method2()


{
Console.WriteLine("Derived - Method2");
}
}
}
Aşağıdaki örnek farklı bağlamdaki benzer davranışı gösterir. Örnek üç sınıfı tanımlar: adlı Car bir temel sınıf ve
ondan türetilmiş ConvertibleCar iki sınıf ve Minivan . Temel sınıf bir DescribeCar yöntemi içerir. Yöntemi, bir
araba için temel bir açıklama görüntüler ve daha sonra ek ShowDetails bilgi sağlamak için çağırır. Üç sınıfın her
biri bir ShowDetails yöntemi tanımlar. Değiştirici sınıfında tanımlamak ShowDetails için kullanılır.
ConvertibleCar new Değiştirici sınıfında tanımlamak ShowDetails için kullanılır. Minivan override

// Define the base class, Car. The class defines two methods,
// DescribeCar and ShowDetails. DescribeCar calls ShowDetails, and each derived
// class also defines a ShowDetails method. The example tests which version of
// ShowDetails is selected, the base class method or the derived class method.
class Car
{
public void DescribeCar()
{
System.Console.WriteLine("Four wheels and an engine.");
ShowDetails();
}

public virtual void ShowDetails()


{
System.Console.WriteLine("Standard transportation.");
}
}

// Define the derived classes.

// Class ConvertibleCar uses the new modifier to acknowledge that ShowDetails


// hides the base class method.
class ConvertibleCar : Car
{
public new void ShowDetails()
{
System.Console.WriteLine("A roof that opens up.");
}
}

// Class Minivan uses the override modifier to specify that ShowDetails


// extends the base class method.
class Minivan : Car
{
public override void ShowDetails()
{
System.Console.WriteLine("Carries seven people.");
}
}

Örnek, hangi sürümünün ShowDetails çağrıldığını sınar. Aşağıdaki yöntem TestCars1 , her sınıfın bir örneğini
bildirir ve ardından her bir örnek üzerinde çağırır DescribeCar .
public static void TestCars1()
{
System.Console.WriteLine("\nTestCars1");
System.Console.WriteLine("----------");

Car car1 = new Car();


car1.DescribeCar();
System.Console.WriteLine("----------");

// Notice the output from this test case. The new modifier is
// used in the definition of ShowDetails in the ConvertibleCar
// class.

ConvertibleCar car2 = new ConvertibleCar();


car2.DescribeCar();
System.Console.WriteLine("----------");

Minivan car3 = new Minivan();


car3.DescribeCar();
System.Console.WriteLine("----------");
}

TestCars1 Aşağıdaki çıktıyı üretir. Özellikle, beklendikleriniz car2 olmayan büyük olasılıkla için sonuçları
görebilirsiniz. ConvertibleCar Nesnenin new türü, DescribeCar ancak bu yöntem değiştirici değil ShowDetails
ConvertibleCar değiştiriciylebildirildiğiiçinsınıfındatanımlanan override sürümüne erişmez. Sonuç olarak,
ConvertibleCar bir nesnesi bir Car nesneyle aynı açıklamayı görüntüler. car3 Bir Minivan nesnesi olan için
sonuçlarını kontrast. Bu ShowDetails durumda, Minivan sınıfında belirtilen yöntem, Car sınıfında belirtilen
ShowDetails yöntemi geçersiz kılar ve görüntülenen açıklama bir mini Van 'yi tanımlar.

// TestCars1
// ----------
// Four wheels and an engine.
// Standard transportation.
// ----------
// Four wheels and an engine.
// Standard transportation.
// ----------
// Four wheels and an engine.
// Carries seven people.
// ----------

TestCars2 türü Car olan nesnelerin bir listesini oluşturur. Nesnelerin değerleri Car , ConvertibleCar , ve Minivan
sınıflarından oluşturulur. DescribeCar , listedeki her öğe için çağrılır. Aşağıdaki kod tanımını TestCars2 gösterir.

public static void TestCars2()


{
System.Console.WriteLine("\nTestCars2");
System.Console.WriteLine("----------");

var cars = new List<Car> { new Car(), new ConvertibleCar(),


new Minivan() };

foreach (var car in cars)


{
car.DescribeCar();
System.Console.WriteLine("----------");
}
}

Aşağıdaki çıktı görüntülenir. Bunun, tarafından TestCars1 görüntülenen çıktıyla aynı olduğuna dikkat edin.
ShowDetails Car Sınıfının yöntemi , nesne ConvertibleCar türünün ' de olduğu gibi, veya ' de olduğu
TestCars2
gibi çağrılmaz. TestCars1 ConvertibleCar Buna karşılık car3 , tür ShowDetails Minivan veyatür Car içerip
içermediğini her iki durumda da sınıfından yöntemini çağırır. Minivan

// TestCars2
// ----------
// Four wheels and an engine.
// Standard transportation.
// ----------
// Four wheels and an engine.
// Standard transportation.
// ----------
// Four wheels and an engine.
// Carries seven people.
// ----------

Yöntemini TestCars3 doldurun TestCars4 ve örnek. Bu yöntemler, ShowDetails önce türü ConvertibleCar ve
Minivan ( TestCars3 ) olan olarak belirtilen nesnelerden, daha sonra türü Car ( TestCars4 ) olan olarak belirtilen
nesnelerden doğrudan çağrı yapılır. Aşağıdaki kod bu iki yöntemi tanımlar.

public static void TestCars3()


{
System.Console.WriteLine("\nTestCars3");
System.Console.WriteLine("----------");
ConvertibleCar car2 = new ConvertibleCar();
Minivan car3 = new Minivan();
car2.ShowDetails();
car3.ShowDetails();
}

public static void TestCars4()


{
System.Console.WriteLine("\nTestCars4");
System.Console.WriteLine("----------");
Car car2 = new ConvertibleCar();
Car car3 = new Minivan();
car2.ShowDetails();
car3.ShowDetails();
}

Yöntemler, bu konudaki ilk örnekteki sonuçlara karşılık gelen aşağıdaki çıktıyı üretir.

// TestCars3
// ----------
// A roof that opens up.
// Carries seven people.

// TestCars4
// ----------
// Standard transportation.
// Carries seven people.

Aşağıdaki kod, tüm projeyi ve çıktısını gösterir.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace OverrideAndNew2
{
class Program
{
static void Main(string[] args)
{
// Declare objects of the derived classes and test which version
// of ShowDetails is run, base or derived.
TestCars1();

// Declare objects of the base class, instantiated with the


// derived classes, and repeat the tests.
TestCars2();

// Declare objects of the derived classes and call ShowDetails


// directly.
TestCars3();

// Declare objects of the base class, instantiated with the


// derived classes, and repeat the tests.
TestCars4();
}

public static void TestCars1()


{
System.Console.WriteLine("\nTestCars1");
System.Console.WriteLine("----------");

Car car1 = new Car();


car1.DescribeCar();
System.Console.WriteLine("----------");

// Notice the output from this test case. The new modifier is
// used in the definition of ShowDetails in the ConvertibleCar
// class.
ConvertibleCar car2 = new ConvertibleCar();
car2.DescribeCar();
System.Console.WriteLine("----------");

Minivan car3 = new Minivan();


car3.DescribeCar();
System.Console.WriteLine("----------");
}
// Output:
// TestCars1
// ----------
// Four wheels and an engine.
// Standard transportation.
// ----------
// Four wheels and an engine.
// Standard transportation.
// ----------
// Four wheels and an engine.
// Carries seven people.
// ----------

public static void TestCars2()


{
System.Console.WriteLine("\nTestCars2");
System.Console.WriteLine("----------");

var cars = new List<Car> { new Car(), new ConvertibleCar(),


new Minivan() };

foreach (var car in cars)


{
car.DescribeCar();
System.Console.WriteLine("----------");
}
}
// Output:
// Output:
// TestCars2
// ----------
// Four wheels and an engine.
// Standard transportation.
// ----------
// Four wheels and an engine.
// Standard transportation.
// ----------
// Four wheels and an engine.
// Carries seven people.
// ----------

public static void TestCars3()


{
System.Console.WriteLine("\nTestCars3");
System.Console.WriteLine("----------");
ConvertibleCar car2 = new ConvertibleCar();
Minivan car3 = new Minivan();
car2.ShowDetails();
car3.ShowDetails();
}
// Output:
// TestCars3
// ----------
// A roof that opens up.
// Carries seven people.

public static void TestCars4()


{
System.Console.WriteLine("\nTestCars4");
System.Console.WriteLine("----------");
Car car2 = new ConvertibleCar();
Car car3 = new Minivan();
car2.ShowDetails();
car3.ShowDetails();
}
// Output:
// TestCars4
// ----------
// Standard transportation.
// Carries seven people.
}

// Define the base class, Car. The class defines two virtual methods,
// DescribeCar and ShowDetails. DescribeCar calls ShowDetails, and each derived
// class also defines a ShowDetails method. The example tests which version of
// ShowDetails is used, the base class method or the derived class method.
class Car
{
public virtual void DescribeCar()
{
System.Console.WriteLine("Four wheels and an engine.");
ShowDetails();
}

public virtual void ShowDetails()


{
System.Console.WriteLine("Standard transportation.");
}
}

// Define the derived classes.

// Class ConvertibleCar uses the new modifier to acknowledge that ShowDetails


// hides the base class method.
class ConvertibleCar : Car
{
public new void ShowDetails()
{
{
System.Console.WriteLine("A roof that opens up.");
}
}

// Class Minivan uses the override modifier to specify that ShowDetails


// extends the base class method.
class Minivan : Car
{
public override void ShowDetails()
{
System.Console.WriteLine("Carries seven people.");
}
}

Ayrıca bkz.
C# Programlama Kılavuzu
Sınıflar ve Yapılar
Geçersiz Kılma ve Yeni Anahtar Sözcüklerle Sürüm Oluşturma
base
abstract
ToString yöntemini geçersiz kılma (C# Programlama
Kılavuzu)
25.11.2019 • 2 minutes to read • Edit Online

İçindeki C# her sınıf veya yapı, Object sınıfını örtülü olarak devralır. Bu nedenle, içindeki C# her nesne, bu
nesnenin dize gösterimini döndüren ToString yöntemini alır. Örneğin, int türündeki tüm değişkenler bir
ToString yöntemine sahiptir ve bu da bunların içeriğini bir dize olarak döndürmesini sağlar:

int x = 42;
string strx = x.ToString();
Console.WriteLine(strx);
// Output:
// 42

Özel bir sınıf veya yapı oluşturduğunuzda, istemci koduna yazmanız hakkında bilgi sağlamak için ToString
yöntemini geçersiz kılmanız gerekir.
Biçim dizelerini ve ToString yöntemiyle diğer özel biçimlendirme türlerini kullanma hakkında daha fazla bilgi için
bkz. biçimlendirme türleri.

IMPORTANT
Bu yöntem aracılığıyla sağlanacak bilgilere karar verirken, sınıfınızın veya yapının güvenilmeyen kod tarafından kullanılıp
kullanılmayacağını göz önünde bulundurun. Kötü amaçlı kod tarafından yararlanılabilen herhangi bir bilgi sağlamadiğinizden
emin olun.

Sınıfınıza veya yapıda ToString yöntemi geçersiz kılmak için:


1. Aşağıdaki değiştiriciler ve dönüş türü ile bir ToString yöntemi bildirin:

public override string ToString(){}

2. Yöntemini bir dize döndürmesi için uygulayın.


Aşağıdaki örnek, sınıfının belirli bir örneğine özgü verilere ek olarak sınıfının adını döndürür.

class Person
{
public string Name { get; set; }
public int Age { get; set; }

public override string ToString()


{
return "Person: " + Name + " " + Age;
}
}

Aşağıdaki kod örneğinde gösterildiği gibi ToString yöntemini test edebilirsiniz:


Person person = new Person { Name = "John", Age = 12 };
Console.WriteLine(person);
// Output:
// Person: John 12

Ayrıca bkz.
IFormattable
C# Programlama Kılavuzu
Sınıflar ve Yapılar
Dizeler
string
override
virtual
Biçimlendirme Türleri
Üyeler (C# Programlama Kılavuzu)
23.10.2019 • 3 minutes to read • Edit Online

Sınıflar ve yapılar, kendi verilerini ve davranışlarını temsil eden üyelere sahiptir.Bir sınıfın üyeleri, kendi devralma
hiyerarşisindeki tüm sınıflarda belirtilen tüm üyelerle (oluşturucular ve sonlandırıcılar hariç) birlikte sınıfında
belirtilen tüm üyeleri içerir. Temel sınıflardaki özel üyeler devralınır ancak türetilmiş sınıflardan erişilebilir değildir.
Aşağıdaki tablo, bir sınıfın veya yapının içerebileceği üye türlerini listeler:

ÜYE AÇIKLAMA

Alanlar Alanlar, sınıf kapsamında bildirilen değişkenlerdir. Bir alan,


yerleşik bir sayısal tür veya başka bir sınıfın bir örneği olabilir.
Örneğin bir takvim sınıfı, geçerli tarihi içeren bir alana sahip
olabilir.

Sabitler Sabitler, değeri derleme zamanında ayarlanan alanlardır ve


değiştirilemez.

Özellikler Özellikler, bir sınıftaki alanlar gibi erişilen o sınıftaki öğelerdir.


Bir özellik, nesne bilgisi olmadan değiştirilmesini engellemek
üzere bir sınıf alanı için koruma sağlayabilir.

Yöntemler Yöntemler, bir sınıfın gerçekleştirebildiği eylemleri tanımlar.


Yöntemler girdi verilerini sağlayan parametreleri alabilir ve
parametreler ile çıktı verilerini döndürebilir. Ayrıca yöntemler
parametre kullanmadan bir değeri doğrudan döndürebilir.

Olaylar Olaylar, diğer nesnelere düğme tıklamaları veya bir yöntemin


başarıyla tamamlanması gibi örnekleri sağlar. Olaylar,
temsilciler kullanılarak tanımlanır ve tetiklenir.

İşleçler Aşırı yüklenmiş işleçler, tür üyeleri olarak kabul edilir. Bir işleci
aşırı yüklerken, bir tür içinde ortak statik bir yöntem olarak
tanımlarsınız. Daha fazla bilgi için bkz. operatör aşırı yüklemesi.

Dizin Oluşturucular Dizinleyiciler, bir nesnenin dizilere benzer şekilde dizinlenmesini


sağlar.

Oluşturucular Yapıcılar, nesne ilk oluşturulduğunda çağırılan yöntemlerdir.


Bunlar genellikle bir nesneye ait verileri başlatmak için kullanılır.

Sonlandırıcılar Sonlandırıcılar, içinde C#çok seyrek kullanılır. Bunlar, nesne


bellekten kaldırılmak üzereyken çalışma zamanı yürütme alt
yapısı tarafından çağrılan yöntemlerdir. Bu yöntemler,
genellikle yayınlanması gereken tüm kaynakların uygun şekilde
işlendiğinden emin olmak için kullanılır.

İç içe Geçmiş Türler İç içe olan türler, başka bir türde bildirilen türlerdir. İç içe türler
genellikle yalnızca bunları içeren türler tarafından kullanılan
nesneleri tanımlamak için kullanılır.

Ayrıca bkz.
C# Programlama Kılavuzu
Sınıflar
Soyut ve Korumalı Sınıflar ve Sınıf Üyeleri (C#
Programlama Kılavuzu)
25.11.2019 • 4 minutes to read • Edit Online

Abstract anahtar sözcüğü, tamamlanmamış ve türetilmiş bir sınıfta uygulanması gereken sınıflar ve sınıf
üyeleri oluşturmanızı sağlar.
Sealed anahtar sözcüğü, bir sınıfın devralınmasını veya daha önce sanalolarak işaretlenmiş belirli sınıf
üyelerini engellemenizi sağlar.

Soyut sınıflar ve sınıf üyeleri


Sınıflar, sınıf tanımından önce anahtar sözcüğü abstract yerleştirerek Özet olarak bildirilemez. Örneğin:

public abstract class A


{
// Class members here.
}

Soyut bir sınıf örneği oluşturulamıyor. Soyut bir sınıfın amacı, birden fazla türetilmiş sınıfın paylaşabileceği bir
temel sınıfın ortak bir tanımını sağlamaktır. Örneğin, bir sınıf kitaplığı, işlevlerinin çoğuna parametre olarak
kullanılan bir soyut sınıfı tanımlayabilir ve bir türetilmiş sınıf oluşturarak bu kitaplığı kullanan programcıların,
sınıfının kendi uygulamasını sağlamasını gerektirebilir.
Soyut sınıflar, Soyut yöntemler de tanımlayabilir.Bu, yönteminin dönüş türünden önce abstract anahtar
sözcüğü eklenerek gerçekleştirilir. Örneğin:

public abstract class A


{
public abstract void DoWork(int i);
}

Soyut yöntemlerin hiçbir uygulamaya sahip olmadığı için, yöntem tanımının normal yöntem bloğu yerine
noktalı virgül gelmelidir. Soyut sınıfın türetilmiş sınıfları tüm soyut yöntemleri uygulamalıdır. Bir soyut sınıf
bir temel sınıftan sanal bir yöntemi devralıyorsa, soyut sınıf, soyut bir yöntemle sanal yöntemi geçersiz
kılabilir. Örneğin:
// compile with: -target:library
public class D
{
public virtual void DoWork(int i)
{
// Original implementation.
}
}

public abstract class E : D


{
public abstract override void DoWork(int i);
}

public class F : E
{
public override void DoWork(int i)
{
// New implementation.
}
}

Bir virtual yöntemi abstract olarak bildirilirse, bu, soyut sınıftan devralan herhangi bir sınıfta hala sanal
olur. Soyut bir yöntemi devralan sınıf yöntemin orijinal uygulamasına erişemez — önceki örnekte, F
sınıfındaki DoWork , D sınıfında DoWork çağıramaz. Bu şekilde, soyut bir sınıf, türetilmiş sınıfları sanal
yöntemler için yeni yöntem uygulamaları sağlamaya zorlayabilir.

Korumalı sınıflar ve sınıf üyeleri


Sınıflar, sınıf tanımından önce anahtar sözcüğü sealed koyarak mühürlü olarak bildirilemez. Örneğin:

public sealed class D


{
// Class members here.
}

Sealed bir sınıf temel sınıf olarak kullanılamaz. Bu nedenle, bir soyut sınıf de olamaz. Sealed sınıflar
türetmeye engel. Bunlar hiçbir zaman temel sınıf olarak kullanılabileceğinden, bazı çalışma zamanı
iyileştirmeleri sealed sınıf üyelerinin çağrılmasını biraz daha hızlı hale getirir.
Temel sınıfın bir sanal üyesini geçersiz kılan türetilmiş bir sınıfta bir yöntem, Dizin Oluşturucu, özellik veya
olay bu üyeyi korumalı olarak bildirebilir. Bu, daha fazla türetilmiş sınıf için üyenin sanal yönünü geçersiz kılar.
Bu, sınıf üye bildirimindeki override anahtar sözcüğünden önce sealed anahtar sözcüğünü yerleştirerek
gerçekleştirilir. Örneğin:

public class D : C
{
public sealed override void DoWork() { }
}

Ayrıca bkz.
C# Programlama Kılavuzu
Sınıflar ve Yapılar
Devralma
Yöntemler
Alanlar
Soyut özellikleri tanımlama
Statik Sınıflar ve Statik Sınıf Üyeleri (C#
Programlama Kılavuzu)
4.11.2019 • 9 minutes to read • Edit Online

Statik bir sınıf temelde statik olmayan bir sınıfla aynıdır, ancak bir fark vardır: statik bir sınıf örneği
oluşturulamıyor. Diğer bir deyişle, sınıf türünde bir değişken oluşturmak için New işlecini kullanamazsınız.
Örnek değişkeni olmadığından, bir statik sınıfın üyelerine sınıf adının kendisini kullanarak erişirsiniz. Örneğin,
MethodA adlı ortak bir statik yöntemi olan UtilityClass adlı statik bir sınıfınız varsa, aşağıdaki örnekte
gösterildiği gibi yöntemi çağırın:

UtilityClass.MethodA();

Statik bir sınıf, yalnızca giriş parametrelerinde çalışan yöntemlerin kümeleri için uygun bir kapsayıcı olarak
kullanılabilir ve herhangi bir iç örnek alanı almak veya ayarlamak zorunda değildir. Örneğin, .NET Framework
sınıf kitaplığında statik System.Math sınıfı, Math sınıfının belirli bir örneğine özgü verileri depolamak veya
almak için herhangi bir gereksinim olmadan matematik işlemleri gerçekleştiren yöntemler içerir. Diğer bir
deyişle, aşağıdaki örnekte gösterildiği gibi sınıf adını ve yöntem adını belirterek sınıfının üyelerini uygularsınız.

double dub = -3.14;


Console.WriteLine(Math.Abs(dub));
Console.WriteLine(Math.Floor(dub));
Console.WriteLine(Math.Round(Math.Abs(dub)));

// Output:
// 3.14
// -4
// 3

Tüm sınıf türlerinde olduğu gibi, bir statik sınıfa ait tür bilgileri, sınıfa başvuran program yüklendiğinde .NET
Framework ortak dil çalışma zamanı (CLR ) tarafından yüklenir. Program, sınıf yüklendiğinde tam olarak
belirtemez. Ancak, yüklenmesi ve alanları başlatılmış olması garantidir ve bu sınıfın, sınıf ilk kez bir kez
başvurulmadan önce çağrılan statik Oluşturucusu çağırılır. Statik bir Oluşturucu yalnızca bir kez çağrılır ve
programınızın bulunduğu uygulama etki alanının ömrü boyunca statik bir sınıf bellekte kalır.

NOTE
Yalnızca tek bir örneğinin oluşturulmasına izin veren statik olmayan bir sınıf oluşturmak için, bkz. tek Içinde C#uygulama .

Aşağıdaki liste, bir statik sınıfın ana özelliklerini sağlar:


Yalnızca statik üyeleri içerir.
Örneği oluşturulamıyor.
Mühürlü.
Örnek oluşturuculariçeremez.
Statik sınıf oluşturmak, bu nedenle temelde yalnızca statik üyeler ve özel bir Oluşturucu içeren bir sınıf
oluşturma ile aynıdır. Özel Oluşturucu sınıfın oluşturulmasını engeller. Statik sınıf kullanmanın avantajı,
derleyicinin yanlışlıkla hiç örnek üye bulunmadığından emin olmak için denetim yapamamasına olanak sağlar.
Derleyici, bu sınıfın örneklerinin oluşturuoluşturulamadığı garantisi alacak.
Statik sınıflar mühürlenmiş ve bu nedenle devralınamaz. Objectdışında herhangi bir sınıftan devralınabilir.
Statik sınıflar bir örnek oluşturucu içeremez; Ancak, bir statik Oluşturucu içerebilirler. Statik olmayan sınıflar
Ayrıca, sınıf önemsiz olmayan başlatma gerektiren statik üyeler içeriyorsa statik bir Oluşturucu tanımlamalıdır.
Daha fazla bilgi için bkz. statik oluşturucular.

Örnek
Aşağıda, sıcaklığın Fahrenhayt 'e ve Fahrenhayt 'e kadar olan iki yöntem içeren bir statik sınıfa örnek
verilmiştir:

public static class TemperatureConverter


{
public static double CelsiusToFahrenheit(string temperatureCelsius)
{
// Convert argument to double for calculations.
double celsius = Double.Parse(temperatureCelsius);

// Convert Celsius to Fahrenheit.


double fahrenheit = (celsius * 9 / 5) + 32;

return fahrenheit;
}

public static double FahrenheitToCelsius(string temperatureFahrenheit)


{
// Convert argument to double for calculations.
double fahrenheit = Double.Parse(temperatureFahrenheit);

// Convert Fahrenheit to Celsius.


double celsius = (fahrenheit - 32) * 5 / 9;

return celsius;
}
}

class TestTemperatureConverter
{
static void Main()
{
Console.WriteLine("Please select the convertor direction");
Console.WriteLine("1. From Celsius to Fahrenheit.");
Console.WriteLine("2. From Fahrenheit to Celsius.");
Console.Write(":");

string selection = Console.ReadLine();


double F, C = 0;

switch (selection)
{
case "1":
Console.Write("Please enter the Celsius temperature: ");
F = TemperatureConverter.CelsiusToFahrenheit(Console.ReadLine());
Console.WriteLine("Temperature in Fahrenheit: {0:F2}", F);
break;

case "2":
Console.Write("Please enter the Fahrenheit temperature: ");
C = TemperatureConverter.FahrenheitToCelsius(Console.ReadLine());
Console.WriteLine("Temperature in Celsius: {0:F2}", C);
break;

default:
Console.WriteLine("Please select a convertor.");
break;
break;
}

// Keep the console window open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* Example Output:
Please select the convertor direction
1. From Celsius to Fahrenheit.
2. From Fahrenheit to Celsius.
:2
Please enter the Fahrenheit temperature: 20
Temperature in Celsius: -6.67
Press any key to exit.
*/

Statik Üyeler
Statik olmayan bir sınıf statik yöntemler, alanlar, özellikler veya olaylar içerebilir.Statik üye, sınıfın bir örneği
oluşturulmasa bile bir sınıf üzerinde çağrılabilir. Statik üyeye, örnek adı değil, her zaman sınıf adı tarafından
erişilir. Statik üyenin yalnızca bir kopyası, sınıfının kaç örneğinin oluşturulduğuna bakılmaksızın vardır. Statik
yöntemler ve özellikler, kendi kapsayıcı türündeki statik olmayan alanlara ve olaylara erişemez ve bir yöntem
parametresine açıkça geçirilmediği takdirde herhangi bir nesnenin örnek değişkenine erişemez.
Statik olmayan bir sınıfı bazı statik üyelere bildirmek daha tipik bir deyişle, bir sınıfın tamamını statik olarak
bildirmek daha normaldir. Statik alanların iki ortak kullanımı, örneği oluşturulmuş nesne sayısının sayısını
tutmak veya tüm örnekler arasında paylaşılması gereken bir değeri depolamak için kullanılır.
Statik yöntemler, sınıfın herhangi bir örneğine değil, sınıfına ait olduğundan aşırı yüklenebilir ancak geçersiz
kılınmaz.
Bir alan static const olarak bildirilemez olsa da, bir const alanı, davranışında temelde statiktir. Tür örneklerine
değil, türüne aittir. Bu nedenle, const alanlarına statik alanlar için kullanılan ClassName.MemberName gösterimi
kullanılarak erişilebilir. Nesne örneği gerekli değil.
C#statik yerel değişkenleri desteklemez (Yöntem kapsamında belirtilen değişkenler).
Aşağıdaki örnekte gösterildiği gibi, üyenin dönüş türünden önce static anahtar sözcüğünü kullanarak statik
sınıf üyeleri bildirirsiniz:

public class Automobile


{
public static int NumberOfWheels = 4;
public static int SizeOfGasTank
{
get
{
return 15;
}
}
public static void Drive() { }
public static event EventType RunOutOfGas;

// Other non-static fields and properties...


}

Statik üyeler, statik üyeye ilk kez erişilmeden ve statik oluşturucu bir tane varsa, önce başlatılır.Statik sınıf
üyesine erişmek için, aşağıdaki örnekte gösterildiği gibi, üyenin konumunu belirtmek için değişken adı yerine
sınıfın adını kullanın:
Automobile.Drive();
int i = Automobile.NumberOfWheels;

Sınıfınız statik alanlar içeriyorsa, sınıfı yüklendiğinde bunları başlatan bir statik Oluşturucu sağlayın.
Statik bir yönteme yapılan çağrı, Microsoft ara dili (MSIL ) içinde bir çağrı yönergesi oluşturur, ancak bir örnek
yöntemine yapılan çağrı bir callvirt yönerge oluşturur ve bu da null nesne başvurularını denetler. Ancak, ikisi
arasındaki performans farkı çoğu zaman önemli değildir.

C# Dil Belirtimi
Daha fazla bilgi için, C# dil belirtiminde statik sınıflar ve statik ve örnek üyeleri bölümüne bakın. Dil belirtimi,
C# sözdizimi ve kullanımı için kesin bir kaynaktır.

Ayrıca bkz.
C# Programlama Kılavuzu
static
Sınıflar
class
Statik Oluşturucular
Örnek Oluşturucuları
Erişim Değiştiricileri (C# Programlama Kılavuzu)
23.10.2019 • 7 minutes to read • Edit Online

Tüm türler ve tür üyeleri, derlemenizin veya diğer derlemelerinizdeki diğer koddan kullanılıp
kullanılamayacağını denetleyen bir erişilebilirlik düzeyine sahiptir. Aşağıdaki erişim değiştiricilerini, bir tür
veya üyenin bildirimini yaparken belirtmek için kullanabilirsiniz:
public
Türe veya üyeye aynı derlemedeki veya buna başvuran başka bir derlemede bir veya daha fazla kod
tarafından erişilebilir.
private
Türe veya üyeye yalnızca aynı sınıf veya yapı içindeki kodla erişilebilir.
protected
Türe veya üyeye yalnızca aynı sınıftaki kodla veya bu sınıftan türetilmiş bir sınıfta erişilebilir.
internal
Türe veya üyeye aynı derlemedeki kod tarafından erişilebilir, ancak başka bir derlemeden erişilebilir.
korumalı iç Türe veya üyeye, bildirildiği derlemede ya da başka bir derlemedeki türetilmiş bir sınıftan
erişilebilen herhangi bir kod tarafından erişilebilir.
özel korumalı Türe veya üyeye yalnızca bildirim derlemesi içinde, aynı sınıftaki veya bu sınıftan türetilmiş bir
türde koda erişilebilir.
Aşağıdaki örneklerde, bir tür ve üye üzerinde erişim değiştiricilerin nasıl belirtildiğini gösterilmektedir:

public class Bicycle


{
public void Pedal() { }
}

Tüm erişim değiştiricileri tüm bağlamlardaki tüm türler veya Üyeler tarafından kullanılamaz ve bazı
durumlarda bir tür üyesinin erişilebilirliği, kapsayan türünün erişilebilirliği tarafından kısıtlanıyor. Aşağıdaki
bölümler erişilebilirlik hakkında daha fazla ayrıntı sağlar.

Sınıf ve yapı erişilebilirliği


Bir ad alanı içinde doğrudan tanımlanmış sınıflar ve yapılar (diğer bir deyişle, diğer sınıfların veya yapıların
içinde iç içe olmayan), genel veya iç olabilir. Bir erişim değiştiricisi belirtilmemişse, iç varsayılandır.
İç içe sınıflar ve yapılar dahil yapı üyeleri, genel, iç veya özel olarak bildirilebilecek. İç içe sınıflar ve yapılar
dahil olmak üzere sınıf üyeleri ortak, korumalı dahili, korunan, dahili, özel korumalı veya özel olabilir. Sınıf
üyeleri ve yapı üyeleri için iç içe sınıflar ve yapılar dahil erişim düzeyi varsayılan olarak özeldir. Özel iç içe
türlere, kapsayan türün dışından erişilemez.
Türetilmiş sınıfların temel türlerinden daha fazla erişilebilirliği olamaz. Diğer bir deyişle, bir iç sınıftan B A
türeyen ortak bir sınıfa sahip olabilirsiniz. Buna izin verildiyse, tüm korumalı veya iç A A üyelerine türetilmiş
sınıftan erişilebileceğinden, bu, ortak hale getirme etkisine sahip olur.
InternalsVisibleToAttribute kullanarak, özel diğer derlemelerin iç türlerinizi erişmesini sağlayabilirsiniz. Daha
fazla bilgi için bkz. arkadaş derlemeler.
Sınıf ve yapı üye erişilebilirliği
Sınıf üyeleri (iç içe geçmiş sınıflar ve yapılar dahil) altı erişim türlerinden herhangi biriyle bildirilebilecek.
Yapılar devralmayı desteklemediğinden, yapı üyeleri korumalı olarak bildirilemez.
Normalde, bir üyenin erişilebilirliği onu içeren türün erişilebilirliğiyle daha büyük değildir. Ancak, üye arabirim
yöntemleri uygularsa veya ortak bir temel sınıfta tanımlanan sanal yöntemleri geçersiz kıldığında, iç sınıfın
ortak bir üyesine derleme dışından erişilebilir.
Bir alan, özellik veya olay olan herhangi bir üyenin türü, en azından üyenin kendisi olarak erişilebilir olmalıdır.
Benzer şekilde, dönüş türü ve bir yöntem, Dizin Oluşturucu ya da temsilci olan herhangi bir üyenin parametre
türleri en azından üyenin kendisi olarak erişilebilir olmalıdır. Örneğin, ortak M C olmayan bir sınıf C
döndüren ortak bir metoda sahip olamaz. Benzer şekilde, özel olarak bildirilirse türünde A A korumalı bir
özelliği olamaz.
Kullanıcı tanımlı işleçler her zaman ortak ve statik olarak bildirilmelidir. Daha fazla bilgi için bkz. operatör aşırı
yüklemesi.
Sonlandırıcılar erişilebilirlik değiştiricilerine sahip olamaz.
Bir sınıf veya yapı üyesinin erişim düzeyini ayarlamak için, aşağıdaki örnekte gösterildiği gibi, üye bildirimine
uygun anahtar sözcüğü ekleyin.

// public class:
public class Tricycle
{
// protected method:
protected void Pedal() { }

// private field:
private int wheels = 3;

// protected internal property:


protected internal int Wheels
{
get { return wheels; }
}
}

NOTE
Korunan iç erişilebilirlik düzeyi korumalı veya dahili, korumalı ve dahili anlamına gelir. Diğer bir deyişle, korunan bir iç
üyeye, türetilmiş sınıflar dahil olmak üzere aynı derlemedeki herhangi bir sınıftan erişilebilir. Erişilebilirliği yalnızca aynı
derlemede bulunan türetilmiş sınıflarla sınırlamak için, sınıfın kendisini iç bildirin ve üyelerini korumalı olarak bildirin.
Ayrıca, 7,2 ile C# başlayarak, özel korumalı erişim değiştiricisini kullanarak, kapsayan sınıfı iç oluşturmanız gerekmeden
aynı sonucu elde edebilirsiniz.

Diğer türler
Bir ad alanı içinde doğrudan tanımlanmış arabirimler, genel veya iç olarak veya sınıflar ve yapılar gibi,
varsayılan olarak dahili erişim için arabirimler olarak belirtilebilir. Arabirim üyeleri her zaman geneldir çünkü
bir arabirimin amacı başka türlerin bir sınıfa veya yapıya erişmesine olanak sağlamaktır. Arabirim üyelerine
erişim değiştiricileri uygulanamaz.
Numaralandırma üyeleri her zaman geneldir ve erişim değiştiricileri uygulanmaz.
Temsilciler sınıflar ve yapılar gibi davranır. Varsayılan olarak, bir ad alanı içinde doğrudan bildirildiği sırada iç
erişimleri ve iç içe olduğunda özel erişim vardır.
C# Dil Belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
C# Programlama Kılavuzu
Sınıflar ve Yapılar
Arabirimler
private
public
internal
protected
protected internal
private protected
class
struct
interface
Alanlar (C# Programlama Kılavuzu)
25.11.2019 • 5 minutes to read • Edit Online

Alan , bir sınıf veya Yapıiçinde doğrudan tanımlanmış herhangi bir türdeki değişkendir. Alanlar, kapsayan
türlerinin üyeleridir .
Bir sınıf veya yapının örnek alanları veya statik alanları ya da her ikisi birden olabilir. Örnek alanları, bir türün
örneğine özeldir. Örnek alanı F olan bir sınıf T 'si varsa, T türünde iki nesne oluşturabilir ve diğer nesnedeki değeri
etkilemeden her bir nesnede F değerini değiştirebilirsiniz. Buna karşılık, statik bir alan sınıfa aittir ve bu sınıfın tüm
örnekleri arasında paylaşılır. A örneğinden yapılan değişiklikler, alana erişim varsa B ve C örneklerine hemen
görünür.
Genellikle, yalnızca özel veya korumalı erişilebilirliği olan değişkenler için alanları kullanmanız gerekir. Sınıfınızın
istemci koduna sunduğu veriler Yöntemler, Özellikler ve Dizin oluşturuculararacılığıyla sağlanmalıdır. İç alanlara
dolaylı erişim için bu yapıları kullanarak, geçersiz giriş değerlerine karşı koruma sağlayabilirsiniz. Ortak bir özellik
tarafından açığa çıkarılan verileri depolayan özel bir alan, yedekleme deposu veya yedekleme alanıolarak
adlandırılır.
Alanlar genellikle birden fazla sınıf yöntemine erişilebilir olması gereken verileri depolar ve tek bir yöntemin
yaşam süresinden daha uzun bir süre içinde depolanmalıdır. Örneğin, bir takvim tarihini temsil eden bir sınıf üç
tamsayı alanına sahip olabilir: biri ayda, biri gün için ve diğeri yıl için. Tek bir yöntemin kapsamı dışında
kullanılmayan değişkenler, Yöntem gövdesinin içinde yerel değişkenler olarak bildirilmelidir.
Alanlar, alanın erişim düzeyini, ardından alanın türü ve ardından alanın adı tarafından belirtilen sınıf bloğunda
belirtilir. Örneğin:
public class CalendarEntry
{
// private field
private DateTime date;

// public field (Generally not recommended.)


public string day;

// Public property exposes date field safely.


public DateTime Date
{
get
{
return date;
}
set
{
// Set some reasonable boundaries for likely birth dates.
if (value.Year > 1900 && value.Year <= DateTime.Today.Year)
{
date = value;
}
else
throw new ArgumentOutOfRangeException();
}

// Public method also exposes date field safely.


// Example call: birthday.SetDate("1975, 6, 30");
public void SetDate(string dateString)
{
DateTime dt = Convert.ToDateTime(dateString);

// Set some reasonable boundaries for likely birth dates.


if (dt.Year > 1900 && dt.Year <= DateTime.Today.Year)
{
date = dt;
}
else
throw new ArgumentOutOfRangeException();
}

public TimeSpan GetTimeSpan(string dateString)


{
DateTime dt = Convert.ToDateTime(dateString);

if (dt != null && dt.Ticks < date.Ticks)


{
return date - dt;
}
else
throw new ArgumentOutOfRangeException();

}
}

Bir nesnedeki alana erişmek için, nesne adından sonra, objectname.fieldname ' de olduğu gibi alanın adı ile bir
nokta ekleyin. Örneğin:

CalendarEntry birthday = new CalendarEntry();


birthday.day = "Saturday";

Alan bildirildiği zaman atama işleci kullanılarak bir alana ilk değer verilebilir. day alanını "Monday" otomatik
olarak atamak için, örneğin, aşağıdaki örnekte olduğu gibi day bildirimini yapmanız gerekir:

public class CalendarDateWithInitialization


{
public string day = "Monday";
//...
}

Alanlar, nesne örneği Oluşturucusu çağrılmadan hemen önce başlatılır. Oluşturucu bir alanın değerini atadığında,
alan bildirimi sırasında verilen değerin üzerine yazar. Daha fazla bilgi için bkz. oluşturucular kullanma.

NOTE
Alan başlatıcısı diğer örnek alanlarına başvuramaz.

Alanlar ortak, özel, korunan, dahili, korunan iç veya özel korumalıolarak işaretlenebilir. Bu erişim değiştiricileri,
sınıfın kullanıcılarının alanlara nasıl erişebileceğini tanımlar. Daha fazla bilgi için bkz. erişim değiştiricileri.
Bir alan, isteğe bağlı olarak statikolarak bildirilemez. Bu, sınıfın bir örneği mevcut olmasa bile, alanı her zaman
çağıranlar için kullanılabilir hale getirir. Daha fazla bilgi için bkz. statik sınıflar ve statik sınıf üyeleri.
Bir alan ReadOnlyolarak bildirilemez. Salt okunurdur bir alana yalnızca başlatma sırasında veya oluşturucuda bir
değer atanabilir. Bir static readonly alanı, C# derleyicinin derleme zamanında statik bir salt okuma alanının
değerine erişimi olmaması dışında, yalnızca çalışma zamanında bir sabit değere benzer. Daha fazla bilgi için bkz.
sabitler.

C# Dil Belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir kaynaktır.

Ayrıca bkz.
C# Programlama Kılavuzu
Sınıflar ve Yapılar
Oluşturucuları Kullanma
Devralma
Erişim Değiştiricileri
Soyut ve Korumalı Sınıflar ve Sınıf Üyeleri
Sabitler (C# Programlama Kılavuzu)
23.10.2019 • 4 minutes to read • Edit Online

Sabitler, derleme zamanında bilinen ve programın ömrü boyunca değişmeyen sabit değerlerdir. Sabitler const
değiştiricisi ile bildirilmiştir. Yalnızca C# yerleşik türler (hariç System.Object) olarak const bildirilebilecek. Yerleşik
türlerin listesi için bkz. Yerleşik türler tablosu. Sınıflar, yapılar ve diziler const dahil olmak üzere Kullanıcı tanımlı
türler olamaz. Çalışma zamanında bir kez başlatılan bir sınıf, yapı veya dizi oluşturmak için salt okunur
değiştiricisini kullanın (örneğin, bir oluşturucuda) ve bundan sonra değiştirilemez.
C#yöntemleri, özellikleri const veya olayları desteklemez.
Sabit listesi türü, integral yerleşik türler (örneğin int uint long ,, vb.) için adlandırılmış sabitler tanımlamanızı
sağlar. Daha fazla bilgi için bkz. enum.
Sabitler, bildirildiği için başlatılmalıdır. Örneğin:

class Calendar1
{
public const int Months = 12;
}

Bu örnekte, sabit months her zaman 12 ' dir ve sınıfın kendisi tarafından bile değiştirilemez. Aslında, derleyici C#
kaynak kodunda bir sabit tanımlayıcıyla karşılaştığında (örneğin, months ), değişmez değer değerini doğrudan
ürettiği ara dil (IL ) koduna koyar. Çalışma zamanında bir sabitle ilişkili değişken adresi olmadığından, const
alanlar başvuruya göre geçirilemez ve bir ifadede l değeri olarak görünemez.

NOTE
Dll 'Ler gibi başka bir kodda tanımlanan sabit değerlere başvurduğunuzda dikkatli olun. Yeni bir DLL sürümü sabit için yeni
bir değer tanımlıyorsa, programınız yeni sürüme yeniden derlenene kadar eski değişmez değeri de tutar.

Aynı türden birden fazla sabit aynı anda bildirilebilecek, örneğin:

class Calendar2
{
public const int Months = 12, Weeks = 52, Days = 365;
}

Bir sabiti başlatmak için kullanılan ifade, döngüsel başvuru oluşturmayan başka bir sabite başvurabilir. Örneğin:

class Calendar3
{
public const int Months = 12;
public const int Weeks = 52;
public const int Days = 365;

public const double DaysPerWeek = (double) Days / (double) Weeks;


public const double DaysPerMonth = (double) Days / (double) Months;
}

Sabitler, genel, özel, korumalı, dahili, korunan iç veya özel korumalıolarak işaretlenebilir. Bu erişim değiştiricileri,
sınıfın kullanıcılarının sabitine nasıl erişekullanabileceğinizi tanımlar. Daha fazla bilgi için bkz. erişim değiştiricileri.
Sabitlere statik alanlar gibi erişilir çünkü sabit değeri, türün tüm örnekleri için aynı. Bunları bildirmek için static
anahtar sözcüğünü kullanmayın. Sabiti tanımlayan sınıfta olmayan ifadeler, sabit erişim için sınıf adı, nokta ve
sabitin adını kullanmalıdır. Örneğin:

int birthstones = Calendar.Months;

C# Dil Belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir kaynaktır.

Ayrıca bkz.
C# Programlama Kılavuzu
Sınıflar ve Yapılar
Özellikler
Türler
readonly
Birinci C# bölümde imleyici kullanılabilirliği: Imlik kullanılabilirliği türleri
Özet özellikleri tanımlama (C# Programlama
Kılavuzu)
25.11.2019 • 3 minutes to read • Edit Online

Aşağıdaki örnek, soyut özelliklerin nasıl tanımlanacağını gösterir. Soyut özellik bildirimi, özellik erişimcilerinin bir
uygulamasını sağlamaz--sınıfın özellikleri desteklediğini bildirir, ancak erişimci uygulamasını türetilmiş sınıflara
bırakır. Aşağıdaki örnek, temel bir sınıftan devralınan soyut özelliklerin nasıl uygulanacağını gösterir.
Bu örnek, her biri ayrı ayrı derlenen üç dosyadan oluşur ve sonuçta elde edilen derlemeye sonraki derleme
tarafından başvurulur:
abstractshape.cs: soyut bir Area özelliği içeren Shape sınıfı.
shapes.cs: Shape sınıfının alt sınıfları.
shapetest.cs: bazı Shape türetilmiş nesnelerin bölümlerini görüntüleyen bir test programı.
Örneği derlemek için aşağıdaki komutu kullanın:
csc abstractshape.cs shapes.cs shapetest.cs

Bu, shapetest. exe yürütülebilir dosyasını oluşturur.

Örnek
Bu dosya, double türünün Area özelliğini içeren Shape sınıfını bildirir.
// compile with: csc -target:library abstractshape.cs
public abstract class Shape
{
private string name;

public Shape(string s)
{
// calling the set accessor of the Id property.
Id = s;
}

public string Id
{
get
{
return name;
}

set
{
name = value;
}
}

// Area is a read-only property - only a get accessor is needed:


public abstract double Area
{
get;
}

public override string ToString()


{
return $"{Id} Area = {Area:F2}";
}
}

Özelliğindeki değiştiriciler Özellik bildiriminin kendine yerleştirilir. Örneğin:

public abstract double Area

Soyut bir özellik bildirirken (Bu örnekte Area gibi), yalnızca hangi özellik erişimcilerinin kullanılabildiğini,
ancak uygulamadığını belirtirsiniz. Bu örnekte, yalnızca bir Get erişimcisi bulunur, bu nedenle özellik salt
okunurdur.

Örnek
Aşağıdaki kod Shape üç alt kümesini ve kendi uygulamasını sağlamak için Area özelliğini nasıl geçersiz kıladığını
gösterir.
// compile with: csc -target:library -reference:abstractshape.dll shapes.cs
public class Square : Shape
{
private int side;

public Square(int side, string id)


: base(id)
{
this.side = side;
}

public override double Area


{
get
{
// Given the side, return the area of a square:
return side * side;
}
}
}

public class Circle : Shape


{
private int radius;

public Circle(int radius, string id)


: base(id)
{
this.radius = radius;
}

public override double Area


{
get
{
// Given the radius, return the area of a circle:
return radius * radius * System.Math.PI;
}
}
}

public class Rectangle : Shape


{
private int width;
private int height;

public Rectangle(int width, int height, string id)


: base(id)
{
this.width = width;
this.height = height;
}

public override double Area


{
get
{
// Given the width and height, return the area of a rectangle:
return width * height;
}
}
}

Örnek
Aşağıdaki kod Shape türetilmiş bir nesne oluşturan bir test programı gösterir ve kendi alanını yazdırır.

// compile with: csc -reference:abstractshape.dll;shapes.dll shapetest.cs


class TestClass
{
static void Main()
{
Shape[] shapes =
{
new Square(5, "Square #1"),
new Circle(3, "Circle #1"),
new Rectangle( 4, 5, "Rectangle #1")
};

System.Console.WriteLine("Shapes Collection");
foreach (Shape s in shapes)
{
System.Console.WriteLine(s);
}
}
}
/* Output:
Shapes Collection
Square #1 Area = 25.00
Circle #1 Area = 28.27
Rectangle #1 Area = 20.00
*/

Ayrıca bkz.
C# Programlama Kılavuzu
Sınıflar ve Yapılar
Soyut ve Korumalı Sınıflar ve Sınıf Üyeleri
Veri Erişimi
C# sabitleri tanımlama
25.11.2019 • 2 minutes to read • Edit Online

Sabitler, değerleri derleme zamanında ayarlanan alanlardır ve hiçbir zaman değiştirilemez. Özel değerler için
sayısal değişmez değerler ("sihirli sayılar") yerine anlamlı adlar sağlamak için sabitleri kullanın.

NOTE
C# #Define Önişlemci yönergesinde, sabitleri genellikle C ve C++içinde kullanılan biçimde tanımlamak için kullanılamaz.

İntegral türlerinin sabit değerlerini ( int , byte vb.) tanımlamak için numaralandırılmış bir tür kullanın. Daha fazla
bilgi için bkz. enum.
Tamsayı olmayan sabitleri tanımlamak için, tek bir yaklaşım onları Constants adlı tek bir statik sınıfta
gruplandırmaya yönelik bir yaklaşımdır. Bu, aşağıdaki örnekte gösterildiği gibi sabitlerin tüm başvurularının sınıf
adı ile önceden görüntülenmesini gerektirir.

Örnek
static class Constants
{
public const double Pi = 3.14159;
public const int SpeedOfLight = 300000; // km per sec.
}
class Program
{
static void Main()
{
double radius = 5.3;
double area = Constants.Pi * (radius * radius);
int secsFromSun = 149476000 / Constants.SpeedOfLight; // in km
}
}

Sınıf adı niteleyicisi kullanımı, siz ve sabit kullanan diğer kişilerin sabit olduğunu ve değiştirilemeyeceğini
anlamasını sağlar.

Ayrıca bkz.
Sınıflar ve Yapılar
Özellikler (C# Programlama Kılavuzu)
4.11.2019 • 7 minutes to read • Edit Online

Bir özellik, özel bir alanın değerini okumak, yazmak veya hesaplamak için esnek bir mekanizma sağlayan
bir üyesidir. Özellikler, ortak veri üyeleri gibi kullanılabilir, ancak aslında erişimcilerolarak adlandırılan özel
yöntemlerdir. Bu, verilere kolayca erişilmesine olanak sağlar ve yöntemlerin güvenliğini ve esnekliğini
yükseltmeye devam eder.

Özelliklere genel bakış


Özellikler, uygulama veya doğrulama kodunu gizlerken, değerleri almak ve ayarlamak için bir
sınıfın ortak bir yöntemini kullanıma sunar.
Get Property erişimcisi, özellik değerini döndürmek için kullanılır ve yeni bir değer atamak için bir
set özellik erişimcisi kullanılır. Bu erişimciler farklı erişim düzeylerine sahip olabilir. Daha fazla bilgi
için bkz. erişimci erişilebilirliğini kısıtlama.
Value anahtar sözcüğü, set erişimcisi tarafından atanan değeri tanımlamak için kullanılır.
Özellikler , salt yazılır (bir get ve set erişimcisine sahiptir), salt okunurdur (bir get erişimcisi
vardır ancak set erişimcisi yoktur) ya da salt yazılır (bir set erişimcisi vardır ancak get
erişimcisi yoktur). Salt yazılır özellikler nadir ve hassas verilere erişimi kısıtlamak için en yaygın
olarak kullanılır.
Özel erişimci kodu gerektirmeyen basit özellikler, ifade gövde tanımları ya da Otomatik uygulanan
özelliklerolarak uygulanabilir.

Yedekleme alanları olan özellikler


Özelliği uygulamak için bir temel model, özellik değerini ayarlamak ve almak için özel bir yedekleme alanı
kullanmayı içerir. get erişimci özel alanın değerini döndürür ve özel alana bir değer atamadan önce set
erişimci bazı veri doğrulaması gerçekleştirebilir. Her iki erişimci de verilerin depolanmadan veya
döndürülmeden önce veri üzerinde bazı dönüştürme veya hesaplama işlemleri yapabilir.
Aşağıdaki örnekte bu desenler gösterilmektedir. Bu örnekte, TimePeriod sınıfı bir zaman aralığını temsil
eder. Dahili olarak, sınıf, _seconds adlı bir özel alanda zaman aralığını saniye cinsinden depolar. Hours
adlı bir okuma-yazma özelliği, müşterinin saat cinsinden zaman aralığını belirtmesini sağlar. Hem get
hem de set erişimcileri, saat ve saniyeler arasında gerekli dönüştürme yapar. Ayrıca, set erişimcisi
verileri doğrular ve saat sayısı geçersizse bir ArgumentOutOfRangeException oluşturur.
using System;

class TimePeriod
{
private double _seconds;

public double Hours


{
get { return _seconds / 3600; }
set {
if (value < 0 || value > 24)
throw new ArgumentOutOfRangeException(
$"{nameof(value)} must be between 0 and 24.");

_seconds = value * 3600;


}
}
}

class Program
{
static void Main()
{
TimePeriod t = new TimePeriod();
// The property assignment causes the 'set' accessor to be called.
t.Hours = 24;

// Retrieving the property causes the 'get' accessor to be called.


Console.WriteLine($"Time in hours: {t.Hours}");
}
}
// The example displays the following output:
// Time in hours: 24

İfade gövdesi tanımları


Özellik erişimcileri genellikle yalnızca bir ifadenin sonucunu atayan veya döndüren tek satırlık
deyimlerden oluşur. Bu özellikleri ifade Bodied Üyeler olarak uygulayabilirsiniz. İfade gövdesi tanımları
=> sembolünden ve sonra, özelliğe atanacak veya bu kümeden alınacak olan ifadenin yer aldığı bir yer
içerir.
C# 6 ' dan itibaren, salt okuma özellikleri get erişimcisini ifade eden bir üye olarak uygulayabilir. Bu
durumda, get erişimci anahtar sözcüğünün ne de return anahtar sözcüğü kullanılmaz. Aşağıdaki
örnek, salt okunurdur Name özelliğini ifade-Bodied üyesi olarak uygular.
using System;

public class Person


{
private string _firstName;
private string _lastName;

public Person(string first, string last)


{
_firstName = first;
_lastName = last;
}

public string Name => $"{_firstName} {_lastName}";


}

public class Example


{
public static void Main()
{
var person = new Person("Magnus", "Hedlund");
Console.WriteLine(person.Name);
}
}
// The example displays the following output:
// Magnus Hedlund

7,0 ile C# başlayarak, hem get hem de set erişimcisi ifade Bodied Üyeler olarak uygulanabilir. Bu
durumda get ve set anahtar sözcükleri mevcut olmalıdır. Aşağıdaki örnek her iki erişimci için ifade
gövde tanımlarının kullanımını gösterir. return anahtar sözcüğünün get erişimcisi ile kullanılmadığını
unutmayın.
using System;

public class SaleItem


{
string _name;
decimal _cost;

public SaleItem(string name, decimal cost)


{
_name = name;
_cost = cost;
}

public string Name


{
get => _name;
set => _name = value;
}

public decimal Price


{
get => _cost;
set => _cost = value;
}
}

class Program
{
static void Main(string[] args)
{
var item = new SaleItem("Shoes", 19.95m);
Console.WriteLine($"{item.Name}: sells for {item.Price:C2}");
}
}
// The example displays output like the following:
// Shoes: sells for $19.95

Otomatik uygulanan özellikler


Bazı durumlarda, özellik get ve set erişimcileri, ek bir mantık dahil etmeden bir yalnızca bir değer
atayabilir veya bir yedekleme alanından bir değer alır. Otomatik uygulanan özellikleri kullanarak, C#
derleyicinin sizin için bir yedekleme alanı sunarak kodunuzu saydam bir şekilde sağlamasına gerek
kalmadan kodunuzu basitleştirebilirsiniz.
Bir özelliğin hem get hem de bir set erişimcisi varsa, her ikisinin de otomatik olarak uygulanması
gerekir. Herhangi bir uygulama sağlamadan get ve set anahtar sözcüklerini kullanarak otomatik
uygulanan bir özellik tanımlarsınız. Aşağıdaki örnek, Name ve Price otomatik olarak uygulanan
özellikler dışında, önceki bir şekilde yinelenir. Örneğin, SaleItem nesnelerinin parametresiz oluşturucuya
ve bir nesne başlatıcısınaçağrısıyla başlatılmış olması için, aynı zamanda parametreli oluşturucuyu de
kaldırdığına unutmayın.
using System;

public class SaleItem


{
public string Name
{ get; set; }

public decimal Price


{ get; set; }
}

class Program
{
static void Main(string[] args)
{
var item = new SaleItem{ Name = "Shoes", Price = 19.95m };
Console.WriteLine($"{item.Name}: sells for {item.Price:C2}");
}
}
// The example displays output like the following:
// Shoes: sells for $19.95

İlgili bölümler
Özellikleri Kullanma
Arabirim Özellikleri
Özellikler ve Dizin Oluşturucular Arasında Karşılaştırma
Erişimci Erişilebilirliğini Kısıtlama
Otomatik Uygulanan Özellikler

C# Dil Belirtimi
Daha fazla bilgi için bkz. C# dil belirtiminde Özellikler . Dil belirtimi, C# sözdizimi ve kullanımı için kesin
bir kaynaktır.

Ayrıca bkz.
C# Programlama Kılavuzu
Özellikleri Kullanma
Dizin Oluşturucular
anahtar sözcüğü al
anahtar sözcük ayarla
Özellikleri Kullanma (C# Programlama Kılavuzu)
23.10.2019 • 12 minutes to read • Edit Online

Özellikler her iki alanın ve yöntemin yönlerini birleştirir. Bir nesnenin kullanıcısına, bir özellik bir alan gibi görünür,
özelliğe erişim de aynı sözdizimini gerektirir. Bir sınıfın uygulayıcısı için bir özellik bir veya iki kod blobunun yanı
sıra bir Get erişimcisini ve/veya set erişimcisini temsil eder. @No__t_0 erişimcisinin kod bloğu, özellik okuma
sırasında yürütülür; set erişimcisine yönelik kod bloğu, özelliğe yeni bir değer atandığında yürütülür. @No__t_0
erişimcisi olmayan bir özellik salt okunurdur. @No__t_0 erişimcisi olmayan bir özellik salt yazılır olarak
değerlendirilir. Her iki erişimciyi sahip bir özellik okuma-yazma ' dır.
Alanların aksine, özellikler değişken olarak sınıflandırılmaz. Bu nedenle, bir özelliği ref veya Out parametresi
olarak geçiremezsiniz.
Özelliklerin birçok kullanımı vardır: bir değişikliğe izin vermeden önce verileri doğrulayabilir; verilerin aslında bir
veritabanı gibi başka bir kaynaktan alındığı bir sınıf üzerinde saydam bir şekilde veri sunabilir; bir olayı oluşturma
veya diğer alanların değerini değiştirme gibi veriler değiştirildiğinde bir eylem gerçekleştirebilir.
Özellikler, alanın erişim düzeyini, sonra özelliğin türünü ve sonra da bir get erişimcisi ve/veya set erişimcisi
bildiren bir kod bloğu belirtilerek, sınıf bloğunda bildirilir. Örneğin:

public class Date


{
private int _month = 7; // Backing store

public int Month


{
get => _month;
set
{
if ((value > 0) && (value < 13))
{
_month = value;
}
}
}
}

Bu örnekte, Month özellik olarak bildirildiği için set erişimcisinin Month değerinin 1 ile 12 arasında ayarlanmış
olduğundan emin olabilir. @No__t_0 özelliği, gerçek değeri izlemek için özel bir alan kullanır. Özelliğin verilerinin
gerçek konumu genellikle özelliğin "yedekleme deposu" olarak adlandırılır. Özelliklerin özel alanları bir yedekleme
deposu olarak kullanması yaygındır. Bu alan, yalnızca özelliği çağırarak değiştirilebilmesi için özel olarak işaretlenir.
Ortak ve özel erişim kısıtlamaları hakkında daha fazla bilgi için bkz. erişim değiştiricileri.
Otomatik uygulanan özellikler basit özellik bildirimleri için Basitleştirilmiş söz dizimi sağlar. Daha fazla bilgi için
bkz. Otomatik uygulanan özellikler.

Get erişimcisi
@No__t_0 erişimcisinin gövdesi bir yönteme benzer. Özellik türünün bir değerini döndürmesi gerekir. @No__t_0
erişimcisinin yürütülmesi alanın değerini okumayla eşdeğerdir. Örneğin, get erişimcisinden özel değişkeni
döndürmekte ve iyileştirmeler etkinleştirildikten sonra, get erişimci metoduna yapılan çağrı derleyici tarafından
satır içine alınır ve bu nedenle bir yöntem çağrı yükü yoktur. Ancak, derleyici derleme zamanında hangi yöntemin
çalışma zamanında çağrıldığı hakkında bilgi sahibi olmadığından, bir sanal get erişimci yöntemi satır içine
alınamaz. Aşağıda bir özel alan _name değerini döndüren bir get erişimcisi verilmiştir:

class Person
{
private string _name; // the name field
public string Name => _name; // the Name property
}

Özelliğe başvurduğunuzda, bir atamanın hedefi dışında, özelliğin değerini okumak için get erişimcisi çağrılır.
Örneğin:

Person person = new Person();


//...

System.Console.Write(person.Name); // the get accessor is invoked here

@No__t_0 erişimcisinin Return veya throw ifadesinde bitmesi ve denetim erişimci gövdesinin akışını kapatamıyor
olması gerekir.
@No__t_0 erişimcisini kullanarak nesnenin durumunu değiştirmek için hatalı bir programlama stilidir. Örneğin,
aşağıdaki erişimci _number alana her erişildiğinde nesnenin durumunu değiştirmenin yan etkisini üretir.

private int _number;


public int Number => _number++; // Don't do this

@No__t_0 erişimcisi, alan değerini döndürmek veya hesaplamak ve döndürmek için kullanılabilir. Örneğin:

class Employee
{
private string _name;
public string Name => _name != null ? _name : "NA";
}

Önceki kod segmentinde, Name özelliğine bir değer atamadıysanız, NA değeri döndürülür.

Set erişimcisi
@No__t_0 erişimcisi, dönüş türü voidolan bir yönteme benzer. Türü özelliğin türü olan value adlı örtük bir
parametre kullanır. Aşağıdaki örnekte, Name özelliğine bir set erişimcisi eklenmiştir:

class Person
{
private string _name; // the name field
public string Name // the Name property
{
get => _name;
set => _name = value;
}
}

Özelliğe bir değer atadığınızda, set erişimcisi yeni değeri sağlayan bir bağımsız değişken kullanılarak çağrılır.
Örneğin:
Person person = new Person();
person.Name = "Joe"; // the set accessor is invoked here

System.Console.Write(person.Name); // the get accessor is invoked here

@No__t_1 erişimcisindeki yerel değişken bildirimi için value örtük parametre adını kullanmak hatadır.

Açıklamalar
Özellikler public , private , protected , internal , protected internal veya private protected olarak
işaretlenebilir. Bu erişim değiştiricileri, sınıfın kullanıcılarının özelliğe nasıl erişekullanabileceğinizi tanımlar. Aynı
özelliğin get ve set erişimcileri farklı erişim değiştiricilerine sahip olabilir. Örneğin get , türün dışından salt
okuma erişimine izin vermek için public olabilir ve set private veya protected olabilir. Daha fazla bilgi için
bkz. erişim değiştiricileri.
Bir özellik static anahtar sözcüğü kullanılarak statik bir özellik olarak bildirilemez. Bu özellik, sınıfın bir örneği
mevcut olmasa bile, özelliği herhangi bir zamanda çağıranlar için kullanılabilir hale getirir. Daha fazla bilgi için bkz.
statik sınıflar ve statik sınıf üyeleri.
Bir özellik sanal anahtar sözcüğü kullanılarak sanal bir özellik olarak işaretlenebilir. Bu, türetilmiş sınıfların geçersiz
kılma anahtar sözcüğünü kullanarak özellik davranışını geçersiz kılmasını sağlar. Bu seçenekler hakkında daha
fazla bilgi için bkz. Devralma.
Sanal bir özelliği geçersiz kılan bir özellik de mühürlenebilir, bu da türetilmiş sınıflar için artık sanal değildir. Son
olarak, bir özellik soyutolarak bildirilemez. Bu, sınıfta bir uygulama olmadığı ve türetilen sınıfların kendi
uygulamasını yazması gerektiği anlamına gelir. Bu seçenekler hakkında daha fazla bilgi için bkz. soyut ve korumalı
sınıflar ve sınıf üyeleri.

NOTE
Statik bir özelliğin erişimcisi üzerinde sanal, Özetveya geçersiz kılma değiştiricisi kullanmak hatadır.

Örnek
Bu örnek örnek, statik ve salt okunurdur özelliklerini gösterir. Klavyeden çalışanın adını kabul eder, 1 ile
NumberOfEmployees artırır ve çalışan adını ve numarasını görüntüler.
public class Employee
{
public static int NumberOfEmployees;
private static int _counter;
private string _name;

// A read-write instance property:


public string Name
{
get => _name;
set => _name = value;
}

// A read-only static property:


public static int Counter => _counter;

// A Constructor:
public Employee() => _counter = ++NumberOfEmployees; // Calculate the employee's number:
}

class TestEmployee
{
static void Main()
{
Employee.NumberOfEmployees = 107;
Employee e1 = new Employee();
e1.Name = "Claude Vige";

System.Console.WriteLine("Employee number: {0}", Employee.Counter);


System.Console.WriteLine("Employee name: {0}", e1.Name);
}
}
/* Output:
Employee number: 108
Employee name: Claude Vige
*/

Örnek
Bu örnekte, türetilmiş bir sınıfta aynı ada sahip başka bir özellik tarafından gizlenen bir temel sınıftaki bir özelliğe
nasıl erişebileceğiniz gösterilmektedir:
public class Employee
{
private string _name;
public string Name
{
get => _name;
set => _name = value;
}
}

public class Manager : Employee


{
private string _name;

// Notice the use of the new modifier:


public new string Name
{
get => _name;
set => _name = value + ", Manager";
}
}

class TestHiding
{
static void Main()
{
Manager m1 = new Manager();

// Derived class property.


m1.Name = "John";

// Base class property.


((Employee)m1).Name = "Mary";

System.Console.WriteLine("Name in the derived class is: {0}", m1.Name);


System.Console.WriteLine("Name in the base class is: {0}", ((Employee)m1).Name);
}
}
/* Output:
Name in the derived class is: John, Manager
Name in the base class is: Mary
*/

Aşağıda, önceki örnekteki önemli noktaları verilmiştir:


Türetilmiş sınıftaki özellik Name , temel sınıftaki özelliği Name gizler. Böyle bir durumda new değiştiricisi
türetilmiş sınıftaki özelliğin bildiriminde kullanılır:

public new string Name

Cast (Employee) , temel sınıftaki Hidden özelliğine erişmek için kullanılır:

((Employee)m1).Name = "Mary";

Üyeleri gizleme hakkında daha fazla bilgi için bkz. Yeni değiştirici.

Örnek
Bu örnekte, iki sınıf, Cube ve Square , soyut bir sınıfı uygular Shape ve soyut Area özelliğini geçersiz kılar.
Özelliklerde geçersiz kılma değiştiricisinin kullanımını göz önünde kılarsınız . Program, yüzü bir giriş olarak kabul
eder ve kare ve küpün alanını hesaplar. Ayrıca, alanı bir girdi olarak kabul eder ve kare ve küp için ilgili tarafı
hesaplar.

abstract class Shape


{
public abstract double Area
{
get;
set;
}
}

class Square : Shape


{
public double side;

//constructor
public Square(double s) => side = s;

public override double Area


{
get => side * side;
set => side = System.Math.Sqrt(value);
}
}

class Cube : Shape


{
public double side;

//constructor
public Cube(double s) => side = s;

public override double Area


{
get => 6 * side * side;
set => side = System.Math.Sqrt(value / 6);
}
}

class TestShapes
{
static void Main()
{
// Input the side:
System.Console.Write("Enter the side: ");
double side = double.Parse(System.Console.ReadLine());

// Compute the areas:


Square s = new Square(side);
Cube c = new Cube(side);

// Display the results:


System.Console.WriteLine("Area of the square = {0:F2}", s.Area);
System.Console.WriteLine("Area of the cube = {0:F2}", c.Area);
System.Console.WriteLine();

// Input the area:


System.Console.Write("Enter the area: ");
double area = double.Parse(System.Console.ReadLine());

// Compute the sides:


s.Area = area;
c.Area = area;

// Display the results:


System.Console.WriteLine("Side of the square = {0:F2}", s.side);
System.Console.WriteLine("Side of the cube = {0:F2}", c.side);
}
}
}
/* Example Output:
Enter the side: 4
Area of the square = 16.00
Area of the cube = 96.00

Enter the area: 24


Side of the square = 4.90
Side of the cube = 2.00
*/

Ayrıca bkz.
C# Programlama Kılavuzu
Veri Erişimi
Arabirim Özellikleri
Otomatik Uygulanan Özellikler
Arabirim Özellikleri (C# Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Özellikler, bir arabirimdebildirilemez. Aşağıda bir arabirim özelliği erişimcisi örneği verilmiştir:

public interface ISampleInterface


{
// Property declaration:
string Name
{
get;
set;
}
}

Bir arabirim özelliğinin erişimcisinin gövdesi yok. Bu nedenle, erişimcilerinin amacı, özelliğin okuma-yazma, salt
okunurdur veya salt yazılır olduğunu belirtsağlamaktır.

Örnek
Bu örnekte, IEmployee arabirim, bir okuma-yazma özelliğine, Name ve salt okunurdur bir özelliğe sahiptir
Counter . Sınıf Employee IEmployee arabirimini uygular ve bu iki özelliği kullanır. Program yeni bir çalışanın adını
ve geçerli çalışan sayısını okur ve çalışan adını ve hesaplanan çalışan numarasını görüntüler.
Özelliğin, üyenin bildirildiği arabirime başvuruda bulunduğu tam nitelikli adını kullanabilirsiniz. Örneğin:

string IEmployee.Name
{
get { return "Employee Name"; }
set { }
}

Buna Açık arabirim uygulamaadı verilir. Örneğin, sınıfı Employee iki arabirimi ICitizen ve IEmployee ve her iki
arabirimde de Name özelliği varsa, açık arabirim üye uygulaması gerekli olacaktır. Diğer bir deyişle, aşağıdaki
özellik bildirimi:

string IEmployee.Name
{
get { return "Employee Name"; }
set { }
}

, aşağıdaki bildirim sırasında IEmployee arabirimindeki Name özelliğini uygular:

string ICitizen.Name
{
get { return "Citizen Name"; }
set { }
}

ICitizen arabirimindeki Name özelliğini uygular.


interface IEmployee
{
string Name
{
get;
set;
}

int Counter
{
get;
}
}

public class Employee : IEmployee


{
public static int numberOfEmployees;

private string _name;


public string Name // read-write instance property
{
get => _name;
set => _name = value;
}

private int _counter;


public int Counter // read-only instance property
{
get => _counter;
}

// constructor
public Employee() => _counter = ++numberOfEmployees;
}

class TestEmployee
{
static void Main()
{
System.Console.Write("Enter number of employees: ");
Employee.numberOfEmployees = int.Parse(System.Console.ReadLine());

Employee e1 = new Employee();


System.Console.Write("Enter the name of the new employee: ");
e1.Name = System.Console.ReadLine();

System.Console.WriteLine("The employee information:");


System.Console.WriteLine("Employee number: {0}", e1.Counter);
System.Console.WriteLine("Employee name: {0}", e1.Name);
}
}

210 Hazem Abolrous

Örnek çıkış
Enter number of employees: 210
Enter the name of the new employee: Hazem Abolrous
The employee information:
Employee number: 211
Employee name: Hazem Abolrous
Ayrıca bkz.
C# Programlama Kılavuzu
Veri Erişimi
Özellikleri Kullanma
Özellikler ve Dizin Oluşturucular Arasında Karşılaştırma
Dizin Oluşturucular
Arabirimler
Erişimci Erişilebilirliğini Kısıtlama (C# Programlama
Kılavuzu)
23.10.2019 • 6 minutes to read • Edit Online

Bir özelliğin veya dizin oluşturucunun Get ve set bölümlerine erişimcilerdenir. Varsayılan olarak, bu erişimciler ait
oldukları özelliğin veya dizin oluşturucunun aynı görünürlük veya erişim düzeyine sahiptir. Daha fazla bilgi için
bkz. Erişilebilirlik düzeyleri. Ancak, bu Erişimcilerde erişimi kısıtlamak bazen yararlı olur. Genellikle bu, erişimcinin
erişilebilirliğini set kısıtlamadan, get erişimcinin genel olarak erişilebilir tutulması ile ilgilidir. Örneğin:

private string _name = "Hello";

public string Name


{
get
{
return _name;
}
protected set
{
_name = value;
}
}

Bu örnekte, adlı Name bir özellik bir get ve set erişimcisi tanımlar. Erişimci, özelliğin public kendi erişilebilirlik
düzeyini alır, set bu durumda erişimci kendisine korumalı erişim değiştiricisi uygulanarak açıkça kısıtlanır. get

Erişimcilerde erişim değiştiricilerine yönelik kısıtlamalar


Özelliklerde veya dizin oluşturucularda erişimci değiştiricilerin kullanılması şu koşullara tabidir:
Bir arabirimde veya açık arabirim üyesi uygulamasında erişimci değiştiricileri kullanamazsınız.
Erişimci değiştiricileri yalnızca özellik veya dizin oluşturucunun hem hem set get de erişimcileri varsa
kullanabilirsiniz. Bu durumda, değiştiriciye yalnızca iki erişimcinin yalnızca birinde izin verilir.
Özelliğin veya dizin oluşturucunun bir geçersiz kılma değiştiricisi varsa, erişimci değiştiricisi, varsa geçersiz
kılınan erişimcinin erişimcisi ile eşleşmelidir.
Erişimcinin erişilebilirlik düzeyi, özelliğin veya dizin oluşturucunun kendi erişilebilirlik düzeyinden daha
kısıtlayıcı olmalıdır.

Geçersiz kılma erişimcileri üzerindeki erişim değiştiricileri


Bir özelliği veya dizin oluşturucuyu geçersiz kıldığınızda geçersiz kılınan erişimcilere geçersiz kılma kodu
tarafından erişilebilir olması gerekir. Ayrıca, hem Property/Indexer hem de erişimcilerinin erişilebilirliği karşılık
gelen geçersiz kılınan Özellik/Dizin Oluşturucu ve erişimcileri ile eşleşmelidir. Örneğin:
public class Parent
{
public virtual int TestProperty
{
// Notice the accessor accessibility level.
protected set { }

// No access modifier is used here.


get { return 0; }
}
}
public class Kid : Parent
{
public override int TestProperty
{
// Use the same accessibility level as in the overridden accessor.
protected set { }

// Cannot use access modifier here.


get { return 0; }
}
}

Arabirimleri uygulama
Bir arabirim uygulamak için erişimci kullandığınızda, erişimci bir erişim değiştiricisine sahip olmayabilir. Ancak,
gibi bir erişimci get kullanarak arabirimi uygularsanız, diğer erişimci aşağıdaki örnekte olduğu gibi bir erişim
değiştiricisine sahip olabilir:

public interface ISomeInterface


{
int TestProperty
{
// No access modifier allowed here
// because this is an interface.
get;
}
}

public class TestClass : ISomeInterface


{
public int TestProperty
{
// Cannot use access modifier here because
// this is an interface implementation.
get { return 10; }

// Interface property does not have set accessor,


// so access modifier is allowed.
protected set { }
}
}

Erişimci erişilebilirlik etki alanı


Erişimci üzerinde bir erişim değiştiricisi kullanırsanız, erişimcinin erişilebilirlik etki alanı bu değiştiriciye göre
belirlenir.
Erişimci üzerinde bir erişim değiştiricisi kullanmıyorsanız, erişimcinin erişilebilirlik etki alanı, özelliğin veya dizin
oluşturucunun erişilebilirlik düzeyine göre belirlenir.
Örnek
Aşağıdaki örnek üç sınıf BaseClass DerivedClass içerir,, ve MainClass . Üzerinde BaseClass Name ve
herikisınıftaikiözelliğivardır. Id Örnek, korumalı veya özelgibi kısıtlayıcı DerivedClass bir erişim değiştiricisi
kullandığınızda üzerinde özelliğinin Id Id nasıl BaseClass gizlendiğini gösterir. Bu nedenle, bu özelliğe değer
atadığınızda, BaseClass sınıfındaki özelliği yerine çağırılır. Erişim değiştiricisinin genel olarak değiştirilmesi,
özelliği erişilebilir hale getirir.
Örnek ayrıca private , içindeki Name protected özelliğininerişimcisinde set bulunan veya gibi kısıtlayıcı bir
erişim değiştiricisinin erişimciye erişimi önlediği ve ' a atarken bir hata üretmesinin gerektiğini gösterir.
DerivedClass içerdiği.

public class BaseClass


{
private string _name = "Name-BaseClass";
private string _id = "ID-BaseClass";

public string Name


{
get { return _name; }
set { }
}

public string Id
{
get { return _id; }
set { }
}
}

public class DerivedClass : BaseClass


{
private string _name = "Name-DerivedClass";
private string _id = "ID-DerivedClass";

new public string Name


{
get
{
return _name;
}

// Using "protected" would make the set accessor not accessible.


set
{
_name = value;
}
}

// Using private on the following property hides it in the Main Class.


// Any assignment to the property will use Id in BaseClass.
new private string Id
{
get
{
return _id;
}
set
{
_id = value;
}
}
}

class MainClass
{
static void Main()
{
BaseClass b1 = new BaseClass();
DerivedClass d1 = new DerivedClass();

b1.Name = "Mary";
d1.Name = "John";

b1.Id = "Mary123";
d1.Id = "John123"; // The BaseClass.Id property is called.

System.Console.WriteLine("Base: {0}, {1}", b1.Name, b1.Id);


System.Console.WriteLine("Derived: {0}, {1}", d1.Name, d1.Id);

// Keep the console window open in debug mode.


System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
}
/* Output:
Base: Name-BaseClass, ID-BaseClass
Derived: John, ID-BaseClass
*/

Açıklamalar
Bildirimini new private string Id ile new public string Id değiştirmeniz durumunda çıktıyı alırsınız:
Name and ID in the base class: Name-BaseClass, ID-BaseClass

Name and ID in the derived class: John, John123

Ayrıca bkz.
C# Programlama Kılavuzu
Özellikler
Dizin Oluşturucular
Erişim Değiştiricileri
Okuma yazma özelliklerini bildirme ve kullanma (C#
Programlama Kılavuzu)
25.11.2019 • 3 minutes to read • Edit Online

Özellikler, bir nesnenin verilerine korumasız, denetlenmeyen ve doğrulanmamış erişimle gelen riskler olmadan
ortak veri üyelerinin rahatlığını sağlar. Bu, erişimcileraracılığıyla gerçekleştirilir: temel alınan veri üyesine değerler
atayan ve alan özel yöntemler. Set erişimcisi veri üyelerinin atanmasını sağlar ve Get erişimcisi veri üyesi
değerlerini alır.
Bu örnek, iki özelliği olan bir Person sınıfını gösterir: Name (dize) ve Age (int). Her iki özellik de get ve set
erişimcileri sağlar, bu nedenle okuma/yazma özellikleri olarak değerlendirilir.

Örnek
class Person
{
private string _name = "N/A";
private int _age = 0;

// Declare a Name property of type string:


public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}

// Declare an Age property of type int:


public int Age
{
get
{
return _age;
}

set
{
_age = value;
}
}

public override string ToString()


{
return "Name = " + Name + ", Age = " + Age;
}
}

class TestPerson
{
static void Main()
{
// Create a new Person object:
Person person = new Person();
// Print out the name and the age associated with the person:
Console.WriteLine("Person details - {0}", person);

// Set some values on the person object:


person.Name = "Joe";
person.Age = 99;
Console.WriteLine("Person details - {0}", person);

// Increment the Age property:


person.Age += 1;
Console.WriteLine("Person details - {0}", person);

// Keep the console window open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* Output:
Person details - Name = N/A, Age = 0
Person details - Name = Joe, Age = 99
Person details - Name = Joe, Age = 100
*/

Güçlü Programlama
Önceki örnekte, Name ve Age özellikleri geneldir ve hem get hem de set erişimcisi içerir. Bu, herhangi bir
nesnenin bu özellikleri okumasına ve yazmasına izin verir. Ancak erişimcilerinin birini dışlamak bazen tercih edilir.
Örneğin set erişimcisini atlayarak, özelliği salt okunurdur:

public string Name


{
get
{
return _name;
}
}

Alternatif olarak, bir erişimciye genel kullanıma sunabilirsiniz, ancak diğerini özel veya korumalı hale
getirebilirsiniz. Daha fazla bilgi için bkz. asimetrik erişimci erişilebilirliği.
Özellikler doğrulandıktan sonra, sınıfının alanları gibi kullanılabilirler. Bu, aşağıdaki deyimlerde olduğu gibi bir
özelliğin değerini alırken ve ayarlarken çok doğal bir sözdizimi sağlar:

person.Name = "Joe";
person.Age = 99;

Bir özellik set yönteminde özel bir value değişkeninin kullanılabildiğini unutmayın. Bu değişken, kullanıcının
belirttiği değeri içerir, örneğin:

_name = value;

Bir Person nesnesindeki Age özelliğini arttırmadan ilgili Temizleme sözdizimine dikkat edin:

person.Age += 1;

Özellikleri modellemek için ayrı set ve get yöntemleri kullanılmışsa, eşdeğer kod şöyle görünebilir:
person.SetAge(person.GetAge() + 1);

ToString yöntemi bu örnekte geçersiz kılınır:

public override string ToString()


{
return "Name = " + Name + ", Age = " + Age;
}

ToString programda açıkça kullanılmadığından emin olun. WriteLine çağrıları tarafından varsayılan olarak
çağrılır.

Ayrıca bkz.
C# Programlama Kılavuzu
Veri Erişimi
Sınıflar ve Yapılar
Otomatik Uygulanan Özellikler (C# Programlama
Kılavuzu)
25.11.2019 • 2 minutes to read • Edit Online

C# 3,0 ve sonraki sürümlerde, özellik erişimcilerinde ek bir mantık gerekmediği zaman otomatik uygulanan
özellikler özellik bildirimini daha kısa hale getirir. Ayrıca, istemci kodunun nesne oluşturmasını da sağlar.
Aşağıdaki örnekte gösterildiği gibi bir özellik bildirdiğinizde, derleyici yalnızca özelliğin get ve set
erişimcileri aracılığıyla erişilebilen özel, anonim bir destek alanı oluşturur.

Örnek
Aşağıdaki örnek, bazı otomatik uygulanmış özelliklere sahip basit bir sınıfı göstermektedir:

// This class is mutable. Its data can be modified from


// outside the class.
class Customer
{
// Auto-implemented properties for trivial get and set
public double TotalPurchases { get; set; }
public string Name { get; set; }
public int CustomerID { get; set; }

// Constructor
public Customer(double purchases, string name, int ID)
{
TotalPurchases = purchases;
Name = name;
CustomerID = ID;
}

// Methods
public string GetContactInfo() { return "ContactInfo"; }
public string GetTransactionHistory() { return "History"; }

// .. Additional methods, events, etc.


}

class Program
{
static void Main()
{
// Intialize a new object.
Customer cust1 = new Customer(4987.63, "Northwind", 90108);

// Modify a property.
cust1.TotalPurchases += 499.99;
}
}

C# 6 ve sonrasında, alanlarla aynı şekilde otomatik uygulanan özellikler başlatabilirsiniz:

public string FirstName { get; set; } = "Jane";

Önceki örnekte gösterilen sınıf değişebilir ' dir. İstemci kodu, oluşturulduktan sonra nesnelerdeki değerleri
değiştirebilir. Önemli davranışları (Yöntemler) ve verileri içeren karmaşık sınıflarda, genellikle ortak
özelliklerin olması gerekir. Bununla birlikte, yalnızca bir değer kümesini (veri) kapsülleyen ve hiç
davranışlarına sahip olan küçük sınıflar veya yapılar için, küme erişimcisini özel (Sabit-tüketiciler) olarak
bildirerek veya yalnızca bir get bildirerek nesneleri sabit yapmalısınız. erişimci (Oluşturucu dışında her yerde
sabit). Daha fazla bilgi için bkz. Otomatik uygulanan özelliklerle hafif bir sınıf uygulama.

Ayrıca bkz.
Veri Erişimi
Değiştiriciler
Otomatik uygulanan özelliklerle hafif bir sınıf
uygulama (C# Programlama Kılavuzu)
25.11.2019 • 3 minutes to read • Edit Online

Bu örnek, yalnızca bir otomatik uygulanan özellikler kümesini kapsüllemek için hizmet veren sabit bir basit sınıfın
nasıl oluşturulacağını gösterir. Başvuru türü semantiğini kullanmanız gerektiğinde, yapı yerine bu tür yapıyı
kullanın.
Değişmez bir özelliği iki şekilde yapabilirsiniz:
Set erişimcisinin Privateolarak bildirilmesini sağlayabilirsiniz. Özelliği yalnızca tür içinde ayarlanabilir, ancak
tüketicilere sabittir.
Özel bir set erişimcisi bildirdiğinizde, özelliği başlatmak için bir nesne Başlatıcısı kullanamazsınız. Bir
Oluşturucu veya Factory yöntemi kullanmanız gerekir.
Yalnızca Get erişimcisini bildirebilirsiniz. Bu, özelliği türün Oluşturucusu dışında her yerde sabit hale getirir.

Örnek
Aşağıdaki örnek, otomatik uygulanan özellikleri olan sabit bir sınıfı uygulamak için iki yol göstermektedir. Her bir
şekilde, özel bir set özelliklerden birini ve yalnızca bir get özelliklerden birini bildirir. İlk sınıf yalnızca özellikleri
başlatmak için bir Oluşturucu kullanır ve ikinci sınıf Oluşturucu çağıran bir statik fabrika yöntemi kullanır.

// This class is immutable. After an object is created,


// it cannot be modified from outside the class. It uses a
// constructor to initialize its properties.
class Contact
{
// Read-only properties.
public string Name { get; }
public string Address { get; private set; }

// Public constructor.
public Contact(string contactName, string contactAddress)
{
Name = contactName;
Address = contactAddress;
}
}

// This class is immutable. After an object is created,


// it cannot be modified from outside the class. It uses a
// static method and private constructor to initialize its properties.
public class Contact2
{
// Read-only properties.
public string Name { get; private set; }
public string Address { get; }

// Private constructor.
private Contact2(string contactName, string contactAddress)
{
Name = contactName;
Address = contactAddress;
}

// Public factory method.


// Public factory method.
public static Contact2 CreateContact(string name, string address)
{
return new Contact2(name, address);
}
}

public class Program


{
static void Main()
{
// Some simple data sources.
string[] names = {"Terry Adams","Fadi Fakhouri", "Hanying Feng",
"Cesar Garcia", "Debra Garcia"};
string[] addresses = {"123 Main St.", "345 Cypress Ave.", "678 1st Ave",
"12 108th St.", "89 E. 42nd St."};

// Simple query to demonstrate object creation in select clause.


// Create Contact objects by using a constructor.
var query1 = from i in Enumerable.Range(0, 5)
select new Contact(names[i], addresses[i]);

// List elements cannot be modified by client code.


var list = query1.ToList();
foreach (var contact in list)
{
Console.WriteLine("{0}, {1}", contact.Name, contact.Address);
}

// Create Contact2 objects by using a static factory method.


var query2 = from i in Enumerable.Range(0, 5)
select Contact2.CreateContact(names[i], addresses[i]);

// Console output is identical to query1.


var list2 = query2.ToList();

// List elements cannot be modified by client code.


// CS0272:
// list2[0].Name = "Eugene Zabokritski";

// Keep the console open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}

/* Output:
Terry Adams, 123 Main St.
Fadi Fakhouri, 345 Cypress Ave.
Hanying Feng, 678 1st Ave
Cesar Garcia, 12 108th St.
Debra Garcia, 89 E. 42nd St.
*/

Derleyici, otomatik uygulanan her özellik için yedekleme alanları oluşturur. Alanlara doğrudan kaynak kodundan
erişilebilir.

Ayrıca bkz.
Veri Erişimi
struct
Nesne ve Koleksiyon Başlatıcıları
Yöntemler (C# Programlama Kılavuzu)
23.11.2019 • 16 minutes to read • Edit Online

Yöntemi, bir dizi deyim içeren bir kod bloğudur. Program, metodu çağırarak ve gerekli Yöntem bağımsız
değişkenlerini belirterek deyimlerin yürütülmesine neden olur. ' C#De, her yürütülen yönerge bir yöntem
bağlamında gerçekleştirilir. Main yöntemi her C# uygulamanın giriş noktasıdır ve program başlatıldığında
ortak dil çalışma zamanı (CLR ) tarafından çağırılır.

NOTE
Bu makalede adlandırılmış yöntemler ele alınmaktadır. Anonim işlevler hakkında daha fazla bilgi için bkz. Anonim
işlevler.

Yöntem imzaları
Yöntemler, public veya private , abstract veya sealed , dönüş değeri, yöntemin adı ve herhangi bir
yöntem parametresi gibi erişim düzeyi belirtilerek bir sınıf veya Yapı içinde bildirilmiştir. Bu parçalar,
yönteminin imzasıdır.

NOTE
Bir yöntemin dönüş türü, yöntem aşırı yüklemesi amaçları için yöntemin imzasının bir parçası değildir. Ancak, bir
temsilci ve işaret ettiği yöntem arasındaki uyumluluğun belirlenmesi sırasında yönteminin imzasının bir parçasıdır.

Yöntem parametreleri parantez içine alınır ve virgülle ayrılır. Boş parantezler, yöntemin hiçbir parametre
gerektirmediğini belirtir. Bu sınıf dört yöntem içerir:

abstract class Motorcycle


{
// Anyone can call this.
public void StartEngine() {/* Method statements here */ }

// Only derived classes can call this.


protected void AddGas(int gallons) { /* Method statements here */ }

// Derived classes can override the base class implementation.


public virtual int Drive(int miles, int speed) { /* Method statements here */ return 1; }

// Derived classes must implement this.


public abstract double GetTopSpeed();
}

Yöntem erişimi
Bir nesne üzerinde bir yöntemi çağırmak, bir alana erişme gibidir. Nesne adından sonra bir nokta, yöntemin
adı ve parantez ekleyin. Bağımsız değişkenler parantez içinde listelenir ve virgülle ayrılır. Motorcycle
sınıfının yöntemleri, bu nedenle aşağıdaki örnekte olduğu gibi çağrılabilir:
class TestMotorcycle : Motorcycle
{

public override double GetTopSpeed()


{
return 108.4;
}

static void Main()


{

TestMotorcycle moto = new TestMotorcycle();

moto.StartEngine();
moto.AddGas(15);
moto.Drive(5, 20);
double speed = moto.GetTopSpeed();
Console.WriteLine("My top speed is {0}", speed);
}
}

Yöntem parametreleri ve bağımsız değişkenler


Yöntem tanımı, gerekli parametrelerin adlarını ve türlerini belirtir. Kodu çağırırken yöntemi çağırdığında,
her parametre için bağımsız değişkenler olarak adlandırılan somut değerler sağlar. Bağımsız değişkenlerin
parametre türüyle uyumlu olması gerekir, ancak çağıran kodda kullanılan bağımsız değişken adı (varsa)
yöntemde tanımlanan parametre ile aynı olmalıdır. Örneğin:

public void Caller()


{
int numA = 4;
// Call with an int variable.
int productA = Square(numA);

int numB = 32;


// Call with another int variable.
int productB = Square(numB);

// Call with an integer literal.


int productC = Square(12);

// Call with an expression that evaulates to int.


productC = Square(productA * 3);
}

int Square(int i)
{
// Store input argument in a local variable.
int input = i;
return input * input;
}

Başvuruya göre geçirme-değere göre geçirme


Varsayılan olarak, bir değer türü bir yönteme geçirildiğinde nesnenin kendisi yerine bir kopya geçirilir. Bu
nedenle, bağımsız değişkende yapılan değişikliklerin, çağırma yönteminde orijinal kopya üzerinde hiçbir
etkisi yoktur. Ref anahtar sözcüğünü kullanarak bir değer türü başvuruya göre geçirebilirsiniz. Daha fazla
bilgi için bkz. değer türü parametrelerini geçirme. Yerleşik değer türlerinin bir listesi için bkz. değer türleri
tablosu.
Başvuru türündeki bir nesne yöntemine geçirildiğinde, nesnesine bir başvuru geçirilir. Diğer bir deyişle,
yöntem nesnenin kendisini değil, nesnenin konumunu gösteren bir bağımsız değişken alır. Bu başvuruyu
kullanarak nesnesinin bir üyesini değiştirirseniz, nesneyi değere göre iletseniz bile, değişiklik çağırma
yöntemindeki bağımsız değişkende yansıtılır.
Aşağıdaki örnekte gösterildiği gibi, class anahtar sözcüğünü kullanarak bir başvuru türü oluşturursunuz:

public class SampleRefType


{
public int value;
}

Artık, bu türü temel alan bir nesneyi bir yönteme geçirirseniz, nesnesine bir başvuru geçirilir. Aşağıdaki
örnek, SampleRefType ModifyObject yöntemine bir nesne geçirir:

public static void TestRefType()


{
SampleRefType rt = new SampleRefType();
rt.value = 44;
ModifyObject(rt);
Console.WriteLine(rt.value);
}
static void ModifyObject(SampleRefType obj)
{
obj.value = 33;
}

Örnek temelde bir yönteme değere göre bir bağımsız değişken geçirdiğinden önceki örnekle aynı şeyi
yapar. Ancak, bir başvuru türü kullanıldığından, sonuç farklıdır. ModifyObject ' de, parametresinin value
alanına yapılan değişiklik obj , rt yönteminde TestRefType bağımsız değişkeninin value alanını da
değiştirir. TestRefType yöntemi çıkış olarak 33 görüntüler.
Başvuru türlerini başvuruya ve değere göre geçirme hakkında daha fazla bilgi için bkz. başvuru türü
parametrelerini ve başvuru türlerinigeçirme.

Döndürülen değerler
Yöntemler çağırana bir değer döndürebilir. Dönüş türü, yöntem adından önce listelenen tür void değilse,
yöntemi return anahtar sözcüğünü kullanarak değeri döndürebilir. Dönüş türüyle eşleşen bir değer gelen
return anahtar sözcüğünü içeren bir ifade, bu değeri çağıran metoda döndürür.

Değer, çağırarak değere göre veya 7,0 ile C# başlayarak başvuruya göredöndürülebilir. Değer, yöntem
imzasında ref anahtar sözcüğü kullanılıyorsa ve her bir return anahtar sözcüğünü takip eden başvuruya
göre çağırana döndürülür. Örneğin, aşağıdaki yöntem imzası ve Return deyimleri, yöntemin çağırana
başvuruya göre estDistance bir değişken adları döndürdüğünü gösterir.

public ref double GetEstimatedDistance()


{
return ref estDistance;
}

return anahtar sözcüğü, yöntemin yürütülmesini de durduruyor. Dönüş türü void ise, değer içermeyen
bir return deyimin, metodun yürütülmesini durdurmak için yine de yararlı olması gerekir. return anahtar
sözcüğü olmadan Yöntem, kod bloğunun sonuna ulaştığında yürütmeyi durdurur. Void olmayan bir dönüş
türüne sahip metotlar, bir değer döndürmek için return anahtar sözcüğünü kullanmak için gereklidir.
Örneğin, bu iki yöntem tamsayılar döndürmek için return anahtar sözcüğünü kullanır:

class SimpleMath
{
public int AddTwoNumbers(int number1, int number2)
{
return number1 + number2;
}

public int SquareANumber(int number)


{
return number * number;
}
}

Bir yöntemden döndürülen bir değer kullanmak için, çağırma yöntemi yöntemi tek bir değer olan her
yerde, aynı türde bir değer yeterli olacak şekilde kullanabilir. Dönüş değerini bir değişkene de
atayabilirsiniz. Örneğin, aşağıdaki iki kod örneği aynı hedefi yerine getirmektedir:

int result = obj.AddTwoNumbers(1, 2);


result = obj.SquareANumber(result);
// The result is 9.
Console.WriteLine(result);

result = obj.SquareANumber(obj.AddTwoNumbers(1, 2));


// The result is 9.
Console.WriteLine(result);

Bu durumda, bir değeri depolamak için result , yerel bir değişken kullanmak isteğe bağlıdır. Kodun
okunabilirliğini yardımcı olabilir veya metodun tüm kapsamı için bağımsız değişkenin özgün değerini
depolamanız gerekirse gerekli olabilir.
Bir yöntemden başvuruya göre döndürülen bir değeri kullanmak için, değerini değiştirmek istiyorsanız bir
ref yerel değişkeni bildirmeniz gerekir. Örneğin, Planet.GetEstimatedDistance yöntemi başvuruya göre bir
Double değeri döndürürse, bunu aşağıdaki gibi kodla bir ref yerel değişkeni olarak tanımlayabilirsiniz:

ref int distance = plant

Çağırma işlevi diziyi M geçirse, dizinin içeriğini değiştiren M bir yöntemden çok boyutlu bir dizi
döndürmektir. M elde edilen diziyi, iyi stil veya işlevsel akış için döndürebilir, ancak gerekli değildir çünkü
C# tüm başvuru türlerini değere göre geçirir ve dizi başvurusunun değeri dizi işaretçisidir. Yöntem M ,
dizideki içeriklerinde yapılan tüm değişiklikler, aşağıdaki örnekte gösterildiği gibi diziye başvuran herhangi
bir kod tarafından Observable ' tır:
static void Main(string[] args)
{
int[,] matrix = new int[2, 2];
FillMatrix(matrix);
// matrix is now full of -1
}

public static void FillMatrix(int[,] matrix)


{
for (int i = 0; i < matrix.GetLength(0); i++)
{
for (int j = 0; j < matrix.GetLength(1); j++)
{
matrix[i, j] = -1;
}
}
}

Daha fazla bilgi için bkz. Return.

Zaman uyumsuz yöntemler


Async özelliğini kullanarak, açık geri çağırmaları kullanmadan zaman uyumsuz yöntemleri çağırabilir veya
kodunuzu birden çok yöntemde veya Lambda ifadelerinde el ile böedebilirsiniz.
Zaman uyumsuz değiştiriciyle bir yöntemi işaretlerseniz, yönteminde await işlecini kullanabilirsiniz.
Denetim zaman uyumsuz yöntemde bir await ifadesine ulaştığında denetim çağırana döner ve beklenen
görev tamamlanana kadar yöntemdeki ilerleme durumu askıya alınır. Görev tamamlandığında, yürütme
yöntemi içinde çalışmaya çalışabilir.

NOTE
Zaman uyumsuz bir yöntem, henüz tamamlanmamış olan ilk beklemiş nesneyle karşılaştığında çağırana döner veya
zaman uyumsuz yöntemin sonuna kadar, hangisi önce gerçekleşiyorsa.

Zaman uyumsuz bir yöntem Task<TResult>, Taskveya void dönüş türüne sahip olabilir. Void dönüş türü
birincil olarak, bir void dönüş türünün gerekli olduğu olay işleyicilerini tanımlamak için kullanılır. Void
döndüren zaman uyumsuz bir yöntem beklenemez ve void döndüren bir yöntemi çağıran yöntemin aldığı
özel durumları yakalayamaz.
Aşağıdaki örnekte DelayAsync , dönüş türü Task<TResult>olan zaman uyumsuz bir yöntemdir. DelayAsync ,
bir tamsayı döndüren bir return bildirimine sahiptir. Bu nedenle DelayAsync yöntemi bildirimi Task<int>
dönüş türüne sahip olmalıdır. Dönüş türü Task<int> olduğundan, aşağıdaki deyimde gösterildiği gibi,
DoSomethingAsync await ifadenin değerlendirmesi bir tamsayı üretir: int result = await delayTask .

startButton_Click yöntemi, void dönüş türüne sahip bir zaman uyumsuz metoda bir örnektir.
DoSomethingAsync zaman uyumsuz bir yöntem olduğundan, aşağıdaki bildirimde gösterildiği gibi,
DoSomethingAsync çağrısının görevi beklenmelidir: await DoSomethingAsync(); . Metodun bir await ifadesi
olduğundan startButton_Click yöntemi async değiştiricisiyle tanımlanmalıdır.
// using System.Diagnostics;
// using System.Threading.Tasks;

// This Click event is marked with the async modifier.


private async void startButton_Click(object sender, RoutedEventArgs e)
{
await DoSomethingAsync();
}

private async Task DoSomethingAsync()


{
Task<int> delayTask = DelayAsync();
int result = await delayTask;

// The previous two statements may be combined into


// the following statement.
//int result = await DelayAsync();

Debug.WriteLine("Result: " + result);


}

private async Task<int> DelayAsync()


{
await Task.Delay(100);
return 5;
}

// Output:
// Result: 5

Zaman uyumsuz bir yöntem herhangi bir ref veya Out parametresi bildiremez, ancak bu parametrelere
sahip yöntemleri çağırabilir.
Zaman uyumsuz yöntemler hakkında daha fazla bilgi için bkz. Async ve await Ile zaman uyumsuz
programlama, zaman uyumsuz programlarda denetim akışıve zaman uyumsuz dönüş türleri.

İfade gövdesi tanımları


Yalnızca bir ifadenin sonucuyla hemen dönen veya yöntemin gövdesi olarak tek bir deyimi olan yöntem
tanımlarının olması yaygındır. => kullanarak bu tür yöntemleri tanımlamaya yönelik bir sözdizimi kısayolu
vardır:

public Point Move(int dx, int dy) => new Point(x + dx, y + dy);
public void Print() => Console.WriteLine(First + " " + Last);
// Works with operators, properties, and indexers too.
public static Complex operator +(Complex a, Complex b) => a.Add(b);
public string Name => First + " " + Last;
public Customer this[long id] => store.LookupCustomer(id);

Yöntem void döndürürse veya zaman uyumsuz bir yöntem ise, yöntemin gövdesi bir deyim ifadesi
olmalıdır (Lambdalar ile aynı). Özellikler ve Dizin oluşturucular için, bunların salt okunmaları gerekir ve
get erişimci anahtar sözcüğünü kullanmayın.

Yineleyiciler
Yineleyici, bir koleksiyon üzerinde liste veya dizi gibi özel bir yineleme gerçekleştirir. Bir yineleyici, her öğeyi
birer birer döndürmek için yield return ifadesini kullanır. Bir yield return ifadesine ulaşıldığında, koddaki
geçerli konum hatırlanır. Yineleyici bir sonraki sefer çağrıldığında, yürütme o konumdan yeniden başlatılır.
Bir foreach ifadesi kullanarak istemci kodundan bir yineleyici çağırın.
Yineleyicinin dönüş türü IEnumerable, IEnumerable<T>, IEnumeratorveya IEnumerator<T>olabilir.
Daha fazla bilgi için bkz. yineleyiciler.

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
C# Programlama Kılavuzu
Sınıflar ve Yapılar
Erişim Değiştiricileri
Statik Sınıflar ve Statik Sınıf Üyeleri
Devralma
Soyut ve Korumalı Sınıflar ve Sınıf Üyeleri
params
return
out
ref
Parametreleri Geçirme
Yerel işlevler (C# Programlama Kılavuzu)
8.11.2019 • 8 minutes to read • Edit Online

7,0 ile C# başlayarak C# Yerel işlevleridestekler. Yerel işlevler, başka bir üyede iç içe yerleştirilmiş bir türün özel
yöntemleridir. Yalnızca kendi kapsayıcı üyelerinden çağrılabilir. Yerel işlevler içinde bildirilebilecek ve şuradan
çağrılabilir:
Yöntemler, özellikle Yineleyici yöntemleri ve zaman uyumsuz yöntemler
Oluşturucular
Özellik erişimcileri
Olay erişimcileri
Anonim Yöntemler
Lambda ifadeleri
Sonlandırıcılar
Diğer yerel işlevler
Ancak, yerel işlevler ifade-Bodied üyesi içinde bildirilemez.

NOTE
Bazı durumlarda, bir yerel işlev tarafından desteklenen işlevselliği uygulamak için bir lambda ifadesi kullanabilirsiniz. Bir
karşılaştırma için bkz. Yerel Işlevler lambda ifadelerine kıyasla.

Yerel işlevler, kodunuzun amacını açık hale getirir.Kodunuzu okuyan herkes, yöntemin kapsayan Yöntem dışında
çağrılabilir olmadığını görebilir. Ekip projeleri için, başka bir geliştiricinin yöntemi doğrudan sınıf veya yapı içinde
başka bir yerde çağırmak olanaksız hale getirir.

Yerel işlev sözdizimi


Yerel bir işlev, kapsayan bir üye içinde iç içe geçmiş bir yöntem olarak tanımlanır. Tanımı aşağıdaki sözdizimine
sahiptir:

<modifiers: async | unsafe> <return-type> <method-name> <parameter-list>

Yerel işlevler, zaman uyumsuz ve güvenli olmayan değiştiriciler kullanabilir.


Kendi Yöntem parametreleri de dahil olmak üzere, kapsayan üyede tanımlanan tüm yerel değişkenlerin yerel
işlevde erişilebilir olduğunu unutmayın.
Bir yöntem tanımının aksine, yerel bir işlev tanımı üye erişim değiştiricisini içeremez. Tüm yerel işlevler özel
olduğundan, private anahtar sözcüğü gibi bir erişim değiştiricisi de dahil olmak üzere, "özel ' değiştiricisi Bu öğe
için geçerli değil."

NOTE
C# 8,0 ' den önce yerel işlevler static değiştiricisini içeremez. static anahtar sözcüğünü içeren derleyici hatası CS0106, "'
static ' değiştiricisi Bu öğe için geçerli değil."

Ayrıca, öznitelikler yerel işleve veya parametrelerine ve parametre türüne uygulanamaz.


Aşağıdaki örnek, GetText adlı bir yönteme özel AppendPathSeparator adlı yerel bir işlevi tanımlar:

using System;
using System.IO;

class Example
{
static void Main()
{
string contents = GetText(@"C:\temp", "example.txt");
Console.WriteLine("Contents of the file:\n" + contents);
}

private static string GetText(string path, string filename)


{
var sr = File.OpenText(AppendPathSeparator(path) + filename);
var text = sr.ReadToEnd();
return text;

// Declare a local function.


string AppendPathSeparator(string filepath)
{
if (! filepath.EndsWith(@"\"))
filepath += @"\";

return filepath;
}
}
}

Yerel işlevler ve özel durumlar


Yerel işlevlerin yararlı özelliklerinden biri, özel durumların hemen yüzeyine izin verebilir. Yöntem yineleyiciler için,
özel durumlar yalnızca döndürülen dizi numaralandırıldıktan sonra, yineleyici alındığında değil, ortaya çıkacak.
Zaman uyumsuz metotlar için, bir zaman uyumsuz yöntemde oluşturulan özel durumlar, döndürülen görev
beklendiğinde gözlemlenir.
Aşağıdaki örnek, belirtilen bir Aralık arasındaki tek sayıları numaralandırır OddSequence yöntemini tanımlar.
OddSequence Numaralandırıcı yöntemine 100 ' den büyük bir sayı geçirdiğinden, yöntem bir
ArgumentOutOfRangeExceptionoluşturur. Örneğin çıkışının gösterdiği gibi, özel durum yalnızca sayıları
tekrarladığı zaman, numaralandırıcıyı alırken değil, yüzeyleri.
using System;
using System.Collections.Generic;

class Example
{
static void Main()
{
IEnumerable<int> ienum = OddSequence(50, 110);
Console.WriteLine("Retrieved enumerator...");

foreach (var i in ienum)


{
Console.Write($"{i} ");
}
}

public static IEnumerable<int> OddSequence(int start, int end)


{
if (start < 0 || start > 99)
throw new ArgumentOutOfRangeException("start must be between 0 and 99.");
if (end > 100)
throw new ArgumentOutOfRangeException("end must be less than or equal to 100.");
if (start >= end)
throw new ArgumentException("start must be less than end.");

for (int i = start; i <= end; i++)


{
if (i % 2 == 1)
yield return i;
}
}
}
// The example displays the following output:
// Retrieved enumerator...
//
// Unhandled Exception: System.ArgumentOutOfRangeException: Specified argument was out of the range of valid
values.
// Parameter name: end must be less than or equal to 100.
// at Sequence.<GetNumericRange>d__1.MoveNext() in Program.cs:line 23
// at Example.Main() in Program.cs:line 43

Bunun yerine, aşağıdaki örnekte gösterildiği gibi, bir yerel işlevden Yineleyici döndürerek, doğrulama
gerçekleştirirken ve yineleyici almadan önce bir özel durum oluşturabilirsiniz.
using System;
using System.Collections.Generic;

class Example
{
static void Main()
{
IEnumerable<int> ienum = OddSequence(50, 110);
Console.WriteLine("Retrieved enumerator...");

foreach (var i in ienum)


{
Console.Write($"{i} ");
}
}

public static IEnumerable<int> OddSequence(int start, int end)


{
if (start < 0 || start > 99)
throw new ArgumentOutOfRangeException("start must be between 0 and 99.");
if (end > 100)
throw new ArgumentOutOfRangeException("end must be less than or equal to 100.");
if (start >= end)
throw new ArgumentException("start must be less than end.");

return GetOddSequenceEnumerator();

IEnumerable<int> GetOddSequenceEnumerator()
{
for (int i = start; i <= end; i++)
{
if (i % 2 == 1)
yield return i;
}
}
}
}
// The example displays the following output:
// Unhandled Exception: System.ArgumentOutOfRangeException: Specified argument was out of the range of valid
values.
// Parameter name: end must be less than or equal to 100.
// at Sequence.<GetNumericRange>d__1.MoveNext() in Program.cs:line 23
// at Example.Main() in Program.cs:line 43

Yerel işlevler, zaman uyumsuz işlem dışındaki özel durumları işlemek için benzer bir şekilde kullanılabilir.Genellikle,
zaman uyumsuz yöntemde oluşturulan özel durumlar, bir AggregateExceptioniç özel durumlarını incelemenizi
gerektirir. Yerel işlevler, kodunuzun hızlı bir şekilde başarısız olmasına olanak tanır ve özel durumun hem zaman
uyumlu olarak hem de aynı şekilde gözlemlenip
Aşağıdaki örnek, belirtilen saniye sayısını duraklatmak için GetMultipleAsync adlı zaman uyumsuz bir yöntem
kullanır ve bu kadar saniye rastgele bir değer döndürür. En fazla gecikme 5 saniyedir; değer 5 ' ten büyükse bir
ArgumentOutOfRangeException sonuç elde edilir. Aşağıdaki örnekte gösterildiği gibi, GetMultipleAsync yöntemine
6 değeri geçirildiğinde oluşturulan özel durum, GetMultipleAsync yöntemi yürütülmeye başladıktan sonra bir
AggregateException sarmalanır.
using System;
using System.Threading.Tasks;

class Example
{
static void Main()
{
int result = GetMultipleAsync(6).Result;
Console.WriteLine($"The returned value is {result:N0}");
}

static async Task<int> GetMultipleAsync(int secondsDelay)


{
Console.WriteLine("Executing GetMultipleAsync...");
if (secondsDelay < 0 || secondsDelay > 5)
throw new ArgumentOutOfRangeException("secondsDelay cannot exceed 5.");

await Task.Delay(secondsDelay * 1000);


return secondsDelay * new Random().Next(2,10);
}
}
// The example displays the following output:
// Executing GetMultipleAsync...
//
// Unhandled Exception: System.AggregateException:
// One or more errors occurred. (Specified argument was out of the range of valid values.
// Parameter name: secondsDelay cannot exceed 5.) --->
// System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
// Parameter name: secondsDelay cannot exceed 5.
// at Example.<GetMultiple>d__1.MoveNext() in Program.cs:line 17
// --- End of inner exception stack trace ---
// at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
// at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
// at Example.Main() in C:\Users\ronpet\Documents\Visual Studio 2017\Projects\local-
functions\async1\Program.cs:line 8

Yöntem yineleyicisi ile yaptığımız gibi, zaman uyumsuz metodu çağırmadan önce doğrulamayı gerçekleştirmek için
bu örnekteki kodu yeniden düzenleyebilirsiniz. Aşağıdaki örnekteki Çıktının gösterdiği gibi,
ArgumentOutOfRangeException bir AggregateExceptionsarmalanmamış.
using System;
using System.Threading.Tasks;

class Example
{
static void Main()
{
int result = GetMultiple(6).Result;
Console.WriteLine($"The returned value is {result:N0}");
}

static Task<int> GetMultiple(int secondsDelay)


{
if (secondsDelay < 0 || secondsDelay > 5)
throw new ArgumentOutOfRangeException("secondsDelay cannot exceed 5.");

return GetValueAsync();

async Task<int> GetValueAsync()


{
Console.WriteLine("Executing GetValueAsync...");
await Task.Delay(secondsDelay * 1000);
return secondsDelay * new Random().Next(2,10);
}
}
}
// The example displays the following output:
// Unhandled Exception: System.ArgumentOutOfRangeException:
// Specified argument was out of the range of valid values.
// Parameter name: secondsDelay cannot exceed 5.
// at Example.GetMultiple(Int32 secondsDelay) in Program.cs:line 17
// at Example.Main() in Program.cs:line 8

Ayrıca bkz.
Yöntemler
Ref dönüşler ve ref yerel ayarlar
8.11.2019 • 11 minutes to read • Edit Online

7,0 ile C# başlayarak, C# başvuru dönüş değerlerini (Ref dönüşler) destekler. Bir başvuru dönüş değeri, bir
yöntemin bir değer yerine bir değişkene geri dönmesi için bir başvuru döndürmesini sağlar. Çağıran, döndürülen
değişkeni değere veya başvuruya göre döndürülmüş gibi kabul edebilir. Çağıran, başvuru yerel olarak
adlandırılan döndürülen değere bir başvuru olan yeni bir değişken oluşturabilir.

Başvuru dönüş değeri nedir?


Çoğu geliştirici, bir bağımsız değişkeni başvuruya göreçağrılan bir yönteme geçirmeyi öğrenmektir. Çağrılan
yöntemin bağımsız değişken listesi, başvuruya göre geçirilmiş bir değişken içerir. Çağrılan yönteme göre
değerinde yapılan tüm değişiklikler arayan tarafından izlenir. Bir Başvuru dönüş değeri , bir yöntemin bazı
değişkene bir başvuru (veya diğer ad) döndürdüğü anlamına gelir. Bu değişkenin kapsamı yöntemi içermelidir. Bu
değişkenin yaşam süresi yöntemin geri dönüşlerinin ötesinde genişlemelidir. Metodun dönüş değerindeki çağıran
tarafından yapılan değişiklikler, yöntemi tarafından döndürülen değişkene yapılır.
Bir yöntemin bir Başvuru dönüş değeri döndürdüğünü bildirmek, yöntemin bir değişkene bir diğer ad
döndürdüğünü gösterir. Tasarım amacı, genellikle çağıran kodun, diğer ad üzerinden bu değişkene, değiştirmek
de dahil olmak üzere erişim sahibi olması gerekir. Başvuruya göre döndüren yöntemlerin dönüş türü void
olamaz.
İfadede bir yöntemin başvuru dönüş değeri olarak döndürebilen bazı kısıtlamalar vardır. Sınırlamalar şunları
içerir:
Dönüş değeri, yönteminin yürütülmesini aşan bir yaşam süresine sahip olmalıdır. Diğer bir deyişle, bu,
döndüren yöntemde yerel bir değişken olamaz. Bir sınıfın örneği veya statik alanı olabilir veya yöntemine
geçirilen bir bağımsız değişken olabilir. Yerel bir değişken döndürme girişimi, "yerel ' obj" bir ref yerel
olmadığından, "yerel ' obj ' başvuru ile döndürülemiyor."
Dönüş değeri null sabit değer olamaz. null derleyici hatası CS8156, "bir ifade başvuru ile
döndürülmeyebilir çünkü bu bağlamda kullanılamaz."
Ref Return içeren bir yöntem, değeri şu anda null (örneklenmiş) değeri olan bir değişkene veya bir değer
türü için null yapılabilir değer türüne sahip bir diğer ad döndürebilir.
Dönüş değeri bir sabit, bir numaralandırma üyesi, bir özellikten değere göre dönüş değeri veya class ya
da struct bir yöntem olamaz. Bu kuralın ihlal edildiğinde derleyici hatası CS8156, "bir ifade başvuru ile
döndürülmeyebilir çünkü bu bağlamda kullanılamaz."
Buna ek olarak, zaman uyumsuz metotlarda başvuru dönüş değerlerine izin verilmez. Zaman uyumsuz bir
yöntem yürütmeyi bitmeden önce dönebilir, ancak dönüş değeri hala bilinmez.

Başvuru dönüş değeri tanımlama


Başvuru dönüş değeri döndüren bir yöntem aşağıdaki iki koşulu karşılamalıdır:
Yöntem imzası, dönüş türünün önünde ref anahtar sözcüğünü içerir.
Yöntem gövdesindeki her dönüş ifadesinde, döndürülen örnek adının önünde başvuru anahtar sözcüğü
bulunur.
Aşağıdaki örnek, bu koşulları karşılayan bir yöntemi gösterir ve p adlı Person nesnesine bir başvuru döndürür:
public ref Person GetContactInformation(string fname, string lname)
{
// ...method implementation...
return ref p;
}

Ref dönüş değeri kullanma


Ref dönüş değeri, çağrılan metodun kapsamındaki başka bir değişken için diğer addır. Ref Return öğesinin
herhangi bir kullanımını, diğer ad olan değişkeni kullanarak yorumlayabilir.
Değerini atadığınızda, diğer ad olan değişkene bir değer atarsınız.
Değerini okurken, diğer adı değişkenin değerini Okuyorda olursunuz.
Başvuruya göregeri döndürülürken, aynı değişkene bir diğer ad döndürürler.
Başvuruya görebaşka bir yönteme geçirirseniz, diğer ad olan değişkene bir başvuru geçirolursunuz.
Bir ref yerel diğer adı yaptığınızda aynı değişkene yeni bir diğer ad yaparsınız.

Başvuru yerelleri
GetContactInformation yönteminin bir ref Return olarak bildirildiği varsayılır:

public ref Person GetContactInformation(string fname, string lname)

Değere göre atama bir değişkenin değerini okur ve bunu yeni bir değişkene atar:

Person p = contacts.GetContactInformation("Brandie", "Best");

Yukarıdaki atama p yerel bir değişken olarak bildirir. İlk değeri GetContactInformation tarafından döndürülen
değerin okunmasından kopyalanır. p gelecekteki tüm atamalar GetContactInformation tarafından döndürülen
değişkenin değerini değiştirmez. p değişkeni artık döndürülen değişkenin diğer adı değildir.
Diğer adı özgün değerine kopyalamak için bir ref yerel değişkeni bildirirsiniz. Aşağıdaki atamada, p
GetContactInformation döndürülen değişkenin diğer adıdır.

ref Person p = ref contacts.GetContactInformation("Brandie", "Best");

p sonraki kullanımı, bu değişken için bir diğer ad p olduğundan, GetContactInformation tarafından döndürülen
değişkeni kullanmakla aynıdır. p yapılan değişiklikler GetContactInformation döndürülen değişkeni de değiştirir.
ref anahtar sözcüğü, hem yerel değişken bildiriminden önce hem de yöntem çağrısından önce kullanılır.
Başvuruya göre bir değere aynı şekilde erişebilirsiniz. Bazı durumlarda, başvuruya göre değere erişmek,
potansiyel olarak pahalı bir kopyalama işlemini önleyerek performansı artırır. Örneğin, aşağıdaki ifade bir değere
başvurmak için kullanılan bir başvuru yerel değerini nasıl tanımlayacağınızı gösterir.

ref VeryLargeStruct reflocal = ref veryLargeStruct;

ref anahtar sözcüğü, hem yerel değişken bildiriminden önce hem de ikinci örnekteki değerden önce kullanılır.
Hem değişken bildiriminde hem de atamaya ref anahtar sözcükleri dahil etme hatası derleyici hatası CS8172,
"bir değere sahip bir başvuru değişkeni başlatılamaz."
C# 7,3 ' den önce, ref yerel değişkenleri, başlatıldıktan sonra farklı depolamaya başvuracak şekilde yeniden
atanamadı. Bu kısıtlama kaldırılmıştır. Aşağıdaki örnekte bir yeniden atama gösterilmektedir:

ref VeryLargeStruct reflocal = ref veryLargeStruct; // initialization


refLocal = ref anotherVeryLargeStruct; // reassigned, refLocal refers to different storage.

Ref yerel değişkenlerinin, bildirildiği zaman yine de başlatılmış olması gerekir.

Ref, ve ref yerelleri: bir örnek


Aşağıdaki örnek, bir tamsayı değerleri dizisini depolayan bir NumberStore sınıfını tanımlar. FindNumber yöntemi,
bir bağımsız değişken olarak geçirilen sayıdan büyük veya ona eşit olan ilk sayı başvuru tarafından döndürülür.
Bir sayı bağımsız değişkenden büyük veya ona eşit değilse, yöntem 0 dizininden sayı döndürür.

using System;

class NumberStore
{
int[] numbers = { 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023 };

public ref int FindNumber(int target)


{
for (int ctr = 0; ctr < numbers.Length; ctr++)
{
if (numbers[ctr] >= target)
return ref numbers[ctr];
}
return ref numbers[0];
}

public override string ToString() => string.Join(" ", numbers);


}

Aşağıdaki örnek, 16 ' dan büyük veya buna eşit ilk değeri almak için NumberStore.FindNumber yöntemini çağırır.
Çağıran, yöntemi tarafından döndürülen değeri iki katına çıkarır. Örneğin çıktısı, NumberStore örneğinin dizi
öğelerinin değerinde yansıtılan değişikliği gösterir.

var store = new NumberStore();


Console.WriteLine($"Original sequence: {store.ToString()}");
int number = 16;
ref var value = ref store.FindNumber(number);
value *= 2;
Console.WriteLine($"New sequence: {store.ToString()}");
// The example displays the following output:
// Original sequence: 1 3 7 15 31 63 127 255 511 1023
// New sequence: 1 3 7 15 62 63 127 255 511 1023

Başvuru dönüş değerleri için destek olmadan, bu tür bir işlem, dizi öğesinin dizinini değeriyle birlikte döndürerek
gerçekleştirilir. Çağıran, bu dizini kullanarak değeri ayrı bir yöntem çağrısında değiştirebilir. Bununla birlikte,
çağıran dizine erişim için de değişiklik yapabilir ve muhtemelen diğer dizi değerlerini değiştirebilir.
Aşağıdaki örnek, FindNumber yönteminin, ref yerel yeniden atamasını kullanmak üzere C# 7,3 sonrasında nasıl
yeniden yazılabilir olduğunu gösterir:
using System;

class NumberStore
{
int[] numbers = { 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023 };

public ref int FindNumber(int target)


{
ref int returnVal = ref numbers[0];
var ctr = numbers.Length - 1;
while ((ctr > 0) && numbers[ctr] >= target)
{
returnVal = ref numbers[ctr];
ctr--;
}
return ref returnVal;
}

public override string ToString() => string.Join(" ", numbers);


}

Bu ikinci sürüm, aranan sayının dizinin sonuna yakın olduğu senaryolarda daha uzun dizileriyle daha etkilidir.

Ayrıca bkz.
ref anahtar sözcüğü
Güvenli verimli kod yazma
Parametreleri Geçirme (C# Programlama Kılavuzu)
4.11.2019 • 2 minutes to read • Edit Online

' C#De, bağımsız değişkenler değere veya başvuruya göre parametrelere geçirilebilir. Başvuruya göre geçirme
işlevi üyeleri, Yöntemler, özellikler, Dizin oluşturucular, işleçler ve oluşturucuların parametrelerin değerini
değiştirmesini ve bu değişikliğin çağrı ortamında kalıcı olmasını sağlar. Değeri değiştirme amacına sahip bir
parametreyi başvuruya göre geçirmek için ref veya out anahtar sözcüğünü kullanın. Kopyalamayı önleme
amacını vererek ve değeri değiştirmezseniz başvuruya göre geçiş yapmak için in değiştiricisini kullanın. Basitlik
için, bu konudaki örneklerde yalnızca ref anahtar sözcüğü kullanılır. in , ref ve out arasındaki fark hakkında
daha fazla bilgi için bkz. ın, refve Out.
Aşağıdaki örnek, değer ve başvuru parametreleri arasındaki farkı gösterir.

class Program
{
static void Main(string[] args)
{
int arg;

// Passing by value.
// The value of arg in Main is not changed.
arg = 4;
squareVal(arg);
Console.WriteLine(arg);
// Output: 4

// Passing by reference.
// The value of arg in Main is changed.
arg = 4;
squareRef(ref arg);
Console.WriteLine(arg);
// Output: 16
}

static void squareVal(int valParameter)


{
valParameter *= valParameter;
}

// Passing by reference
static void squareRef(ref int refParameter)
{
refParameter *= refParameter;
}
}

Daha fazla bilgi için aşağıdaki konulara bakın:


Değer Türü Parametrelerini Geçirme
Başvuru Türü Parametreleri Geçirme

C# Dil Belirtimi
Daha fazla bilgi için bkz. C# dil belirtiminde bağımsız değişken listeleri . Dil belirtimi, C# sözdizimi ve kullanımı
için kesin bir kaynaktır.
Ayrıca bkz.
C# Programlama Kılavuzu
Yöntemler
Değer Türü Parametrelerini Geçirme (C#
Programlama Kılavuzu)
23.10.2019 • 5 minutes to read • Edit Online

Bir değer türü değişkeni, veri başvurusunu içeren bir başvuru türü değişkeni aksine doğrudan verilerini içerir.
Değer türü bir değişkeni değere göre yönteme geçirmek, değişkenin bir kopyasının yöntemine geçirilmesi
anlamına gelir. Yöntemin içinde yer alan parametrede yapılan tüm değişiklikler bağımsız değişken değişkeninde
depolanan özgün veriler üzerinde hiçbir etkisi yoktur. Çağrılan yöntemin bağımsız değişkenin değerini
değiştirmesini istiyorsanız ref veya Out anahtar sözcüğünü kullanarak başvuruya göre geçirmeniz gerekir. Ayrıca,
değerin değişmediğinden emin olmak için bir değer parametresini başvuruya göre geçirmek için ın anahtar
sözcüğünü kullanabilirsiniz. Basitlik için aşağıdaki örneklerde kullanılması ref gerekir.

Değere göre değer türlerini geçirme


Aşağıdaki örnek değer türü parametrelerini değere göre geçirmeyi gösterir. Değişken n değerine göre yöntemine
SquareIt geçirilir. Yöntemin içinde gerçekleşen tüm değişiklikler, değişkenin özgün değeri üzerinde hiçbir etkisi
olmaz.

class PassingValByVal
{
static void SquareIt(int x)
// The parameter x is passed by value.
// Changes to x will not affect the original value of x.
{
x *= x;
System.Console.WriteLine("The value inside the method: {0}", x);
}
static void Main()
{
int n = 5;
System.Console.WriteLine("The value before calling the method: {0}", n);

SquareIt(n); // Passing the variable by value.


System.Console.WriteLine("The value after calling the method: {0}", n);

// Keep the console window open in debug mode.


System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
}
/* Output:
The value before calling the method: 5
The value inside the method: 25
The value after calling the method: 5
*/

Değişken n bir değer türüdür. Verileri, değerini 5 içerir. Çağrıldığında, öğesinin n içeriği, yönteminin içindeki
kare içinde olan parametresine x kopyalanır. SquareIt Ancak Main içindeki değeri, SquareIt yöntemi
öncesindeki gibi çağrıldıktan sonra aynı olur. n Metodun içinde yer alan değişiklik yalnızca yerel değişkeni x
etkiler.

Değer türlerini başvuruya göre geçirme


Aşağıdaki örnek, bağımsız değişkenin ref parametre olarak geçirilmesi dışında, önceki örnekle aynıdır. Temel
bağımsız değişkenin değeri, n yönteminde değiştiğinde x değiştirilir.

class PassingValByRef
{
static void SquareIt(ref int x)
// The parameter x is passed by reference.
// Changes to x will affect the original value of x.
{
x *= x;
System.Console.WriteLine("The value inside the method: {0}", x);
}
static void Main()
{
int n = 5;
System.Console.WriteLine("The value before calling the method: {0}", n);

SquareIt(ref n); // Passing the variable by reference.


System.Console.WriteLine("The value after calling the method: {0}", n);

// Keep the console window open in debug mode.


System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
}
/* Output:
The value before calling the method: 5
The value inside the method: 25
The value after calling the method: 25
*/

Bu örnekte, geçirilen değeri n değildir; Bunun yerine, öğesine n bir başvuru geçirilir. Parametre x bir intdeğil;
int bu durumda öğesine n bir başvuru. Bu nedenle, x yöntemin içinde kare içinde olduğunda, ne zaman kare
x olarak ifade n edilir.

Değer türlerini değiştirme


Bağımsız değişkenlerin değerlerini değiştirmenin yaygın bir örneği, yöntemine iki değişken geçirdiğiniz ve
yöntemi içeriğini değiştiren bir takas yöntemidir. Bağımsız değişkenleri başvuruya göre takas yöntemine
geçirmeniz gerekir. Aksi takdirde, yöntemin içindeki yerel kopyaları değiştirirsiniz ve çağırma yönteminde hiçbir
değişiklik gerçekleşmez. Aşağıdaki örnek, tamsayı değerlerini değiştirir.

static void SwapByRef(ref int x, ref int y)


{
int temp = x;
x = y;
y = temp;
}

SwapByRef Yöntemini çağırdığınızda, aşağıdaki örnekte gösterildiği gibi, ref çağrısındaki anahtar sözcüğünü
kullanın.
static void Main()
{
int i = 2, j = 3;
System.Console.WriteLine("i = {0} j = {1}" , i, j);

SwapByRef (ref i, ref j);

System.Console.WriteLine("i = {0} j = {1}" , i, j);

// Keep the console window open in debug mode.


System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
/* Output:
i = 2 j = 3
i = 3 j = 2
*/

Ayrıca bkz.
C# Programlama Kılavuzu
Parametreleri Geçirme
Başvuru Türü Parametreleri Geçirme
Başvuru Türü Parametreleri Geçirme (C#
Programlama Kılavuzu)
4.11.2019 • 5 minutes to read • Edit Online

Bir başvuru türü değişkeni, verilerini doğrudan içermez; Bu, verilerine bir başvuru içerir. Bir başvuru türü
parametresini değere göre geçirdiğinizde, bir sınıf üyesinin değeri gibi başvurulan nesneye ait verileri değiştirmek
mümkündür. Bununla birlikte, başvurunun kendisi için değerini değiştiremezsiniz; Örneğin, yeni bir nesne için
bellek ayırmak ve yöntemin dışında kalmasını sağlamak için aynı başvuruyu kullanamazsınız. Bunu yapmak için
ref veya Out anahtar sözcüğünü kullanarak parametreyi geçirin. Basitlik için aşağıdaki örneklerde ref kullanılır.

Başvuru türlerini değere göre geçirme


Aşağıdaki örnek, bir başvuru türü parametre arr , değere göre Change bir yönteme geçirmeyi gösterir.
Parametresi arr bir başvuru olduğundan, dizi öğelerinin değerlerini değiştirmek mümkündür. Ancak,
parametreyi farklı bir bellek konumuna yeniden atama girişimi yalnızca yöntemi içinde çalışır ve arr özgün
değişkenini etkilemez.

class PassingRefByVal
{
static void Change(int[] pArray)
{
pArray[0] = 888; // This change affects the original element.
pArray = new int[5] {-3, -1, -2, -3, -4}; // This change is local.
System.Console.WriteLine("Inside the method, the first element is: {0}", pArray[0]);
}

static void Main()


{
int[] arr = {1, 4, 5};
System.Console.WriteLine("Inside Main, before calling the method, the first element is: {0}", arr
[0]);

Change(arr);
System.Console.WriteLine("Inside Main, after calling the method, the first element is: {0}", arr
[0]);
}
}
/* Output:
Inside Main, before calling the method, the first element is: 1
Inside the method, the first element is: -3
Inside Main, after calling the method, the first element is: 888
*/

Önceki örnekte, bir başvuru türü olan arr dizisi, ref parametresi olmadan yöntemine geçirilir. Böyle bir
durumda, başvuruya işaret eden arr bir kopyası yöntemine geçirilir. Çıktı, yönteminin bir dizi öğesinin içeriğini
değiştirmek için 1 , bu durumda 888 . Ancak, Change yöntemi içindeki New işlecini kullanarak belleğin yeni bir
bölümünü ayırmak, değişkenin pArray yeni bir diziye başvurmasına neden olur. Bu nedenle, bundan sonra
yapılan tüm değişiklikler, Main içinde oluşturulan arr orijinal diziyi etkilemez. Aslında, bu örnekte, biri Main
içinde diğeri Change yöntemi içinde iki dizi oluşturulur.

Başvuru türlerini başvuruya göre geçirme


Aşağıdaki örnek, ref anahtar sözcüğünün Yöntem başlığına ve çağrısına eklenmesinin dışında, önceki örnekle
aynıdır. Yönteminde gerçekleşen tüm değişiklikler, çağıran programdaki özgün değişkeni etkiler.

class PassingRefByRef
{
static void Change(ref int[] pArray)
{
// Both of the following changes will affect the original variables:
pArray[0] = 888;
pArray = new int[5] {-3, -1, -2, -3, -4};
System.Console.WriteLine("Inside the method, the first element is: {0}", pArray[0]);
}

static void Main()


{
int[] arr = {1, 4, 5};
System.Console.WriteLine("Inside Main, before calling the method, the first element is: {0}",
arr[0]);

Change(ref arr);
System.Console.WriteLine("Inside Main, after calling the method, the first element is: {0}", arr[0]);
}
}
/* Output:
Inside Main, before calling the method, the first element is: 1
Inside the method, the first element is: -3
Inside Main, after calling the method, the first element is: -3
*/

Yöntemi içinde gerçekleşen tüm değişiklikler Main orijinal diziyi etkiler. Aslında, özgün dizi new işleci kullanılarak
yeniden ayrılır. Bu nedenle, Change yöntemini çağırdıktan sonra, arr için herhangi bir başvuru Change
yönteminde oluşturulan beş öğeli diziyi işaret eder.

Iki dizeyi değiştirme


Dizeleri değiştirme, başvuru türü parametrelerini başvuruya göre geçirmek için iyi bir örnektir. Örnekte, str1 ve
str2 iki dize Main başlatılır ve ref anahtar sözcüğüyle değiştirilen parametreler olarak SwapStrings yöntemine
geçirilir. İki dize, yönteminin içinde ve Main içinde yer değiştirir.
class SwappingStrings
{
static void SwapStrings(ref string s1, ref string s2)
// The string parameter is passed by reference.
// Any changes on parameters will affect the original variables.
{
string temp = s1;
s1 = s2;
s2 = temp;
System.Console.WriteLine("Inside the method: {0} {1}", s1, s2);
}

static void Main()


{
string str1 = "John";
string str2 = "Smith";
System.Console.WriteLine("Inside Main, before swapping: {0} {1}", str1, str2);

SwapStrings(ref str1, ref str2); // Passing strings by reference


System.Console.WriteLine("Inside Main, after swapping: {0} {1}", str1, str2);
}
}
/* Output:
Inside Main, before swapping: John Smith
Inside the method: Smith John
Inside Main, after swapping: Smith John
*/

Bu örnekte, çağıran programdaki değişkenleri etkilemek için parametrelerin başvuruya göre geçirilmesi gerekir.
Hem Yöntem başlığından hem de yöntem çağrısından ref anahtar sözcüğünü kaldırırsanız, çağıran programda
hiçbir değişiklik gerçekleşmeyecektir.
Dizeler hakkında daha fazla bilgi için bkz. String.

Ayrıca bkz.
C# Programlama Kılavuzu
Parametreleri Geçirme
ref
in
out
Başvuru Türleri
Bir struct geçirme ve bir yönteme sınıf başvurusu
geçirme arasındaki farkı nasıl anlarsınız (C#
Programlama Kılavuzu)
25.11.2019 • 3 minutes to read • Edit Online

Aşağıdaki örnek bir yapının bir yönteme nasıl geçtiğini gösterir bir yönteme nasıl bir sınıf örneği geçirmekten
farklıdır. Örnekte, bağımsız değişkenlerin (struct ve sınıf örneği) her ikisi de değere göre geçirilir ve her iki yöntem
de bağımsız değişkenin bir alanının değerini değiştirir. Ancak, bir yapı geçirdiğinizde geçirilen özellikler, bir sınıfın
örneğini geçirdiğinizde geçirilen verilerden farklı olduğundan, iki yöntemin sonuçları aynı değildir.
Bir struct bir değer türüolduğundan, bir yapıya değere göre bir yönteme geçirdiğinizde, yöntemi struct bağımsız
değişkeninin bir kopyası üzerinde alır ve çalışır. Yöntemi çağıran yöntemde orijinal yapıya erişemez ve bu nedenle
herhangi bir şekilde değiştirilemez. Yöntemi yalnızca kopyayı değiştirebilir.
Bir sınıf örneği, bir değer türü değil başvuru türüdür. Bir başvuru türü değere göre bir yönteme geçirildiğinde,
yöntemi sınıf örneğine başvurunun bir kopyasını alır. Diğer bir deyişle, çağrılan yöntem örneğin adresinin bir
kopyasını alır ve çağırma yöntemi örneğin özgün adresini korur. Çağıran yöntemdeki sınıf örneği bir adrese
sahiptir, çağrılan yöntemdeki parametresi adresin bir kopyasına sahiptir ve her iki adres de aynı nesneye başvurur.
Parametresi yalnızca adresin bir kopyasını içerdiğinden, çağrılan yöntem çağıran yöntemde sınıf örneğinin adresini
değiştiremiyor. Ancak çağrılan yöntem, sınıf üyelerine hem özgün adresin hem de adres başvurusunun kopyasına
erişmek için adresin kopyasını kullanabilir. Çağrılan yöntem bir sınıf üyesini değiştirirse, çağıran yöntemdeki özgün
sınıf örneği de değişir.
Aşağıdaki örnek çıktıda fark gösterilmektedir. Sınıf örneğinin willIChange alanının değeri, yöntem, sınıf örneğinin
belirtilen alanını bulmak için parametresindeki adresi kullandığından, yöntem ClassTaker çağrısıyla değiştirilir.
Bağımsız değişkenin değeri, adresinin bir kopyası değil, yapısının kendisi bir kopyası olduğundan, çağırma
yöntemindeki yapının willIChange alanı, StructTaker yöntemi çağrısıyla değiştirilmez. StructTaker kopyayı
değiştirir ve StructTaker çağrısı tamamlandığında kopya kaybedilir.

Örnek
class TheClass
{
public string willIChange;
}

struct TheStruct
{
public string willIChange;
}

class TestClassAndStruct
{
static void ClassTaker(TheClass c)
{
c.willIChange = "Changed";
}

static void StructTaker(TheStruct s)


{
s.willIChange = "Changed";
}

static void Main()


{
TheClass testClass = new TheClass();
TheStruct testStruct = new TheStruct();

testClass.willIChange = "Not Changed";


testStruct.willIChange = "Not Changed";

ClassTaker(testClass);
StructTaker(testStruct);

Console.WriteLine("Class field = {0}", testClass.willIChange);


Console.WriteLine("Struct field = {0}", testStruct.willIChange);

// Keep the console window open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* Output:
Class field = Changed
Struct field = Not Changed
*/

Ayrıca bkz.
C# Programlama Kılavuzu
Sınıflar
Yapılar
Parametreleri Geçirme
Örtük olarak yazılan yerel değişkenlerC#
(Programlama Kılavuzu)
25.11.2019 • 8 minutes to read • Edit Online

Yerel değişkenler açık bir tür vermeden bildirilebilecek. var anahtar sözcüğü, derleyiciye, başlatma
deyiminin sağ tarafındaki ifadeden değişkenin türünü çıkarmasını söyler. Çıkarsanan tür bir yerleşik tür,
anonim tür, Kullanıcı tanımlı tür veya .NET Framework sınıf kitaplığında tanımlanmış bir tür olabilir. Dizileri
var ile başlatma hakkında daha fazla bilgi için, bkz. örtülü olarak yazılan diziler.

Aşağıdaki örneklerde, yerel değişkenlerin var ile bildirilebilecek çeşitli yolları gösterilmektedir:

// i is compiled as an int
var i = 5;

// s is compiled as a string
var s = "Hello";

// a is compiled as int[]
var a = new[] { 0, 1, 2 };

// expr is compiled as IEnumerable<Customer>


// or perhaps IQueryable<Customer>
var expr =
from c in customers
where c.City == "London"
select c;

// anon is compiled as an anonymous type


var anon = new { Name = "Terry", Age = 34 };

// list is compiled as List<int>


var list = new List<int>();

var anahtar sözcüğünün "değişken" anlamına gelmeyeceğini ve değişkenin gevşek olarak yazılmış
olduğunu veya geç bağlandığını belirtmeyeceğini anlamak önemlidir. Yalnızca derleyicinin en uygun türü
belirlediği ve atayacağı anlamına gelir.
var anahtar sözcüğü aşağıdaki bağlamlarda kullanılabilir:
Yerel değişkenlerde (Yöntem kapsamında belirtilen değişkenler) önceki örnekte gösterildiği gibi.
For Initialization ifadesinde.

for (var x = 1; x < 10; x++)

Bir foreach başlatma bildiriminde.

foreach (var item in list) {...}

Bir using ifadesinde.

using (var file = new StreamReader("C:\\myfile.txt")) {...}


Daha fazla bilgi için bkz. bir sorgu ifadesinde örtük olarak yazılan yerel değişkenleri ve dizileri kullanma.

var ve anonim türler


Çoğu durumda var kullanımı isteğe bağlıdır ve yalnızca sözdizimsel bir kolaylık vardır. Ancak, bir değişken
anonim bir türle başlatıldığında, nesnenin özelliklerine sonraki bir noktada erişmeniz gerekiyorsa değişkeni
var olarak bildirmeniz gerekir. Bu, LINQ sorgu ifadelerinde yaygın bir senaryodur. Daha fazla bilgi için bkz.
anonim türler.
Kaynak kodunuzun perspektifinden adsız bir türün adı yoktur. Bu nedenle, bir sorgu değişkeni var ile
başlatılmışsa, nesne dizisinde döndürülen özelliklere erişmenin tek yolu, foreach deyimindeki yineleme
değişkeninin türü olarak var kullanmaktır.

class ImplicitlyTypedLocals2
{
static void Main()
{
string[] words = { "aPPLE", "BlUeBeRrY", "cHeRry" };

// If a query produces a sequence of anonymous types,


// then use var in the foreach statement to access the properties.
var upperLowerWords =
from w in words
select new { Upper = w.ToUpper(), Lower = w.ToLower() };

// Execute the query


foreach (var ul in upperLowerWords)
{
Console.WriteLine("Uppercase: {0}, Lowercase: {1}", ul.Upper, ul.Lower);
}
}
}
/* Outputs:
Uppercase: APPLE, Lowercase: apple
Uppercase: BLUEBERRY, Lowercase: blueberry
Uppercase: CHERRY, Lowercase: cherry
*/

Açıklamalar
Aşağıdaki kısıtlamalar, örtük olarak belirlenmiş değişken bildirimleri için geçerlidir:
, yalnızca yerel bir değişken aynı deyimde bildirildiği ve başlatıldığı zaman kullanılabilir;
var
değişken null veya bir yöntem grubuna veya anonim işleve başlatılamaz.
var sınıf kapsamındaki alanlarda kullanılamaz.
kullanılarak belirtilen değişkenler başlatma ifadesinde kullanılamaz. Diğer bir deyişle, bu ifade
var
geçerli: int i = (i = 20); ancak bu ifade derleme zamanı hatası veriyor: var i = (i = 20);
Birden çok örtük olarak yazılmış değişkenler aynı ifadede başlatılamaz.
varadlı bir tür kapsamdadır, var anahtar sözcüğü bu tür adına çözümlenir ve örtük olarak yazılmış
bir yerel değişken bildiriminin parçası olarak değerlendirilmez.
var anahtar sözcüğüyle örtük yazma, yalnızca yerel Yöntem kapsamındaki değişkenlere uygulanabilir. C#
Derleyici, kodu işlediği bir mantıksal Paradox ile karşılaşacağından, sınıf alanları için örtülü yazma
kullanılamaz: derleyicinin alanın türünü bilmesi gerekir, ancak atama ifadesi çözümlenene kadar türü
belirleyemez ve ifade, türü bilmeden değerlendirilemiyor. Aşağıdaki kodu göz önünde bulundurun:
private var bookTitles;

bookTitles , var türü verilen bir sınıf alanıdır. Alan değerlendirilecek bir ifadeye sahip olmadığı için
derleyicinin ne tür bookTitles olması gerektiğini çıkarması olanaksızdır. Ayrıca, alana bir ifade eklemek
(yerel bir değişken gibi) de yeterli değildir:

private var bookTitles = new List<string>();

Derleyici kod derleme sırasında alanlarla karşılaştığında, onunla ilişkili herhangi bir ifadeyi işlemeden önce
her alanın türünü kaydeder. Derleyici, bookTitles ayrıştırmaya çalışan aynı Paradox ile karşılaştığında:
alanın türünü bilmesi gerekir, ancak derleyici, daha önce türü bilmeden mümkün olmayan ifadeyi analiz
ederek normalde var türünü saptayabilir.
var , sorgu değişkeninin tam olarak oluşturulan türünün belirlenmesi zor olduğu sorgu ifadeleri ile de
yararlı olabileceğini fark edebilirsiniz. Gruplandırma ve sıralama işlemlerinde bu durum oluşabilir.
var anahtar sözcüğü, değişkenin belirli türü klavyede yazmak sıkıcı veya belirgin olduğunda ya da kodun
okunabilirliğini eklememe olduğunda da yararlı olabilir. Bu şekilde var yararlı olduğu bir örnek, Grup
işlemleriyle kullanılanlar gibi iç içe geçmiş genel türlerdir. Aşağıdaki sorguda, sorgu değişkeninin türü
IEnumerable<IGrouping<string, Student>> . Siz ve kodunuzun bakımını yapmak zorunda olan başkaları bunu
anlamış olduğu sürece, kolaylık ve kısaltma için örtük yazma kullanmayla ilgili bir sorun yoktur.

// Same as previous example except we use the entire last name as a key.
// Query variable is an IEnumerable<IGrouping<string, Student>>
var studentQuery3 =
from student in students
group student by student.Last;

Ancak var kullanımı, kodunuzun diğer geliştiriciler için anlaşılması daha zor hale getirmek için en az
olasılığından oluşur. Bu nedenle, C# belgeler yalnızca gerekli olduğunda var kullanır.

Ayrıca bkz.
C#Başvurunun
Örtük Olarak Yazılan Diziler
Sorgu ifadesinde örtük olarak yazılan yerel değişkenleri ve dizileri kullanma
Anonim Tipler
Nesne ve Koleksiyon Başlatıcıları
var
C# üzerinde LINQ
LINQ (dil ile tümleşik sorgu)
for
foreach, in
using Deyimi
Bir sorgu ifadesinde örtük olarak yazılan yerel
değişkenleri ve dizileri kullanma (C# Programlama
Kılavuzu)
25.11.2019 • 3 minutes to read • Edit Online

Derleyicinin yerel bir değişken türünü belirlemesini istediğinizde örtülü olarak yazılan yerel değişkenleri
kullanabilirsiniz. Genellikle sorgu ifadelerinde kullanılan anonim türleri depolamak için örtük olarak belirlenmiş
yerel değişkenleri kullanmanız gerekir. Aşağıdaki örneklerde, sorgularda örtük olarak belirlenmiş yerel
değişkenlerin hem isteğe bağlı hem de gerekli kullanımları gösterilmektedir.
Örtük olarak yazılan yerel değişkenler, var olan anahtar sözcüğü kullanılarak bildirilmiştir. Daha fazla bilgi için bkz.
örtülü olarak yazılan yerel değişkenler ve örtük olarak yazılan diziler.

Örnek
Aşağıdaki örnek, var anahtar sözcüğünün gerekli olduğu ortak bir senaryoyu göstermektedir: anonim türler
dizisi üreten bir sorgu ifadesi. Bu senaryoda, anonim türdeki bir tür adına erişiminizin olmadığı için, hem sorgu
değişkeni hem de foreach deyimdeki yineleme değişkeni var kullanılarak örtük olarak yazılmalıdır. Anonim
türler hakkında daha fazla bilgi için bkz. anonim türler.

private static void QueryNames(char firstLetter)


{
// Create the query. Use of var is required because
// the query produces a sequence of anonymous types:
// System.Collections.Generic.IEnumerable<????>.
var studentQuery =
from student in students
where student.FirstName[0] == firstLetter
select new { student.FirstName, student.LastName };

// Execute the query and display the results.


foreach (var anonType in studentQuery)
{
Console.WriteLine("First = {0}, Last = {1}", anonType.FirstName, anonType.LastName);
}
}

Örnek
Aşağıdaki örnek, benzer bir durumda var anahtar sözcüğünü kullanır, ancak var kullanımı isteğe bağlıdır.
student.LastName bir dize olduğundan, sorgunun yürütülmesi dizeler dizisini döndürür. Bu nedenle queryID türü
var yerine System.Collections.Generic.IEnumerable<string> olarak bildirilemez. Anahtar sözcük var kolaylık
sağlamak için kullanılır. Örnekte, foreach deyimindeki yineleme değişkeni açıkça bir dize olarak yazılır, ancak
bunun yerine var kullanılarak bildirilebilecek. Yineleme değişkeninin türü anonim bir tür olmadığından, var
kullanımı gereksinim değil bir seçenektir. var kendisinin bir tür değil, ancak türü çıkarsanmak ve atamak için
derleyicinin bir yönergesini unutmayın.
// Variable queryID could be declared by using
// System.Collections.Generic.IEnumerable<string>
// instead of var.
var queryID =
from student in students
where student.ID > 111
select student.LastName;

// Variable str could be declared by using var instead of string.


foreach (string str in queryID)
{
Console.WriteLine("Last name: {0}", str);
}

Ayrıca bkz.
C# Programlama Kılavuzu
Genişletme Yöntemleri
LINQ (dil ile tümleşik sorgu)
var
C# üzerinde LINQ
Uzantı Metotları (C# Programlama Kılavuzu)
25.11.2019 • 11 minutes to read • Edit Online

Uzantı yöntemleri, yeni türetilmiş bir tür oluşturmadan, yeniden derlemeden ya da özgün türü
değiştirmeden yöntemler "eklemenizi" sağlar. Uzantı yöntemleri özel bir statik yöntem türüdür, ancak bunlar
genişletilmiş türdeki örnek yöntemler ise çağrılır. F# Ve Visual Basic yazılmış C#istemci kodu için, bir uzantı
yöntemi çağırma ile gerçekte bir tür içinde tanımlanan Yöntemler arasında görünür bir fark yoktur.
En yaygın genişletme yöntemleri, varolan System.Collections.IEnumerable ve
System.Collections.Generic.IEnumerable<T> türlerine sorgu işlevselliği ekleyen LINQ standart sorgu
işleçleridir. Standart sorgu işleçlerini kullanmak için, önce bunları bir using System.Linq yönergesi ile
kapsama taşıyın. Ardından IEnumerable<T> uygulayan herhangi bir tür GroupBy, OrderBy, Averagegibi
örnek yöntemlere sahip olacak şekilde görünür. List<T> veya Arraygibi bir IEnumerable<T> türünün
örneğinden sonra "Dot" yazdığınızda bu ek yöntemleri IntelliSense bildiri tamamlanmasında görebilirsiniz.
Aşağıdaki örnek, bir tamsayı dizisinde standart sorgu işleci OrderBy yönteminin nasıl çağrılacağını gösterir.
Parantez içindeki ifade bir lambda ifadesidir. Birçok standart sorgu işleçleri, lambda ifadeleri parametre
olarak alır, ancak bu uzantı yöntemleri için bir gereklilik değildir. Daha fazla bilgi için bkz. lambda ifadeleri.

class ExtensionMethods2
{

static void Main()


{
int[] ints = { 10, 45, 15, 39, 21, 26 };
var result = ints.OrderBy(g => g);
foreach (var i in result)
{
System.Console.Write(i + " ");
}
}
}
//Output: 10 15 21 26 39 45

Uzantı yöntemleri statik yöntemler olarak adlandırılır ancak örnek yöntemi söz dizimi kullanılarak çağrılır.
İlk parametresi, yöntemin hangi tür üzerinde çalıştığını belirtir ve parametresi bundan önce bu
değiştiriciden gelir. Uzantı yöntemleri yalnızca ad alanını kaynak kodunuza bir using yönergesi ile açıkça
içeri aktardığınızda kapsamdadır.
Aşağıdaki örnek, System.String sınıfı için tanımlanmış bir uzantı yöntemini gösterir. Bunun iç içe ve genel
olmayan bir statik sınıf içinde tanımlandığına dikkat edin:

namespace ExtensionMethods
{
public static class MyExtensions
{
public static int WordCount(this String str)
{
return str.Split(new char[] { ' ', '.', '?' },
StringSplitOptions.RemoveEmptyEntries).Length;
}
}
}
WordCount uzantısı yöntemi bu using yönergesi ile kapsama getirilebilir:

using ExtensionMethods;

Ve bu sözdizimi kullanılarak bir uygulamadan çağrılabilir:

string s = "Hello Extension Methods";


int i = s.WordCount();

Kodunuzda örnek yöntemi sözdizimini ile genişletme yöntemi çağırırsınız. Ancak derleyici tarafından
üretilen ara dil (IL ), kodunuzu statik yöntemdeki bir çağrıya dönüştürür. Bu nedenle, kapsülleme ilkesi
gerçekten ihlal edilmez. Aslında genişletme yöntemleri, genişletildikleri türde özel değişkenlere erişemez.
Daha fazla bilgi için bkz. özel bir genişletme yöntemi uygulama ve çağırma.
Genel olarak, büyük olasılıkla kendinizinkileri uygulamayla kıyaslandığında genişletme yöntemlerini çok
daha arayacaksınız. Genişletme yöntemleri örnek yöntem sözdizimi tarafından çağrıldığından istemci
kodundan kullanmak için herhangi bir özel bilgi gerekli değildir. Belirli bir tür için uzantı yöntemlerini
etkinleştirmek için, yöntemlerin tanımlandığı ad alanı için bir using yönergesi eklemeniz yeterlidir.
Örneğin, standart sorgu işleçlerini kullanmak için bu using yönergesini kodunuza ekleyin:

using System.Linq;

(System. Core. dll dosyasına da bir başvuru eklemeniz gerekebilir.) Standart sorgu işleçlerinin artık
IEnumerable<T> türleri için ek yöntemler olarak IntelliSense 'de göründüğünü fark edeceksiniz.

Derleme Zamanında Uzantı Yöntemleri Bağlama


Bir sınıfı veya arabirimi genişletmek için genişletme yöntemini kullanabilir, ancak bunları geçersiz
kılamazsınız. Arabirim veya sınıf yöntemiyle aynı ada ve imzaya sahip genişletme yöntemi asla çağrılmaz.
Derleme sırasında genişletme yöntemleri, her zaman türün kendisinde tanımlı örnek yöntemlerden daha
düşük önceliğe sahiptir. Diğer bir deyişle, bir türün Process(int i) adlı bir yöntemi varsa ve aynı imzaya
sahip bir uzantı yönteminiz varsa, derleyici her zaman örnek yöntemine bağlanır. Derleyici bir yöntem
çağırmayla karşılaştığında, türün örnek yöntemleri önce bir eşleşme arar. Eşleşme bulunmazsa, tür için
tanımlanan uzantı yöntemleri aranır ve ilk bulunan uzantı yöntemine bağlanılır. Aşağıdaki örnek,
derleyicinin hangi genişletme yöntemine veya örnek yöntemine bağlanılacağını nasıl belirlediğini gösterir.

Örnek
Aşağıdaki örnek, C# derleyicisinin bir yöntem çağrısını türde bir örnek yöntemine mi yoksa bir genişletme
yöntemine mi bağlayacağını belirlemede izlediği kuralları gösterir. Statik sınıf Extensions , IMyInterface
uygulayan her tür için tanımlanmış genişletme yöntemleri içerir. A , B ve C tüm sınıfları arabirimini
uygular.
Ad ve imza, sınıflar tarafından zaten uygulanmış yöntemlerle tam olarak eşleştiğinden MethodB uzantısı
yöntemi hiçbir şekilde çağrılmaz.
Derleyici eşleştirilen imzayla bir oluşum yöntemi bulamadığında, varsa, eşleşen bir uzantı yöntemini
bağlayın.

// Define an interface named IMyInterface.


namespace DefineIMyInterface
{
using System;
using System;

public interface IMyInterface


{
// Any class that implements IMyInterface must define a method
// that matches the following signature.
void MethodB();
}
}

// Define extension methods for IMyInterface.


namespace Extensions
{
using System;
using DefineIMyInterface;

// The following extension methods can be accessed by instances of any


// class that implements IMyInterface.
public static class Extension
{
public static void MethodA(this IMyInterface myInterface, int i)
{
Console.WriteLine
("Extension.MethodA(this IMyInterface myInterface, int i)");
}

public static void MethodA(this IMyInterface myInterface, string s)


{
Console.WriteLine
("Extension.MethodA(this IMyInterface myInterface, string s)");
}

// This method is never called in ExtensionMethodsDemo1, because each


// of the three classes A, B, and C implements a method named MethodB
// that has a matching signature.
public static void MethodB(this IMyInterface myInterface)
{
Console.WriteLine
("Extension.MethodB(this IMyInterface myInterface)");
}
}
}

// Define three classes that implement IMyInterface, and then use them to test
// the extension methods.
namespace ExtensionMethodsDemo1
{
using System;
using Extensions;
using DefineIMyInterface;

class A : IMyInterface
{
public void MethodB() { Console.WriteLine("A.MethodB()"); }
}

class B : IMyInterface
{
public void MethodB() { Console.WriteLine("B.MethodB()"); }
public void MethodA(int i) { Console.WriteLine("B.MethodA(int i)"); }
}

class C : IMyInterface
{
public void MethodB() { Console.WriteLine("C.MethodB()"); }
public void MethodA(object obj)
{
Console.WriteLine("C.MethodA(object obj)");
Console.WriteLine("C.MethodA(object obj)");
}
}

class ExtMethodDemo
{
static void Main(string[] args)
{
// Declare an instance of class A, class B, and class C.
A a = new A();
B b = new B();
C c = new C();

// For a, b, and c, call the following methods:


// -- MethodA with an int argument
// -- MethodA with a string argument
// -- MethodB with no argument.

// A contains no MethodA, so each call to MethodA resolves to


// the extension method that has a matching signature.
a.MethodA(1); // Extension.MethodA(IMyInterface, int)
a.MethodA("hello"); // Extension.MethodA(IMyInterface, string)

// A has a method that matches the signature of the following call


// to MethodB.
a.MethodB(); // A.MethodB()

// B has methods that match the signatures of the following


// method calls.
b.MethodA(1); // B.MethodA(int)
b.MethodB(); // B.MethodB()

// B has no matching method for the following call, but


// class Extension does.
b.MethodA("hello"); // Extension.MethodA(IMyInterface, string)

// C contains an instance method that matches each of the following


// method calls.
c.MethodA(1); // C.MethodA(object)
c.MethodA("hello"); // C.MethodA(object)
c.MethodB(); // C.MethodB()
}
}
}
/* Output:
Extension.MethodA(this IMyInterface myInterface, int i)
Extension.MethodA(this IMyInterface myInterface, string s)
A.MethodB()
B.MethodA(int i)
B.MethodB()
Extension.MethodA(this IMyInterface myInterface, string s)
C.MethodA(object obj)
C.MethodA(object obj)
C.MethodB()
*/

Genel Yönergeler
Genel olarak, genişletme yöntemlerini tutumlu ve yalnızca gerektiğinde uygulamanızı öneririz. Mümkün
olduğunda, varolan türü genişletmesi gereken istemci kodu, bunu varolan türden türetilmiş yeni bir tür
oluşturarak yapmalıdır. Daha fazla bilgi için bkz. Devralma.
Kaynak kodunu değiştiremediğiniz bir türü genişletmek üzere genişletme yöntemini kullanırsanız, türün
uygulanmasındaki bir değişikliğin genişletme yönteminizin kesilmesine neden olabileceği riskini göze
alırsınız.
Belirli bir tür için uzantı yöntemleri uygularsanız, aşağıdaki noktaları hatırlayın:
Türden tanımlı yöntemle aynı imzaya sahip değilse genişletme yöntemi asla çağrılmaz.
Uzantı yöntemleri ad alanı seviyesinde kapsama alınır. Örneğin, Extensions adlı tek bir ad alanında
uzantı yöntemlerini içeren birden fazla statik sınıfınız varsa, bunların hepsi using Extensions;
yönergesi tarafından kapsama alınır.
Uygulanan bir sınıf kitaplığı için derleme sürüm numarasının artıyor olmasını önlemek için uzantı
yöntemleri kullanmamanız gerekir. Kaynak koduna sahip olduğunuz kitaplığa önemli işlevsellik eklemek
isterseniz, derleme sürüm oluşturma için standart .NET Framework yönergelerini izlemeniz gerekir. Daha
fazla bilgi için bkz. derleme sürümü oluşturma.

Ayrıca bkz.
C# Programlama Kılavuzu
Paralel programlama örnekleri (bunlar birçok örnek genişletme yöntemi içerir)
Lambda İfadeleri
Standart Sorgu İşleçlerine Genel Bakış
Örnek parametreleri ve bunların etkileri için dönüştürme kuralları
Diller arasında uzantı yöntemleri birlikte çalışabilirliği
Uzantı yöntemleri ve curried temsilciler
Uzantı yöntemi bağlama ve hata raporlama
Özel bir genişletme yöntemi uygulama ve çağırma
(C# Programlama Kılavuzu)
25.11.2019 • 3 minutes to read • Edit Online

Bu konu başlığı altında, tüm .NET türleri için kendi genişletme yöntemlerinizi nasıl uygulanacağı gösterilmektedir.
İstemci kodu, uzantıları içeren DLL 'ye bir başvuru ekleyerek ve uzantı yöntemlerinin tanımlandığı ad alanını
belirten bir using yönergesi ekleyerek uzantı yöntemlerinizi kullanabilir.

Genişletme yöntemini tanımlamak ve çağırmak için


1. Uzantı yöntemini içerecek bir statik sınıf tanımlayın.
Sınıf, istemci koduna görünür olmalıdır. Erişilebilirlik kuralları hakkında daha fazla bilgi için bkz. erişim
değiştiricileri.
2. Genişletme yöntemini, en az içeren sınıfla aynı görünürlüğe sahip statik bir yöntem olarak uygulayın.
3. Metodun ilk parametresi, yöntemin üzerinde çalıştığı türü belirtir; önünde Bu değiştiriciye sahip olmalıdır.
4. Çağıran kodda, uzantı yöntemi sınıfını içeren ad alanını belirtmek için bir using yönergesi ekleyin.
5. Yöntemleri, tür üzerinde örnek yöntemmiş gibi çağırın.
İlk parametrenin, işlecin uygulandığı türü temsil ettiğinden ve derleyicinin zaten nesnenizin türünü bildiği
için kodu çağırarak belirtildiğine unutmayın. Parametreleri yalnızca 2 ' den n için bağımsız değişkenler
sağlamanız gerekir.

Örnek
Aşağıdaki örnek, CustomExtensions.StringExtension sınıfında WordCount adlı bir genişletme yöntemi uygular.
Yöntemi, ilk yöntem parametresi olarak belirtilen String sınıfında çalışır. CustomExtensions ad alanı uygulama ad
alanına aktarılır ve yöntemi Main yönteminin içinde çağırılır.
using System.Linq;
using System.Text;
using System;

namespace CustomExtensions
{
// Extension methods must be defined in a static class.
public static class StringExtension
{
// This is the extension method.
// The first parameter takes the "this" modifier
// and specifies the type for which the method is defined.
public static int WordCount(this String str)
{
return str.Split(new char[] {' ', '.','?'}, StringSplitOptions.RemoveEmptyEntries).Length;
}
}
}
namespace Extension_Methods_Simple
{
// Import the extension method namespace.
using CustomExtensions;
class Program
{
static void Main(string[] args)
{
string s = "The quick brown fox jumped over the lazy dog.";
// Call the method as if it were an
// instance method on the type. Note that the first
// parameter is not specified by the calling code.
int i = s.WordCount();
System.Console.WriteLine("Word count of s is {0}", i);
}
}
}

.NET Framework Güvenliği


Uzantı yöntemleri, belirli bir güvenlik güvenlik açığı sunmaz. Tüm ad çakışmaları, türün kendisi tarafından
tanımlanan örnek veya statik yöntem üzerinde çözümlendikleri için, bir tür üzerindeki mevcut yöntemlerin
kimliğine bürünmek için hiçbir şekilde kullanılamaz. Genişletme metotları genişletilmiş sınıftaki herhangi bir özel
veriye erişemez.

Ayrıca bkz.
C# Programlama Kılavuzu
Genişletme Yöntemleri
LINQ (dil ile tümleşik sorgu)
Statik Sınıflar ve Statik Sınıf Üyeleri
protected
internal
public
this
namespace
Numaralandırma için yeni bir yöntem oluşturma (C#
Programlama Kılavuzu)
25.11.2019 • 2 minutes to read • Edit Online

Belirli bir numaralandırma türüne özgü işlevselliği eklemek için uzantı yöntemlerini kullanabilirsiniz.

Örnek
Aşağıdaki örnekte Grades numaralandırması, bir öğrencinin bir sınıfta alabileceği olası harf çalışmalarını temsil
eder. Passing adlı bir genişletme yöntemi Grades türüne eklenir, böylece bu türün her örneği, bir geçen sınıfı
temsil edip etmediğini "bilir".

using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;

namespace EnumExtension
{
// Define an extension method in a non-nested static class.
public static class Extensions
{
public static Grades minPassing = Grades.D;
public static bool Passing(this Grades grade)
{
return grade >= minPassing;
}
}

public enum Grades { F = 0, D=1, C=2, B=3, A=4 };


class Program
{
static void Main(string[] args)
{
Grades g1 = Grades.D;
Grades g2 = Grades.F;
Console.WriteLine("First {0} a passing grade.", g1.Passing() ? "is" : "is not");
Console.WriteLine("Second {0} a passing grade.", g2.Passing() ? "is" : "is not");

Extensions.minPassing = Grades.C;
Console.WriteLine("\r\nRaising the bar!\r\n");
Console.WriteLine("First {0} a passing grade.", g1.Passing() ? "is" : "is not");
Console.WriteLine("Second {0} a passing grade.", g2.Passing() ? "is" : "is not");
}
}
}
/* Output:
First is a passing grade.
Second is not a passing grade.

Raising the bar!

First is not a passing grade.


Second is not a passing grade.
*/

Extensions sınıfının ayrıca dinamik olarak güncellenen bir statik değişken içerdiğini ve Genişletme yönteminin
dönüş değerinin o değişkenin geçerli değerini yansıttığını unutmayın. Bu, arka planda uzantı yöntemlerinin
tanımlandıkları statik sınıfta doğrudan çağrılacağını gösterir.

Ayrıca bkz.
C# Programlama Kılavuzu
Genişletme Yöntemleri
Adlandırılmış ve İsteğe Bağlı Bağımsız Değişkenler
(C# Programlama Kılavuzu)
25.11.2019 • 12 minutes to read • Edit Online

C#4 adlandırılmış ve isteğe bağlı bağımsız değişkenleri tanıtır. Adlandırılmış bağımsız değişkenler , bağımsız
değişkenini parametrenin adıyla ilişkilendirerek parametre listesindeki konumuyla değil, belirli bir parametre için
bir bağımsız değişken belirtmenizi sağlar. Isteğe bağlı bağımsız değişkenler bazı parametrelerin bağımsız
değişkenlerini atlamanızı sağlar. Her iki yöntem de Yöntemler, Dizin oluşturucular, oluşturucular ve temsilcilerle
birlikte kullanılabilir.
Adlandırılmış ve isteğe bağlı bağımsız değişkenler kullandığınızda, bağımsız değişkenler parametre listesinde
değil, bağımsız değişken listesinde göründükleri sırada değerlendirilir.
Adlandırılmış ve isteğe bağlı parametreler birlikte kullanıldığında, isteğe bağlı parametrelerin bir listesinden
yalnızca birkaç parametre için bağımsız değişkenler vermenizi sağlar. Bu yetenek, Microsoft Office Automation
API 'Leri gibi COM arabirimlerine yönelik çağrıları büyük ölçüde kolaylaştırır.

Adlandırılmış bağımsız değişkenler


Adlandırılmış bağımsız değişkenler, çağrılan yöntemlerin parametre listelerindeki parametrelerin sırasını aramak
ya da sağlamak için sizi hatırlamanız ya da aramanız gereksiniminizden muaf değildir. Her bağımsız değişkenin
parametresi parametre adı ile belirtilebilir. Örneğin, sipariş ayrıntılarını (örneğin, satıcı adı, sipariş numarası &
ürün adı) yazdıran bir işlev, işlev tarafından tanımlanan sırada konuma göre bağımsız değişkenler gönderilerek
standart şekilde çağrılabilir.
PrintOrderDetails("Gift Shop", 31, "Red Mug");

Parametrelerin sırasını hatırlamıyorsanız ancak adlarını biliyorsanız, bağımsız değişkenleri istediğiniz sırada
gönderebilirsiniz.
PrintOrderDetails(orderNum: 31, productName: "Red Mug", sellerName: "Gift Shop");

PrintOrderDetails(productName: "Red Mug", sellerName: "Gift Shop", orderNum: 31);

Adlandırılmış bağımsız değişkenler, her bir bağımsız değişkenin ne temsil ettiğini tanımlayarak kodunuzun
okunabilirliğini de artırır. Aşağıdaki örnek yöntemde sellerName null veya boşluk olamaz. Hem sellerName
hem de productName dize türlerdir, bu da konuma göre bağımsız değişken göndermek yerine adlandırılmış
bağımsız değişkenlerin kullanımını ortadan kaldırmak ve kodu okuyan kişilerin karışmasını azaltmak için anlamlı
bir değer sunar.
Konumsal bağımsız değişkenlerle birlikte kullanıldığında adlandırılmış bağımsız değişkenler şu kadar geçerlidir
Bunlar, herhangi bir Konumsal bağımsız değişkenle izlenmez veya
PrintOrderDetails("Gift Shop", 31, productName: "Red Mug");

7,2 ile C# başlayarak, doğru konumda kullanılırlar. Aşağıdaki örnekte, orderNum parametresi doğru
konumda, ancak açıkça adlandırılmıyor.
PrintOrderDetails(sellerName: "Gift Shop", 31, productName: "Red Mug");

Herhangi bir sıra dışı adlandırılmış bağımsız değişkeni izleyen Konumsal bağımsız değişkenler geçersiz.
// This generates CS1738: Named argument specifications must appear after all fixed arguments have been
specified.
PrintOrderDetails(productName: "Red Mug", 31, "Gift Shop");

Örnek
Aşağıdaki kod, bu bölümdeki örnekleri bazı ek kişilerle birlikte uygular.

class NamedExample
{
static void Main(string[] args)
{
// The method can be called in the normal way, by using positional arguments.
PrintOrderDetails("Gift Shop", 31, "Red Mug");

// Named arguments can be supplied for the parameters in any order.


PrintOrderDetails(orderNum: 31, productName: "Red Mug", sellerName: "Gift Shop");
PrintOrderDetails(productName: "Red Mug", sellerName: "Gift Shop", orderNum: 31);

// Named arguments mixed with positional arguments are valid


// as long as they are used in their correct position.
PrintOrderDetails("Gift Shop", 31, productName: "Red Mug");
PrintOrderDetails(sellerName: "Gift Shop", 31, productName: "Red Mug"); // C# 7.2 onwards
PrintOrderDetails("Gift Shop", orderNum: 31, "Red Mug"); // C# 7.2 onwards

// However, mixed arguments are invalid if used out-of-order.


// The following statements will cause a compiler error.
// PrintOrderDetails(productName: "Red Mug", 31, "Gift Shop");
// PrintOrderDetails(31, sellerName: "Gift Shop", "Red Mug");
// PrintOrderDetails(31, "Red Mug", sellerName: "Gift Shop");
}

static void PrintOrderDetails(string sellerName, int orderNum, string productName)


{
if (string.IsNullOrWhiteSpace(sellerName))
{
throw new ArgumentException(message: "Seller name cannot be null or empty.", paramName:
nameof(sellerName));
}

Console.WriteLine($"Seller: {sellerName}, Order #: {orderNum}, Product: {productName}");


}
}

İsteğe bağlı bağımsız değişkenler


Bir yöntem, Oluşturucu, Dizin Oluşturucu veya temsilci tanımı, parametrelerinin gerekli olduğunu veya isteğe
bağlı olduğunu belirtebilir. Herhangi bir çağrı gerekli tüm parametrelerin bağımsız değişkenlerini sağlamalıdır,
ancak isteğe bağlı parametrelerin bağımsız değişkenlerini atlayabilir.
Her isteğe bağlı parametre, tanımının bir parçası olarak varsayılan bir değer içerir. Bu parametre için bir
bağımsız değişken gönderilmezse, varsayılan değer kullanılır. Varsayılan değer, aşağıdaki ifade türlerinden biri
olmalıdır:
sabit bir ifade;
new ValType() , ValType bir numaralandırma ya da Yapıgibi bir değer türü olduğunda formun bir ifadesi;
varsayılan form (ValType)bir ifade, burada ValType bir değer türüdür.

İsteğe bağlı parametreler, gerekli parametrelerden sonra parametre listesinin sonunda tanımlanmıştır.Çağıran
isteğe bağlı parametrelerin her biri için bir bağımsız değişken sağlıyorsa, önceki tüm isteğe bağlı parametrelerin
bağımsız değişkenlerini sağlamalıdır. Bağımsız değişken listesindeki virgülle ayrılmış boşluklar desteklenmez.
Örneğin, aşağıdaki kodda, örnek yöntemi ExampleMethod bir zorunlu ve iki isteğe bağlı parametre ile
tanımlanmıştır.

public void ExampleMethod(int required, string optionalstr = "default string",


int optionalint = 10)

Aşağıdaki ExampleMethod çağrısı bir derleyici hatasına neden olur, çünkü üçüncü parametre için bir bağımsız
değişken sağlanır, ikincisi için değil.
//anExample.ExampleMethod(3, ,4);

Ancak, üçüncü parametrenin adını biliyorsanız, görevi gerçekleştirmek için adlandırılmış bağımsız değişkeni
kullanabilirsiniz.
anExample.ExampleMethod(3, optionalint: 4);

IntelliSense, aşağıdaki çizimde gösterildiği gibi isteğe bağlı parametreleri göstermek için köşeli ayraçları kullanır:

NOTE
.NET OptionalAttribute sınıfını kullanarak isteğe bağlı parametreler de bildirebilirsiniz. OptionalAttribute parametreler
için varsayılan değer gerekmez.

Örnek
Aşağıdaki örnekte ExampleClass oluşturucusunun bir parametresi vardır, bu isteğe bağlıdır. Örnek metodu
ExampleMethod , bir gerekli parametreye, required ve iki isteğe bağlı parametreye sahiptir optionalstr ve
optionalint . Main kod, oluşturucunun ve yöntemin çağrılabileceği farklı yolları gösterir.

namespace OptionalNamespace
{
class OptionalExample
{
static void Main(string[] args)
{
// Instance anExample does not send an argument for the constructor's
// optional parameter.
ExampleClass anExample = new ExampleClass();
anExample.ExampleMethod(1, "One", 1);
anExample.ExampleMethod(2, "Two");
anExample.ExampleMethod(3);

// Instance anotherExample sends an argument for the constructor's


// optional parameter.
ExampleClass anotherExample = new ExampleClass("Provided name");
anotherExample.ExampleMethod(1, "One", 1);
anotherExample.ExampleMethod(2, "Two");
anotherExample.ExampleMethod(3);

// The following statements produce compiler errors.

// An argument must be supplied for the first parameter, and it


// must be an integer.
//anExample.ExampleMethod("One", 1);
//anExample.ExampleMethod();

// You cannot leave a gap in the provided arguments.


//anExample.ExampleMethod(3, ,4);
//anExample.ExampleMethod(3, 4);

// You can use a named parameter to make the previous


// statement work.
anExample.ExampleMethod(3, optionalint: 4);
}
}

class ExampleClass
{
private string _name;

// Because the parameter for the constructor, name, has a default


// value assigned to it, it is optional.
public ExampleClass(string name = "Default name")
{
_name = name;
}

// The first parameter, required, has no default value assigned


// to it. Therefore, it is not optional. Both optionalstr and
// optionalint have default values assigned to them. They are optional.
public void ExampleMethod(int required, string optionalstr = "default string",
int optionalint = 10)
{
Console.WriteLine("{0}: {1}, {2}, and {3}.", _name, required, optionalstr,
optionalint);
}
}

// The output from this example is the following:


// Default name: 1, One, and 1.
// Default name: 2, Two, and 10.
// Default name: 3, default string, and 10.
// Provided name: 1, One, and 1.
// Provided name: 2, Two, and 10.
// Provided name: 3, default string, and 10.
// Default name: 3, default string, and 4.

COM arabirimleri
Adlandırılmış ve isteğe bağlı bağımsız değişkenler, dinamik nesneler ve diğer geliştirmeler desteğiyle birlikte,
Office Otomasyonu API 'leri gibi COM API 'Leri ile birlikte çalışabilirliği büyük ölçüde geliştirir.
Örneğin, Microsoft Office Excel Range arabirimindeki AutoFormat yöntemi yedi parametreye sahiptir ve
bunların tümü isteğe bağlıdır. Bu parametreler aşağıdaki çizimde gösterilmiştir:

C# 3,0 ve önceki sürümlerde, aşağıdaki örnekte gösterildiği gibi her bir parametre için bir bağımsız değişken
gereklidir.
// In C# 3.0 and earlier versions, you need to supply an argument for
// every parameter. The following call specifies a value for the first
// parameter, and sends a placeholder value for the other six. The
// default values are used for those parameters.
var excelApp = new Microsoft.Office.Interop.Excel.Application();
excelApp.Workbooks.Add();
excelApp.Visible = true;

var myFormat =
Microsoft.Office.Interop.Excel.XlRangeAutoFormat.xlRangeAutoFormatAccounting1;

excelApp.get_Range("A1", "B4").AutoFormat(myFormat, Type.Missing,


Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);

Ancak, 4,0 ' de C# tanıtılan adlandırılmış ve isteğe bağlı bağımsız değişkenleri kullanarak AutoFormat çağrısını
büyük ölçüde kolaylaştırabilirsiniz. Adlandırılmış ve isteğe bağlı bağımsız değişkenler, parametrenin varsayılan
değerini değiştirmek istemiyorsanız isteğe bağlı bir parametre için bağımsız değişkenini atlamanızı sağlar.
Aşağıdaki çağrıda, yedi parametreden yalnızca biri için bir değer belirtilir.

// The following code shows the same call to AutoFormat in C# 4.0. Only
// the argument for which you want to provide a specific value is listed.
excelApp.Range["A1", "B4"].AutoFormat( Format: myFormat );

Daha fazla bilgi ve örnek için bkz. Office Programlamada adlandırılmış ve isteğe bağlı bağımsız değişkenleri
kullanma ve nasıl yapılır: görsel C# özellikler kullanarak Office birlikte çalışma nesnelerine erişme.

Aşırı Yükleme Çözümü


Adlandırılmış ve isteğe bağlı bağımsız değişkenlerin kullanılması, aşırı yükleme çözünürlüğünü aşağıdaki
yollarla etkiler:
Bir yöntem, Dizin Oluşturucu veya Oluşturucu, parametrelerinden her biri isteğe bağlı veya bir konuma
göre, çağırma deyimindeki tek bir bağımsız değişkene ve bu bağımsız değişken parametre türüne
dönüştürülebileceğinden yürütme için bir adaydır.
Birden fazla aday bulunursa, tercih edilen dönüştürmeler için aşırı yükleme çözümleme kuralları, açıkça
belirtilen bağımsız değişkenlere uygulanır. İsteğe bağlı parametreler için Atlanan bağımsız değişkenler
yoksayılır.
İki aday eşit derecede iyi bir şekilde yarar olursa, tercih, çağrıda bağımsız değişkenlerin atlandığı isteğe
bağlı parametreleri olmayan bir adaya gider. Bu, daha az parametreye sahip adaylar için aşırı yükleme
çözünürlüğünde genel bir tercihin sonucudur.

C# Dil Belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
Nasıl yapılır: Office Programlamada adlandırılmış ve isteğe bağlı bağımsız değişkenleri kullanma
Tür dinamiği kullanma
Oluşturucuları Kullanma
Dizin Oluşturucular Kullanma
Office Programlamada adlandırılmış ve isteğe bağlı
bağımsız değişkenleri kullanma (C# Programlama
Kılavuzu)
25.11.2019 • 7 minutes to read • Edit Online

Adlandırılmış bağımsız değişkenler ve isteğe bağlı bağımsız değişkenler C# , 4 ' te tanıtılan ve C# programlamada
kolaylık, esneklik ve okunabilirliği geliştirir. Ayrıca, bu özellikler Microsoft Office Automation API 'Leri gibi COM
arabirimlerine erişimi büyük ölçüde kolaylaştırır.
Aşağıdaki örnekte, ConvertToTable yönteminin sütun ve satır sayısı, biçimlendirme, kenarlık, yazı tipi ve renkler
gibi bir tablonun özelliklerini temsil eden on altı parametresi vardır. Tüm on altı parametresi isteğe bağlıdır, çünkü
çoğu zaman belirli değerleri belirtmek istemezsiniz. Ancak, adlandırılmış ve isteğe bağlı bağımsız değişkenler
olmadan her bir parametre için bir değer veya yer tutucu değeri sağlanmalıdır. Adlandırılmış ve isteğe bağlı
bağımsız değişkenlerle, yalnızca projeniz için gerekli olan parametrelerin değerlerini belirtirsiniz.
Bu yordamları gerçekleştirmek için bilgisayarınızda Microsoft Office Word yüklü olmalıdır.

NOTE
Bilgisayarınız, aşağıdaki yönergelerde yer alan Visual Studio kullanıcı arabirimi öğelerinden bazıları için farklı adlar veya
konumlar gösterebilir. Sahip olduğunuz Visual Studio sürümü ve kullandığınız ayarlar bu öğeleri belirler. Daha fazla bilgi için
IDE'yi kişiselleştirme.

Yeni bir konsol uygulaması oluşturmak için


1. Visual Studio 'Yu başlatın.
2. Dosya menüsünde, Yeni' nin üzerine gelin ve ardından Proje' ye tıklayın.
3. Şablonlar kategorileri bölmesinde, görsel C# ' i genişletin ve ardından Windows' a tıklayın.
4. .NET Framework 4 ' ün hedef çerçeve kutusunda göründüğünden emin olmak için Şablonlar
bölmesinin üst kısmına bakın.
5. Şablonlar bölmesinde konsol uygulaması' na tıklayın.
6. Ad alanına projeniz için bir ad yazın.
7. Tamam'a tıklayın.
Yeni proje Çözüm Gezginigörüntülenir.

Başvuru eklemek için


1. Çözüm Gezgini, projenizin adına sağ tıklayın ve ardından Başvuru Ekle' ye tıklayın. Başvuru Ekle
iletişim kutusu görüntülenir.
2. .Net sayfasında, bileşen adı listesinde Microsoft. Office. Interop. Word öğesini seçin.
3. Tamam'a tıklayın.
Gerekli yönergeleri kullanarak ekleme
1. Çözüm Gezgini, program.cs dosyasına sağ tıklayın ve ardından kodu görüntüle' ye tıklayın.
2. Aşağıdaki using yönergelerini kod dosyasının en üstüne ekleyin:

using Word = Microsoft.Office.Interop.Word;

Bir Word belgesinde metin göstermek için


1. Program.csiçindeki Program sınıfında, bir Word uygulaması ve Word belgesi oluşturmak için aşağıdaki
yöntemi ekleyin. Add yönteminde dört isteğe bağlı parametre vardır. Bu örnek, varsayılan değerlerini
kullanır. Bu nedenle, çağırma ifadesinde herhangi bir bağımsız değişken gerekmez.

static void DisplayInWord()


{
var wordApp = new Word.Application();
wordApp.Visible = true;
// docs is a collection of all the Document objects currently
// open in Word.
Word.Documents docs = wordApp.Documents;

// Add a document to the collection and name it doc.


Word.Document doc = docs.Add();
}

2. İçinde metnin nerede görüntüleneceğini ve hangi metnin görüntüleneceğini tanımlamak için yönteminin
sonuna aşağıdaki kodu ekleyin:

// Define a range, a contiguous area in the document, by specifying


// a starting and ending character position. Currently, the document
// is empty.
Word.Range range = doc.Range(0, 0);

// Use the InsertAfter method to insert a string at the end of the


// current range.
range.InsertAfter("Testing, testing, testing. . .");

Uygulamayı çalıştırmak için


1. Aşağıdaki ifadeyi Main öğesine ekleyin:

DisplayInWord();

2. Projeyi çalıştırmak için CTRL+F5 tuşuna basın. Belirtilen metni içeren bir Word belgesi görüntülenir.

Metni bir tabloya dönüştürmek için


1. Metni bir tabloya kapsamak için ConvertToTable yöntemini kullanın. Yönteminde on altı isteğe bağlı
parametre vardır. IntelliSense, aşağıdaki çizimde gösterildiği gibi isteğe bağlı parametreleri köşeli ayraç
içine alır.
Adlandırılmış ve isteğe bağlı bağımsız değişkenler yalnızca değiştirmek istediğiniz parametrelerin
değerlerini belirtmenizi sağlar. Basit bir tablo oluşturmak için DisplayInWord yönteminin sonuna aşağıdaki
kodu ekleyin. Bağımsız değişkeni, range içindeki metin dizesindeki virgüllerin tablonun hücrelerini
ayırabelirtir.

// Convert to a simple table. The table will have a single row with
// three columns.
range.ConvertToTable(Separator: ",");

Önceki sürümlerinde C#, aşağıdaki kodda gösterildiği gibi, ConvertToTable çağrısı her parametre için bir
başvuru bağımsız değişkeni gerektirir:

// Call to ConvertToTable in Visual C# 2008 or earlier. This code


// is not part of the solution.
var missing = Type.Missing;
object separator = ",";
range.ConvertToTable(ref separator, ref missing, ref missing,
ref missing, ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing, ref missing,
ref missing);

2. Projeyi çalıştırmak için CTRL+F5 tuşuna basın.

Diğer parametrelerle denemek için


1. Tabloyu tek bir sütuna ve üç satıra sahip olacak şekilde değiştirmek için DisplayInWord son satırını
aşağıdaki deyimle değiştirin ve ardından CTRL+F5yazın.

range.ConvertToTable(Separator: ",", AutoFit: true, NumColumns: 1);

2. Tablo için önceden tanımlanmış bir biçim belirtmek üzere DisplayInWord son satırını aşağıdaki deyimle
değiştirin ve ardından CTRL+F5yazın. Biçim, WdTableFormat sabitlerinden herhangi biri olabilir.

range.ConvertToTable(Separator: ",", AutoFit: true, NumColumns: 1,


Format: Word.WdTableFormat.wdTableFormatElegant);

Örnek
Aşağıdaki kod tam örneği içerir:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Word = Microsoft.Office.Interop.Word;

namespace OfficeHowTo
{
class WordProgram
{
static void Main(string[] args)
{
DisplayInWord();
}

static void DisplayInWord()


{
var wordApp = new Word.Application();
wordApp.Visible = true;
// docs is a collection of all the Document objects currently
// open in Word.
Word.Documents docs = wordApp.Documents;

// Add a document to the collection and name it doc.


Word.Document doc = docs.Add();

// Define a range, a contiguous area in the document, by specifying


// a starting and ending character position. Currently, the document
// is empty.
Word.Range range = doc.Range(0, 0);

// Use the InsertAfter method to insert a string at the end of the


// current range.
range.InsertAfter("Testing, testing, testing. . .");

// You can comment out any or all of the following statements to


// see the effect of each one in the Word document.

// Next, use the ConvertToTable method to put the text into a table.
// The method has 16 optional parameters. You only have to specify
// values for those you want to change.

// Convert to a simple table. The table will have a single row with
// three columns.
range.ConvertToTable(Separator: ",");

// Change to a single column with three rows..


range.ConvertToTable(Separator: ",", AutoFit: true, NumColumns: 1);

// Format the table.


range.ConvertToTable(Separator: ",", AutoFit: true, NumColumns: 1,
Format: Word.WdTableFormat.wdTableFormatElegant);
}
}
}

Ayrıca bkz.
Adlandırılmış ve İsteğe Bağlı Bağımsız Değişkenler
Oluşturucular (C# Programlama Kılavuzu)
25.11.2019 • 3 minutes to read • Edit Online

Bir sınıf veya Yapı oluşturulduğunda, Oluşturucusu çağırılır. Bir sınıf veya yapının farklı bağımsız değişkenler
alan birden çok Oluşturucusu olabilir. Oluşturucular, programcının varsayılan değerleri ayarlama, örnek
oluşturmayı sınırlandırma ve esnek ve okunması kolay bir kod yazma olanağı sağlar. Daha fazla bilgi ve
örnek için bkz. oluşturucular ve örnek oluşturucular kullanma .

Parametresiz oluşturucular
Sınıfınız için bir Oluşturucu sağlamazsanız, C# nesneyi örnekleyen ve varsayılan değerler
tablosundalistelenen üye değişkenlerini varsayılan değerlere ayarlayan varsayılan olarak bir tane oluşturur.
Struct için bir Oluşturucu sağlamazsanız, C# varsayılan değerler tablosundalistelenen bir değer türünün her
alanını varsayılan değerine otomatik olarak başlatmak için örtük parametresiz bir oluşturucuya bağımlıdır.
Daha fazla bilgi ve örnek için bkz. örnek oluşturucular.

Oluşturucu sözdizimi
Oluşturucu, adı türünün adı ile aynı olan bir yöntemdir. Yöntemi imzasında yalnızca Yöntem adı ve parametre
listesi bulunur; dönüş türü içermez. Aşağıdaki örnek, Person adlı bir sınıf için oluşturucuyu gösterir.

public class Person


{
private string last;
private string first;

public Person(string lastName, string firstName)


{
last = lastName;
first = firstName;
}

// Remaining implementation of Person class.


}

Bir Oluşturucu tek bir deyim olarak uygulan, bir ifade gövdesi tanımıkullanabilirsiniz. Aşağıdaki örnek,
oluşturucusunun adıadlı tek bir dize parametresine sahip bir Location sınıfını tanımlar. İfade gövdesi tanımı,
locationName alanına bağımsız değişkenini atar.

public class Location


{
private string locationName;

public Location(string name) => Name = name;

public string Name


{
get => locationName;
set => locationName = value;
}
}
Statik oluşturucular
Önceki örneklerde, yeni bir nesne oluşturan tüm gösterilen örnek oluşturucuları vardır. Bir sınıf veya yapı,
türün statik üyelerini Başlatan statik bir oluşturucuya de sahip olabilir. Statik oluşturucular parametresiz.
Statik alanları başlatmak için statik bir Oluşturucu sağlamazsanız, C# derleyici varsayılan değerler
tablosundalistelenen statik alanları varsayılan değerlerine başlatır.
Aşağıdaki örnek, statik bir alanı başlatmak için statik bir Oluşturucu kullanır.

public class Adult : Person


{
private static int minimumAge;

public Adult(string lastName, string firstName) : base(lastName, firstName)


{ }

static Adult()
{
minimumAge = 18;
}

// Remaining implementation of Adult class.


}

Aşağıdaki örnekte gösterildiği gibi, bir ifade gövdesi tanımıyla bir statik oluşturucu da tanımlayabilirsiniz.

public class Child : Person


{
private static int maximumAge;

public Child(string lastName, string firstName) : base(lastName, firstName)


{ }

static Child() => maximumAge = 18;

// Remaining implementation of Child class.


}

Daha fazla bilgi ve örnek için bkz. statik oluşturucular.

Bu Bölümde
Oluşturucuları Kullanma
Örnek Oluşturucuları
Özel Oluşturucular
Statik Oluşturucular
Kopya Oluşturucu yazma

Ayrıca bkz.
C# Programlama Kılavuzu
Sınıflar ve Yapılar
Sonlandırıcılar
static
Başlatıcılar neden oluşturucular olarak ters sırada çalışıyor? Birinci bölüm
Oluşturucular Kullanma (C# Programlama Kılavuzu)
4.11.2019 • 6 minutes to read • Edit Online

Bir sınıf veya Yapı oluşturulduğunda, Oluşturucusu çağırılır. Oluşturucular, sınıf veya struct ile aynı ada sahiptir ve
genellikle yeni nesnenin veri üyelerini başlatır.
Aşağıdaki örnekte, Taxi adlı bir sınıf basit bir Oluşturucu kullanılarak tanımlanır. Bu sınıf daha sonra New
işleciyle oluşturulur. Taxi Oluşturucusu, yeni nesne için bellek ayrıldıktan hemen sonra new işleci tarafından
çağrılır.

public class Taxi


{
public bool IsInitialized;
public Taxi()
{
IsInitialized = true;
}
}

class TestTaxi
{
static void Main()
{
Taxi t = new Taxi();
Console.WriteLine(t.IsInitialized);
}
}

Parametresiz Oluşturucuolarak hiçbir parametre alan bir oluşturucuya. Parametresiz oluşturucular, bir nesne new
işleci kullanılarak örneklendiğinde ve new için herhangi bir bağımsız değişken sağlanmadıkça çağrılır. Daha fazla
bilgi için bkz. örnek oluşturucular.
Sınıf statikolmadığı takdirde, oluşturucuları olmayan sınıflara sınıf örneğini etkinleştirmek için C# derleyici
tarafından ortak parametresiz bir Oluşturucu verilirler. Daha fazla bilgi için bkz. statik sınıflar ve statik sınıf üyeleri.
Aşağıdaki gibi, oluşturucuyu özel yaparak bir sınıfın örneğinin oluşturulmasını engelleyebilirsiniz:

class NLog
{
// Private Constructor:
private NLog() { }

public static double e = Math.E; //2.71828...


}

Daha fazla bilgi için bkz. özel oluşturucular.


Yapı türleri için oluşturucular Sınıf oluşturuculara benzer, ancak structs derleyici tarafından otomatik olarak
sağlandığı için açık parametresiz bir oluşturucu içeremez. Bu Oluşturucu struct her alanı varsayılan değerlerine
başlatır. Daha fazla bilgi için bkz. varsayılan değerler tablosu. Ancak, bu parametresiz Oluşturucu yalnızca struct
new ile birlikte oluşturulduğunda çağrılır. Örneğin, bu kod, tamsayının başlatıldığından emin olmak için
Int32parametresiz oluşturucuyu kullanır.
int i = new int();
Console.WriteLine(i);

Ancak, aşağıdaki kod, bir derleyici hatasına neden olur çünkü new kullanmaz ve başlatılmamış bir nesneyi
kullanmaya çalışır:

int i;
Console.WriteLine(i);

Alternatif olarak, structs tabanlı nesneler (tüm yerleşik sayısal türler dahil) başlatılabilir veya atanabilir ve daha
sonra aşağıdaki örnekte olduğu gibi kullanılabilir:

int a = 44; // Initialize the value type...


int b;
b = 33; // Or assign it before using it.
Console.WriteLine("{0}, {1}", a, b);

Bu nedenle, bir değer türü için parametresiz oluşturucunun çağrılması gerekli değildir.
Her iki sınıf ve structs de parametre alma oluşturucuları tanımlayabilir. Parametreleri alan oluşturucuların bir
new ifadesiyle veya bir taban ifadesiyle çağrılması gerekir. Sınıflar ve structs de birden çok Oluşturucu
tanımlayabilir ve parametresiz bir Oluşturucu tanımlamak gerekmez. Örneğin:

public class Employee


{
public int Salary;

public Employee(int annualSalary)


{
Salary = annualSalary;
}

public Employee(int weeklySalary, int numberOfWeeks)


{
Salary = weeklySalary * numberOfWeeks;
}
}

Bu sınıf aşağıdaki deyimlerden herhangi biri kullanılarak oluşturulabilir:

Employee e1 = new Employee(30000);


Employee e2 = new Employee(500, 52);

Bir Oluşturucu, bir temel sınıfın yapıcısını çağırmak için base anahtar sözcüğünü kullanabilir. Örneğin:

public class Manager : Employee


{
public Manager(int annualSalary)
: base(annualSalary)
{
//Add further instructions here.
}
}

Bu örnekte, Oluşturucu için blok yürütülmeden önce temel sınıfın Oluşturucusu çağırılır. base anahtar sözcüğü
parametresiz ya da olmadan kullanılabilir. Oluşturucuya yönelik tüm parametreler base parametre olarak veya
bir ifadenin bir parçası olarak kullanılabilir. Daha fazla bilgi için bkz. Base.
Türetilmiş bir sınıfta, bir temel sınıf oluşturucu açıkça base anahtar sözcüğü kullanılarak çağrılmamasından,
varsa parametresiz Oluşturucu örtük olarak çağırılır. Bu, aşağıdaki Oluşturucu bildirimlerinin etkili bir şekilde aynı
olduğu anlamına gelir:

public Manager(int initialData)


{
//Add further instructions here.
}

public Manager(int initialData)


: base()
{
//Add further instructions here.
}

Bir temel sınıf parametresiz bir Oluşturucu sunmuyor ise, türetilmiş sınıf base kullanarak temel oluşturucuya açık
bir çağrı vermelidir.
Bu anahtar sözcüğünü kullanarak bir Oluşturucu aynı nesnede başka bir Oluşturucu çağırabilir. base gibi, this
parametresiz veya parametresiz olarak kullanılabilir ve kurucudaki herhangi bir parametre this parametre
olarak veya bir ifadenin parçası olarak kullanılabilir. Örneğin, önceki örnekteki ikinci Oluşturucu this kullanılarak
yeniden yazılabilir:

public Employee(int weeklySalary, int numberOfWeeks)


: this(weeklySalary * numberOfWeeks)
{
}

Önceki örnekte this anahtar sözcüğünün kullanılması, bu oluşturucunun çağrılmasına neden olur:

public Employee(int annualSalary)


{
Salary = annualSalary;
}

Oluşturucular ortak, özel, korunan, dahili, korunan iç veya özel korumalıolarak işaretlenebilir. Bu erişim
değiştiricileri, sınıfın kullanıcılarının sınıfı nasıl oluşturabileceğinize ilişkin tanımlar. Daha fazla bilgi için bkz. erişim
değiştiricileri.
Bir Oluşturucu static anahtar sözcüğü kullanılarak statik olarak bildirilemez. Statik oluşturucular, herhangi bir
statik alana erişildikten hemen önce otomatik olarak çağrılır ve genellikle statik sınıf üyelerini başlatmak için
kullanılır. Daha fazla bilgi için bkz. statik oluşturucular.

C# Dil Belirtimi
Daha fazla bilgi için bkz. C# dil belirtiminde örnek oluşturucular ve statik oluşturucular . Dil belirtimi, C#
sözdizimi ve kullanımı için kesin bir kaynaktır.

Ayrıca bkz.
C# Programlama Kılavuzu
Sınıflar ve Yapılar
Oluşturucular
Sonlandırıcılar
Örnek Oluşturucuları (C# Programlama Kılavuzu)
23.10.2019 • 6 minutes to read • Edit Online

Örnek oluşturucular, bir sınıfınnesnesini oluşturmak için Yeni ifadeyi kullandığınızda herhangi bir örnek üye
değişkeni oluşturmak ve başlatmak için kullanılır. Statik bir sınıf veya statik değişkenleri statik olmayan bir sınıfta
başlatmak için statik bir Oluşturucu tanımlarsınız. Daha fazla bilgi için bkz. statik oluşturucular.
Aşağıdaki örnek bir örnek Oluşturucu göstermektedir:

class Coords
{
public int x, y;

// constructor
public Coords()
{
x = 0;
y = 0;
}
}

NOTE
Açıklık için, bu sınıf ortak alanlar içerir. Ortak alanların kullanımı önerilen bir programlama uygulaması değildir çünkü bir
programda herhangi bir yerde herhangi bir yerdeki herhangi bir yönteme izin verir ve bir nesnenin iç işleyişi için
doğrulanmamış erişimdir. Veri üyeleri genellikle özel olmalıdır ve yalnızca sınıf yöntemleri ve özellikleri aracılığıyla
erişilmelidir.

Bu örnek Oluşturucu, Coords sınıfı temel alan bir nesne oluşturulduğunda çağrılır. Böyle bir bağımsız değişken
alan bir Oluşturucu gibi bir oluşturucuya parametresiz Oluşturucudenir. Ancak, genellikle ek oluşturucular
sağlamak yararlı olur. Örneğin, Coords sınıfa veri üyeleri için başlangıç değerlerini belirtmemizi sağlayan bir
Oluşturucu ekleyebiliriz:

// A constructor with two arguments.


public Coords(int x, int y)
{
this.x = x;
this.y = y;
}

Bu, Coords nesnelerin varsayılan veya belirli başlangıç değerleriyle oluşturulmasına izin verir, örneğin:

var p1 = new Coords();


var p2 = new Coords(5, 3);

Bir sınıfın Oluşturucusu yoksa, parametresiz bir Oluşturucu otomatik olarak oluşturulur ve nesne alanlarını
başlatmak için varsayılan değerler kullanılır. Örneğin, bir int 0 olarak başlatılır. Varsayılan değerler hakkında daha
fazla bilgi için bkz. varsayılan değerler tablosu. Bu nedenle, Coords parametresiz bir Oluşturucu tüm veri
üyelerini sıfıra başlattığında, sınıfın çalışma biçimini değiştirmeden tamamen kaldırılabilir. Bu konunun ilerleyen
kısımlarında örnek 1 ' de birden çok Oluşturucu kullanan bir örnek verilmiştir ve örnek 2 ' de otomatik olarak
oluşturulan bir oluşturucuya örnek verilmiştir.
Örnek oluşturucular, temel sınıfların örnek oluşturucularını çağırmak için de kullanılabilir.Sınıf oluşturucusu,
aşağıdaki gibi, başlatıcı aracılığıyla temel sınıfın oluşturucusunu çağırabilir:

class Circle : Shape


{
public Circle(double radius)
: base(radius, 0)
{
}
}

Bu örnekte, Circle sınıfı, RADIUS ve yüksekliği temsil eden değerleri, öğesinden Circle türetilmiş tarafından
Shape sunulan oluşturucuya geçirir. Shape Ve Circle bu konuda örnek 3 olarak görünen bir örnek.

Örnek 1
Aşağıdaki örnek, bağımsız değişkenler olmadan biri ve iki bağımsız değişken içeren iki sınıf oluşturucusuna
sahip bir sınıfı gösterir.

class Coords
{
public int x, y;

// Default constructor.
public Coords()
{
x = 0;
y = 0;
}

// A constructor with two arguments.


public Coords(int x, int y)
{
this.x = x;
this.y = y;
}

// Override the ToString method.


public override string ToString()
{
return $"({x},{y})";
}
}

class MainClass
{
static void Main()
{
var p1 = new Coords();
var p2 = new Coords(5, 3);

// Display the results using the overriden ToString method.


Console.WriteLine($"Coords #1 at {p1}");
Console.WriteLine($"Coords #2 at {p2}");
Console.ReadKey();
}
}
/* Output:
Coords #1 at (0,0)
Coords #2 at (5,3)
*/
Örnek 2
Bu örnekte, sınıfın Person herhangi bir Oluşturucusu yoktur, bu durumda parametresiz bir Oluşturucu otomatik
olarak sağlanır ve alanlar varsayılan değerlerine başlatılır.

public class Person


{
public int age;
public string name;
}

class TestPerson
{
static void Main()
{
var person = new Person();

Console.WriteLine("Name: {person.name}, Age: {person.age}");


// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
// Output: Name: , Age: 0

age Varsayılan değerinin 0 vevarsayılan null değerinin olduğunu unutmayın. name Varsayılan değerler
hakkında daha fazla bilgi için bkz. varsayılan değerler tablosu.

Örnek 3
Aşağıdaki örnek, temel sınıf başlatıcısının kullanımını gösterir. Sınıfı genel sınıftan Shape türetilir ve Cylinder
sınıfı Circle sınıfından türetilir. Circle Türetilmiş her sınıftaki Oluşturucu kendi temel sınıf başlatıcısını
kullanıyor.
abstract class Shape
{
public const double pi = Math.PI;
protected double x, y;

public Shape(double x, double y)


{
this.x = x;
this.y = y;
}

public abstract double Area();


}

class Circle : Shape


{
public Circle(double radius)
: base(radius, 0)
{
}
public override double Area()
{
return pi * x * x;
}
}

class Cylinder : Circle


{
public Cylinder(double radius, double height)
: base(radius)
{
y = height;
}

public override double Area()


{
return (2 * base.Area()) + (2 * pi * x * y);
}
}

class TestShapes
{
static void Main()
{
double radius = 2.5;
double height = 3.0;

Circle ring = new Circle(radius);


Cylinder tube = new Cylinder(radius, height);

Console.WriteLine("Area of the circle = {0:F2}", ring.Area());


Console.WriteLine("Area of the cylinder = {0:F2}", tube.Area());

// Keep the console window open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* Output:
Area of the circle = 19.63
Area of the cylinder = 86.39
*/

Temel sınıf oluşturucularını çağırma hakkında daha fazla örnek için bkz. sanal, geçersiz kılmave temel.
Ayrıca bkz.
C# Programlama Kılavuzu
Sınıflar ve Yapılar
Oluşturucular
Sonlandırıcılar
static
Özel Oluşturucular (C# Programlama Kılavuzu)
4.11.2019 • 2 minutes to read • Edit Online

Özel Oluşturucu özel bir örnek oluşturucudur. Genellikle yalnızca statik üyeler içeren sınıflarda kullanılır. Bir sınıfta
bir veya daha fazla özel Oluşturucu varsa ve ortak oluşturucu yoksa, diğer sınıflar (iç içe sınıflar hariç) bu sınıfın
örneklerini oluşturamaz. Örneğin:

class NLog
{
// Private Constructor:
private NLog() { }

public static double e = Math.E; //2.71828...


}

Boş oluşturucunun bildirimi parametresiz bir oluşturucunun otomatik olarak oluşturulmasını engeller. Oluşturucu
ile bir erişim değiştiricisi kullanmıyorsanız, varsayılan olarak hala Private olacağını unutmayın. Ancak, özel
değiştirici genellikle sınıfın örneklendirilmediğini açık hale getirmek için açıkça kullanılır.
Özel oluşturucular, Math sınıfı gibi bir örnek alanı veya yöntem olmadığında veya bir sınıfın örneğini almak için bir
yöntem çağrıldığında bir sınıfın örneklerinin oluşturulmasını engellemek için kullanılır. Sınıftaki tüm yöntemler
statikse, tüm sınıfı statik hale getirmeyi düşünün. Daha fazla bilgi için bkz. statik sınıflar ve statik sınıf üyeleri.

Örnek
Aşağıda özel Oluşturucu kullanan bir sınıf örneği verilmiştir.

public class Counter


{
private Counter() { }
public static int currentCount;
public static int IncrementCount()
{
return ++currentCount;
}
}

class TestCounter
{
static void Main()
{
// If you uncomment the following statement, it will generate
// an error because the constructor is inaccessible:
// Counter aCounter = new Counter(); // Error

Counter.currentCount = 100;
Counter.IncrementCount();
Console.WriteLine("New count: {0}", Counter.currentCount);

// Keep the console window open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
// Output: New count: 101
Aşağıdaki deyimin örnek olarak açıklama eklendiğinde, koruma düzeyi nedeniyle Oluşturucu erişilemediğinden bir
hata üretir:

// Counter aCounter = new Counter(); // Error

C# Dil Belirtimi
Daha fazla bilgi için bkz. C# dil belirtiminde özel oluşturucular . Dil belirtimi, C# sözdizimi ve kullanımı için kesin
bir kaynaktır.

Ayrıca bkz.
C# Programlama Kılavuzu
Sınıflar ve Yapılar
Oluşturucular
Sonlandırıcılar
private
public
Statik Oluşturucular (C# Programlama Kılavuzu)
23.10.2019 • 6 minutes to read • Edit Online

Statik bir Oluşturucu, herhangi bir statik veriyi başlatmak veya yalnızca bir kez gerçekleştirilmesi gereken belirli
bir eylemi gerçekleştirmek için kullanılır. İlk örnek oluşturulmadan veya herhangi bir statik üyeye
başvurulmadan önce bu otomatik olarak çağrılır.

class SimpleClass
{
// Static variable that must be initialized at run time.
static readonly long baseline;

// Static constructor is called at most one time, before any


// instance constructor is invoked or member is accessed.
static SimpleClass()
{
baseline = DateTime.Now.Ticks;
}
}

Açıklamalar
Statik oluşturucular aşağıdaki özelliklere sahiptir:
Statik bir Oluşturucu erişim değiştiricileri almaz veya parametrelere sahip değildir.
Bir sınıf veya yapı birimi yalnızca bir statik oluşturucuya sahip olabilir.
Statik oluşturucular devralınamaz veya aşırı yüklenemez.
Statik bir Oluşturucu doğrudan çağrılamaz ve yalnızca ortak dil çalışma zamanı (CLR ) tarafından
çağrılabilir. Otomatik olarak çağrılır.
Programda statik Oluşturucu yürütüldüğünde kullanıcının denetimi yoktur.
Statik bir Oluşturucu, ilk örnek oluşturulmadan veya herhangi bir statik üyeye başvurulmadan önce sınıfı
başlatmak için otomatik olarak çağrılır. Bir statik oluşturucu, örnek oluşturucudan önce çalışacaktır. Bir
olaya atanan statik bir yöntem çağrıldığında ya da bir temsilci atandığında, bir türün statik
oluşturucusunun çağrıldığını unutmayın. Statik alan değişkeni başlatıcıları statik oluşturucunun sınıfında
mevcutsa, statik oluşturucunun yürütülmesinden hemen önce sınıf bildiriminde göründükleri metin
sırasına göre yürütülür.
Statik alanları başlatmak için statik bir Oluşturucu sağlamazsanız, varsayılan değerler
tablosundalistelendiği gibi tüm statik alanlar varsayılan değerlerine başlatılır.
Statik bir Oluşturucu bir özel durum oluşturursa, çalışma zamanı ikinci bir kez çağrılmaz ve
programınızın çalıştığı uygulama etki alanının ömrü boyunca tür başlatılmamış olarak kalır. En yaygın
olarak, TypeInitializationException statik bir Oluşturucu bir tür örneklememediğinde veya statik
oluşturucu içinde oluşan işlenmeyen bir özel durum için bir özel durum oluşturulur. Kaynak kodunda
açıkça tanımlanmayan örtük statik oluşturucular için, sorun giderme ara dil (IL ) kodunu denetlemesini
gerektirebilir.
Statik bir oluşturucunun varlığı BeforeFieldInit tür özniteliğinin eklenmesini engeller. Bu, çalışma
zamanının iyileştirmesini sınırlandırır.
Olarak static readonly belirtilen bir alan, bildiriminin bir parçası olarak veya bir statik oluşturucuda
atanabilir. Açık bir statik Oluşturucu gerekli olmadığında, daha iyi çalışma zamanı iyileştirmesi için bir
statik Oluşturucu yerine bildiriminde statik alanları başlatın.

NOTE
Doğrudan erişilemeyen halde, açık bir statik oluşturucunun varlığı, başlatma özel durumlarının giderilmesi için yardımcı
olmak üzere açıklanmalıdır.

Kullanım
Statik oluşturucuların tipik kullanımı, sınıfın bir günlük dosyası kullanıldığı ve oluşturucunun bu dosyaya
giriş yazmak için kullanıldığı durumlarda kullanılır.
Statik oluşturucular, Oluşturucu LoadLibrary yöntemi çağırabilmesini, yönetilmeyen kod için sarmalayıcı
sınıflar oluştururken de kullanışlıdır.
Statik oluşturucular, derleme zamanında kısıtlamalar aracılığıyla denetlenemeyen tür parametresinde
çalışma zamanı denetimlerini zorlamak için de kullanışlı bir yerdir (tür parametresi kısıtlamaları).

Örnek
Bu örnekte, sınıfının Bus statik bir Oluşturucusu vardır. İlk örneği Bus oluşturulduğunda ( bus1 ), sınıfı
başlatmak için statik oluşturucu çağrılır. Örnek çıktı, statik oluşturucunun, iki örneği Bus oluşturulsa ve örnek
Oluşturucu çalışmadan önce çalışmasına rağmen yalnızca bir kez çalıştığını doğrular.

public class Bus


{
// Static variable used by all Bus instances.
// Represents the time the first bus of the day starts its route.
protected static readonly DateTime globalStartTime;

// Property for the number of each bus.


protected int RouteNumber { get; set; }

// Static constructor to initialize the static variable.


// It is invoked before the first instance constructor is run.
static Bus()
{
globalStartTime = DateTime.Now;

// The following statement produces the first line of output,


// and the line occurs only once.
Console.WriteLine("Static constructor sets global start time to {0}",
globalStartTime.ToLongTimeString());
}

// Instance constructor.
public Bus(int routeNum)
{
RouteNumber = routeNum;
Console.WriteLine("Bus #{0} is created.", RouteNumber);
}

// Instance method.
public void Drive()
{
TimeSpan elapsedTime = DateTime.Now - globalStartTime;

// For demonstration purposes we treat milliseconds as minutes to simulate


// actual bus times. Do not do this in your actual bus schedule program!
Console.WriteLine("{0} is starting its route {1:N2} minutes after global start time {2}.",
this.RouteNumber,
this.RouteNumber,
elapsedTime.Milliseconds,
globalStartTime.ToShortTimeString());
}
}

class TestBus
{
static void Main()
{
// The creation of this instance activates the static constructor.
Bus bus1 = new Bus(71);

// Create a second bus.


Bus bus2 = new Bus(72);

// Send bus1 on its way.


bus1.Drive();

// Wait for bus2 to warm up.


System.Threading.Thread.Sleep(25);

// Send bus2 on its way.


bus2.Drive();

// Keep the console window open in debug mode.


System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
}
/* Sample output:
Static constructor sets global start time to 3:57:08 PM.
Bus #71 is created.
Bus #72 is created.
71 is starting its route 6.00 minutes after global start time 3:57 PM.
72 is starting its route 31.00 minutes after global start time 3:57 PM.
*/

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin statik oluşturucular bölümüne bakın.

Ayrıca bkz.
C# Programlama Kılavuzu
Sınıflar ve Yapılar
Oluşturucular
Statik Sınıflar ve Statik Sınıf Üyeleri
Sonlandırıcılar
Oluşturucu tasarım yönergeleri
Güvenlik Uyarısı-CA2121: Statik oluşturucular özel olmalıdır
Kopya Oluşturucu yazma (C# Programlama Kılavuzu)
25.11.2019 • 2 minutes to read • Edit Online

C#nesneler için bir kopya Oluşturucu sağlamaz, ancak kendiniz bir tane yazabilirsiniz.

Örnek
Aşağıdaki örnekte Person sınıfı , bir Person örneği olan bağımsız değişkeni olarak alan bir kopya Oluşturucu
tanımlar. Bağımsız değişkeninin özelliklerinin değerleri Person yeni örneğinin özelliklerine atanır. Kod, sınıfının
örnek oluşturucusuna kopyalamak istediğiniz örneğin Name ve Age özelliklerini gönderen alternatif bir kopya
Oluşturucu içerir.
class Person
{
// Copy constructor.
public Person(Person previousPerson)
{
Name = previousPerson.Name;
Age = previousPerson.Age;
}

//// Alternate copy constructor calls the instance constructor.


//public Person(Person previousPerson)
// : this(previousPerson.Name, previousPerson.Age)
//{
//}

// Instance constructor.
public Person(string name, int age)
{
Name = name;
Age = age;
}

public int Age { get; set; }

public string Name { get; set; }

public string Details()


{
return Name + " is " + Age.ToString();
}
}

class TestPerson
{
static void Main()
{
// Create a Person object by using the instance constructor.
Person person1 = new Person("George", 40);

// Create another Person object, copying person1.


Person person2 = new Person(person1);

// Change each person's age.


person1.Age = 39;
person2.Age = 41;

// Change person2's name.


person2.Name = "Charles";

// Show details to verify that the name and age fields are distinct.
Console.WriteLine(person1.Details());
Console.WriteLine(person2.Details());

// Keep the console window open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
// Output:
// George is 39
// Charles is 41

Ayrıca bkz.
ICloneable
C# Programlama Kılavuzu
Sınıflar ve Yapılar
Oluşturucular
Sonlandırıcılar
Sonlandırıcılar (C# Programlama Kılavuzu)
4.11.2019 • 5 minutes to read • Edit Online

Sonlandırıcılar (yani Yıkıcılarolarak da bilinir), bir sınıf örneği çöp toplayıcısı tarafından toplandığında gerekli
son temizleme işlemini gerçekleştirmek için kullanılır.

Açıklamalar
Sonlandırıcılar yapılar içinde tanımlanamaz. Bunlar yalnızca sınıflarla birlikte kullanılır.
Bir sınıfın yalnızca bir sonlandırıcısı olabilir.
Sonlandırıcılar devralınamaz veya aşırı yüklenemez.
Sonlandırıcılar çağrılamaz. Bunlar otomatik olarak çağırılır.
Sonlandırıcı değiştirici almaz veya parametrelere sahip değildir.
Örneğin, Car sınıfı için sonlandırıcının bildirimi aşağıda verilmiştir.

class Car
{
~Car() // finalizer
{
// cleanup statements...
}
}

Bir Sonlandırıcı, aşağıdaki örnekte gösterildiği gibi bir ifade gövdesi tanımı olarak da uygulanabilir.

using System;

public class Destroyer


{
public override string ToString() => GetType().Name;

~Destroyer() => Console.WriteLine($"The {ToString()} destructor is executing.");


}

Sonlandırıcı nesnenin temel sınıfında Finalize dolaylı olarak çağırır. Bu nedenle, sonlandırıcının çağrısı dolaylı
olarak aşağıdaki koda çevrilir:

protected override void Finalize()


{
try
{
// Cleanup statements...
}
finally
{
base.Finalize();
}
}

Bu, Finalize yönteminin devralma zincirindeki tüm örnekler için özyinelemeli olarak çağrıldığı, en az türetilen
' ın en küçük bir değer olarak çağrıldığı anlamına gelir.

NOTE
Boş sonlandırıcılar kullanılmamalıdır. Bir sınıf bir Sonlandırıcı içerdiğinde, Finalize kuyrukta bir giriş oluşturulur.
Sonlandırıcı çağrıldığında, atık toplayıcı kuyruğu işleyecek şekilde çağrılır. Boş bir Sonlandırıcı yalnızca gereksiz performans
kaybına neden olur.

Bu, çöp toplayıcı tarafından belirlendiği için sonlandırıcının çağrıldığı zaman üzerinde denetime sahip değildir.
Çöp toplayıcı, artık uygulama tarafından kullanılmayan nesneleri denetler. Sonlandırma için uygun bir nesne
kabul eder, sonlandırıcıyı çağırır (varsa) ve nesneyi depolamak için kullanılan belleği geri kazanır.
.NET Framework uygulamalarda (.NET Core uygulamalarında değil), program çıkıldığında sonlandırıcılar da
çağırılır.
Collectçağırarak çöp toplamayı zorlamak mümkündür, ancak çoğu zaman performans sorunları
oluşturabileceğinden bu durum kaçınılmalıdır.

Kaynakları serbest bırakmak için sonlandırıcıları kullanma


Genel olarak, C# çöp toplama ile çalışma zamanını hedeflemez bir dille geliştirirken gereken kadar bellek
yönetimi gerekmez. Bunun nedeni, .NET Framework atık toplayıcının nesneleriniz için bellek ayırmayı ve
serbest bırakma işlemini örtülü olarak yönetmesinden kaynaklanır. Ancak, uygulamanız Windows, dosyalar ve
ağ bağlantıları gibi yönetilmeyen kaynakları kapsüller, bu kaynakları serbest bırakmak için sonlandırıcıları
kullanmanız gerekir. Nesne sonlandırmaya uygun olduğunda, çöp toplayıcı nesnenin Finalize yöntemini
çalıştırır.

Kaynakların açık yayını


Uygulamanız pahalı bir dış kaynak kullanıyorsa, atık toplayıcı nesneyi serbest bırakmadan önce kaynağı açıkça
serbest bırakmak için bir yol sağlamanızı öneririz. Bu, nesnesi için gerekli temizleme işlemini gerçekleştiren
IDisposable arabiriminden bir Dispose yöntemi uygulayarak yapılır. Bu, uygulamanın performansını önemli
ölçüde iyileştirebilirler. Kaynak üzerinde bu açık denetimle birlikte, Dispose yöntemine yapılan çağrı başarısız
olursa Sonlandırıcı, kaynakları temizlemek için bir güvenlik önlemi haline gelir.
Kaynakları Temizleme hakkında daha fazla bilgi için aşağıdaki konulara bakın:
Yönetilmeyen Kaynakları Temizleme
Dispose Yöntemi Uygulama
using Deyimi

Örnek
Aşağıdaki örnek, bir devralım zinciri oluşturan üç sınıf oluşturur. Sınıf First temel sınıftır, Second First
türetilir ve Third Second türetilir. Tüm üçünün sonlandırıcıları vardır. Main , en çok türetilen sınıfın bir örneği
oluşturulur. Program çalıştığında, üç sınıfa ait sonlandırıcılara otomatik olarak ve sırasıyla en az türetilmiş ' dan
türetilmiş ' a göre çağrıldığını unutmayın.
class First
{
~First()
{
System.Diagnostics.Trace.WriteLine("First's destructor is called.");
}
}

class Second : First


{
~Second()
{
System.Diagnostics.Trace.WriteLine("Second's destructor is called.");
}
}

class Third : Second


{
~Third()
{
System.Diagnostics.Trace.WriteLine("Third's destructor is called.");
}
}

class TestDestructors
{
static void Main()
{
Third t = new Third();
}

}
/* Output (to VS Output Window):
Third's destructor is called.
Second's destructor is called.
First's destructor is called.
*/

C# dili belirtimi
Daha fazla bilgi için C# dil belirtiminin Yıkıcılar bölümüne bakın.

Ayrıca bkz.
IDisposable
C# Programlama Kılavuzu
Oluşturucular
Atık Toplama
Nesne ve Koleksiyon Başlatıcıları (C#
Programlama Kılavuzu)
4.11.2019 • 11 minutes to read • Edit Online

C#bir nesne veya koleksiyon örneklemenizi ve tek bir ifadede üye atamaları gerçekleştirmenizi sağlar.

Nesne başlatıcıları
Nesne başlatıcıları, oluşturma zamanında ardından atama deyimleri satırları gelecek şekilde bir oluşturucu
çağırmak zorunda kalmadan, bir nesnenin istediğiniz erişilebilir alanlarına veya özelliklerine değerler
atamanıza olanak tanır. Nesne başlatıcı sözdizimi, bir oluşturucu için bağımsız değişkenler belirtmenize veya
bağımsız değişkenleri (ve parantez sözdizimini) atmanıza olanak tanır. Aşağıdaki örnek, Cat adlandırılmış bir
tür ile bir nesne Başlatıcısı kullanmayı ve parametresiz oluşturucuyu çağırmayı gösterir. Cat sınıfında
otomatik uygulanan özelliklerin kullanımını göz önünde edin. Daha fazla bilgi için bkz. Otomatik uygulanan
özellikler.

public class Cat


{
// Auto-implemented properties.
public int Age { get; set; }
public string Name { get; set; }

public Cat()
{
}

public Cat(string name)


{
this.Name = name;
}
}

Cat cat = new Cat { Age = 10, Name = "Fluffy" };


Cat sameCat = new Cat("Fluffy"){ Age = 10 };

Nesne başlatıcıları sözdizimi, bir örnek oluşturmanıza olanak sağlar ve sonra, atanan özelliklerine sahip yeni
oluşturulan nesneyi atamadaki değişkene atar.
C# 6 ' dan itibaren, nesne başlatıcıları alanları ve özellikleri atamaya ek olarak Dizin oluşturucular
ayarlayabilir. Bu temel Matrix sınıfını göz önünde bulundurun:

public class Matrix


{
private double[,] storage = new double[3, 3];

public double this[int row, int column]


{
// The embedded array will throw out of range exceptions as appropriate.
get { return storage[row, column]; }
set { storage[row, column] = value; }
}
}
Kimlik matrisini aşağıdaki kodla başlatabilirsiniz:

var identity = new Matrix


{
[0, 0] = 1.0,
[0, 1] = 0.0,
[0, 2] = 0.0,

[1, 0] = 0.0,
[1, 1] = 1.0,
[1, 2] = 0.0,

[2, 0] = 0.0,
[2, 1] = 0.0,
[2, 2] = 1.0,
};

Erişilebilir bir ayarlayıcı içeren erişilebilir Dizin Oluşturucu, bağımsız değişkenlerin sayısı veya türleri ne
olursa olsun, nesne başlatıcısındaki ifadelerden biri olarak kullanılabilir. Dizin bağımsız değişkenleri atamanın
sol tarafını oluşturur ve değer ifadenin sağ tarafındadır. Örneğin, IndexersExample uygun dizin
oluşturuculardan biri varsa bunlar geçerlidir:

var thing = new IndexersExample {


name = "object one",
[1] = '1',
[2] = '4',
[3] = '9',
Size = Math.PI,
['C',4] = "Middle C"
}

Yukarıdaki kodun derlenmesi için IndexersExample türü aşağıdaki üyelere sahip olmalıdır:

public string name;


public double Size { set { ... }; }
public char this[int i] { set { ... }; }
public string this[char c, int i] { set { ... }; }

Anonim türlerde Nesne Başlatıcıları


Nesne başlatıcıları herhangi bir bağlamda kullanılabilse de, LINQ sorgu ifadelerinde özellikle faydalıdır.
Sorgu ifadeleri, aşağıdaki bildirimde gösterildiği gibi, yalnızca bir nesne Başlatıcısı kullanılarak başlatılan
anonim türleriçin sık kullanılan kullanımı kolaylaştırır.

var pet = new { Age = 10, Name = "Fluffy" };

Anonim türler, özgün dizinin nesnelerini değeri ve şekli orijinalden farklı olabilecek nesnelere dönüştürmek
için bir LINQ sorgu ifadesinde select yan tümcesini etkinleştirir. Bir sıradaki her bir nesneden elde edilen
bilgilerin yalnızca bir kısmını depolamak isterseniz, bu kullanışlıdır. Aşağıdaki örnekte, bir ürün nesnesinin (
p ) birçok alanı ve yöntemi içerdiğini ve yalnızca ürün adını ve birim fiyatını içeren bir nesne dizisi
oluşturmak istediğinizi varsayalım.

var productInfos =
from p in products
select new { p.ProductName, p.UnitPrice };
Bu sorgu yürütüldüğünde productInfos değişkeni, bu örnekte gösterildiği gibi bir foreach bildiriminde
erişilebilen bir nesne dizisi içerir:

foreach(var p in productInfos){...}

Yeni anonim türdeki her nesnenin, özgün nesnedeki özellikler veya alanlarla aynı adları alan iki ortak özelliği
vardır. Ayrıca, anonim bir tür oluştururken bir alanı yeniden adlandırabilirsiniz; Aşağıdaki örnek, UnitPrice
alanı Price olarak yeniden adlandırır.

select new {p.ProductName, Price = p.UnitPrice};

Koleksiyon başlatıcıları
Koleksiyon başlatıcıları, IEnumerable uygulayan bir koleksiyon türü başlattığınızda bir veya daha fazla öğe
başlatıcısını belirtmenizi sağlar ve bir örnek yöntemi veya bir genişletme yöntemi olarak uygun imzaya sahip
Add . Öğe başlatıcıları basit bir değer, bir ifade veya nesne Başlatıcısı olabilir.Bir koleksiyon başlatıcısı
kullanarak birden çok çağrı belirtmeniz gerekmez; Derleyici çağrıları otomatik olarak ekler.
Aşağıdaki örnekte iki basit koleksiyon başlatıcıları gösterilmektedir:

List<int> digits = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };


List<int> digits2 = new List<int> { 0 + 1, 12 % 3, MakeInt() };

Aşağıdaki koleksiyon başlatıcısı, önceki örnekte tanımlanan Cat sınıfının nesnelerini başlatmak için nesne
başlatıcıları kullanır. Nesne başlatıcıların tek tek küme ayraçları içine alındığına ve virgüllerle ayrıldığına
dikkat edin.

List<Cat> cats = new List<Cat>


{
new Cat{ Name = "Sylvester", Age=8 },
new Cat{ Name = "Whiskers", Age=2 },
new Cat{ Name = "Sasha", Age=14 }
};

Koleksiyonun Add yöntemi izin veriyorsa, koleksiyon başlatıcısında bir öğe olarak null belirtebilirsiniz.

List<Cat> moreCats = new List<Cat>


{
new Cat{ Name = "Furrytail", Age=5 },
new Cat{ Name = "Peaches", Age=4 },
null
};

Koleksiyon okuma/yazma dizinlemeyi destekliyorsa, dizinli öğeleri belirtebilirsiniz.

var numbers = new Dictionary<int, string>


{
[7] = "seven",
[9] = "nine",
[13] = "thirteen"
};

Yukarıdaki örnek, değerlerini ayarlamak için Item[TKey] çağıran kodu oluşturur. 6 C# ' dan önce, aşağıdaki
sözdizimini kullanarak sözlükleri ve diğer İlişkilendirilebilir kapsayıcıları başlatabilirsiniz. Dizin Oluşturucu
sözdizimi yerine parantez ve atama ile birden çok değerli bir nesne kullandığını fark edin:

var moreNumbers = new Dictionary<int, string>


{
{19, "nineteen" },
{23, "twenty-three" },
{42, "forty-two" }
};

Bu başlatıcı örneği, sözlüğe üç öğe eklemek için Add(TKey, TValue) çağırır. İlişkilendirilebilir koleksiyonları
başlatmanın bu iki farklı yolu, derleyicinin oluşturduğu Yöntem çağrıları nedeniyle biraz farklı davranışa
sahiptir. Her iki çeşit de Dictionary sınıfıyla çalışır. Diğer türler, genel API 'lerine göre yalnızca bir veya
diğerini destekleyebilir.

Örnekler
Aşağıdaki örnek, nesne ve koleksiyon başlatıcıları kavramlarını birleştirir.
public class InitializationSample
{
public class Cat
{
// Auto-implemented properties.
public int Age { get; set; }
public string Name { get; set; }

public Cat() { }

public Cat(string name)


{
Name = name;
}
}

public static void Main()


{
Cat cat = new Cat { Age = 10, Name = "Fluffy" };
Cat sameCat = new Cat("Fluffy"){ Age = 10 };

List<Cat> cats = new List<Cat>


{
new Cat { Name = "Sylvester", Age = 8 },
new Cat { Name = "Whiskers", Age = 2 },
new Cat { Name = "Sasha", Age = 14 }
};

List<Cat> moreCats = new List<Cat>


{
new Cat { Name = "Furrytail", Age = 5 },
new Cat { Name = "Peaches", Age = 4 },
null
};

// Display results.
System.Console.WriteLine(cat.Name);

foreach (Cat c in cats)


System.Console.WriteLine(c.Name);

foreach (Cat c in moreCats)


if (c != null)
System.Console.WriteLine(c.Name);
else
System.Console.WriteLine("List element has null value.");
}
// Output:
//Fluffy
//Sylvester
//Whiskers
//Sasha
//Furrytail
//Peaches
//List element has null value.
}

Aşağıdaki örnek, IEnumerable uygulayan ve birden çok parametreli bir Add yöntemi içeren bir nesnesi
gösterir, bu, Add yönteminin imzasına karşılık gelen listede öğe başına birden çok öğe içeren bir koleksiyon
başlatıcısı kullanır.
public class FullExample
{
class FormattedAddresses : IEnumerable<string>
{
private List<string> internalList = new List<string>();
public IEnumerator<string> GetEnumerator() => internalList.GetEnumerator();

System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() =>


internalList.GetEnumerator();

public void Add(string firstname, string lastname,


string street, string city,
string state, string zipcode) => internalList.Add(
$@"{firstname} {lastname}
{street}
{city}, {state} {zipcode}"
);
}

public static void Main()


{
FormattedAddresses addresses = new FormattedAddresses()
{
{"John", "Doe", "123 Street", "Topeka", "KS", "00000" },
{"Jane", "Smith", "456 Street", "Topeka", "KS", "00000" }
};

Console.WriteLine("Address Entries:");

foreach (string addressEntry in addresses)


{
Console.WriteLine("\r\n" + addressEntry);
}
}

/*
* Prints:

Address Entries:

John Doe
123 Street
Topeka, KS 00000

Jane Smith
456 Street
Topeka, KS 00000
*/
}

Add Yöntemler, aşağıdaki örnekte gösterildiği gibi, değişken sayıda bağımsız değişken almak için params
anahtar sözcüğünü kullanabilir. Bu örnek ayrıca dizin kullanarak bir koleksiyonu başlatmak için bir dizin
oluşturucunun özel uygulamasını gösterir.

public class DictionaryExample


{
class RudimentaryMultiValuedDictionary<TKey, TValue> : IEnumerable<KeyValuePair<TKey, List<TValue>>>
{
private Dictionary<TKey, List<TValue>> internalDictionary = new Dictionary<TKey, List<TValue>>
();

public IEnumerator<KeyValuePair<TKey, List<TValue>>> GetEnumerator() =>


internalDictionary.GetEnumerator();

System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() =>


internalDictionary.GetEnumerator();
internalDictionary.GetEnumerator();

public List<TValue> this[TKey key]


{
get => internalDictionary[key];
set => Add(key, value);
}

public void Add(TKey key, params TValue[] values) => Add(key, (IEnumerable<TValue>)values);

public void Add(TKey key, IEnumerable<TValue> values)


{
if (!internalDictionary.TryGetValue(key, out List<TValue> storedValues))
internalDictionary.Add(key, storedValues = new List<TValue>());

storedValues.AddRange(values);
}
}

public static void Main()


{
RudimentaryMultiValuedDictionary<string, string> rudimentaryMultiValuedDictionary1
= new RudimentaryMultiValuedDictionary<string, string>()
{
{"Group1", "Bob", "John", "Mary" },
{"Group2", "Eric", "Emily", "Debbie", "Jesse" }
};
RudimentaryMultiValuedDictionary<string, string> rudimentaryMultiValuedDictionary2
= new RudimentaryMultiValuedDictionary<string, string>()
{
["Group1"] = new List<string>() { "Bob", "John", "Mary" },
["Group2"] = new List<string>() { "Eric", "Emily", "Debbie", "Jesse" }
};
RudimentaryMultiValuedDictionary<string, string> rudimentaryMultiValuedDictionary3
= new RudimentaryMultiValuedDictionary<string, string>()
{
{"Group1", new string []{ "Bob", "John", "Mary" } },
{ "Group2", new string[]{ "Eric", "Emily", "Debbie", "Jesse" } }
};

Console.WriteLine("Using first multi-valued dictionary created with a collection initializer:");

foreach (KeyValuePair<string, List<string>> group in rudimentaryMultiValuedDictionary1)


{
Console.WriteLine($"\r\nMembers of group {group.Key}: ");

foreach (string member in group.Value)


{
Console.WriteLine(member);
}
}

Console.WriteLine("\r\nUsing second multi-valued dictionary created with a collection


initializer using indexing:");

foreach (KeyValuePair<string, List<string>> group in rudimentaryMultiValuedDictionary2)


{
Console.WriteLine($"\r\nMembers of group {group.Key}: ");

foreach (string member in group.Value)


{
Console.WriteLine(member);
}
}
Console.WriteLine("\r\nUsing third multi-valued dictionary created with a collection initializer
using indexing:");

foreach (KeyValuePair<string, List<string>> group in rudimentaryMultiValuedDictionary3)


{
Console.WriteLine($"\r\nMembers of group {group.Key}: ");
Console.WriteLine($"\r\nMembers of group {group.Key}: ");

foreach (string member in group.Value)


{
Console.WriteLine(member);
}
}
}

/*
* Prints:

Using first multi-valued dictionary created with a collection initializer:

Members of group Group1:


Bob
John
Mary

Members of group Group2:


Eric
Emily
Debbie
Jesse

Using second multi-valued dictionary created with a collection initializer using indexing:

Members of group Group1:


Bob
John
Mary

Members of group Group2:


Eric
Emily
Debbie
Jesse

Using third multi-valued dictionary created with a collection initializer using indexing:

Members of group Group1:


Bob
John
Mary

Members of group Group2:


Eric
Emily
Debbie
Jesse
*/
}

Ayrıca bkz.
C# Programlama Kılavuzu
C# üzerinde LINQ
Anonim Tipler
Nesne Başlatıcısı kullanarak nesneleri başlatma (C#
Programlama Kılavuzu)
25.11.2019 • 3 minutes to read • Edit Online

Tür nesnelerini, tür için açıkça bir Oluşturucu çağırmadan, bildirime dayalı olarak başlatmak için nesne başlatıcıları
' nı kullanabilirsiniz.
Aşağıdaki örneklerde, adlandırılmış nesneler ile nesne başlatıcılarının nasıl kullanılacağı gösterilmektedir. Derleyici,
önce varsayılan örnek oluşturucusuna erişerek ve sonra üye başlatmaları işleyerek nesne başlatıcıları işler. Bu
nedenle, parametresiz Oluşturucu sınıfında private olarak bildirilirse, genel erişim gerektiren nesne başlatıcıları
başarısız olur.
Anonim bir tür tanımlıyorsanız bir nesne Başlatıcısı kullanmanız gerekir. Daha fazla bilgi için bkz. bir sorgudaki öğe
özelliklerinin alt kümelerini döndürme.

Örnek
Aşağıdaki örnekte, nesne başlatıcıları kullanarak yeni bir StudentName türünün nasıl başlatılacağını
gösterilmektedir. Bu örnek StudentName türündeki özellikleri ayarlar:

public class HowToObjectInitializers


{
public static void Main()
{
// Declare a StudentName by using the constructor that has two parameters.
StudentName student1 = new StudentName("Craig", "Playstead");

// Make the same declaration by using an object initializer and sending


// arguments for the first and last names. The default constructor is
// invoked in processing this declaration, not the constructor that has
// two parameters.
StudentName student2 = new StudentName
{
FirstName = "Craig",
LastName = "Playstead",
};

// Declare a StudentName by using an object initializer and sending


// an argument for only the ID property. No corresponding constructor is
// necessary. Only the default constructor is used to process object
// initializers.
StudentName student3 = new StudentName
{
ID = 183
};

// Declare a StudentName by using an object initializer and sending


// arguments for all three properties. No corresponding constructor is
// defined in the class.
StudentName student4 = new StudentName
{
FirstName = "Craig",
LastName = "Playstead",
ID = 116
};

Console.WriteLine(student1.ToString());
Console.WriteLine(student2.ToString());
Console.WriteLine(student2.ToString());
Console.WriteLine(student3.ToString());
Console.WriteLine(student4.ToString());
}
// Output:
// Craig 0
// Craig 0
// 183
// Craig 116

public class StudentName


{
// The default constructor has no parameters. The default constructor
// is invoked in the processing of object initializers.
// You can test this by changing the access modifier from public to
// private. The declarations in Main that use object initializers will
// fail.
public StudentName() { }

// The following constructor has parameters for two of the three


// properties.
public StudentName(string first, string last)
{
FirstName = first;
LastName = last;
}

// Properties.
public string FirstName { get; set; }
public string LastName { get; set; }
public int ID { get; set; }

public override string ToString() => FirstName + " " + ID;


}
}

Nesne başlatıcıları, bir nesnedeki Dizin oluşturucuyu ayarlamak için kullanılabilir. Aşağıdaki örnek, farklı
konumlarda oynatıcı almak ve ayarlamak için bir dizin oluşturucu kullanan bir BaseballTeam sınıfını tanımlar.
Başlatıcı, konum kısaltmasını veya her bir konum için kullanılan her bir konum için kullanılan sayıyı temel alarak
oyuncuları atayabilir:
public class HowToIndexInitializer
{
public class BaseballTeam
{
private string[] players = new string[9];
private readonly List<string> positionAbbreviations = new List<string>
{
"P", "C", "1B", "2B", "3B", "SS", "LF", "CF", "RF"
};

public string this[int position]


{
// Baseball positions are 1 - 9.
get { return players[position-1]; }
set { players[position-1] = value; }
}
public string this[string position]
{
get { return players[positionAbbreviations.IndexOf(position)]; }
set { players[positionAbbreviations.IndexOf(position)] = value; }
}
}

public static void Main()


{
var team = new BaseballTeam
{
["RF"] = "Mookie Betts",
[4] = "Jose Altuve",
["CF"] = "Mike Trout"
};

Console.WriteLine(team["2B"]);
}
}

Ayrıca bkz.
C# Programlama Kılavuzu
Nesne ve Koleksiyon Başlatıcıları
Koleksiyon başlatıcısı ile bir sözlük başlatma (C#
Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Bir Dictionary<TKey,TValue> anahtar/değer çiftleri koleksiyonu içerir. Add Yöntemi, biri anahtar ve diğeri değer
için olmak üzere iki parametre alır. Ya da Add yöntemi birden çok Dictionary<TKey,TValue>parametre alan
herhangi bir koleksiyonu başlatmanın bir yolu, aşağıdaki örnekte gösterildiği gibi her bir parametre kümesini
küme ayraçları içine allemektir. Diğer bir seçenek de aşağıdaki örnekte gösterilen bir dizin başlatıcısı kullanmaktır.

Örnek
Aşağıdaki kod örneğinde,, Dictionary<TKey,TValue> türünde StudentName örneklerle başlatılır. İlk başlatma Add
yöntemi iki bağımsız değişkenle birlikte kullanır. Derleyici, her Add int anahtar ve StudentName değer çiftlerinin
her biri için bir çağrı oluşturur. İkincisi, Dictionary sınıfının ortak bir okuma/yazma Indexer yöntemini kullanır:

public class HowToDictionaryInitializer


{
class StudentName
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int ID { get; set; }
}

public static void Main()


{
var students = new Dictionary<int, StudentName>()
{
{ 111, new StudentName { FirstName="Sachin", LastName="Karnik", ID=211 } },
{ 112, new StudentName { FirstName="Dina", LastName="Salimzianova", ID=317 } },
{ 113, new StudentName { FirstName="Andy", LastName="Ruth", ID=198 } }
};

foreach(var index in Enumerable.Range(111, 3))


{
Console.WriteLine($"Student {index} is {students[index].FirstName} {students[index].LastName}");
}
Console.WriteLine();

var students2 = new Dictionary<int, StudentName>()


{
[111] = new StudentName { FirstName="Sachin", LastName="Karnik", ID=211 },
[112] = new StudentName { FirstName="Dina", LastName="Salimzianova", ID=317 } ,
[113] = new StudentName { FirstName="Andy", LastName="Ruth", ID=198 }
};

foreach (var index in Enumerable.Range(111, 3))


{
Console.WriteLine($"Student {index} is {students2[index].FirstName} {students2[index].LastName}");
}
}
}

İlk bildirimde koleksiyonun her bir öğesinde iki ayraç çiftini aklınızda edin. En içteki ayraç, StudentName için nesne
başlatıcısını kapsar ve en dıştaki küme ayraçları students Dictionary<TKey,TValue>öğesine eklenecek
anahtar/değer çifti için başlatıcıyı kapsar. Son olarak, sözlük için tüm koleksiyon başlatıcısı küme ayraçları içine
alınmıştır. İkinci başlatmada atamanın sol tarafı anahtardır ve sağ tarafta ise, için StudentName bir nesne Başlatıcısı
kullanılarak değer bulunur.

Ayrıca bkz.
C# Programlama Kılavuzu
Nesne ve Koleksiyon Başlatıcıları
İç içe Geçmiş Türler (C# Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Bir sınıf veya Yapı içinde tanımlanan bir türe iç içe geçmiş tür denir. Örneğin:

class Container
{
class Nested
{
Nested() { }
}
}

Dış türün bir sınıf veya yapı olmasından bağımsız olarak, iç içe geçmiş türler varsayılan olarak özeldir; bunlara
yalnızca kendi içerilen türden erişilebilir. Önceki örnekte, Nested sınıfına dış türler erişilemez.
Ayrıca, iç içe geçmiş bir türün erişilebilirliğini tanımlamak için aşağıdaki gibi bir erişim değiştiricisi belirtebilirsiniz:
Bir sınıfın iç içe geçmiş türleri ortak, korumalı, dahili, korunan iç, özel veya özel korumalıolabilir.
Ancak, korumalı bir protected sınıf içinde private protected protected internal veya iç içe yerleştirilmiş
bir sınıf tanımlamak, "korumalı sınıfta belirtilen yeni korunan üye" Derleyici Uyarısı CS0628oluşturur.
Bir yapının iç içe geçmiş türleri ortak, içveya özelolabilir.
Aşağıdaki örnek, Nested sınıfı genel yapar:

class Container
{
public class Nested
{
Nested() { }
}
}

İç içe geçmiş veya iç, türü kapsayan veya OUTER öğesine erişebilir. Kapsayan türe erişmek için, onu iç içe geçmiş
türün oluşturucusuna bağımsız değişken olarak geçirin. Örneğin:

public class Container


{
public class Nested
{
private Container parent;

public Nested()
{
}
public Nested(Container parent)
{
this.parent = parent;
}
}
}

İç içe bir tür, kapsayan türü tarafından erişilebilen tüm üyelere erişebilir.Devralınan korunan üyeler de dahil olmak
üzere, kapsayan türün özel ve korumalı üyelerine erişebilir.
Önceki bildirimde, sınıfının Nested Container.Nested tam adı. Bu, aşağıdaki gibi, iç içe yerleştirilmiş sınıfın yeni bir
örneğini oluşturmak için kullanılan addır:

Container.Nested nest = new Container.Nested();

Ayrıca bkz.
C# Programlama Kılavuzu
Sınıflar ve Yapılar
Erişim Değiştiricileri
Oluşturucular
Kısmi Sınıflar ve Yöntemler (C# Programlama
Kılavuzu)
4.11.2019 • 10 minutes to read • Edit Online

Bir sınıfıntanımını, bir yapıyı, arabirimi veya bir yöntemi iki veya daha fazla kaynak dosya üzerinde ayırmak
mümkündür. Her kaynak dosya, tür veya yöntem tanımının bir bölümünü içerir ve uygulama derlendiğinde tüm
parçalar birleştirilir.

Kısmi sınıflar
Bir sınıf tanımını bölmek istenen birkaç durum vardır:
Büyük projeler üzerinde çalışırken, bir sınıfın ayrı dosyalar üzerinde yayılması, birden fazla programcıların
aynı anda üzerinde çalışmasını sağlar.
Otomatik olarak oluşturulan kaynakla çalışırken, kaynak dosyayı yeniden oluşturmak zorunda kalmadan
kod sınıfa eklenebilir. Visual Studio, Windows Forms, Web hizmeti sarmalayıcı kodu vb. oluşturduğunda
bu yaklaşımı kullanır. Visual Studio tarafından oluşturulan dosyayı değiştirmek zorunda kalmadan, bu
sınıfları kullanan kod oluşturabilirsiniz.
Bir sınıf tanımını ayırmak için, burada gösterildiği gibi kısmi anahtar sözcük değiştiricisini kullanın:

public partial class Employee


{
public void DoWork()
{
}
}

public partial class Employee


{
public void GoToLunch()
{
}
}

partial anahtar sözcüğü, sınıfın, yapının veya arabirimin diğer bölümlerinin ad alanında tanımlanamayacağını
belirtir. Tüm parçaların partial anahtar sözcüğünü kullanması gerekir. Son türü oluşturmak için tüm parçalar
derleme zamanında kullanılabilir olmalıdır. Tüm parçalar public , private vb. gibi aynı erişilebilirliği içermelidir.
Herhangi bir bölüm soyut olarak bildirilirse, tüm tür soyut olarak değerlendirilir. Herhangi bir bölüm Sealed
olarak bildirilirse, tüm tür Sealed olarak değerlendirilir. Herhangi bir parça bir temel tür bildiriyorsa, tüm tür o
sınıfı devralır.
Bir temel sınıf belirten tüm parçalar kabul etmelidir, ancak temel bir sınıfı atlayan parçalar hala temel türü miras
alır. Parçalar farklı temel arabirimler belirtebilir ve son tür tüm kısmi bildirimlerin listelebileceği tüm arabirimleri
uygular. Kısmi bir tanımda belirtilen herhangi bir sınıf, yapı veya arabirim üyesi diğer tüm parçalar için
kullanılabilir. Son tür derleme zamanında tüm parçaların birleşimidir.

NOTE
partial değiştiricisi temsilci veya numaralandırma bildirimlerinde kullanılamıyor.
Aşağıdaki örnek iç içe geçmiş türlerin kısmen, iç içe yerleştirilmiş olması durumunda bile kısmi bir tür olduğunu
gösterir.

class Container
{
partial class Nested
{
void Test() { }
}
partial class Nested
{
void Test2() { }
}
}

Derleme zamanında, kısmi tür tanımlarının öznitelikleri birleştirilir. Örneğin, aşağıdaki bildirimleri göz önünde
bulundurun:

[SerializableAttribute]
partial class Moon { }

[ObsoleteAttribute]
partial class Moon { }

Bunlar aşağıdaki bildirimlerle eşdeğerdir:

[SerializableAttribute]
[ObsoleteAttribute]
class Moon { }

Aşağıdakiler tüm kısmi tür tanımlarından birleştirilir:


XML açıklamaları
arabirimler
Genel tür parametre öznitelikleri
class öznitelikleri
üyeler
Örneğin, aşağıdaki bildirimleri göz önünde bulundurun:

partial class Earth : Planet, IRotate { }


partial class Earth : IRevolve { }

Bunlar aşağıdaki bildirimlerle eşdeğerdir:

class Earth : Planet, IRotate, IRevolve { }

Kısıtlamalar
Kısmi sınıf tanımlarına çalışırken izlenecek birkaç kural vardır:
Aynı türdeki parçalar olması amaçlanan tüm kısmi tür tanımlarının partial ile değiştirilmesi gerekir.
Örneğin, aşağıdaki sınıf bildirimleri bir hata oluşturur:
public partial class A { }
//public class A { } // Error, must also be marked partial

partial değiştirici yalnızca, class , struct veya interface anahtar kelimeleriyle hemen önce yer alabilir.
İç içe geçmiş kısmi türlere, aşağıdaki örnekte gösterildiği gibi kısmi tür tanımlarında izin verilir:

partial class ClassWithNestedClass


{
partial class NestedClass { }
}

partial class ClassWithNestedClass


{
partial class NestedClass { }
}

Aynı türde parçalar olması gereken tüm kısmi tür tanımlarının aynı derlemede ve aynı modülde (. exe veya.
dll dosyası) tanımlanması gerekir. Kısmi tanımlar birden çok modüle yayılamaz.
Sınıf adı ve genel tür parametreleri tüm kısmi tür tanımlarında eşleşmelidir. Genel türler kısmi olabilir. Her
kısmi bildirimin aynı parametre adlarını aynı sırada kullanması gerekir.
Kısmi tür tanımında aşağıdaki anahtar sözcükler isteğe bağlıdır, ancak bir kısmi tür tanımında varsa, aynı
türde başka bir kısmi tanımda belirtilen anahtar sözcüklerle çakışamaz:
public
private
protected
internal
abstract
sealed
taban sınıfı
Yeni değiştirici (iç içe yerleştirilmiş parçalar)
genel kısıtlamalar
Daha fazla bilgi için bkz. tür parametrelerindeki kısıtlamalar.

Örnek 1
Açıklama
Aşağıdaki örnekte, Coords sınıfının alanları ve Oluşturucusu tek bir kısmi sınıf tanımında ve PrintCoords üyesi
başka bir kısmi sınıf tanımında bildirilmiştir.
Kod
public partial class Coords
{
private int x;
private int y;

public Coords(int x, int y)


{
this.x = x;
this.y = y;
}
}

public partial class Coords


{
public void PrintCoords()
{
Console.WriteLine("Coords: {0},{1}", x, y);
}

class TestCoords
{
static void Main()
{
Coords myCoords = new Coords(10, 15);
myCoords.PrintCoords();

// Keep the console window open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
// Output: Coords: 10,15

Örnek 2
Açıklama
Aşağıdaki örnek ayrıca kısmi yapılar ve arabirimler geliştirebileceğinizi gösterir.
Kod

partial interface ITest


{
void Interface_Test();
}

partial interface ITest


{
void Interface_Test2();
}

partial struct S1
{
void Struct_Test() { }
}

partial struct S1
{
void Struct_Test2() { }
}
Kısmi Yöntemler
Kısmi bir sınıf veya yapı, kısmi bir yöntem içerebilir. Sınıfın bir kısmı metodun imzasını içerir. İsteğe bağlı bir
uygulama aynı bölümde veya başka bir bölümde tanımlanabilir. Uygulama sağlanmazsa, yöntemi ve yöntemine
yapılan tüm çağrılar derleme sırasında kaldırılır.
Kısmi Yöntemler, bir olaya benzer bir yöntemi tanımlamak için bir sınıfın bir parçasının Uygulayıcısı sağlar.
Sınıfının diğer bölümünün uygulayıcısı, yöntemi uygulayıp uygulamamaya karar verebilir. Yöntem
uygulanmadığından, derleyici yöntem imzasını ve yönteme yapılan tüm çağrıları kaldırır. Çağrılardaki bağımsız
değişkenlerin değerlendirmesinden kaynaklanan sonuçlar da dahil olmak üzere yöntemine yapılan çağrılar,
çalışma zamanında hiçbir etkiye sahip değildir. Bu nedenle, kısmi sınıftaki herhangi bir kod, uygulama
sağlanmasa bile, kısmi bir yöntemi serbestçe kullanabilir. Yöntem çağrılırsa ancak uygulanmadığında, derleme
zamanı veya çalışma zamanı hataları ortaya alınmaz.
Kısmi Yöntemler özellikle oluşturulan kodu özelleştirmenin bir yolu olarak faydalıdır. Bir yöntem adının ve
imzasının ayrılmaya izin verir, böylece oluşturulan kod yöntemi çağırabilir, ancak geliştirici yöntemin uygulanıp
uygulamamaya karar verebilir. Kısmi sınıflara çok benzeyen kısmi Yöntemler, bir kod üreticisi tarafından
oluşturulan kodu ve bir insan geliştiricisi tarafından oluşturulan kodu, çalışma zamanı maliyetleri olmadan
birlikte çalışmak üzere etkinleştirir.
Kısmi yöntem bildirimi iki bölümden oluşur: tanım ve uygulama. Bunlar kısmi bir sınıfın ayrı bölümlerinde veya
aynı bölümde olabilir. Uygulama bildirimi yoksa, derleyici hem tanımlama bildirimini hem de yönteme yapılan
tüm çağrıları en iyi duruma getirir.

// Definition in file1.cs
partial void onNameChanged();

// Implementation in file2.cs
partial void onNameChanged()
{
// method body
}

Kısmi yöntem bildirimleri, bağlamsal anahtar sözcüğüyle kısmen başlamalı ve yöntemin voiddöndürmesi
gerekir.
Kısmi yöntemlerin içinde veya ref , ancak Out parametreleri olabilir.
Kısmi Yöntemler örtük olarak özeldirve bu nedenle sanalolamaz.
Gövde varlığı, tanımlama veya uygulama yapılıp yapılmayacağını belirlerse, kısmi Yöntemler
externolamaz.
Kısmi yöntemlerin statik ve güvenli olmayan değiştiriciler olabilir.
Kısmi yöntemler genel olabilir. Kısıtlamalar, tanımlayıcı kısmi Yöntem bildirimine konur ve isteğe bağlı
olarak uygulama bir tane üzerinde yinelenebilir. Parametre ve tür parametre adları, uygulama bildiriminde,
tanımlanmasıyla aynı olmak zorunda değildir.
Tanımlanmış ve uygulanmış, ancak yalnızca tanımlanmış kısmi bir yönteme değil kısmi bir yönteme
temsilci oluşturabilirsiniz.

C# Dil Belirtimi
Daha fazla bilgi için bkz. C# dil belirtiminde kısmi türler . Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.
Ayrıca bkz.
C# Programlama Kılavuzu
Sınıflar
Yapılar
Arabirimler
partial (Tür)
Anonim Türler (C# Programlama Kılavuzu)
4.11.2019 • 6 minutes to read • Edit Online

Anonim türler, salt bir türü açıkça tanımlamak zorunda kalmadan tek bir nesne içinde salt okunurdur bir
özellik kümesini kapsüllemek için kullanışlı bir yol sağlar. Tür adı derleyici tarafından oluşturulur ve
kaynak kodu düzeyinde kullanılabilir değildir. Her özelliğin türü derleyici tarafından algılanır.
Yeni işleci bir nesne başlatıcısıyla birlikte kullanarak anonim türler oluşturursunuz. Nesne başlatıcıları
hakkında daha fazla bilgi için bkz. nesne ve koleksiyon başlatıcıları.
Aşağıdaki örnek, Amount ve Message adlı iki özellik ile başlatılan anonim bir türü gösterir.

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

Anonim türler genellikle bir sorgu ifadesinin Select yan tümcesinde, kaynak dizisindeki her bir nesneden
özelliklerin bir alt kümesini döndürmek için kullanılır. Sorgular hakkında daha fazla bilgi için bkz. LINQ
C#ın .
Anonim türler bir veya daha fazla genel salt okunurdur özelliği içerir. Yöntemler veya olaylar gibi başka
tür sınıf üyeleri geçerli değildir. Bir özelliği başlatmak için kullanılan ifade null , anonim bir işlev veya bir
işaretçi türü olamaz.
En yaygın senaryo, başka bir türden özelliklerle adsız bir tür başlatmalıdır. Aşağıdaki örnekte, Product adlı
bir sınıfın var olduğunu varsayalım. Sınıf Product , Color ve Price özelliklerini, ilgilenmediğiniz diğer
özelliklerle birlikte içerir. Değişken products , bir Product nesneleri koleksiyonudur. Anonim tür bildirimi
new anahtar sözcüğüyle başlar. Bildirim, Product yalnızca iki özellik kullanan yeni bir tür başlatır. Bu,
sorguda daha az miktarda veri döndürülmesine neden olur.
Anonim türde üye adları belirtmezseniz, derleyici anonim tür üyelerine onları başlatmak için kullanılan
özellik ile aynı adı verir. Önceki örnekte gösterildiği gibi, ifadesiyle başlatılan bir özellik için bir ad
sağlamalısınız. Aşağıdaki örnekte, anonim türün özelliklerinin adları Color ve 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);
}

Genellikle, bir değişkeni başlatmak için anonim bir tür kullandığınızda değişkeni, değişken kullanarak
örtükolarak yazılmış bir yerel değişken olarak bildirirsiniz. Tür adı değişken bildiriminde belirtilemiyor,
çünkü yalnızca derleyicinin adsız türdeki temel alınan ada erişimi vardır. var hakkında daha fazla bilgi için
bkz. örtülü olarak yazılan yerel değişkenler.
Aşağıdaki örnekte gösterildiği gibi örtük olarak yazılmış bir yerel değişkeni ve örtük olarak yazılmış bir
diziyi birleştirerek anonim olarak belirlenmiş öğelerin bir dizisini oluşturabilirsiniz.
var anonArray = new[] { new { name = "apple", diam = 4 }, new { name = "grape", diam = 1 }};

Açıklamalar
Anonim türler nesnesindendoğrudan türeten ve nesnedışında herhangi bir türe atanamaz olan sınıf
türleridir. Derleyici her adsız tür için bir ad sağlar, ancak uygulamanız buna erişemez. Ortak dil çalışma
zamanının perspektifinden, anonim bir tür diğer herhangi bir başvuru türünden farklı değildir.
Bir derlemede iki veya daha fazla anonim nesne başlatıcıları aynı sırada olan ve aynı ada ve türe sahip bir
özellikler sırası belirtse, derleyici nesneleri aynı türdeki örnekler olarak değerlendirir. Derleyici tarafından
oluşturulan tür bilgilerini paylaşır.
Bir alanı, özelliği, olayı veya bir yöntemin dönüş türünü anonim bir türe sahip olarak bildiremezsiniz.
Benzer şekilde, bir yöntem, özellik, Oluşturucu veya dizin oluşturucunun yapısal bir parametresini anonim
bir türe sahip olacak şekilde bildiremezsiniz. Anonim bir tür veya anonim türler içeren bir koleksiyonu, bir
yönteme bağımsız değişken olarak geçirmek için, parametreyi tür nesnesi olarak bildirebilirsiniz. Ancak,
bu işlem güçlü yazma amacını artırıyor. Sorgu sonuçlarını depolamanız veya yöntem sınırının dışında
geçirmeniz gerekiyorsa, anonim bir tür yerine sıradan adlandırılmış bir yapı veya sınıf kullanmayı
düşünün.
Anonim türlerdeki Equals ve GetHashCode yöntemleri, özelliklerinin Equals ve GetHashCode
yöntemlerine göre tanımlandığından, aynı anonim türdeki iki örnek yalnızca tüm özellikleri eşitse eşittir.

Ayrıca bkz.
C# Programlama Kılavuzu
Nesne ve Koleksiyon Başlatıcıları
C#'de LINQ Kullanmaya Başlama
C# üzerinde LINQ
Sorguda öğe özelliklerinin alt kümelerini döndürme
(C# Programlama Kılavuzu)
25.11.2019 • 2 minutes to read • Edit Online

Bu koşulların her ikisi de geçerli olduğunda bir sorgu ifadesinde anonim bir tür kullanın:
Her bir kaynak öğenin özelliklerinden yalnızca bazılarını döndürmek istiyorsunuz.
Sorgu sonuçlarını sorgunun yürütüldüğü yöntemin kapsamı dışında saklamak zorunda değilsiniz.
Her kaynak öğesinden yalnızca bir özellik veya alan döndürmek istiyorsanız, select yan tümcesindeki nokta
işlecini kullanabilirsiniz. Örneğin, her bir student yalnızca ID döndürmek için select yan tümcesini aşağıdaki
gibi yazın:

select student.ID;

Örnek
Aşağıdaki örnek, belirtilen koşulla eşleşen her bir kaynak öğenin özelliklerinin yalnızca bir alt kümesini
döndürmek için anonim bir türün nasıl kullanılacağını gösterir.

private static void QueryByScore()


{
// Create the query. var is required because
// the query produces a sequence of anonymous types.
var queryHighScores =
from student in students
where student.ExamScores[0] > 95
select new { student.FirstName, student.LastName };

// Execute the query.


foreach (var obj in queryHighScores)
{
// The anonymous type's properties were not named. Therefore
// they have the same names as the Student properties.
Console.WriteLine(obj.FirstName + ", " + obj.LastName);
}
}
/* Output:
Adams, Terry
Fakhouri, Fadi
Garcia, Cesar
Omelchenko, Svetlana
Zabokritski, Eugene
*/

Anonim türün, hiçbir ad belirtilmemişse, özellikleri için kaynak öğenin adlarını kullandığını unutmayın. Anonim
türdeki özelliklere yeni adlar vermek için select ifadesini aşağıdaki gibi yazın:

select new { First = student.FirstName, Last = student.LastName };

Önceki örnekte bunu denerseniz Console.WriteLine deyimin de değiştirilmesi gerekir:


Console.WriteLine(student.First + " " + student.Last);

Kod Derleniyor
Bu kodu çalıştırmak için, System. LINQ için using yönergesi ile C# sınıfı kopyalayıp bir konsol uygulamasına
yapıştırın.

Ayrıca bkz.
C# Programlama Kılavuzu
Anonim Tipler
C# üzerinde LINQ
Arabirimler (C# Programlama Kılavuzu)
31.10.2019 • 7 minutes to read • Edit Online

Bir arabirim, soyut olmayan bir sınıfın veya yapının uygulanması gereken ilgili işlevler grubu için tanımlar
içerir.
Arabirimleri kullanarak, örneğin, bir sınıftaki birden çok kaynaktan davranış ekleyebilirsiniz. Dil, sınıfların
birden çok C# devralınmasını desteklemediğinden bu özellik önemlidir. Bunlara ek olarak, başka bir struct
veya sınıftan gerçekten devralmadıklarından yapılar için devralmayı taklit etmek istiyorsanız bir arabirim
kullanmanız gerekir.
Arabirim anahtar sözcüğünü kullanarak bir arabirim tanımlarsınız. Aşağıdaki örnekte gösterildiği gibi.

interface IEquatable<T>
{
bool Equals(T obj);
}

Yapının adı geçerli C# bir tanımlayıcı adıolmalıdır. Kural gereği, arabirim adları büyük I başlar.
IEquatable<T> arabirimini uygulayan herhangi bir sınıf veya yapı, arabirimin belirttiği imzayla eşleşen bir
Equals yöntemi tanımı içermelidir. Sonuç olarak, sınıfının bir örneğinin aynı sınıfın başka bir örneğine eşit
olup olmadığını belirleyebildiği bir Equals yöntemi içermesi için IEquatable<T> uygulayan bir sınıf
üzerinde sayım yapabilirsiniz.
IEquatable<T> tanımı Equals için bir uygulama sağlamaz. Bir sınıf veya yapı birden çok arabirim
uygulayabilir, ancak bir sınıf yalnızca tek bir sınıftan devralınabilir.
Soyut sınıflar hakkında daha fazla bilgi için bkz. soyut ve korumalı sınıflar ve sınıf üyeleri.
Arabirimler Yöntemler, özellikler, olaylar, Dizin oluşturucular veya bu dört üye türlerinin herhangi bir
birleşimini içerebilir. Örneklere bağlantılar için Ilgili bölümlerbölümüne bakın. Arabirim, sabitler, alanlar,
işleçler, örnek oluşturucular, sonlandırıcılar veya türler içeremez. Arabirim üyeleri otomatik olarak geneldir
ve erişim değiştiricileri içeremez. Üyeler de statikolamaz.
Bir arabirim üyesini uygulamak için, uygulama sınıfının karşılık gelen üyesi ortak, statik değil olmalıdır ve
arabirim üyesiyle aynı ada ve imzaya sahip olmalıdır.
Bir sınıf veya yapı bir arabirim uygularsa, sınıf veya yapı, arabirimin tanımladığı tüm Üyeler için bir
uygulama sağlamalıdır. Arabirimin kendisi bir sınıf veya yapının, temel sınıf işlevini devraldığı şekilde
devraldığı bir işlevsellik sağlamaz. Ancak, bir temel sınıf bir arabirim uygularsa, taban sınıftan türetilmiş
herhangi bir sınıf bu uygulamayı devralır.
Aşağıdaki örnek, IEquatable<T> arabiriminin bir uygulamasını gösterir. Uygulama sınıfı Car , Equals
yönteminin bir uygulamasını sağlamalıdır.
public class Car : IEquatable<Car>
{
public string Make {get; set;}
public string Model { get; set; }
public string Year { get; set; }

// Implementation of IEquatable<T> interface


public bool Equals(Car car)
{
return this.Make == car.Make &&
this.Model == car.Model &&
this.Year == car.Year;
}
}

Bir sınıfın özellikleri ve Dizin oluşturucular, bir arabirimde tanımlı bir özellik veya Dizin Oluşturucu için ek
erişimciler tanımlayabilir. Örneğin, bir arabirim bir Get erişimcisine sahip bir özellik bildirebilir. Arabirimini
uygulayan sınıf, hem get hem de set erişimcisi ile aynı özelliği bildirebilir. Ancak, özellik veya Dizin
Oluşturucu açık uygulama kullanıyorsa, erişimcilerinin eşleşmesi gerekir. Açık uygulama hakkında daha fazla
bilgi için bkz. Açık arabirim uygulama ve arabirim özellikleri.
Arabirimler, diğer arabirimlerden devralınabilir. Bir sınıf, devraldığı temel sınıflar veya diğer arabirimlerin
devraldığı arabirimler aracılığıyla birden çok kez arabirim içerebilir. Ancak, sınıfı bir arabirimin uygulamasını
yalnızca bir kez ve yalnızca sınıf sınıfın tanımının bir parçası olarak bildirir ( class ClassName : InterfaceName
). Arabirimi uygulayan bir temel sınıf devralmış olduğunuz için arabirim devralınmışsa, taban sınıf arabirimin
üyelerinin uygulanmasını sağlar. Ancak, türetilen sınıf devralınan uygulamayı kullanmak yerine herhangi bir
sanal arabirim üyesini yeniden uygulayabilir.
Bir temel sınıf, sanal Üyeler kullanarak arabirim üyeleri de uygulayabilir. Bu durumda, türetilmiş bir sınıf
sanal üyeleri geçersiz kılarak arabirim davranışını değiştirebilir. Sanal üyeler hakkında daha fazla bilgi için
bkz. çok biçimlilik.

Arabirimler Özeti
Bir arabirim aşağıdaki özelliklere sahiptir:
Bir arabirim, yalnızca soyut üyelere sahip bir soyut temel sınıf gibidir. Arabirimi uygulayan herhangi bir
sınıf veya yapının tüm üyelerini uygulaması gerekir.
Arabirim doğrudan başlatılamaz. Üyeleri, arabirimini uygulayan herhangi bir sınıf veya yapı tarafından
uygulanır.
Arabirimler olay, Dizin oluşturucular, Yöntemler ve özellikler içerebilir.
Arabirimler yöntemlerin uygulanmasını içermez.
Bir sınıf veya yapı, birden çok arabirim uygulayabilir. Bir sınıf bir temel sınıfı devralınabilir ve ayrıca bir
veya daha fazla arabirim uygulayabilir.

Bu bölümde
Belirtik Arabirim Kullanma
Bir arabirime özgü bir sınıf üyesinin nasıl oluşturulacağını açıklar.
Nasıl yapılır: Arabirim Üyelerini Açıkça Uygulama
Arabirimlerin üyelerini açıkça nasıl uygulayacağınızı gösteren bir örnek sağlar.
Nasıl yapılır: İki Arabirimin Üyelerini Açıkça Uygulama
Devralma ile arabirimlerin üyelerini açıkça nasıl uygulayabileceğinizi gösteren bir örnek sağlar.
İlgili bölümler
Arabirim Özellikleri
Arabirimlerdeki Dizin Oluşturucular
Nasıl yapılır: arabirim olaylarını uygulama
Sınıflar ve Yapılar
Devralma
Yöntemler
Çok biçimlilik
Soyut ve Korumalı Sınıflar ve Sınıf Üyeleri
Veri Erişimi
Olaylar
Dizin Oluşturucular

öne çıkan kitap bölümü


Öğrenme C# 3,0 ' deki arabirimler: C# 3,0 temelleri ana

Ayrıca bkz.
C# Programlama Kılavuzu
Devralma
Tanımlayıcı adları
Açık Arabirim Uygulaması (C# Programlama
Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Bir sınıf , aynı imzaya sahip bir üye içeren iki arabirim uygularsa, bu üyeyi sınıfında uygulamak, her iki arabirimin
de uygulama olarak bu üyeyi kullanmasına neden olur. Aşağıdaki örnekte, tüm çağrıları aynı yöntemi çağırmak
için Paint çağırır.

class Test
{
static void Main()
{
SampleClass sc = new SampleClass();
IControl ctrl = sc;
ISurface srfc = sc;

// The following lines all call the same method.


sc.Paint();
ctrl.Paint();
srfc.Paint();
}
}

interface IControl
{
void Paint();
}
interface ISurface
{
void Paint();
}
class SampleClass : IControl, ISurface
{
// Both ISurface.Paint and IControl.Paint call this method.
public void Paint()
{
Console.WriteLine("Paint method in SampleClass");
}
}

// Output:
// Paint method in SampleClass
// Paint method in SampleClass
// Paint method in SampleClass

İki arabirim üyesi aynı işlevi gerçekleştirmez, ancak bu, arabirimlerin bir veya her ikisinin yanlış bir uygulamasına
neden olabilir. Yalnızca arabirim aracılığıyla çağrılan ve bu arabirime özgü olan bir sınıf üyesi oluşturarak, bir
arabirim üyesini açıkça uygulamak mümkündür. Bu, sınıf üyesini arabirim adı ve nokta ile adlandırarak yapılır.
Örneğin:
public class SampleClass : IControl, ISurface
{
void IControl.Paint()
{
System.Console.WriteLine("IControl.Paint");
}
void ISurface.Paint()
{
System.Console.WriteLine("ISurface.Paint");
}
}

Sınıf üyesi IControl.Paint yalnızca IControl arabirim aracılığıyla kullanılabilir ve ISurface.Paint yalnızca ile
ISurface kullanılabilir. Her iki yöntem uygulaması ayrı değildir ve doğrudan sınıfta kullanılamaz. Örneğin:

// Call the Paint methods from Main.

SampleClass obj = new SampleClass();


//obj.Paint(); // Compiler error.

IControl c = obj;
c.Paint(); // Calls IControl.Paint on SampleClass.

ISurface s = obj;
s.Paint(); // Calls ISurface.Paint on SampleClass.

// Output:
// IControl.Paint
// ISurface.Paint

Açık uygulama, her biri bir özellik ve bir yöntem gibi aynı ada sahip farklı Üyeler bildiren iki arabirimin da
bulunduğu durumları çözümlemek için de kullanılır:

interface ILeft
{
int P { get;}
}
interface IRight
{
int P();
}

Her iki arabirimi de uygulamak için bir sınıf, derleyici hatasından kaçınmak için P ya da Yöntem P ya da her ikisi
için açık uygulamayı kullanmalıdır. Örneğin:

class Middle : ILeft, IRight


{
public int P() { return 0; }
int ILeft.P { get { return 0; } }
}

Ayrıca bkz.
C# Programlama Kılavuzu
Sınıflar ve Yapılar
Arabirimler
Devralma
Nasıl yapılır: Arabirim üyelerini açıkça uygulama (C#
Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Bu örnek, ve arabirim üyelerini IDimensions Box getLength açıkçauygulayan bir arabirim, ve sınıfını bildirir.
getWidth Üyelere arabirim örneği dimensions üzerinden erişilir.

Örnek
interface IDimensions
{
float getLength();
float getWidth();
}

class Box : IDimensions


{
float lengthInches;
float widthInches;

Box(float length, float width)


{
lengthInches = length;
widthInches = width;
}
// Explicit interface member implementation:
float IDimensions.getLength()
{
return lengthInches;
}
// Explicit interface member implementation:
float IDimensions.getWidth()
{
return widthInches;
}

static void Main()


{
// Declare a class instance box1:
Box box1 = new Box(30.0f, 20.0f);

// Declare an interface instance dimensions:


IDimensions dimensions = box1;

// The following commented lines would produce compilation


// errors because they try to access an explicitly implemented
// interface member from a class instance:
//System.Console.WriteLine("Length: {0}", box1.getLength());
//System.Console.WriteLine("Width: {0}", box1.getWidth());

// Print out the dimensions of the box by calling the methods


// from an instance of the interface:
System.Console.WriteLine("Length: {0}", dimensions.getLength());
System.Console.WriteLine("Width: {0}", dimensions.getWidth());
}
}
/* Output:
Length: 30
Width: 20
*/

Güçlü Programlama
Aşağıdaki çizgilerin, derleme hataları ürettikleri için Main , yönteminin açıklama olarak bildirildiğine dikkat
edin. Açıkça uygulanan bir arabirim üyesine bir sınıf örneğinden erişilemez:

//System.Console.WriteLine("Length: {0}", box1.getLength());


//System.Console.WriteLine("Width: {0}", box1.getWidth());

Ayrıca, Main yöntemi arabirimin bir örneğinden çağrılmakta olduğundan, yönteminde aşağıdaki çizgilerin,
kutudaki boyutları başarıyla yazdıradığına dikkat edin:
System.Console.WriteLine("Length: {0}", dimensions.getLength());
System.Console.WriteLine("Width: {0}", dimensions.getWidth());

Ayrıca bkz.
C# Programlama Kılavuzu
Sınıflar ve Yapılar
Arabirimler
Nasıl yapılır: Iki arabirimin üyelerini açıkça uygulama
Nasıl yapılır: Iki arabirimin üyelerini açıkça uygulama
(C# Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Açık arabirim uygulaması Ayrıca, programcı 'nin aynı üye adlarına sahip iki arabirim uygulamasına ve her
arabirime ayrı bir uygulama sağlamasına izin verir. Bu örnek, hem ölçüm hem de Ingilizce birimlerindeki bir
kutunun boyutlarını görüntüler. Box sınıfı , farklı ölçü sistemlerini temsil eden iki arabirim olan
IEnglishDimensions ve IMetricDimensions uygular. Her iki arabirimde de aynı üye adları, uzunluğu ve genişliği
vardır.

Örnek
// Declare the English units interface:
interface IEnglishDimensions
{
float Length();
float Width();
}

// Declare the metric units interface:


interface IMetricDimensions
{
float Length();
float Width();
}

// Declare the Box class that implements the two interfaces:


// IEnglishDimensions and IMetricDimensions:
class Box : IEnglishDimensions, IMetricDimensions
{
float lengthInches;
float widthInches;

public Box(float lengthInches, float widthInches)


{
this.lengthInches = lengthInches;
this.widthInches = widthInches;
}

// Explicitly implement the members of IEnglishDimensions:


float IEnglishDimensions.Length() => lengthInches;

float IEnglishDimensions.Width() => widthInches;

// Explicitly implement the members of IMetricDimensions:


float IMetricDimensions.Length() => lengthInches * 2.54f;

float IMetricDimensions.Width() => widthInches * 2.54f;

static void Main()


{
// Declare a class instance box1:
Box box1 = new Box(30.0f, 20.0f);

// Declare an instance of the English units interface:


IEnglishDimensions eDimensions = box1;

// Declare an instance of the metric units interface:


IMetricDimensions mDimensions = box1;

// Print dimensions in English units:


System.Console.WriteLine("Length(in): {0}", eDimensions.Length());
System.Console.WriteLine("Width (in): {0}", eDimensions.Width());

// Print dimensions in metric units:


System.Console.WriteLine("Length(cm): {0}", mDimensions.Length());
System.Console.WriteLine("Width (cm): {0}", mDimensions.Width());
}
}
/* Output:
Length(in): 30
Width (in): 20
Length(cm): 76.2
Width (cm): 50.8
*/

Güçlü Programlama
Varsayılan ölçümleri Ingilizce birimlerde yapmak istiyorsanız, yöntem uzunluğunu ve genişliğini normal şekilde
uygulayın ve IMetricDimensions arabiriminden length ve Width yöntemlerini açık bir şekilde uygulayın:

// Normal implementation:
public float Length() => lengthInches;
public float Width() => widthInches;

// Explicit implementation:
float IMetricDimensions.Length() => lengthInches * 2.54f;
float IMetricDimensions.Width() => widthInches * 2.54f;

Bu durumda, sınıf örneğinden Ingilizce birimlere erişebilir ve arabirim örneğinden ölçüm birimlerine
erişebilirsiniz:

public static void Test()


{
Box box1 = new Box(30.0f, 20.0f);
IMetricDimensions mDimensions = box1;

System.Console.WriteLine("Length(in): {0}", box1.Length());


System.Console.WriteLine("Width (in): {0}", box1.Width());
System.Console.WriteLine("Length(cm): {0}", mDimensions.Length());
System.Console.WriteLine("Width (cm): {0}", mDimensions.Width());
}

Ayrıca bkz.
C# Programlama Kılavuzu
Sınıflar ve Yapılar
Arabirimler
Nasıl yapılır: Arabirim üyelerini açıkça uygulama
2 minutes to read
Temsilciler (C# Programlama Kılavuzu)
4.11.2019 • 4 minutes to read • Edit Online

Temsilci , belirli bir parametre listesi ve dönüş türü olan yöntemlere yapılan başvuruları temsil eden bir türdür.
Bir temsilci oluşturduğunuzda, örneğini uyumlu bir imza ve dönüş türü içeren herhangi bir yöntemle
ilişkilendirebilirsiniz. Yöntemi, temsilci örneği aracılığıyla çağırabilirsiniz.
Temsilciler, yöntemleri bağımsız değişkenler olarak diğer yöntemlere geçirmek için kullanılır. Olay işleyicileri,
temsilciler aracılığıyla çağrılan yöntemlerden başka bir şey değildir. Özel bir yöntem oluşturabilirsiniz ve bir
pencere denetimi gibi bir sınıf, belirli bir olay olduğunda yönteminizi çağırabilir. Aşağıdaki örnek, bir temsilci
bildirimini gösterir:

public delegate int PerformCalculation(int x, int y);

Temsilci türüyle eşleşen herhangi bir erişilebilir sınıf veya yapıdan alınan herhangi bir yöntem temsilciye
atanabilir. Yöntem, statik veya örnek bir yöntem olabilir. Bu, yöntem çağrılarını programatik olarak
değiştirmeyi ve varolan sınıflara yeni kod eklemeyi olanaklı kılar.

NOTE
Yöntem aşırı yükü bağlamında, yöntemin imzası dönüş değeri içermez. Ancak, temsilciler bağlamında, imza dönüş
değerini içermez. Başka bir deyişle, bir yöntemin dönüş türü temsilciyle aynı olmalıdır.

Bir yönteme bir parametre olarak başvurma yeteneği, temsilciyi geri çağırma yöntemleri için ideal hale getirir.
Örneğin, iki nesneyi karşılaştıran bir yönteme yapılan bir başvuru, bir sıralama algoritmasına bir bağımsız
değişken olarak geçirilebilir. Karşılaştırma kodu ayrı bir yordamda olduğundan, sıralama algoritması daha
genel bir şekilde yazılabilir.

Temsilcilere Genel Bakış


Temsilciler aşağıdaki özelliklere sahiptir:
Temsilciler C++ işlev işaretçilerine benzer, ancak temsilciler tam nesne yönelimli ve üye işlevlerine
yönelik işaretçilerin C++ aksine, temsilciler hem bir nesne örneğini hem de bir yöntemi kapsüller.
Temsilciler, yöntemlerin parametre olarak geçirilmesine olanak tanır.
Temsilciler, geri çağırma yöntemlerini tanımlamak için kullanılabilir.
Temsilciler birlikte zincirleme yapılabilir; Örneğin, tek bir olay üzerine birden çok yöntem çağrılabilir.
Yöntemlerin temsilci türüyle tam olarak eşleşmesi gerekmez. Daha fazla bilgi için bkz. Temsilcilerde
varyans kullanma.
C#sürüm 2,0, kod bloklarının ayrı olarak tanımlanmış bir yöntem yerine parametre olarak geçirilmesine
izin veren Anonim yöntemlerkavramını sunmuştur. C# 3.0, satır içi kod blokları yazmak için daha kısa
bir yol olarak lambda ifadelerini kullanmaya başladı. Hem anonim yöntemler hem de lambda ifadeleri
(belirli bağlamlarda) temsilci türleri olarak derlenir. Birlikte, bu özellikler artık anonim işlevler olarak
bilinir. Lambda ifadeleri hakkında daha fazla bilgi için bkz. lambda ifadeleri.

Bu Bölümde
Temsilcileri Kullanma
Arabirimler yerine temsilcilerin ne zaman kullanılacağı (C# Programlama Kılavuzu)
Adlandırılmış ve anonim yöntemler ile Temsilciler
Temsilcilerde Varyans Kullanma
Nasıl yapılır: temsilcileri birleştirme (çok noktaya yayın temsilcileri)
Nasıl yapılır: Temsilci Bildirme, Oluşturma ve Kullanma

C# Dil Belirtimi
Daha fazla bilgi için bkz. C# dil belirtiminde Temsilciler . Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Özel Kitap Bölümleri


3,0 tanımlama kitabı, üçüncü sürüm 'de Temsilciler, olaylar ve lambda ifadeleri C# : 3,0 programcılar için C#
250 ' den fazla çözüm
Öğrenme C# 3,0 C# ' deki Temsilciler ve olaylar : 3,0 temelleri ana

Ayrıca bkz.
Delegate
C# Programlama Kılavuzu
Olaylar
Temsilcileri Kullanma (C# Programlama Kılavuzu)
4.11.2019 • 8 minutes to read • Edit Online

Temsilci , bir yöntemi güvenli bir şekilde kapsülleyen, C ve C++içindeki işlev işaretçisine benzer bir türdür. C işlev
işaretçilerinden farklı olarak, temsilciler nesne odaklı, tür kullanımı güvenli ve güvenli. Temsilcinin türü, temsilcinin
adı tarafından tanımlanır. Aşağıdaki örnek, bir dizeyi bağımsız değişken olarak alan ve voiddöndüren bir yöntemi
kapsülledebilir Del adlı bir temsilci bildirir:

public delegate void Del(string message);

Temsilci nesnesi normalde, temsilcinin kaydıralacağı yöntemin adı veya anonim bir işlevleoluşturulur. Bir temsilci
örneği oluşturulduktan sonra temsilciye yapılan bir yöntem çağrısı, bu yönteme verilen temsilci tarafından geçirilir.
Çağıran tarafından temsilciye geçirilen parametreler yöntemine geçirilir ve yöntem, varsa dönüş değeri, temsilci
tarafından çağırana döndürülür. Bu, temsilciyi çağırmak olarak bilinir. Örneklenen bir temsilci, Sarmalanan
yöntemin kendisi gibi çağrılabilir. Örneğin:

// Create a method for a delegate.


public static void DelegateMethod(string message)
{
Console.WriteLine(message);
}

// Instantiate the delegate.


Del handler = DelegateMethod;

// Call the delegate.


handler("Hello World");

Temsilci türleri .NET Framework Delegate sınıfından türetilir. Temsilci türleri mühürlenmiş—, öğesinden
türetilemez ve Delegate ' den özel sınıflar türetmek mümkün değildir. Örneklenmiş temsilci bir nesne olduğundan,
parametre olarak geçirilebilir veya bir özelliğe atanabilir. Bu, bir yöntemin bir temsilciyi bir parametre olarak kabul
etmesine izin verir ve daha sonra temsilciyi daha sonra çağırabilir. Bu, zaman uyumsuz geri arama olarak bilinir ve
uzun bir işlem tamamlandığında bir çağrıyı bildirmeye yönelik yaygın bir yöntemdir. Bu şekilde bir temsilci
kullanıldığında, temsilciyi kullanan koda, kullanılmakta olan yöntemin uygulanması hakkında herhangi bir bilgi
gerekmez. İşlevselliği, kapsülleme arabirimlerine benzer.
Geri aramaların diğer yaygın kullanımları özel bir karşılaştırma yöntemi tanımlayarak bu temsilciyi bir sıralama
yöntemine geçirmektir. Çağıran kodun sıralama algoritmasının bir parçası haline gelmesine izin verir. Aşağıdaki
örnek yöntemi bir parametre olarak Del türünü kullanır:

public static void MethodWithCallback(int param1, int param2, Del callback)


{
callback("The number is: " + (param1 + param2).ToString());
}

Daha sonra, yukarıda oluşturulan temsilciyi Bu metoda geçirebilirsiniz:

MethodWithCallback(1, 2, handler);
ve konsola aşağıdaki çıktıyı alın:

The number is: 3

Temsilciyi bir soyutlama olarak kullanarak, MethodWithCallback konsolunun doğrudan çağrı yapması gerekmez —
bir konsol göz önünde bulundurularak tasarlanmamalıdır. Ne MethodWithCallback , yalnızca bir dizeyi hazırlar ve
dizeyi başka bir yönteme iletir. Bu, temsilci bir yöntemin herhangi bir sayıda parametreyi kullanabilmesi nedeniyle
özellikle güçlüdür.
Bir temsilci bir örnek yöntemini kaydırmak üzere oluşturulduğunda, temsilci hem örneğe hem de yöntemine
başvurur. Bir temsilcinin, sarmaladığı yöntemden farklı olarak örnek türü bilgisi yoktur, bu nedenle bir temsilci, bu
nesnede temsilci imzasıyla eşleşen bir yöntem olduğu sürece herhangi bir nesne türüne başvurabilir. Statik bir
yöntemi kaydırmak için bir temsilci oluşturulduğunda, yalnızca yöntemine başvurur. Aşağıdaki bildirimleri dikkate
alın:

public class MethodClass


{
public void Method1(string message) { }
public void Method2(string message) { }
}

Daha önce gösterilen statik DelegateMethod ile birlikte, artık bir Del örneği tarafından sarmalanabilir üç yöntem
vardır.
Bir temsilci, çağrıldığında birden fazla yöntem çağırabilir. Bu, çok noktaya yayın olarak adlandırılır. Temsilcinin
Yöntemler listesine ek bir yöntem eklemek için — çağırma listesi — ekleme veya ekleme atama işleçlerini (' + '
veya ' + = ') kullanarak yalnızca iki temsilci eklenmesini gerektirir. Örneğin:

var obj = new MethodClass();


Del d1 = obj.Method1;
Del d2 = obj.Method2;
Del d3 = DelegateMethod;

//Both types of assignment are valid.


Del allMethodsDelegate = d1 + d2;
allMethodsDelegate += d3;

Bu noktada allMethodsDelegate , çağrı listesinde üç yöntem içerir — Method1 , Method2 ve DelegateMethod . Özgün
üç temsilci, d1 , d2 ve d3 değişmeden kalır. allMethodsDelegate çağrıldığında, üç yöntemin tümü sırasıyla
çağrılır. Temsilci başvuru parametreleri kullanıyorsa, başvuru her üç yöntemin her birine sırayla geçirilir ve bir
yönteme göre yapılan değişiklikler sonraki yönteme göre görünür. Metotlardan herhangi biri, yöntemi içinde
yakalanmayan bir özel durum oluşturduğunda, bu özel durum temsilci çağıranına geçirilir ve çağrı listesinde
sonraki Yöntemler çağrılmaz. Temsilcinin dönüş değeri ve/veya out parametreleri varsa, çağrılan son yöntemin
dönüş değerini ve parametrelerini döndürür. Çağırma listesinden bir yöntemi kaldırmak için çıkarma veya çıkarma
atama işleçlerini ( - veya -= ) kullanın. Örneğin:

//remove Method1
allMethodsDelegate -= d1;

// copy AllMethodsDelegate while removing d2


Del oneMethodDelegate = allMethodsDelegate - d2;

Temsilci türleri System.Delegate ' dan türetildiğinden, bu sınıf tarafından tanımlanan Yöntemler ve Özellikler
temsilci üzerinde çağrılabilir. Örneğin, bir temsilcinin çağrı listesindeki Yöntem sayısını bulmak için şunu
yazabilirsiniz:
int invocationCount = d1.GetInvocationList().GetLength(0);

Çağırma listesinde birden fazla yöntemi olan temsilciler, System.Delegate ' in bir alt sınıfı olan MulticastDelegate '
dan türetilir. Her iki sınıf de GetInvocationList ' i desteklediği için yukarıdaki kod her iki durumda da çalışmaktadır.
Çok noktaya yayın temsilcileri, yoğun şekilde olay İşlemede kullanılır. Olay kaynak nesneleri olay bildirimlerini, bu
olayı almak için kaydedilen alıcı nesnelerine gönderir. Bir olaya kaydolmak için alıcı, olayı işlemek için tasarlanan bir
yöntem oluşturur, ardından bu yöntem için bir temsilci oluşturur ve temsilciyi olay kaynağına geçirir. Kaynak, olay
gerçekleştiğinde temsilciyi çağırır. Temsilci daha sonra olay verilerini teslim eden, alıcı üzerinde olay işleme
yöntemini çağırır. Belirli bir olayın temsilci türü olay kaynağı tarafından tanımlanır. Daha fazla bilgi için bkz. Olaylar.
Derleme zamanında atanan iki farklı türün temsilcilerin karşılaştırılması, derleme hatasına neden olur. Temsilci
örnekleri System.Delegate türünde statik olarak varsa, karşılaştırmaya izin verilir, ancak çalışma zamanında false
döndürür. Örneğin:

delegate void Delegate1();


delegate void Delegate2();

static void method(Delegate1 d, Delegate2 e, System.Delegate f)


{
// Compile-time error.
//Console.WriteLine(d == e);

// OK at compile-time. False if the run-time type of f


// is not the same as that of d.
Console.WriteLine(d == f);
}

Ayrıca bkz.
C# Programlama Kılavuzu
Temsilciler
Temsilcilerde Varyans Kullanma
Temsilcilerde Varyans
İşlev ve Eylem Genel Temsilcileri için Varyans Kullanma
Olaylar
Adlandırılmış ve Anonim Yöntemler ile Temsilciler (C#
Programlama Kılavuzu)
4.11.2019 • 3 minutes to read • Edit Online

Bir temsilci , adlandırılmış bir yöntemle ilişkilendirilebilir. Adlandırılmış bir yöntemi kullanarak bir temsilciyi
örneklediğinizde, yöntemi parametre olarak geçirilir, örneğin:

// Declare a delegate.
delegate void Del(int x);

// Define a named method.


void DoWork(int k) { /* ... */ }

// Instantiate the delegate using the method as a parameter.


Del d = obj.DoWork;

Bu, adlandırılmış bir yöntem kullanılarak çağrılır. Adlandırılmış bir yöntemle oluşturulan temsilciler statik bir
yöntem veya örnek yöntemi kapsülleyebilirsiniz. Adlandırılmış Yöntemler, daha önceki sürümlerinde bir temsilci
örneketmenin tek yoludur C#. Bununla birlikte, yeni bir yöntemin oluşturulması istenmeyen ek yüktür bir
durumda, C# bir temsilci örneklemenize ve her çağrıldığında temsilcinin işlemesini sağlayacak bir kod bloğunu
hemen belirtmenize olanak sağlar. Blok bir lambda ifadesi veya anonim bir yöntem içerebilir. Daha fazla bilgi için
bkz. Anonim işlevler.

Açıklamalar
Temsilci parametresi olarak geçirdiğiniz yöntemin, temsilci bildirimiyle aynı imzaya sahip olması gerekir.
Bir temsilci örneği, statik veya örnek yöntemini kapsülleyebilirsiniz.
Temsilci bir Out parametresi kullanabilse de, hangi temsilcinin çağrlanmasını bilemediğinizde çok noktaya yayın
olay temsilcilerle kullanımını önermiyoruz.

Örnek 1
Aşağıda, bir temsilciyi bildirme ve kullanma konusunda basit bir örnek verilmiştir. Hem temsilci, Del hem de ilişkili
Yöntem MultiplyNumbers aynı imzaya sahip olduğuna dikkat edin.
// Declare a delegate
delegate void Del(int i, double j);

class MathClass
{
static void Main()
{
MathClass m = new MathClass();

// Delegate instantiation using "MultiplyNumbers"


Del d = m.MultiplyNumbers;

// Invoke the delegate object.


Console.WriteLine("Invoking the delegate using 'MultiplyNumbers':");
for (int i = 1; i <= 5; i++)
{
d(i, 2);
}

// Keep the console window open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}

// Declare the associated method.


void MultiplyNumbers(int m, double n)
{
Console.Write(m * n + " ");
}
}
/* Output:
Invoking the delegate using 'MultiplyNumbers':
2 4 6 8 10
*/

Örnek 2
Aşağıdaki örnekte, bir temsilci hem statik hem de örnek yöntemlerine eşlenir ve her birinden belirli bilgileri
döndürür.
// Declare a delegate
delegate void Del();

class SampleClass
{
public void InstanceMethod()
{
Console.WriteLine("A message from the instance method.");
}

static public void StaticMethod()


{
Console.WriteLine("A message from the static method.");
}
}

class TestSampleClass
{
static void Main()
{
var sc = new SampleClass();

// Map the delegate to the instance method:


Del d = sc.InstanceMethod;
d();

// Map to the static method:


d = SampleClass.StaticMethod;
d();
}
}
/* Output:
A message from the instance method.
A message from the static method.
*/

Ayrıca bkz.
C# Programlama Kılavuzu
Temsilciler
Nasıl yapılır: temsilcileri birleştirme (çok noktaya yayın temsilcileri)
Olaylar
Nasıl yapılır: Temsilcileri Birleştirme (Çok Noktaya
Yayın Temsilcileri)(C# Programlama Kılavuzu)
4.11.2019 • 2 minutes to read • Edit Online

Bu örnek, çok noktaya yayın temsilcileri oluşturmayı gösterir. Temsilci nesnelerinin yararlı bir özelliği, + işleci
kullanılarak bir temsilci örneğine birden çok nesne atanabilmesini sağlar. Çok noktaya yayın temsilcisi, atanan
temsilcilerin bir listesini içerir. Çok noktaya yayın temsilcisi çağrıldığında, listedeki temsilcileri sırayla çağırır.
Yalnızca aynı türde temsilciler birleştirilebilir.
- işleci bir çok noktaya yayın temsilcisinden bir bileşen temsilcisini kaldırmak için kullanılabilir.

Örnek
using System;

// Define a custom delegate that has a string parameter and returns void.
delegate void CustomDel(string s);

class TestClass
{
// Define two methods that have the same signature as CustomDel.
static void Hello(string s)
{
Console.WriteLine($" Hello, {s}!");
}

static void Goodbye(string s)


{
Console.WriteLine($" Goodbye, {s}!");
}

static void Main()


{
// Declare instances of the custom delegate.
CustomDel hiDel, byeDel, multiDel, multiMinusHiDel;

// In this example, you can omit the custom delegate if you


// want to and use Action<string> instead.
//Action<string> hiDel, byeDel, multiDel, multiMinusHiDel;

// Create the delegate object hiDel that references the


// method Hello.
hiDel = Hello;

// Create the delegate object byeDel that references the


// method Goodbye.
byeDel = Goodbye;

// The two delegates, hiDel and byeDel, are combined to


// form multiDel.
multiDel = hiDel + byeDel;

// Remove hiDel from the multicast delegate, leaving byeDel,


// which calls only the method Goodbye.
multiMinusHiDel = multiDel - hiDel;

Console.WriteLine("Invoking delegate hiDel:");


hiDel("A");
Console.WriteLine("Invoking delegate byeDel:");
byeDel("B");
Console.WriteLine("Invoking delegate multiDel:");
multiDel("C");
Console.WriteLine("Invoking delegate multiMinusHiDel:");
multiMinusHiDel("D");
}
}
/* Output:
Invoking delegate hiDel:
Hello, A!
Invoking delegate byeDel:
Goodbye, B!
Invoking delegate multiDel:
Hello, C!
Goodbye, C!
Invoking delegate multiMinusHiDel:
Goodbye, D!
*/
Ayrıca bkz.
MulticastDelegate
C# Programlama Kılavuzu
Olaylar
Nasıl yapılır: Temsilci Bildirme, Oluşturma ve
Kullanma (C# Programlama Kılavuzu)
4.11.2019 • 6 minutes to read • Edit Online

C# 1,0 ve sonraki sürümlerde, temsilciler aşağıdaki örnekte gösterildiği gibi bildirilebilecek.

// Declare a delegate.
delegate void Del(string str);

// Declare a method with the same signature as the delegate.


static void Notify(string name)
{
Console.WriteLine($"Notification received for: {name}");
}

// Create an instance of the delegate.


Del del1 = new Del(Notify);

C#2,0, aşağıdaki örnekte gösterildiği gibi önceki bildirimi yazmak için daha basit bir yol sağlar.

// C# 2.0 provides a simpler way to declare an instance of Del.


Del del2 = Notify;

C# 2,0 ve sonraki sürümlerde, aşağıdaki örnekte gösterildiği gibi bir temsilciyibildirmek ve başlatmak için anonim
bir yöntem kullanmak da mümkündür.

// Instantiate Del by using an anonymous method.


Del del3 = delegate(string name)
{ Console.WriteLine($"Notification received for: {name}"); };

C# 3,0 ve sonraki sürümlerde temsilciler, aşağıdaki örnekte gösterildiği gibi bir lambda ifadesi kullanılarak da
bildirilebilecek ve örneklenebilir.

// Instantiate Del by using a lambda expression.


Del del4 = name => { Console.WriteLine($"Notification received for: {name}"); };

Daha fazla bilgi için bkz. lambda ifadeleri.


Aşağıdaki örnek, bir temsilciyi bildirme, örneklendirme ve kullanma hakkında gösterilmektedir. BookDB sınıfı, kitap
veritabanını tutan bir kitaplığı veritabanını kapsüller. Bu, veritabanındaki tüm kağıt geri kitaplarını bulan ve her biri
için bir temsilci çağıran ProcessPaperbackBooks bir yöntem sunar. Kullanılan delegate türü ProcessBookDelegate
olarak adlandırılır. Test sınıfı, Paperback kitaplarının başlıklarını ve ortalama fiyatını yazdırmak için bu sınıfı
kullanır.
Temsilcilerin kullanımı, kitaplığı veritabanı ve istemci kodu arasındaki işlevlerin iyi bir şekilde ayrılmasını yükseltir.
İstemci kodu kitaplarının nasıl depolandığını veya kitaplığı kodunun kağıt geri defterlerini nasıl bulduğunu
bilmiştir. Kitaplığı kodu, her şeyi bulduktan sonra, kağıt geri defterlerinde gerçekleştirilen işleme ilişkin hiçbir
bilgiye sahip değildir.
Örnek
// A set of classes for handling a bookstore:
namespace Bookstore
{
using System.Collections;

// Describes a book in the book list:


public struct Book
{
public string Title; // Title of the book.
public string Author; // Author of the book.
public decimal Price; // Price of the book.
public bool Paperback; // Is it paperback?

public Book(string title, string author, decimal price, bool paperBack)


{
Title = title;
Author = author;
Price = price;
Paperback = paperBack;
}
}

// Declare a delegate type for processing a book:


public delegate void ProcessBookDelegate(Book book);

// Maintains a book database.


public class BookDB
{
// List of all books in the database:
ArrayList list = new ArrayList();

// Add a book to the database:


public void AddBook(string title, string author, decimal price, bool paperBack)
{
list.Add(new Book(title, author, price, paperBack));
}

// Call a passed-in delegate on each paperback book to process it:


public void ProcessPaperbackBooks(ProcessBookDelegate processBook)
{
foreach (Book b in list)
{
if (b.Paperback)
// Calling the delegate:
processBook(b);
}
}
}
}

// Using the Bookstore classes:


namespace BookTestClient
{
using Bookstore;

// Class to total and average prices of books:


class PriceTotaller
{
int countBooks = 0;
decimal priceBooks = 0.0m;

internal void AddBookToTotal(Book book)


{
countBooks += 1;
priceBooks += book.Price;
priceBooks += book.Price;
}

internal decimal AveragePrice()


{
return priceBooks / countBooks;
}
}

// Class to test the book database:


class Test
{
// Print the title of the book.
static void PrintTitle(Book b)
{
Console.WriteLine($" {b.Title}");
}

// Execution starts here.


static void Main()
{
BookDB bookDB = new BookDB();

// Initialize the database with some books:


AddBooks(bookDB);

// Print all the titles of paperbacks:


Console.WriteLine("Paperback Book Titles:");

// Create a new delegate object associated with the static


// method Test.PrintTitle:
bookDB.ProcessPaperbackBooks(PrintTitle);

// Get the average price of a paperback by using


// a PriceTotaller object:
PriceTotaller totaller = new PriceTotaller();

// Create a new delegate object associated with the nonstatic


// method AddBookToTotal on the object totaller:
bookDB.ProcessPaperbackBooks(totaller.AddBookToTotal);

Console.WriteLine("Average Paperback Book Price: ${0:#.##}",


totaller.AveragePrice());
}

// Initialize the book database with some test books:


static void AddBooks(BookDB bookDB)
{
bookDB.AddBook("The C Programming Language", "Brian W. Kernighan and Dennis M. Ritchie", 19.95m,
true);
bookDB.AddBook("The Unicode Standard 2.0", "The Unicode Consortium", 39.95m, true);
bookDB.AddBook("The MS-DOS Encyclopedia", "Ray Duncan", 129.95m, false);
bookDB.AddBook("Dogbert's Clues for the Clueless", "Scott Adams", 12.00m, true);
}
}
}
/* Output:
Paperback Book Titles:
The C Programming Language
The Unicode Standard 2.0
Dogbert's Clues for the Clueless
Average Paperback Book Price: $23.97
*/

Güçlü Programlama
Temsilci bildirme.
Aşağıdaki ifade yeni bir temsilci türü bildirir.

public delegate void ProcessBookDelegate(Book book);

Her temsilci türü, bağımsız değişkenlerin sayısını ve türlerini ve kapsülleyeşabolduğu yöntemlerin dönüş
değeri türünü tanımlar. Bağımsız değişken türlerinin veya dönüş değeri türünün her yeni kümesi
gerektiğinde, yeni bir temsilci türü bildirilmelidir.
Bir temsilciyi örnekleme.
Bir temsilci türü bildirildiğinde, bir temsilci nesnesi oluşturulmalı ve belirli bir yöntemle ilişkilendirilmelidir.
Önceki örnekte, aşağıdaki örnekte olduğu gibi PrintTitle yöntemini ProcessPaperbackBooks yöntemine
geçirerek bunu yapabilirsiniz:

bookDB.ProcessPaperbackBooks(PrintTitle);

Bu, Test.PrintTitlestatik yöntemiyle ilişkili yeni bir temsilci nesnesi oluşturur. Benzer şekilde, nesne
totaller AddBookToTotal statik olmayan yöntem aşağıdaki örnekte olduğu gibi geçirilir:

bookDB.ProcessPaperbackBooks(totaller.AddBookToTotal);

Her iki durumda da ProcessPaperbackBooks yöntemine yeni bir temsilci nesnesi geçirilir.
Bir temsilci oluşturulduktan sonra, ilişkili olduğu yöntem hiçbir değişiklik hiçbir şekilde değişmez; temsilci
nesneleri sabittir.
Temsilci çağırma.
Temsilci nesnesi oluşturulduktan sonra temsilci nesnesi genellikle temsilciyi çağıran diğer koda geçirilir.
Temsilci nesnesi, temsilci nesnesinin adı kullanılarak çağrılır ve ardından temsilciye geçirilecek parantez
içine alınmış bağımsız değişkenler gelir. Aşağıda bir temsilci çağrısı örneği verilmiştir:

processBook(b);

Bir temsilci, bu örnekte olduğu gibi zaman uyumlu olarak ya da BeginInvoke ve EndInvoke yöntemleri
kullanılarak zaman uyumsuz olarak çağrılabilir.

Ayrıca bkz.
C# Programlama Kılavuzu
Olaylar
Temsilciler
Diziler (C# Programlama Kılavuzu)
24.10.2019 • 2 minutes to read • Edit Online

Aynı türde birden çok değişkeni bir dizi veri yapısına saklayabilirsiniz. Öğelerinin türünü belirterek bir dizi
bildirirsiniz. Dizinin herhangi bir türdeki öğeleri depolamasını istiyorsanız, türü olarak object belirtebilirsiniz.
Birleşik tür sisteminde C#, tüm türler, önceden tanımlanmış ve Kullanıcı tanımlı, başvuru türleri ve değer türleri,
Object doğrudan veya dolaylı olarak devralınır.

type[] arrayName;

Örnek
Aşağıdaki örnek, tek boyutlu, çok boyutlu ve pürüzlü Diziler oluşturur:

class TestArraysClass
{
static void Main()
{
// Declare a single-dimensional array.
int[] array1 = new int[5];

// Declare and set array element values.


int[] array2 = new int[] { 1, 3, 5, 7, 9 };

// Alternative syntax.
int[] array3 = { 1, 2, 3, 4, 5, 6 };

// Declare a two dimensional array.


int[,] multiDimensionalArray1 = new int[2, 3];

// Declare and set array element values.


int[,] multiDimensionalArray2 = { { 1, 2, 3 }, { 4, 5, 6 } };

// Declare a jagged array.


int[][] jaggedArray = new int[6][];

// Set the values of the first array in the jagged array structure.
jaggedArray[0] = new int[4] { 1, 2, 3, 4 };
}
}

Diziye genel bakış


Bir dizi aşağıdaki özelliklere sahiptir:
Bir dizi tek boyutlu, çok boyutlu veya pürüzlüolabilir.
Boyut sayısı ve her boyutun uzunluğu, dizi örneği oluşturulduğunda oluşturulur. Bu değerler, örneğin
kullanım ömrü boyunca değiştirilemez.
Sayısal dizi öğelerinin varsayılan değerleri sıfır olarak ayarlanır ve başvuru öğeleri null olarak ayarlanır.
Sivri dizi dizi dizilerdir ve bu nedenle öğeleri başvuru türleridir ve null olarak başlatılır.
Diziler sıfır dizinli: n öğeler içeren bir dizi 0 n-1 olarak dizinlenir.
Dizi öğeleri, bir dizi türü de dahil olmak üzere herhangi bir türde olabilir.
Dizi türleri, Array soyut temel türünden türetilmiş başvuru türleridir . Bu tür IEnumerable ve
IEnumerable<T> uyguladığından, içindeki C#tüm dizilerde foreach yineleme kullanabilirsiniz.

İlgili bölümler
Nesne Olarak Diziler
Dizilerle foreach kullanma
Dizileri Bağımsız Değişkenler Olarak Geçirme

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
C# Programlama Kılavuzu
Koleksiyonlar
Nesne Olarak Diziler (C# Programlama Kılavuzu)
24.10.2019 • 2 minutes to read • Edit Online

' C#De, diziler aslında nesneler ve yalnızca C ve C++' de olduğu gibi bitişik belleğin adreslenebilir bölgelerini
içermez. Array, tüm dizi türlerinin soyut temel türüdür. @No__t_0 sahip olduğu özellikleri ve diğer sınıf üyelerini
kullanabilirsiniz. Bunun bir örneği, bir dizinin uzunluğunu almak için Length özelliğini kullanmaktır. Aşağıdaki kod,
5 numbers dizinin uzunluğunu lengthOfNumbers adlı bir değişkene atar:

int[] numbers = { 1, 2, 3, 4, 5 };
int lengthOfNumbers = numbers.Length;

@No__t_0 sınıfı, dizileri sıralamak, aramak ve kopyalamak için diğer birçok yararlı yöntem ve özellik sağlar.

Örnek
Bu örnek, bir dizinin boyut sayısını göstermek için Rank özelliğini kullanır.

class TestArraysClass
{
static void Main()
{
// Declare and initialize an array.
int[,] theArray = new int[5, 10];
System.Console.WriteLine("The array has {0} dimensions.", theArray.Rank);
}
}
// Output: The array has 2 dimensions.

Ayrıca bkz.
C# Programlama Kılavuzu
Diziler
Tek Boyutlu Diziler
Çok Boyutlu Diziler
Düzensiz Diziler
Tek Boyutlu Diziler (C# Programlama Kılavuzu)
4.11.2019 • 2 minutes to read • Edit Online

Aşağıdaki örnekte gösterildiği gibi, beş tamsayının tek boyutlu bir dizisini bildirebilirsiniz:

int[] array = new int[5];

Bu dizi array[4]``array[0] öğeleri içerir. New işleci diziyi oluşturmak için kullanılır ve dizi öğelerini varsayılan
değerlerine başlatır. Bu örnekte, tüm dizi öğeleri sıfır olarak başlatılır.
Dize öğelerini depolayan bir dizi aynı şekilde bildirilebilecek. Örneğin:

string[] stringArray = new string[6];

Dizi başlatma
Bildirim üzerine bir diziyi başlatmak mümkündür, bu durumda, başlatma listesindeki öğe sayısı tarafından zaten
sağlandığı için uzunluk belirleyicisi gerekli değildir. Örneğin:

int[] array1 = new int[] { 1, 3, 5, 7, 9 };

Dize dizisi aynı şekilde başlatılabilir. Aşağıda her dizi öğesinin bir günün adı ile başlatıldığı bir dize dizisinin
bildirimi verilmiştir:

string[] weekDays = new string[] { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };

Bildirim üzerine bir diziyi başlattığınızda, aşağıdaki kısayolları kullanabilirsiniz:

int[] array2 = { 1, 3, 5, 7, 9 };
string[] weekDays2 = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };

Başlatma olmadan bir dizi değişkeni bildirmek mümkündür, ancak bu değişkene bir dizi atadığınızda new işlecini
kullanmanız gerekir. Örneğin:

int[] array3;
array3 = new int[] { 1, 3, 5, 7, 9 }; // OK
//array3 = {1, 3, 5, 7, 9}; // Error

C#3,0 örtük olarak yazılmış dizileri tanıtır. Daha fazla bilgi için bkz. örtülü olarak yazılan diziler.

Değer türü ve başvuru türü dizileri


Aşağıdaki dizi bildirimini göz önünde bulundurun:

SomeType[] array4 = new SomeType[10];


Bu deyimin sonucu, SomeType bir değer türü veya bir başvuru türü olmasına bağlıdır. Değer bir tür ise, ifade, her
birinin türü SomeType olan 10 öğeden oluşan bir dizi oluşturur. SomeType bir başvuru türü ise, ifade her biri null
başvuruya başlatılan 10 öğeden oluşan bir dizi oluşturur.
Değer türleri ve başvuru türleri hakkında daha fazla bilgi için bkz. türler.

Ayrıca bkz.
Array
C# Programlama Kılavuzu
Diziler
Çok Boyutlu Diziler
Düzensiz Diziler
Çok Boyutlu Diziler (C# Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Diziler birden fazla boyuta sahip olabilir. Örneğin, aşağıdaki bildirim dört satırlık ve iki sütundan oluşan iki
boyutlu bir dizi oluşturur.

int[,] array = new int[4, 2];

Aşağıdaki bildirim üç boyutlu bir dizi oluşturur, 4, 2 ve 3.

int[, ,] array1 = new int[4, 2, 3];

Dizi başlatma
Aşağıdaki örnekte gösterildiği gibi, bildirimi üzerinde diziyi başlatabilirsiniz.
// Two-dimensional array.
int[,] array2D = new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
// The same array with dimensions specified.
int[,] array2Da = new int[4, 2] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
// A similar array with string elements.
string[,] array2Db = new string[3, 2] { { "one", "two" }, { "three", "four" },
{ "five", "six" } };

// Three-dimensional array.
int[, ,] array3D = new int[,,] { { { 1, 2, 3 }, { 4, 5, 6 } },
{ { 7, 8, 9 }, { 10, 11, 12 } } };
// The same array with dimensions specified.
int[, ,] array3Da = new int[2, 2, 3] { { { 1, 2, 3 }, { 4, 5, 6 } },
{ { 7, 8, 9 }, { 10, 11, 12 } } };

// Accessing array elements.


System.Console.WriteLine(array2D[0, 0]);
System.Console.WriteLine(array2D[0, 1]);
System.Console.WriteLine(array2D[1, 0]);
System.Console.WriteLine(array2D[1, 1]);
System.Console.WriteLine(array2D[3, 0]);
System.Console.WriteLine(array2Db[1, 0]);
System.Console.WriteLine(array3Da[1, 0, 1]);
System.Console.WriteLine(array3D[1, 1, 2]);

// Getting the total count of elements or the length of a given dimension.


var allLength = array3D.Length;
var total = 1;
for (int i = 0; i < array3D.Rank; i++) {
total *= array3D.GetLength(i);
}
System.Console.WriteLine("{0} equals {1}", allLength, total);

// Output:
// 1
// 2
// 3
// 4
// 7
// three
// 8
// 12
// 12 equals 12

Ayrıca, sırası belirtmeden diziyi başlatabilirsiniz.

int[,] array4 = { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };

Başlatma olmadan bir dizi değişkeni tanımlamayı seçerseniz, değişkenine bir dizi atamak için new işlecini
kullanmanız gerekir. Öğesinin new kullanımı aşağıdaki örnekte gösterilmiştir.

int[,] array5;
array5 = new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } }; // OK
//array5 = {{1,2}, {3,4}, {5,6}, {7,8}}; // Error

Aşağıdaki örnek, belirli bir dizi öğesine bir değer atar.

array5[2, 1] = 25;

Benzer şekilde, aşağıdaki örnek, belirli bir dizi öğesinin değerini alır ve bunu değişkenine elementValue atar.
int elementValue = array5[2, 1];

Aşağıdaki kod örneği, dizi öğelerini varsayılan değerlere (pürüzlü Diziler hariç) başlatır.

int[,] array6 = new int[10, 10];

Ayrıca bkz.
C# Programlama Kılavuzu
Diziler
Tek Boyutlu Diziler
Düzensiz Diziler
Basit Diziler (C# Programlama Kılavuzu)
23.10.2019 • 4 minutes to read • Edit Online

Basit bir dizi, öğeleri dizi olan bir dizidir. Pürüzlü bir dizinin öğeleri farklı boyutlarda ve boyutlarda olabilir. Pürüzlü
bir dizi bazen "dizi dizisi" olarak adlandırılır. Aşağıdaki örneklerde, pürüzlü dizileri bildirme, başlatma ve erişme
işlemlerinin nasıl yapılacağı gösterilmektedir.
Aşağıda, her biri tek boyutlu tamsayılar dizisi olan üç öğesi olan tek boyutlu bir dizinin bildirimi verilmiştir:

int[][] jaggedArray = new int[3][];

Kullanabilmeniz jaggedArray için, öğesinin öğelerinin başlatılmış olması gerekir. Aşağıdaki gibi öğeleri
başlatabilirsiniz:

jaggedArray[0] = new int[5];


jaggedArray[1] = new int[4];
jaggedArray[2] = new int[2];

Öğelerin her biri, tamsayıların tek boyutlu dizisidir. İlk öğe, 5 tamsayının dizisidir, ikincisi 4 tamsayının dizisidir ve
üçüncüsü 2 tamsayının dizisidir.
Ayrıca, dizi öğelerini değerlerle doldurmanız için başlatıcıları kullanmak mümkündür, bu durumda dizi boyutuna
ihtiyacınız yoktur. Örneğin:

jaggedArray[0] = new int[] { 1, 3, 5, 7, 9 };


jaggedArray[1] = new int[] { 0, 2, 4, 6 };
jaggedArray[2] = new int[] { 11, 22 };

Ayrıca, aşağıdaki gibi bildirim üzerine diziyi de başlatabilirsiniz:

int[][] jaggedArray2 = new int[][]


{
new int[] { 1, 3, 5, 7, 9 },
new int[] { 0, 2, 4, 6 },
new int[] { 11, 22 }
};

Aşağıdaki toplu formu kullanabilirsiniz. Öğeler için varsayılan başlatma olmadığından öğe new başlatmasında
operatörü atlayamazsınız.

int[][] jaggedArray3 =
{
new int[] { 1, 3, 5, 7, 9 },
new int[] { 0, 2, 4, 6 },
new int[] { 11, 22 }
};

Sivri dizi dizi dizilerdir ve bu nedenle öğeleri başvuru türleridir ve olarak null başlatılır.
Aşağıdaki örnekler gibi ayrı dizi öğelerine erişebilirsiniz:
// Assign 77 to the second element ([1]) of the first array ([0]):
jaggedArray3[0][1] = 77;

// Assign 88 to the second element ([1]) of the third array ([2]):


jaggedArray3[2][1] = 88;

Sivri ve çok boyutlu dizileri karıştırmak mümkündür. Aşağıda, farklı boyutlarda 3 2 boyutlu dizi öğeleri içeren tek
boyutlu pürüzlü bir dizinin bildirimi ve başlatılması yer almaktadır. İki boyutlu diziler hakkında daha fazla bilgi için
bkz. çok boyutlu diziler.

int[][,] jaggedArray4 = new int[3][,]


{
new int[,] { {1,3}, {5,7} },
new int[,] { {0,2}, {4,6}, {8,10} },
new int[,] { {11,22}, {99,88}, {0,9} }
};

Bu örnekte gösterildiği gibi, her bir öğeye, ilk dizinin (değer [1,0] 5 ) öğesinin değerini görüntüleyen tek bir
erişebilirsiniz:

System.Console.Write("{0}", jaggedArray4[0][1, 0]);

Yöntemi Length , pürüzlü dizide bulunan dizilerin sayısını döndürür. Örneğin, önceki diziyi bildirdiğiniz
varsayılarak, bu satır:

System.Console.WriteLine(jaggedArray4.Length);

3 değerini döndürür.

Örnek
Bu örnek, öğeleri kendi dizileri olan bir dizi oluşturur. Dizi öğelerinden her birinin farklı bir boyutu vardır.
class ArrayTest
{
static void Main()
{
// Declare the array of two elements.
int[][] arr = new int[2][];

// Initialize the elements.


arr[0] = new int[5] { 1, 3, 5, 7, 9 };
arr[1] = new int[4] { 2, 4, 6, 8 };

// Display the array elements.


for (int i = 0; i < arr.Length; i++)
{
System.Console.Write("Element({0}): ", i);

for (int j = 0; j < arr[i].Length; j++)


{
System.Console.Write("{0}{1}", arr[i][j], j == (arr[i].Length - 1) ? "" : " ");
}
System.Console.WriteLine();
}
// Keep the console window open in debug mode.
System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
}
/* Output:
Element(0): 1 3 5 7 9
Element(1): 2 4 6 8
*/

Ayrıca bkz.
Array
C# Programlama Kılavuzu
Diziler
Tek Boyutlu Diziler
Çok Boyutlu Diziler
Dizilerle foreach kullanma (C# Programlama
Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Foreach deyimi bir dizi öğelerinde yineleme yapmak için basit ve temiz bir yol sağlar.
Tek boyutlu diziler için foreach deyimi, artan dizin sırasıyla dizini 0'ile başlayıp diziniyle öğeleri işler Length - 1 :

int[] numbers = { 4, 5, 6, 1, 2, 3, -2, -1, 0 };


foreach (int i in numbers)
{
System.Console.Write("{0} ", i);
}
// Output: 4 5 6 1 2 3 -2 -1 0

En sağdaki boyutu dizinleri artan ilk sonra sonraki sol boyut vb. için sol olduğuna gibi çok boyutlu diziler için
öğeleri geçirilir:

int[,] numbers2D = new int[3, 2] { { 9, 99 }, { 3, 33 }, { 5, 55 } };


// Or use the short form:
// int[,] numbers2D = { { 9, 99 }, { 3, 33 }, { 5, 55 } };

foreach (int i in numbers2D)


{
System.Console.Write("{0} ", i);
}
// Output: 9 99 3 33 5 55

Ancak, çok boyutlu dizilerle, iç içe bir kullanarak için döngü, dizi öğeleri işlemek sırada üzerinde daha fazla denetim
sağlar.

Ayrıca bkz.
Array
C# Programlama Kılavuzu
Diziler
Tek Boyutlu Diziler
Çok Boyutlu Diziler
Düzensiz Diziler
Dizileri bağımsız değişkenler (C# programlama
Kılavuzu) olarak geçirme
23.10.2019 • 4 minutes to read • Edit Online

Dizileri bağımsız değişkenler olarak yöntemi parametrelerine geçirilebilir. Yöntemi, diziler, başvuru türleri
olduğundan, öğelerin değerini değiştirebilirsiniz.

Tek boyutlu dizileri bağımsız değişkenler olarak geçirme


Başlatılmış bir tek boyutlu dizi için bir yöntem geçirebilirsiniz. Örneğin, aşağıdaki deyim, yazdırma bir yönteme bir
dizi gönderir.

int[] theArray = { 1, 3, 5, 7, 9 };
PrintArray(theArray);

Aşağıdaki kod, yazdırma yöntemin kısmi bir uygulamasını gösterir.

void PrintArray(int[] arr)


{
// Method code.
}

Başlatın ve aşağıdaki örnekte gösterildiği gibi bir adım, yeni bir dizi geçirin.

PrintArray(new int[] { 1, 3, 5, 7, 9 });

Örnek
Aşağıdaki örnekte, dize dizisi başlatılır ve bağımsız değişken olarak geçirilen bir DisplayArray dizeler için yöntemi.
Yöntemi, dizinin öğeleri görüntüler. Ardından, ChangeArray yöntemi, dizi öğelerinin tersine çevirir ve ardından
ChangeArrayElements yöntemi, dizinin ilk üç öğeleri değiştirir. Her yöntemin dönüşünün ardından DisplayArray
yöntemi bir dizi değere göre geçirme değişiklikleri dizi öğelerine engellemez olduğunu gösterir.
using System;

class ArrayExample
{
static void DisplayArray(string[] arr) => Console.WriteLine(string.Join(" ", arr));

// Change the array by reversing its elements.


static void ChangeArray(string[] arr) => Array.Reverse(arr);

static void ChangeArrayElements(string[] arr)


{
// Change the value of the first three array elements.
arr[0] = "Mon";
arr[1] = "Wed";
arr[2] = "Fri";
}

static void Main()


{
// Declare and initialize an array.
string[] weekDays = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
// Display the array elements.
DisplayArray(weekDays);
Console.WriteLine();

// Reverse the array.


ChangeArray(weekDays);
// Display the array again to verify that it stays reversed.
Console.WriteLine("Array weekDays after the call to ChangeArray:");
DisplayArray(weekDays);
Console.WriteLine();

// Assign new values to individual array elements.


ChangeArrayElements(weekDays);
// Display the array again to verify that it has changed.
Console.WriteLine("Array weekDays after the call to ChangeArrayElements:");
DisplayArray(weekDays);
}
}
// The example displays the following output:
// Sun Mon Tue Wed Thu Fri Sat
//
// Array weekDays after the call to ChangeArray:
// Sat Fri Thu Wed Tue Mon Sun
//
// Array weekDays after the call to ChangeArrayElements:
// Mon Wed Fri Wed Tue Mon Sun

Çok boyutlu diziler bağımsız değişken olarak geçirme


Başlatılmış bir çok boyutlu dizi tek boyutlu dizi geçirdiğiniz aynı şekilde bir yönteme geçirin.

int[,] theArray = { { 1, 2 }, { 2, 3 }, { 3, 4 } };
Print2DArray(theArray);

Aşağıdaki kod iki boyutlu bir dizi bağımsız değişken olarak kabul eden bir yazdırma yöntemin kısmi bir bildirimi
gösterir.
void Print2DArray(int[,] arr)
{
// Method code.
}

Başlatın ve aşağıdaki örnekte gösterildiği gibi bir adım, yeni bir dizi geçirin:

Print2DArray(new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } });

Örnek
Aşağıdaki örnekte, iki boyutlu bir tamsayı dizisi başlatılır ve geçirilen Print2DArray yöntemi. Yöntemi, dizinin
öğeleri görüntüler.

class ArrayClass2D
{
static void Print2DArray(int[,] arr)
{
// Display the array elements.
for (int i = 0; i < arr.GetLength(0); i++)
{
for (int j = 0; j < arr.GetLength(1); j++)
{
System.Console.WriteLine("Element({0},{1})={2}", i, j, arr[i, j]);
}
}
}
static void Main()
{
// Pass the array as an argument.
Print2DArray(new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } });

// Keep the console window open in debug mode.


System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
}
/* Output:
Element(0,0)=1
Element(0,1)=2
Element(1,0)=3
Element(1,1)=4
Element(2,0)=5
Element(2,1)=6
Element(3,0)=7
Element(3,1)=8
*/

Ayrıca bkz.
C# Programlama Kılavuzu
Diziler
Tek Boyutlu Diziler
Çok Boyutlu Diziler
Düzensiz Diziler
Türü Örtük Olarak Belirlenmiş Diziler (C#
Programlama Kılavuzu)
4.11.2019 • 2 minutes to read • Edit Online

Dizi başlatıcısında belirtilen öğelerden dizi örneği türünün Çıkarsanan türü örtük olarak belirlenmiş bir dizi
oluşturabilirsiniz. Örtük olarak yazılmış herhangi bir değişken için kurallar, örtülü olarak belirlenmiş diziler için de
geçerlidir. Daha fazla bilgi için bkz. örtülü olarak yazılan yerel değişkenler.
Örtük olarak yazılmış diziler genellikle anonim türler ve nesne ve koleksiyon başlatıcıları ile birlikte sorgu
ifadelerinde kullanılır.
Aşağıdaki örneklerde, örtülü olarak yazılmış bir dizinin nasıl oluşturulacağı gösterilmektedir:

class ImplicitlyTypedArraySample
{
static void Main()
{
var a = new[] { 1, 10, 100, 1000 }; // int[]
var b = new[] { "hello", null, "world" }; // string[]

// single-dimension jagged array


var c = new[]
{
new[]{1,2,3,4},
new[]{5,6,7,8}
};

// jagged array of strings


var d = new[]
{
new[]{"Luca", "Mads", "Luke", "Dinesh"},
new[]{"Karen", "Suma", "Frances"}
};
}
}

Önceki örnekte, örtük olarak yazılmış diziler ile, başlatma ifadesinin sol tarafında bir köşeli ayraç kullanılmaması
fark edilir. Ayrıca, tek boyutlu diziler gibi new [] kullanılarak pürüzlü Diziler başlatılmış olduğunu unutmayın.

Nesne başlatıcılarında örtük olarak yazılmış diziler


Bir dizi içeren anonim bir tür oluşturduğunuzda, dizi türün nesne başlatıcısında örtük olarak yazılmalıdır.
Aşağıdaki örnekte contacts , her biri PhoneNumbers adlı bir dizi içeren anonim türlerin örtük olarak yazılmış bir
dizisidir. var anahtar sözcüğünün nesne başlatıcıları içinde kullanılmadığını unutmayın.
var contacts = new[]
{
new {
Name = " Eugene Zabokritski",
PhoneNumbers = new[] { "206-555-0108", "425-555-0001" }
},
new {
Name = " Hanying Feng",
PhoneNumbers = new[] { "650-555-0199" }
}
};

Ayrıca bkz.
C# Programlama Kılavuzu
Örtülü Olarak Yazılan Yerel Değişkenler
Diziler
Anonim Tipler
Nesne ve Koleksiyon Başlatıcıları
var
C# üzerinde LINQ
Dizeler (C# Programlama Kılavuzu)
25.11.2019 • 19 minutes to read • Edit Online

Dize, değeri Text olan String türünde bir nesnedir. Dahili olarak, metin, Char nesnelerinin sıralı salt okunurdur
koleksiyonu olarak depolanır. C# Dizenin sonunda null sonlandırma karakteri yoktur; Bu nedenle C# , bir dize
herhangi bir sayıda katıştırılmış null karakteri (' \ 0 ') içerebilir. Bir dizenin Length özelliği, Unicode karakterlerin
sayısını değil, içerdiği Char nesne sayısını temsil eder. Bir dizedeki tek tek Unicode kod noktalarına erişmek için
StringInfo nesnesini kullanın.

String ve System. String karşılaştırması


' C#De, string anahtar sözcüğü Stringbir diğer addır. Bu nedenle, String ve string eşdeğerdir ve tercih
ettiğiniz adlandırma kuralını kullanabilirsiniz. String sınıfı dizeleri güvenli bir şekilde oluşturmak, işlemek ve
karşılaştırmak için birçok yöntem sağlar. Ayrıca, C# dil, yaygın dize işlemlerini basitleştirmek için bazı işleçleri aşırı
yükler. Anahtar sözcüğü hakkında daha fazla bilgi için bkz. String. Türü ve yöntemleri hakkında daha fazla bilgi
için bkz. String.

Dizeleri bildirme ve başlatma


Aşağıdaki örnekte gösterildiği gibi çeşitli yollarla dizeler bildirebilir ve başlatabilirsiniz:

// Declare without initializing.


string message1;

// Initialize to null.
string message2 = null;

// Initialize as an empty string.


// Use the Empty constant instead of the literal "".
string message3 = System.String.Empty;

// Initialize with a regular string literal.


string oldPath = "c:\\Program Files\\Microsoft Visual Studio 8.0";

// Initialize with a verbatim string literal.


string newPath = @"c:\Program Files\Microsoft Visual Studio 9.0";

// Use System.String if you prefer.


System.String greeting = "Hello World!";

// In local variables (i.e. within a method body)


// you can use implicit typing.
var temp = "I'm still a strongly-typed System.String!";

// Use a const string to prevent 'message4' from


// being used to store another string value.
const string message4 = "You can't get rid of me!";

// Use the String constructor only when creating


// a string from a char*, char[], or sbyte*. See
// System.String documentation for details.
char[] letters = { 'A', 'B', 'C' };
string alphabet = new string(letters);

Dizenin bir karakter dizisiyle başlatılması dışında bir dize nesnesi oluşturmak için New işlecini kullanmayacağınızı
unutmayın.
Dizesi sıfır uzunluklu olan yeni bir String nesnesi oluşturmak için Empty sabit değeri ile bir dize başlatın. Sıfır
uzunluklu bir dizenin dize sabit temsili "" dir. Dizeleri nullyerine Empty değeriyle başlatarak, bir
NullReferenceException oluşma olasılığını azaltabilirsiniz. Bir dizenin değerini erişmeyi denemeden önce
doğrulamak için statik IsNullOrEmpty(String) yöntemini kullanın.

Dize nesnelerinin kullanılabilirliği


Dize nesneleri sabittir: oluşturulduktan sonra değiştirilemez. Bir dizeyi değiştirmek için görünen tüm C# String
yöntemleri ve işleçleri, sonuçları yeni bir dize nesnesi olarak döndürür. Aşağıdaki örnekte, s1 ve s2 içerikleri
tek bir dize oluşturacak şekilde bitiştirildiği zaman, iki özgün dize değiştirilmemiş olur. += işleci, Birleşik içerikleri
içeren yeni bir dize oluşturur. Bu yeni nesne s1 değişkenine atanır ve başka bir değişken kendisine başvuru
içermediğinden, s1 atanmış olan özgün nesne çöp toplama için serbest bırakılır.

string s1 = "A string is more ";


string s2 = "than the sum of its chars.";

// Concatenate s1 and s2. This actually creates a new


// string object and stores it in s1, releasing the
// reference to the original object.
s1 += s2;

System.Console.WriteLine(s1);
// Output: A string is more than the sum of its chars.

Bir "değişiklik" dizesi aslında yeni bir dize oluşturma olduğundan, dizelere başvurular oluştururken dikkatli
olmanız gerekir. Bir dizeye başvuru oluşturursanız ve sonra özgün dizeyi "değiştirirseniz", başvuru, dize
değiştirildiğinde oluşturulan yeni nesne yerine özgün nesneyi işaret etmeye devam edecektir. Aşağıdaki kod bu
davranışı göstermektedir:

string s1 = "Hello ";


string s2 = s1;
s1 += "World";

System.Console.WriteLine(s2);
//Output: Hello

Özgün dizedeki arama ve değiştirme işlemleri gibi değişikliklere dayalı yeni dizeler oluşturma hakkında daha
fazla bilgi için bkz. dize içeriğini değiştirme.

Normal ve tam dize sabit değerleri


Aşağıdaki örnekte gösterildiği gibi, tarafından C#verilen kaçış karakterlerini katıştırmanız gerektiğinde normal
dize değişmez değerlerini kullanın:

string columns = "Column 1\tColumn 2\tColumn 3";


//Output: Column 1 Column 2 Column 3

string rows = "Row 1\r\nRow 2\r\nRow 3";


/* Output:
Row 1
Row 2
Row 3
*/

string title = "\"The \u00C6olean Harp\", by Samuel Taylor Coleridge";


//Output: "The Æolean Harp", by Samuel Taylor Coleridge
Dize metninde, örneğin dosya yollarında ters eğik çizgi karakterleri içerdiğinde, kolay ve daha iyi okunabilirlik için
tam dizeler kullanın. Harfine dizeler dize metninin bir parçası olarak yeni satır karakterlerini koruduğundan, çok
satırlı dizeleri başlatmak için kullanılabilirler. Tam bir dizenin içine tırnak işareti eklemek için çift tırnak işaretleri
kullanın. Aşağıdaki örnek, tam dizeler için bazı yaygın kullanımları göstermektedir:

string filePath = @"C:\Users\scoleridge\Documents\";


//Output: C:\Users\scoleridge\Documents\

string text = @"My pensive SARA ! thy soft cheek reclined


Thus on mine arm, most soothing sweet it is
To sit beside our Cot,...";
/* Output:
My pensive SARA ! thy soft cheek reclined
Thus on mine arm, most soothing sweet it is
To sit beside our Cot,...
*/

string quote = @"Her name was ""Sara.""";


//Output: Her name was "Sara."

Dize kaçış dizileri


KAÇIŞ SIRASI KARAKTER ADI UNICODE KODLAMASI

\' Tek tırnak 0x0027

\" Çift tırnak 0x0022

\\ Sola 0x005C

izin Null 0x0000

</span> Uyarı 0x0007

\b Geri Al tuşu 0x0008

\f Form akışı 0x000C

\n Yeni satır 0x000A

\r Satır başı 0x000D

\t Yatay sekme 0x0009

\v Dikey sekme 0x000B

\u Unicode kaçış sırası (UTF-16) \uHHHH (Aralık: 0000-FFFF; örnek:


\u00E7 = "ç")

\U Unicode kaçış sırası (UTF-32) \U00HHHHHH (Range: 000000 yazın-


10FFFF; örnek: \U0001F47D = " ")
KAÇIŞ SIRASI KARAKTER ADI UNICODE KODLAMASI

\x Değişken uzunluğu dışında, "\u" şuna \xH[H][H][H] (Aralık: 0-FFFF; örnek:


benzer Unicode kaçış sırası \x00E7 veya \x0E7 ya da \xE7 =
"ç")

WARNING
\x kaçış sırasını kullanırken ve 4 onaltılık basamak belirtirken, kaçış sırasını hemen izleyen karakterler geçerli onaltılık
basamaklar (yani 0-9, A-F ve a-f), kaçış sırasının bir parçası olarak yorumlanır. Örneğin, \xA1 , U +¡00A1 kod noktası olan
"" üretir. Ancak, sonraki karakter "A" veya "a" ise, kaçış sırası \xA1A olarak yorumlanır ve "" kod noktası U + 0A1A olan ""
üretir. Bu gibi durumlarda, tüm 4 onaltılık basamakları (örn. \x00A1 ) belirtmek olası hatalı yorumlamayı engeller.

NOTE
Derleme zamanında, tam dizeler aynı kaçış dizileri ile normal dizelere dönüştürülür. Bu nedenle, hata ayıklayıcı izleme
penceresinde tam bir dizeyi görürseniz, kaynak kodunuzdaki tam sürümü değil, derleyici tarafından eklenen kaçış
karakterlerini görürsünüz. Örneğin, tam dize @"C:\files.txt" izleme penceresinde "C:\\files.txt" olarak görüntülenir.

Biçim dizeleri
Biçim dizesi, içeriği çalışma zamanında dinamik olarak belirlenen bir dizedir. Biçim dizeleri, bir dize içindeki küme
ayraçları içine enterpolasyonlu ifadeler veya yer tutucuları katıştırarak oluşturulur. Küme ayraçları ( {...} )
içindeki her şey, çalışma zamanında biçimli bir dize olarak bir değer ve çıkışa çözümlenir. Biçim dizeleri
oluşturmak için iki yöntem vardır: dize ilişkilendirme ve bileşik biçimlendirme.
Dize Ilişkilendirme
C# 6,0 ve üzeri sürümlerde bulunan, enterpolasyonlu dizeler $ özel karakter tarafından tanımlanır ve araya
alınmış ifadeleri küme ayraçları içine dahil eder. Dize ilişkilendirme konusunda yeni bir adım için bkz. hızlı bir
genel bakış için dize ilişkilendirme- C# Etkileşimli öğretici .
Kodlarınızın okunabilirliğini ve bakımlılığını artırmak için dize ilişkilendirmeyi kullanın. Dize ilişkilendirme
String.Format yöntemiyle aynı sonuçlara erişir, ancak kullanım kolaylığı ve satır içi açıklık geliştirir.

var jh = (firstName: "Jupiter", lastName: "Hammon", born: 1711, published: 1761);


Console.WriteLine($"{jh.firstName} {jh.lastName} was an African American poet born in {jh.born}.");
Console.WriteLine($"He was first published in {jh.published} at the age of {jh.published - jh.born}.");
Console.WriteLine($"He'd be over {Math.Round((2018d - jh.born) / 100d) * 100d} years old today.");

// Output:
// Jupiter Hammon was an African American poet born in 1711.
// He was first published in 1761 at the age of 50.
// He'd be over 300 years old today.

Bileşik Biçimlendirme
String.Format, biçim dizesi oluşturmak için yer tutucuları parantez içinde kullanır. Bu örnek, yukarıda kullanılan
dize ilişkilendirme yöntemine benzer bir çıkışa neden olur.
var pw = (firstName: "Phillis", lastName: "Wheatley", born: 1753, published: 1773);
Console.WriteLine("{0} {1} was an African American poet born in {2}.", pw.firstName, pw.lastName, pw.born);
Console.WriteLine("She was first published in {0} at the age of {1}.", pw.published, pw.published - pw.born);
Console.WriteLine("She'd be over {0} years old today.", Math.Round((2018d - pw.born) / 100d) * 100d);

// Output:
// Phillis Wheatley was an African American poet born in 1753.
// She was first published in 1773 at the age of 20.
// She'd be over 300 years old today.

.NET türlerini biçimlendirme hakkında daha fazla bilgi için bkz. .net 'Teki biçimlendirme türleri.

Dizelerin
Alt dize, bir dizede yer alan herhangi bir karakter dizisidir. Özgün dizenin bir bölümünden yeni bir dize
oluşturmak için Substring yöntemini kullanın. IndexOf yöntemini kullanarak bir alt dizenin bir veya daha fazla
örneğini arayabilirsiniz. Belirtilen bir alt dizenin tüm oluşumlarını yeni bir dizeyle değiştirmek için Replace
yöntemini kullanın. Substring yöntemi gibi, Replace aslında yeni bir dize döndürür ve özgün dizeyi değiştirmez.
Daha fazla bilgi için bkz. dizeleri arama ve dize içeriğini değiştirme.

string s3 = "Visual C# Express";


System.Console.WriteLine(s3.Substring(7, 2));
// Output: "C#"

System.Console.WriteLine(s3.Replace("C#", "Basic"));
// Output: "Visual Basic Express"

// Index values are zero-based


int index = s3.IndexOf("C");
// index = 7

Ayrı karakterlere erişme


Aşağıdaki örnekte olduğu gibi tek tek karakterlere salt okuma erişimi elde etmek için dizi gösterimini bir dizin
değeriyle birlikte kullanabilirsiniz:

string s5 = "Printing backwards";

for (int i = 0; i < s5.Length; i++)


{
System.Console.Write(s5[s5.Length - i - 1]);
}
// Output: "sdrawkcab gnitnirP"

String Yöntemler bir dizedeki bağımsız karakterleri değiştirmek için sahip olmanız gereken işlevselliği
sağlamıyorsa, "yerinde" karakterlerini tek tek değiştirmek için bir StringBuilder nesnesi kullanabilir ve sonra
sonuçları depolamak için yeni bir dize oluşturabilirsiniz StringBuilder Yöntem. Aşağıdaki örnekte, özgün dizeyi
belirli bir şekilde değiştirmeniz ve ardından daha sonra kullanmak üzere sonuçları depolamanız gerektiğini
varsayalım:
string question = "hOW DOES mICROSOFT wORD DEAL WITH THE cAPS lOCK KEY?";
System.Text.StringBuilder sb = new System.Text.StringBuilder(question);

for (int j = 0; j < sb.Length; j++)


{
if (System.Char.IsLower(sb[j]) == true)
sb[j] = System.Char.ToUpper(sb[j]);
else if (System.Char.IsUpper(sb[j]) == true)
sb[j] = System.Char.ToLower(sb[j]);
}
// Store the new string.
string corrected = sb.ToString();
System.Console.WriteLine(corrected);
// Output: How does Microsoft Word deal with the Caps Lock key?

Null dizeler ve boş dizeler


Boş dize, sıfır karakter içeren bir System.String nesnesinin örneğidir. Boş dizeler, genellikle boş bir metin alanını
göstermek için çeşitli programlama senaryolarında kullanılır. Nesneleri System.String geçerli dizeler için
çağırabilirsiniz. Boş dizeler aşağıdaki şekilde başlatılır:

string s = String.Empty;

Buna karşılık, bir null dize bir System.String nesnesinin örneğine başvurmaz ve null dize üzerinde bir yöntemi
çağırma girişimi bir NullReferenceExceptionneden olur. Ancak, birleştirme ve karşılaştırma işlemlerinde aynı
dizeleri diğer dizelerle birlikte kullanabilirsiniz. Aşağıdaki örneklerde, bir null dize başvurusunun oluşturulduğu
ve bir özel durumun oluşturulmasına neden olmadığı bazı durumlar gösterilmektedir:
static void Main()
{
string str = "hello";
string nullStr = null;
string emptyStr = String.Empty;

string tempStr = str + nullStr;


// Output of the following line: hello
Console.WriteLine(tempStr);

bool b = (emptyStr == nullStr);


// Output of the following line: False
Console.WriteLine(b);

// The following line creates a new empty string.


string newStr = emptyStr + nullStr;

// Null strings and empty strings behave differently. The following


// two lines display 0.
Console.WriteLine(emptyStr.Length);
Console.WriteLine(newStr.Length);
// The following line raises a NullReferenceException.
//Console.WriteLine(nullStr.Length);

// The null character can be displayed and counted, like other chars.
string s1 = "\x0" + "abc";
string s2 = "abc" + "\x0";
// Output of the following line: * abc*
Console.WriteLine("*" + s1 + "*");
// Output of the following line: *abc *
Console.WriteLine("*" + s2 + "*");
// Output of the following line: 4
Console.WriteLine(s2.Length);
}

Hızlı dize oluşturma için StringBuilder kullanma


.NET 'teki dize işlemleri yüksek oranda iyileştirilmiştir ve çoğu durumda performansı önemli ölçüde etkilemez.
Ancak, çok sayıda yüzlerce veya binlerce kez yürütülen sıkı döngüler gibi bazı senaryolarda, dize işlemleri
performansı etkileyebilir. StringBuilder sınıfı, programınız çok sayıda dize işlemeleri gerçekleştiriyorsa daha iyi
performans sağlayan bir dize arabelleği oluşturur. StringBuilder dize, yerleşik dize veri türünün desteklemediği
bir şeyi tek tek yeniden atayabilmenizi de sağlar. Bu kod, örneğin, yeni bir dize oluşturmadan bir dizenin içeriğini
değiştirir:

System.Text.StringBuilder sb = new System.Text.StringBuilder("Rat: the ideal pet");


sb[0] = 'C';
System.Console.WriteLine(sb.ToString());
System.Console.ReadLine();

//Outputs Cat: the ideal pet

Bu örnekte, bir StringBuilder nesnesi bir sayısal türler kümesinden dize oluşturmak için kullanılır:
using System;
using System.Text;

namespace CSRefStrings
{
class TestStringBuilder
{
static void Main()
{
var sb = new StringBuilder();

// Create a string composed of numbers 0 - 9


for (int i = 0; i < 10; i++)
{
sb.Append(i.ToString());
}
Console.WriteLine(sb); // displays 0123456789

// Copy one character of the string (not possible with a System.String)


sb[0] = sb[9];

Console.WriteLine(sb); // displays 9123456789


Console.WriteLine();
}
}
}

Dizeler, uzantı yöntemleri ve LINQ


String türü IEnumerable<T>uyguladığından, dizeler üzerinde Enumerable sınıfında tanımlanan genişletme
yöntemlerini kullanabilirsiniz. Görsel dağınıklığı önlemek için, bu yöntemler String türü için IntelliSense 'den
dışlanır, ancak yine de kullanılabilir. Ayrıca, dizeler üzerinde LINQ sorgu ifadeleri de kullanabilirsiniz. Daha fazla
bilgi için bkz. LINQ ve dizeler.

İlgili Konular
KONU AÇIKLAMA

Dize içeriklerini değiştirme Dizeleri dönüştürme ve dizelerin içeriğini değiştirme


tekniklerini gösterir.

Dizeleri karşılaştırma Dizelerin sıralı ve kültüre özgü karşılaştırmalarının nasıl


gerçekleştirileceğini gösterir.

Birden çok dizeyi birleştirme Birden çok dizeyi tek tek birleştirmek için çeşitli yollar gösterir.

String. Split kullanarak dizeleri ayrıştırma Dizeleri ayrıştırmak için String.Split yönteminin nasıl
kullanılacağını gösteren kod örnekleri içerir.

Dizeleri arama Dizelerde belirli metin veya desenler için aramanın nasıl
kullanılacağını açıklar.

Bir dizenin sayısal bir değeri temsil edip etmediğini belirleme Geçerli bir sayısal değer olup olmadığını görmek için bir dizeyi
güvenli bir şekilde ayrıştırmayı gösterir.

Dize ilişkilendirme Dizeleri biçimlendirmek için uygun bir sözdizimi sağlayan dize
ilişkilendirme özelliğini açıklar.
KONU AÇIKLAMA

Temel Dize İşlemleri Temel dize işlemleri gerçekleştirmek için System.String ve


System.Text.StringBuilder yöntemlerini kullanan konulara
bağlantılar sağlar.

Dizeleri Ayrıştırma .NET temel türlerinin dize temsillerini karşılık gelen türlerin
örneklerine nasıl dönüştüreceğiniz açıklanmıştır.

.NET 'teki tarih ve saat dizelerini ayrıştırma "01/24/2008" gibi bir dizenin System.DateTime nesnesine
nasıl dönüştürüleceğini gösterir.

Dizeleri Karşılaştırma Dizelerin nasıl karşılaştırılacağı hakkında bilgiler içerir ve C# ve


Visual Basic örnekler sağlar.

StringBuilder Sınıfını Kullanma StringBuilder sınıfını kullanarak dinamik dize nesnelerinin nasıl
oluşturulduğunu ve değiştirileceğini açıklar.

LINQ ve Dizeler LINQ sorguları kullanılarak çeşitli dize işlemlerinin nasıl


gerçekleştirileceği hakkında bilgi sağlar.

C# Programlama Kılavuzu İçinde C#programlama yapılarını açıklayan konuların


bağlantılarını sağlar.
Nasıl yapılır: Bir dizenin sayısal bir değeri temsil edip
etmediğini belirlemeC# (Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Bir dizenin belirtilen bir sayısal türün geçerli bir gösterimi olup olmadığını anlamak için, tüm ilkel sayısal türler
TryParse tarafından uygulanan statik yöntemi ve ayrıca DateTime ve IPAddressgibi türleri kullanın. Aşağıdaki
örnek, "108" nin geçerli bir intolup olmadığını nasıl belirleyeceğini gösterir.

int i = 0;
string s = "108";
bool result = int.TryParse(s, out i); //i now = 108

Dize sayısal olmayan karakterler içeriyorsa veya belirttiğiniz belirli tür için çok büyük veya çok küçükse, TryParse
false değerini döndürür ve out parametresini sıfıra ayarlar. Aksi takdirde, true döndürür ve out parametresini
dizenin sayısal değerine ayarlar.

NOTE
Dize yalnızca sayısal karakterler içerebilir ve bu TryParse yöntemi kullandığınız tür için geçerli olmayabilir. Örneğin, "256",
için byte geçerli bir değer değildir ancak için int geçerlidir. "98,6", için int geçerli bir değer değil, ancak geçerli
decimal bir.

Örnek
Aşağıdaki TryParse örneklerde,, ve long byte değerlerinin decimal dize gösterimiyle nasıl kullanılacağı
gösterilmektedir.

string numString = "1287543"; //"1287543.0" will return false for a long


long number1 = 0;
bool canConvert = long.TryParse(numString, out number1);
if (canConvert == true)
Console.WriteLine("number1 now = {0}", number1);
else
Console.WriteLine("numString is not a valid long");

byte number2 = 0;
numString = "255"; // A value of 256 will return false
canConvert = byte.TryParse(numString, out number2);
if (canConvert == true)
Console.WriteLine("number2 now = {0}", number2);
else
Console.WriteLine("numString is not a valid byte");

decimal number3 = 0;
numString = "27.3"; //"27" is also a valid decimal
canConvert = decimal.TryParse(numString, out number3);
if (canConvert == true)
Console.WriteLine("number3 now = {0}", number3);
else
Console.WriteLine("number3 is not a valid decimal");
Güçlü Programlama
İlkel sayısal türler Ayrıca, dize Parse geçerli bir sayı değilse özel bir durum oluşturan statik yöntemini de uygular.
TryParse Genellikle, sayı geçerli değilse false döndürdüğünden, bu, genellikle daha etkilidir.

.NET Framework Güvenliği


Metin kutuları ve TryParse Birleşik Parse giriş kutuları gibi denetimlerden Kullanıcı girişini doğrulamak için her
zaman veya yöntemlerini kullanın.

Ayrıca bkz.
Nasıl yapılır: Byte dizisini int 'e dönüştürme
Nasıl yapılır: Bir dizeyi sayıya Dönüştür
Nasıl yapılır: Onaltılık dizeler ve sayısal türler arasında dönüştürme
Sayısal Dizeleri Ayrıştırma
Biçimlendirme Türleri
Dizin Oluşturucular (C# Programlama Kılavuzu)
4.11.2019 • 4 minutes to read • Edit Online

Dizin oluşturucular, bir sınıf veya yapının örneklerinin, tıpkı diziler gibi dizine eklenmesine izin verir.Dizinli
değer, açıkça bir tür veya örnek üyesi belirtilmeden ayarlanabilir veya alınabilir. Dizin oluşturucular,
erişimcilerinin parametre kazanması dışında özelliklere benzer.
Aşağıdaki örnek, değer atamak ve almak için basit Get ve set erişimcisi yöntemleriyle genel bir sınıf
tanımlar. Program sınıfı dizeleri depolamak için bu sınıfın bir örneğini oluşturur.

using System;

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 { return arr[i]; }
set { arr[i] = value; }
}
}

class Program
{
static void Main()
{
var stringCollection = new SampleCollection<string>();
stringCollection[0] = "Hello, World";
Console.WriteLine(stringCollection[0]);
}
}
// The example displays the following output:
// Hello, World.

NOTE
Daha fazla örnek için bkz. Ilgili bölümler.

İfade gövdesi tanımları


Bir dizin oluşturucunun Get veya set erişimcisinin bir değer döndüren ya da ayarlayan tek bir deyimden
oluşması yaygındır. İfade-Bodied Üyeler, bu senaryoyu desteklemek için basitleştirilmiş bir sözdizimi sağlar.
C# 6 ' dan itibaren, aşağıdaki örnekte gösterildiği gibi, salt okunurdur bir Dizin Oluşturucu, bir ifade Bodied
üyesi olarak uygulanabilir.
using System;

class SampleCollection<T>
{
// Declare an array to store the data elements.
private T[] arr = new T[100];
int nextIndex = 0;

// Define the indexer to allow client code to use [] notation.


public T this[int i] => arr[i];

public void Add(T value)


{
if (nextIndex >= arr.Length)
throw new IndexOutOfRangeException($"The collection can hold only {arr.Length} elements.");
arr[nextIndex++] = value;
}
}

class Program
{
static void Main()
{
var stringCollection = new SampleCollection<string>();
stringCollection.Add("Hello, World");
System.Console.WriteLine(stringCollection[0]);
}
}
// The example displays the following output:
// Hello, World.

=> ifade gövdesini tanıtdığına ve get anahtar sözcüğünün kullanılmadığını unutmayın.


7,0 ile C# başlayarak, hem Get hem de set erişimcisi, ifade Bodied Üyeler olarak uygulanan bir uygulanmış
olabilir. Bu durumda, hem get hem de set anahtar sözcükleri kullanılmalıdır. Örneğin:

using System;

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

class Program
{
static void Main()
{
var stringCollection = new SampleCollection<string>();
stringCollection[0] = "Hello, World.";
Console.WriteLine(stringCollection[0]);
}
}
// The example displays the following output:
// Hello, World.
Dizin Oluşturuculara Genel Bakış
Dizin oluşturucular, nesnelerin dizilere benzer bir şekilde dizine alınmasını sağlar.
get erişimcisi bir değer döndürür. set erişimcisi bir değer atar.
Bu anahtar sözcük, Dizin oluşturucuyu tanımlamak için kullanılır.
Value anahtar sözcüğü, set Indexer tarafından atanan değeri tanımlamak için kullanılır.
Dizin oluşturucuların bir tamsayı değeri ile dizinlenmesini gerekmez; Bu, belirli bir arama
mekanizmasını nasıl tanımlayacaksınız.
Dizin oluşturucular aşırı yüklenebilir.
Dizin oluşturucular birden fazla biçimsel parametreye sahip olabilir, örneğin iki boyutlu bir diziye
erişirken.

İlgili bölümler
Dizin Oluşturucular Kullanma
Arabirimlerdeki Dizin Oluşturucular
Özellikler ve Dizin Oluşturucular Arasında Karşılaştırma
Erişimci Erişilebilirliğini Kısıtlama

C# Dil Belirtimi
Daha fazla bilgi için bkz. C# dil belirtiminde Dizin oluşturucular . Dil belirtimi, C# sözdizimi ve kullanımı
için kesin bir kaynaktır.

Ayrıca bkz.
C# Programlama Kılavuzu
Veri Erişimi
Dizin oluşturucular kullanmaC# (Programlama
Kılavuzu)
23.10.2019 • 7 minutes to read • Edit Online

Dizin oluşturucular, istemci uygulamaların yalnızca bir dizi olarak erişebileceği bir sınıf, Yapıveya arabirim
oluşturmanıza imkan tanıyan sözdizimsel bir kolaydır. Dizin oluşturucular en sık, birincil amacı bir iç koleksiyonu
veya diziyi kapsüllemek olan türlerde uygulanır. Örneğin, 24 saatlik bir dönemde 10 farklı TempRecord zamanda
kaydedildiği gibi Fahrenhayt 'teki sıcaklığı temsil eden bir sınıfınız olduğunu varsayalım. Sınıfı, sıcaklık değerlerini
depolamak temps için türünde float[] bir dizi içerir. Bu sınıfta bir Dizin Oluşturucu uygulayarak istemciler, gibi
bir TempRecord float temp = tr[4] örnekteki sıcakya farklı float temp = tr.temps[4] şekilde erişebilir. Dizin
Oluşturucu gösterimi yalnızca istemci uygulamaları için söz dizimini basitleştirir; Ayrıca, diğer geliştiricilerin
anlayabilmesi için sınıfı ve amacını daha sezgisel hale getirir.
Bir sınıf veya yapı biriminde bir Dizin Oluşturucu bildirmek için aşağıdaki örnekte gösterildiği gibi this anahtar
sözcüğünü kullanın:

public int this[int index] // Indexer declaration


{
// get and set accessors
}

Açıklamalar
Bir dizin oluşturucunun türü ve parametrelerinin türü en az dizin oluşturucunun kendisi olarak erişilebilir olmalıdır.
Erişilebilirlik düzeyleri hakkında daha fazla bilgi için bkz. erişim değiştiricileri.
Arabirim ile Dizin oluşturucular kullanma hakkında daha fazla bilgi için bkz. arabirim dizin oluşturucular.
Bir dizin oluşturucunun imzası, biçimsel parametrelerinin sayısı ve türlerinden oluşur. Dizin Oluşturucu türü veya
biçimsel parametrelerin adlarını içermez. Aynı sınıfta birden fazla Dizin Oluşturucu bildirirseniz, bunların farklı
imzaları olmalıdır.
Dizin Oluşturucu değeri bir değişken olarak sınıflandırılmıyor; Bu nedenle, Dizin Oluşturucu değeri bir ref veya
Out parametresi olarak geçirilemez.
Dizin oluşturucuyu diğer dillerin kullanabileceği bir adla sağlamak için, aşağıdaki örnekte gösterildiği gibi
System.Runtime.CompilerServices.IndexerNameAttributekullanın:

[System.Runtime.CompilerServices.IndexerName("TheItem")]
public int this[int index] // Indexer declaration
{
// get and set accessors
}

Bu dizin oluşturucunun adı TheItem olacaktır. Ad özniteliği sağlanmaması varsayılan adı yapar Item .

Örnek 1
Aşağıdaki örnek, bir özel dizi alanının, temps ve bir dizin oluşturucunun nasıl bildirilemeyeceğini gösterir. Dizin
Oluşturucu örneğe tempRecord[i] doğrudan erişim sağlar. Dizin oluşturucuyu kullanmanın alternatifi, diziyi ortak
bir üye olarak bildirmeli ve üyelerine tempRecord.temps[i] doğrudan erişim sağlar.
Bir dizin oluşturucunun erişim değerlendirildiği zaman, örneğin bir Console.Write ifadede, Get erişimcisinin
çağrıldığına dikkat edin. Bu nedenle, get bir erişimci yoksa, bir derleme zamanı hatası oluşur.

class TempRecord
{
// Array of temperature values
private float[] temps = new float[10] { 56.2F, 56.7F, 56.5F, 56.9F, 58.8F,
61.3F, 65.9F, 62.1F, 59.2F, 57.5F };

// To enable client code to validate input


// when accessing your indexer.
public int Length
{
get { return temps.Length; }
}
// Indexer declaration.
// If index is out of range, the temps array will throw the exception.
public float this[int index]
{
get
{
return temps[index];
}

set
{
temps[index] = value;
}
}
}

class MainClass
{
static void Main()
{
TempRecord tempRecord = new TempRecord();
// Use the indexer's set accessor
tempRecord[3] = 58.3F;
tempRecord[5] = 60.1F;

// Use the indexer's get accessor


for (int i = 0; i < 10; i++)
{
System.Console.WriteLine("Element #{0} = {1}", i, tempRecord[i]);
}

// Keep the console window open in debug mode.


System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();

}
}
/* Output:
Element #0 = 56.2
Element #1 = 56.7
Element #2 = 56.5
Element #3 = 58.3
Element #4 = 58.8
Element #5 = 60.1
Element #6 = 65.9
Element #7 = 62.1
Element #8 = 59.2
Element #9 = 57.5
*/
Diğer değerleri kullanarak dizin oluşturma
C#Dizin Oluşturucu parametre türü tamsayı olarak sınırlandırmaz. Örneğin, bir Dizin Oluşturucu ile dize
kullanmak yararlı olabilir. Bu tür bir Dizin Oluşturucu koleksiyondaki dizeyi arayarak ve uygun değeri döndürerek
uygulanabilir. Erişimciler aşırı yüklenmiş olabilir, dize ve tamsayı sürümleri birlikte bulunabilir.

Örnek 2
Aşağıdaki örnek, haftanın günlerini depolayan bir sınıf bildirir. get Erişimci bir dize, bir günün adı alır ve karşılık
gelen tamsayıyı döndürür. Örneğin, "Pazar" 0, "Pazartesi" 1 döndürür ve bu şekilde devam eder.

// Using a string as an indexer value


class DayCollection
{
string[] days = { "Sun", "Mon", "Tues", "Wed", "Thurs", "Fri", "Sat" };

// This method finds the day or returns an Exception if the day is not found
private int GetDay(string testDay)
{

for (int j = 0; j < days.Length; j++)


{
if (days[j] == testDay)
{
return j;
}
}

throw new System.ArgumentOutOfRangeException(testDay, "testDay must be in the form \"Sun\", \"Mon\",


etc");
}

// The get accessor returns an integer for a given string


public int this[string day]
{
get
{
return (GetDay(day));
}
}
}

class Program
{
static void Main(string[] args)
{
DayCollection week = new DayCollection();
System.Console.WriteLine(week["Fri"]);

// Raises ArgumentOutOfRangeException
System.Console.WriteLine(week["Made-up Day"]);

// Keep the console window open in debug mode.


System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
}
// Output: 5

Güçlü programlama
Dizin oluşturucularının güvenliğinin ve güvenilirliğinin iyileşmesi için kullanabileceğiniz iki ana yol vardır:
İstemci kodunun geçersiz bir dizin değeri geçirme olasılığını işlemek için bir tür hata işleme stratejisi
eklediğinizden emin olun. Bu konunun önceki kısımlarında yer alan ilk örnekte, TempRecord sınıfı, istemci
kodun dizin oluşturucuya geçirmeden önce girişi doğrulamasını sağlayan bir length özelliği sağlar. Hata
işleme kodunu dizin oluşturucunun içine de yerleştirebilirsiniz. Bir Dizin Oluşturucu erişimcisinde
oluşturduğunuz tüm özel durumları kullanıcılara belgelediğinizden emin olun.
Get ve set erişimcilerinin erişilebilirliğini makul olacak şekilde kısıtlayıcı olarak belirleyin. Bu, set özellikle
erişimcinin açısından önemlidir. Daha fazla bilgi için bkz. erişimci erişilebilirliğini kısıtlama.

Ayrıca bkz.
C# Programlama Kılavuzu
Dizin Oluşturucular
Özellikler
Arabirimlerdeki Dizin Oluşturucular (C#
Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Dizin oluşturucular bir arabirimdebildirilemez. Arabirim dizin oluşturucularının erişimcileri, sınıf dizin
oluşturucularının erişimcilerine aşağıdaki yollarla göre farklılık gösterir:
Arabirim erişimcileri değiştiriciler kullanmaz.
Arabirim erişimcisinin gövdesi yok.
Bu nedenle, erişimcinin amacı, dizin oluşturucunun okuma-yazma, salt okunurdur veya salt yazılır olduğunu
belirtsağlamaktır.
Arabirim dizin oluşturucu erişimcisine bir örnek aşağıda verilmiştir:

public interface ISomeInterface


{
//...

// Indexer declaration:
string this[int index]
{
get;
set;
}
}

Bir dizin oluşturucunun imzası aynı arabirimde belirtilen diğer tüm dizin oluşturucularının imzalarından farklı
olmalıdır.

Örnek
Aşağıdaki örnek, arabirim dizin oluşturucularının nasıl uygulanacağını gösterir.
// Indexer on an interface:
public interface ISomeInterface
{
// Indexer declaration:
int this[int index]
{
get;
set;
}
}

// Implementing the interface.


class IndexerClass : ISomeInterface
{
private int[] arr = new int[100];
public int this[int index] // indexer declaration
{
get
{
// The arr object will throw IndexOutOfRange exception.
return arr[index];
}
set
{
arr[index] = value;
}
}
}

class MainClass
{
static void Main()
{
IndexerClass test = new IndexerClass();
System.Random rand = new System.Random();
// Call the indexer to initialize its elements.
for (int i = 0; i < 10; i++)
{
test[i] = rand.Next();
}
for (int i = 0; i < 10; i++)
{
System.Console.WriteLine("Element #{0} = {1}", i, test[i]);
}

// Keep the console window open in debug mode.


System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
}
/* Sample output:
Element #0 = 360877544
Element #1 = 327058047
Element #2 = 1913480832
Element #3 = 1519039937
Element #4 = 601472233
Element #5 = 323352310
Element #6 = 1422639981
Element #7 = 1797892494
Element #8 = 875761049
Element #9 = 393083859
*/

Yukarıdaki örnekte, arabirim üyesinin tam adını kullanarak açık arabirim üye uygulamasını kullanabilirsiniz.
Örneğin:
string ISomeInterface.this[int index]
{
}

Ancak, tam adı yalnızca, sınıf aynı Dizin Oluşturucu imzasına sahip birden fazla arabirim uygularken karışıklığı
önlemek için gereklidir. Örneğin, bir Employee sınıf iki ICitizen arabirim IEmployee uygusa ve her iki arabirimde
de aynı Dizin Oluşturucu imzası varsa, açık arabirim üye uygulaması gereklidir. Diğer bir deyişle, aşağıdaki Dizin
Oluşturucu bildirimi:

string IEmployee.this[int index]


{
}

IEmployee arabirim üzerinde dizin oluşturucuyu uygular, aşağıdaki bildirim:

string ICitizen.this[int index]


{
}

ICitizen arabirimindeki Dizin oluşturucuyu uygular.

Ayrıca bkz.
C# Programlama Kılavuzu
Dizin Oluşturucular
Özellikler
Arabirimler
Özellikler ve Dizin Oluşturucular Arasında
Karşılaştırma (C# Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Dizin oluşturucular Özellikler gibidir. Aşağıdaki tabloda gösterilen farklar dışında, özellik erişimcileri için
tanımlanan tüm kurallar Dizin Oluşturucu erişimcileri için de geçerlidir.

ÖZELLIK DIZINLEYIC

Yöntemlerin ortak veri üyeleri gibi çağrılmasına izin verir. Nesne üzerinde dizi gösterimi kullanılarak bir nesne iç
koleksiyonunun öğelerine erişilmesine izin verir.

Basit bir ad üzerinden erişilir. Bir dizin üzerinden erişilir.

Statik veya örnek üyesi olabilir. Örnek üye olmalıdır.

Özelliğin Get erişimcisinin parametresi yok. Bir dizin oluşturucunun erişimcisi, Dizin Oluşturucu ile aynı
biçimsel parametre listesine sahiptir. get

Bir özelliğin set erişimcisi örtük value parametresi içerir. Bir dizin oluşturucunun
erişimcisi,DizinOluşturucuileaynıbiçimselparametrelistesineveay
rıcadeğerparametresine set sahiptir.

Otomatik uygulanan özelliklerlekısaltılmış sözdizimini destekler. Yalnızca Get Dizin oluşturucular için ifade gövdeli üyelerini
destekler.

Ayrıca bkz.
C# Programlama Kılavuzu
Dizin Oluşturucular
Özellikler
Olaylar (C# Programlama Kılavuzu)
4.11.2019 • 3 minutes to read • Edit Online

Olaylar, bir sınıf ya da nesnenin, ilgi çekici bir şeyler gerçekleştiğinde diğer sınıflara veya nesnelere
bildirilmesini sağlar. Olayı gönderen (veya başlatan) sınıf Yayımcı olarak adlandırılır ve olayı alan (veya
işleyen) sınıflar abonelerolarak adlandırılır.
Tipik C# bir Windows Forms veya Web uygulamasında, düğmeler ve liste kutuları gibi denetimler tarafından
oluşturulan olaylara abone olursunuz. Bir denetimin yayımladığı olaylara gözatabilmek ve işlemek
istediklerinizi seçmek için Visual C# tümleşik geliştirme ortamı 'Nı (IDE ) kullanabilirsiniz. IDE, otomatik
olarak boş bir olay işleyici yöntemi ve olaya abone olmak için kod eklemenin kolay bir yolunu sunar. Daha
fazla bilgi için bkz. nasıl yapılır: olaylara abone olma ve aboneliği kaldırma.

Olaylara Genel Bakış


Olaylar aşağıdaki özelliklere sahiptir:
Yayımcı bir olayın ne zaman gerçekleştiğini belirler; aboneler olaya yanıt olarak hangi eylemin
alınacağını tespit ediyor.
Bir olay birden çok aboneye sahip olabilir. Bir abone birden çok yayımcıların birden çok olayını
işleyebilir.
Abone olmayan olaylar hiçbir şekilde oluşturulmaz.
Olaylar genellikle grafik kullanıcı arabirimlerinde düğme tıklamaları veya menü seçimleri gibi kullanıcı
eylemlerini işaret etmek için kullanılır.
Bir olayda birden çok abone olduğunda, olay işleyicileri bir olay oluşturulduğunda zaman uyumlu
olarak çağrılır. Olayları zaman uyumsuz olarak çağırmak için bkz. zaman uyumlu yöntemleri zaman
uyumsuz çağırma.
.NET Framework sınıf kitaplığında olaylar, EventHandler temsilciyi ve EventArgs temel sınıfını temel
alır.

İlgili Bölümler
Daha fazla bilgi için bkz.:
Nasıl yapılır: Olaylara Abone Olma ve Aboneliği Kaldırma
Nasıl yapılır: .NET Framework Yönergeleriyle Uyumlu Olayları Yayımlama
Nasıl yapılır: Türetilmiş Sınıflarda Temel Sınıf Olayları Oluşturma
Nasıl yapılır: arabirim olaylarını uygulama
Nasıl yapılır: Özel Olay Erişimcilerini Uygulama

C# Dil Belirtimi
Daha fazla bilgi için bkz. C# dil belirtiminde Olaylar . Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.
Özel Kitap Bölümleri
3,0 tanımlama kitabı, üçüncü sürüm 'de Temsilciler, olaylar ve lambda ifadeleri C# : 3,0 programcılar için C#
250 ' den fazla çözüm
Öğrenme C# 3,0 C# ' deki Temsilciler ve olaylar : 3,0 temelleri ana

Ayrıca bkz.
EventHandler
C# Programlama Kılavuzu
Temsilciler
Windows Forms'ta Olay İşleyicileri Oluşturma
Nasıl yapılır: Olaylara abone olma ve aboneliği
kaldırma (C# Programlama Kılavuzu)
23.10.2019 • 5 minutes to read • Edit Online

Bu olay ortaya çıktığında çağrılan özel kod yazmak istediğinizde, başka bir sınıf tarafından yayımlanan bir olaya
abone olursunuz. Örneğin, Kullanıcı düğmeye tıkladığında uygulamanızı yararlı hale getirmek için click bir
düğmenin olayına abone olabilirsiniz.
Visual Studio IDE kullanarak olaylara abone olma
1. Özellikler penceresini göremiyorsanız, Tasarım görünümü ' nde, olay işleyicisi oluşturmak istediğiniz
form veya denetime sağ tıklayın ve Özellikler' i seçin.
2. Özellikler penceresinin üstünde Olaylar simgesine tıklayın.
3. Oluşturmak istediğiniz olaya çift tıklayın, örneğin Load olay.
Visual C# , boş bir olay işleyici yöntemi oluşturur ve bunu kodunuza ekler. Alternatif olarak, kod
görünümünde kodu el ile de ekleyebilirsiniz. Örneğin, aşağıdaki kod satırları, Form sınıf Load olayı
harekete geçirirse çağrılacak bir olay işleyicisi yöntemi bildirir.

private void Form1_Load(object sender, System.EventArgs e)


{
// Add your form load event handling code here.
}

Olaya abone olmak için gereken kod satırı, projenizdeki Form1.Designer.cs dosyasındaki
InitializeComponent yönteminde de otomatik olarak oluşturulur. Şuna benzer:

this.Load += new System.EventHandler(this.Form1_Load);

Olaylara programlı bir şekilde abone olmak için


1. İmzası, olayın temsilci imzasıyla eşleşen bir olay işleyici yöntemi tanımlayın. Örneğin, olay EventHandler
temsilci türünü temel alıyorsa, aşağıdaki kod yöntem saplaması ' nı temsil eder:

void HandleCustomEvent(object sender, CustomEventArgs a)


{
// Do something useful here.
}

2. Olaya bir olay işleyicisi iliştirmek için += ekleme atama işlecini () kullanın. Aşağıdaki örnekte adlı
publisher bir nesnesinin adlı RaiseCustomEvent bir olayı olduğunu varsayalım. Abone sınıfının olaylarına
abone olmak için yayımcı sınıfına bir başvuru ihtiyacı olduğunu unutmayın.

publisher.RaiseCustomEvent += HandleCustomEvent;

Önceki sözdiziminin 2,0 ' de C# yeni olduğunu unutmayın. Bu, kapsülleme temsilcisinin C# new anahtar
sözcüğü kullanılarak açıkça oluşturulması gereken 1,0 sözdizimine tam olarak eşdeğerdir:
publisher.RaiseCustomEvent += new CustomEventHandler(HandleCustomEvent);

Bir olay işleyicisi belirtmek için de bir lambda ifadesi kullanabilirsiniz:

public Form1()
{
InitializeComponent();
this.Click += (s,e) =>
{
MessageBox.Show(((MouseEventArgs)e).Location.ToString());
};
}

Anonim bir yöntem kullanarak olaylara abone olma


Bir olayı daha sonra kaldırmak zorunda değilseniz, olaya anonim bir yöntem iliştirmek için ekleme atama
işlecini ( += ) kullanabilirsiniz. Aşağıdaki örnekte, adlı publisher bir nesnesinin adlı RaiseCustomEvent bir
olayı olduğunu ve bir sınıfın bir CustomEventArgs tür özel olay bilgilerini taşımak için de tanımlandığını
varsayalım. Abone sınıfının olaylarına abone olmak için bir başvuruya publisher ihtiyacı olduğunu
unutmayın.

publisher.RaiseCustomEvent += delegate(object o, CustomEventArgs e)


{
string s = o.ToString() + " " + e.ToString();
Console.WriteLine(s);
};

Abone olmak için anonim bir işlev kullandıysanız, bir olaydan kolayca abonelik yapamayacağını fark
etmeniz önemlidir. Bu senaryoda aboneliğinizi kaldırmak için, olaya abone olduğunuz koda geri dönmek,
anonim yöntemi bir temsilci değişkeninde depolamak ve ardından temsilciyi olaya eklemek gereklidir.
Genel olarak, kodunuzda daha sonraki bir noktada olay aboneliğinizi kaldırmak zorunda olmanız
durumunda olaylara abone olmak için anonim işlevler kullanmayın. Anonim işlevler hakkında daha fazla
bilgi için bkz. Anonim işlevler.

Aboneliği kaldırılıyor
Olay işleyicinizin olay ortaya çıktığında çağrılmasını engellemek için, olaydan aboneliği kaldırın. Kaynak
sızıntılarını engellemek için, bir abone nesnesini atmadan önce etkinliklerden aboneliğinizi iptal etmelisiniz. Bir
olaydan abonelik aboneliğini kaldırana kadar, yayımlama nesnesindeki olayı oluşturan çok noktaya yayın
temsilcisi, abonenin olay işleyicisini kapsülleyen temsilciye bir başvuruya sahiptir. Yayımlama nesnesi bu
başvuruyu taşıdığı sürece çöp toplama işlemi abone nesneniz silinmez.
Bir olaydan aboneliğinizi kaldırmak için
Bir olaydan aboneliğinizi kaldırmak için çıkarma -= atama işlecini () kullanın:

publisher.RaiseCustomEvent -= HandleCustomEvent;

Tüm aboneler bir olaydan aboneliği kaldırdığınızda, yayımcı sınıfındaki olay örneği olarak null ayarlanır.

Ayrıca bkz.
Olaylar
event
Nasıl yapılır: .NET Framework yönergeleriyle uyumlu olayları yayımlama
-ve-= işleçleri
+ ve + = işleçleri
Nasıl yapılır: .NET Framework yönergelerine uygun
olan olayları yayımlama (C# Programlama Kılavuzu)
23.10.2019 • 4 minutes to read • Edit Online

Aşağıdaki yordam, sınıflarınıza ve yapılarına standart .NET Framework modelini izleyen olayların nasıl
ekleneceğini göstermektedir. .NET Framework sınıf kitaplığındaki tüm olaylar, aşağıdaki şekilde tanımlanan
EventHandler temsilciyi temel alır:

public delegate void EventHandler(object sender, EventArgs e);

NOTE
.NET Framework 2,0, bu temsilcinin EventHandler<TEventArgs>genel bir sürümünü sunmaktadır. Aşağıdaki örneklerde her
iki sürümün de nasıl kullanılacağı gösterilmektedir.

Tanımladığınız sınıflardaki olaylar geçerli temsilci türlerini temel alabilir, hatta bir değer döndüren temsilciler olsa
da, aşağıdaki örnekte gösterildiği gibi, kullanarak EventHandlerolaylarınızın .NET Framework düzeniyle temel
almanız önerilir.
Olayları EventHandler düzenine göre yayımlamak için
1. (Bu adımı atlayın ve olaylarınız ile özel veriler göndermeniz gerekmez. adıma gidin.) Özel verilerinize ait
sınıfı, hem Yayımcı hem de abone sınıflarınızda görünen bir kapsamda bildirin. Ardından, özel olay
verilerinizi tutmak için gerekli üyeleri ekleyin. Bu örnekte basit bir dize döndürülür.

public class CustomEventArgs : EventArgs


{
public CustomEventArgs(string s)
{
msg = s;
}
private string msg;
public string Message
{
get { return msg; }
}
}

2. (Genel sürümünü EventHandler<TEventArgs> kullanıyorsanız bu adımı atlayın.) Yayımlama sınıfınıza bir


temsilci bildirin. Buna EventHandlerile biten bir ad verin. İkinci parametre özel EventArgs türünü belirtir.

public delegate void CustomEventHandler(object sender, CustomEventArgs a);

3. Aşağıdaki adımlardan birini kullanarak, yayımlama sınıfınıza olayı bildirin.


a. Özel EventArgs sınıfınız yoksa, olay türü genel olmayan EventHandler temsilcisi olur. Projenizi
oluştururken dahil edilen System ad alanında zaten bildirildiği için temsilciyi bildirmeniz gerekmez.
C# Aşağıdaki kodu Publisher sınıfınıza ekleyin.
public event EventHandler RaiseCustomEvent;

b. Öğesinin EventHandler genel olmayan sürümünü kullanıyorsanız ve öğesinden EventArgstüretilmiş


özel bir sınıfınız varsa, bu kodunuzu yayımlama sınıfınız içinde bildirin ve 2. adımdaki temsilcinizi tür
olarak kullanın.

public event CustomEventHandler RaiseCustomEvent;

c. Genel sürümü kullanıyorsanız özel bir temsilciye ihtiyacınız yoktur. Bunun yerine, yayımlama
sınıfınız içinde, kendi sınıfınızın adını açılı ayraçlar arasında EventHandler<CustomEventArgs>
değiştirerek olay türü olarak belirtirsiniz.

public event EventHandler<CustomEventArgs> RaiseCustomEvent;

Örnek
Aşağıdaki örnek, bir özel EventArgs sınıfı ve EventHandler<TEventArgs> olay türü olarak önceki adımları gösterir.

namespace DotNetEvents
{
using System;
using System.Collections.Generic;

// Define a class to hold custom event info


public class CustomEventArgs : EventArgs
{
public CustomEventArgs(string s)
{
message = s;
}
private string message;

public string Message


{
get { return message; }
set { message = value; }
}
}

// Class that publishes an event


class Publisher
{

// Declare the event using EventHandler<T>


public event EventHandler<CustomEventArgs> RaiseCustomEvent;

public void DoSomething()


{
// Write some code that does something useful here
// then raise the event. You can also raise an event
// before you execute a block of code.
OnRaiseCustomEvent(new CustomEventArgs("Did something"));

// Wrap event invocations inside a protected virtual method


// to allow derived classes to override the event invocation behavior
protected virtual void OnRaiseCustomEvent(CustomEventArgs e)
{
// Make a temporary copy of the event to avoid possibility of
// a race condition if the last subscriber unsubscribes
// immediately after the null check and before the event is raised.
EventHandler<CustomEventArgs> handler = RaiseCustomEvent;

// Event will be null if there are no subscribers


if (handler != null)
{
// Format the string to send inside the CustomEventArgs parameter
e.Message += $" at {DateTime.Now}";

// Use the () operator to raise the event.


handler(this, e);
}
}
}

//Class that subscribes to an event


class Subscriber
{
private string id;
public Subscriber(string ID, Publisher pub)
{
id = ID;
// Subscribe to the event using C# 2.0 syntax
pub.RaiseCustomEvent += HandleCustomEvent;
}

// Define what actions to take when the event is raised.


void HandleCustomEvent(object sender, CustomEventArgs e)
{
Console.WriteLine(id + " received this message: {0}", e.Message);
}
}

class Program
{
static void Main(string[] args)
{
Publisher pub = new Publisher();
Subscriber sub1 = new Subscriber("sub1", pub);
Subscriber sub2 = new Subscriber("sub2", pub);

// Call the method that raises the event.


pub.DoSomething();

// Keep the console window open


Console.WriteLine("Press Enter to close this window.");
Console.ReadLine();

}
}
}

Ayrıca bkz.
Delegate
C# Programlama Kılavuzu
Olaylar
Temsilciler
Nasıl yapılır: Türetilmiş sınıflarda temel sınıf olayları
oluştur (C# Programlama Kılavuzu)
23.10.2019 • 4 minutes to read • Edit Online

Aşağıdaki basit örnek, bir temel sınıfta olayları bildirmenin standart yolunu gösterir ve bu sayede türetilmiş
sınıflardan da oluşturulabilir. Bu model, .NET Framework sınıf kitaplığındaki Windows Forms sınıflarında yaygın
olarak kullanılır.
Diğer sınıflar için temel sınıf olarak kullanılabilecek bir sınıf oluşturduğunuzda, olayların yalnızca kendilerini
tanımlayan sınıfın içinden çağrılabilen özel bir temsilci türü olduğunu düşünmelisiniz. Türetilmiş sınıflar, temel sınıf
içinde belirtilen olayları doğrudan çağıramaz. Bazen yalnızca temel sınıf tarafından ortaya çıkarılan bir olay
isteyebilir, çoğu zaman, temel sınıf olaylarını çağırmak için türetilmiş sınıfı etkinleştirmelisiniz. Bunu yapmak için,
olayı sarmalayan temel sınıfta korumalı çağırma yöntemi oluşturabilirsiniz. Bu çağırma yöntemini çağırarak veya
geçersiz kılarak, türetilmiş sınıflar olayı dolaylı olarak çağırabilir.

NOTE
Bir temel sınıfta sanal olayları bildirmeyin ve bunları türetilmiş bir sınıfta geçersiz kılarsınız. C# Derleyici bunları doğru işlemez
ve türetilmiş olaya bir abonenin gerçekten de temel sınıf olayına abone olup olmayacağını tahmin edilemez.

Örnek
namespace BaseClassEvents
{
using System;
using System.Collections.Generic;

// Special EventArgs class to hold info about Shapes.


public class ShapeEventArgs : EventArgs
{
private double newArea;

public ShapeEventArgs(double d)
{
newArea = d;
}
public double NewArea
{
get { return newArea; }
}
}

// Base class event publisher


public abstract class Shape
{
protected double area;

public double Area


{
get { return area; }
set { area = value; }
}
// The event. Note that by using the generic EventHandler<T> event type
// we do not need to declare a separate delegate type.
public event EventHandler<ShapeEventArgs> ShapeChanged;
public event EventHandler<ShapeEventArgs> ShapeChanged;

public abstract void Draw();

//The event-invoking method that derived classes can override.


protected virtual void OnShapeChanged(ShapeEventArgs e)
{
// Make a temporary copy of the event to avoid possibility of
// a race condition if the last subscriber unsubscribes
// immediately after the null check and before the event is raised.
EventHandler<ShapeEventArgs> handler = ShapeChanged;
if (handler != null)
{
handler(this, e);
}
}
}

public class Circle : Shape


{
private double radius;
public Circle(double d)
{
radius = d;
area = 3.14 * radius * radius;
}
public void Update(double d)
{
radius = d;
area = 3.14 * radius * radius;
OnShapeChanged(new ShapeEventArgs(area));
}
protected override void OnShapeChanged(ShapeEventArgs e)
{
// Do any circle-specific processing here.

// Call the base class event invocation method.


base.OnShapeChanged(e);
}
public override void Draw()
{
Console.WriteLine("Drawing a circle");
}
}

public class Rectangle : Shape


{
private double length;
private double width;
public Rectangle(double length, double width)
{
this.length = length;
this.width = width;
area = length * width;
}
public void Update(double length, double width)
{
this.length = length;
this.width = width;
area = length * width;
OnShapeChanged(new ShapeEventArgs(area));
}
protected override void OnShapeChanged(ShapeEventArgs e)
{
// Do any rectangle-specific processing here.

// Call the base class event invocation method.


base.OnShapeChanged(e);
}
public override void Draw()
public override void Draw()
{
Console.WriteLine("Drawing a rectangle");
}

// Represents the surface on which the shapes are drawn


// Subscribes to shape events so that it knows
// when to redraw a shape.
public class ShapeContainer
{
List<Shape> _list;

public ShapeContainer()
{
_list = new List<Shape>();
}

public void AddShape(Shape s)


{
_list.Add(s);
// Subscribe to the base class event.
s.ShapeChanged += HandleShapeChanged;
}

// ...Other methods to draw, resize, etc.

private void HandleShapeChanged(object sender, ShapeEventArgs e)


{
Shape s = (Shape)sender;

// Diagnostic message for demonstration purposes.


Console.WriteLine("Received event. Shape area is now {0}", e.NewArea);

// Redraw the shape here.


s.Draw();
}
}

class Test
{

static void Main(string[] args)


{
//Create the event publishers and subscriber
Circle c1 = new Circle(54);
Rectangle r1 = new Rectangle(12, 9);
ShapeContainer sc = new ShapeContainer();

// Add the shapes to the container.


sc.AddShape(c1);
sc.AddShape(r1);

// Cause some events to be raised.


c1.Update(57);
r1.Update(7, 7);

// Keep the console window open in debug mode.


System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
}
}
/* Output:
Received event. Shape area is now 10201.86
Drawing a circle
Received event. Shape area is now 49
Drawing a rectangle
*/
*/

Ayrıca bkz.
C# Programlama Kılavuzu
Olaylar
Temsilciler
Erişim Değiştiricileri
Windows Forms'ta Olay İşleyicileri Oluşturma
Nasıl yapılır: Arabirim olaylarını uygulama (C#
Programlama Kılavuzu)
23.10.2019 • 4 minutes to read • Edit Online

Bir arabirim , bir olayıbildirebilir. Aşağıdaki örnek, bir sınıfında arabirim olaylarının nasıl uygulanacağını gösterir.
Temel olarak kurallar, herhangi bir arabirim yöntemi veya özelliği uygularken olduğu gibidir.

Arabirim olaylarını bir sınıfta uygulamak için


Sınıfınıza olayı bildirin ve uygun alanlarda çağırın.

namespace ImplementInterfaceEvents
{
public interface IDrawingObject
{
event EventHandler ShapeChanged;
}
public class MyEventArgs : EventArgs
{
// class members
}
public class Shape : IDrawingObject
{
public event EventHandler ShapeChanged;
void ChangeShape()
{
// Do something here before the event…

OnShapeChanged(new MyEventArgs(/*arguments*/));

// or do something here after the event.


}
protected virtual void OnShapeChanged(MyEventArgs e)
{
ShapeChanged?.Invoke(this, e);
}
}

Örnek
Aşağıdaki örnek, sınıfınızın iki veya daha fazla arabirimden devraldığı daha az yaygın olan durumun nasıl
işleneceğini ve her arabirimin aynı ada sahip bir olaya sahip olduğunu gösterir. Bu durumda, en az bir olay için
açık bir arabirim uygulamasını sağlamalısınız. Bir olay için açık arabirim uygulama yazdığınızda, add ve remove
olay erişimcilerini de yazmanız gerekir. Bunlar normalde derleyici tarafından sağlanır, ancak bu durumda derleyici
bunları sağlayamaz.
Kendi erişimclerinizi sunarak, iki olayın sınıfınıza aynı olay ile mi yoksa farklı olaylara göre mi temsil edileceğini
belirtebilirsiniz. Örneğin, olayların arabirim belirtimlerine göre farklı zamanlarda oluşturulması gerekiyorsa, her
bir olayı sınıfınıza ayrı bir uygulamayla ilişkilendirebilirsiniz. Aşağıdaki örnekte, aboneler bir OnDraw IShape
veya bir veya bir IDrawingObject öğesine şekil başvurusunu kaldırarak hangi olayın alacağını tespit eder.

namespace WrapTwoInterfaceEvents
{
{
using System;

public interface IDrawingObject


{
// Raise this event before drawing
// the object.
event EventHandler OnDraw;
}
public interface IShape
{
// Raise this event after drawing
// the shape.
event EventHandler OnDraw;
}

// Base class event publisher inherits two


// interfaces, each with an OnDraw event
public class Shape : IDrawingObject, IShape
{
// Create an event for each interface event
event EventHandler PreDrawEvent;
event EventHandler PostDrawEvent;

object objectLock = new Object();

// Explicit interface implementation required.


// Associate IDrawingObject's event with
// PreDrawEvent
#region IDrawingObjectOnDraw
event EventHandler IDrawingObject.OnDraw
{
add
{
lock (objectLock)
{
PreDrawEvent += value;
}
}
remove
{
lock (objectLock)
{
PreDrawEvent -= value;
}
}
}
#endregion
// Explicit interface implementation required.
// Associate IShape's event with
// PostDrawEvent
event EventHandler IShape.OnDraw
{
add
{
lock (objectLock)
{
PostDrawEvent += value;
}
}
remove
{
lock (objectLock)
{
PostDrawEvent -= value;
}
}
}

// For the sake of simplicity this one method


// implements both interfaces.
public void Draw()
{
// Raise IDrawingObject's event before the object is drawn.
PreDrawEvent?.Invoke(this, EventArgs.Empty);

Console.WriteLine("Drawing a shape.");

// Raise IShape's event after the object is drawn.


PostDrawEvent?.Invoke(this, EventArgs.Empty);
}
}
public class Subscriber1
{
// References the shape object as an IDrawingObject
public Subscriber1(Shape shape)
{
IDrawingObject d = (IDrawingObject)shape;
d.OnDraw += d_OnDraw;
}

void d_OnDraw(object sender, EventArgs e)


{
Console.WriteLine("Sub1 receives the IDrawingObject event.");
}
}
// References the shape object as an IShape
public class Subscriber2
{
public Subscriber2(Shape shape)
{
IShape d = (IShape)shape;
d.OnDraw += d_OnDraw;
}

void d_OnDraw(object sender, EventArgs e)


{
Console.WriteLine("Sub2 receives the IShape event.");
}
}

public class Program


{
static void Main(string[] args)
{
Shape shape = new Shape();
Subscriber1 sub = new Subscriber1(shape);
Subscriber2 sub2 = new Subscriber2(shape);
shape.Draw();

// Keep the console window open in debug mode.


System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
}

}
/* Output:
Sub1 receives the IDrawingObject event.
Drawing a shape.
Sub2 receives the IShape event.
*/
Ayrıca bkz.
C# Programlama Kılavuzu
Olaylar
Temsilciler
Belirtik Arabirim Kullanma
Nasıl yapılır: Türetilmiş sınıflarda temel sınıf olayları oluştur
Nasıl yapılır: Özel olay erişimcileri uygulama (C#
Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Bir olay, yalnızca içinde bildirildiği sınıftan çağrılabilir olan özel bir çok noktaya yayın temsilcisi türüdür. İstemci
kodu olay harekete geçirildiğinde çağrılması gereken bir yönteme başvuru sağlayarak olaya abone olur. Bu
yöntemler, olay erişimcileri, ve add remove ' nin adlandırılmasının dışında, özellik erişimcilerine benzeyen,
temsilcinin çağrı listesine eklenir. Çoğu durumda, özel olay erişimcileri sağlamanız gerekmez. Kodunuzda hiçbir
özel olay erişimcisi sağlanmadığında, derleyici bunları otomatik olarak ekler. Ancak, bazı durumlarda özel davranış
sağlamanız gerekebilir. Böyle bir durum söz konusu şekilde gösterilmiştir: Arabirim olaylarınıuygulayın.

Örnek
Aşağıdaki örnek, özel ekleme ve kaldırma olay erişimcilerinin nasıl uygulanacağını gösterir. Erişimcilerinin içinde
herhangi bir kodu değiştirebilseniz de, yeni bir olay işleyici yöntemi eklemeden veya kaldırmadan önce olayı
kilitlemenizi öneririz.

event EventHandler IDrawingObject.OnDraw


{
add
{
lock (objectLock)
{
PreDrawEvent += value;
}
}
remove
{
lock (objectLock)
{
PreDrawEvent -= value;
}
}
}

Ayrıca bkz.
Olaylar
event
Genel Türler (C# Programlama Kılavuzu)
30.10.2019 • 5 minutes to read • Edit Online

Genel türler, sınıf veya yöntem istemci kodu tarafından bildirilene ve örneklendirilene kadar bir veya daha
fazla türün belirtimini erteleme sınıfları ve yöntemleri tasarlamak için .NET Framework parametre türü
kavramını ortaya çıkarabilir. Örneğin, bir genel tür parametresi kullanarak T , diğer istemci kodunun,
çalışma zamanı yayınları veya paketleme işlemlerinin maliyetini ya da riskini göstermeden, burada
gösterildiği gibi, kullanabileceği tek bir sınıf yazabilirsiniz:

// Declare the generic class.


public class GenericList<T>
{
public void Add(T input) { }
}
class TestGenericList
{
private class ExampleClass { }
static void Main()
{
// Declare a list of type int.
GenericList<int> list1 = new GenericList<int>();
list1.Add(1);

// Declare a list of type string.


GenericList<string> list2 = new GenericList<string>();
list2.Add("");

// Declare a list of type ExampleClass.


GenericList<ExampleClass> list3 = new GenericList<ExampleClass>();
list3.Add(new ExampleClass());
}
}

Genel sınıflar ve Yöntemler, yeniden kullanılabilirlik, tür güvenliği ve verimliliği genel olmayan
karşılıklarının bir şekilde birleştirir. Genel türler, koleksiyonlarla ve bunlarla çalışan yöntemlerle en sık
kullanılır. System.Collections.Generic ad alanı, genel tabanlı birkaç koleksiyon sınıfı içerir. ArrayList gibi
genel olmayan koleksiyonlar önerilmez ve uyumluluk amacıyla korunur. Daha fazla bilgi için bkz. .net 'Teki
genel türler.
Kuşkusuz, özel genel türler ve Yöntemler oluşturarak tür açısından güvenli ve verimli bir şekilde kendi
Genelleştirilmiş çözümlerinizi ve tasarım düzenlerini sağlayabilirsiniz. Aşağıdaki kod örneğinde, tanıtım
amacıyla basit bir genel bağlantılı liste sınıfı gösterilmektedir. (Çoğu durumda, kendinizinkini oluşturmak
yerine .NET Framework sınıf kitaplığı tarafından sunulan List<T> sınıfını kullanmanız gerekir.) Tür
parametresi T , somut bir türün genellikle listede depolanan öğenin türünü belirtmek için kullanıldığı
çeşitli konumlarda kullanılır. Aşağıdaki yollarla kullanılır:
AddHead yönteminde bir yöntem parametresinin türü olarak.
İç içe Node sınıfındaki Data özelliğinin dönüş türü olarak.
Özel üyenin türü, iç içe yerleştirilmiş sınıfta data .
T iç içe Node sınıfı için kullanılabilir olduğunu unutmayın. GenericList<T> , GenericList<int> gibi somut
bir türle başlatıldığında T her oluşumu int ile yerine geçer.
// type parameter T in angle brackets
public class GenericList<T>
{
// The nested class is also generic on T.
private class Node
{
// T used in non-generic constructor.
public Node(T t)
{
next = null;
data = t;
}

private Node next;


public Node Next
{
get { return next; }
set { next = value; }
}

// T as private member data type.


private T data;

// T as return type of property.


public T Data
{
get { return data; }
set { data = value; }
}
}

private Node head;

// constructor
public GenericList()
{
head = null;
}

// T as method parameter type:


public void AddHead(T t)
{
Node n = new Node(t);
n.Next = head;
head = n;
}

public IEnumerator<T> GetEnumerator()


{
Node current = head;

while (current != null)


{
yield return current.Data;
current = current.Next;
}
}
}

Aşağıdaki kod örneği, istemci kodunun tamsayılar listesini oluşturmak için genel GenericList<T> sınıfını
nasıl kullandığını gösterir. Yalnızca tür bağımsız değişkenini değiştirerek aşağıdaki kod, dizelerin veya
diğer özel türün listesini oluşturmak için kolayca değiştirilebilir:
class TestGenericList
{
static void Main()
{
// int is the type argument
GenericList<int> list = new GenericList<int>();

for (int x = 0; x < 10; x++)


{
list.AddHead(x);
}

foreach (int i in list)


{
System.Console.Write(i + " ");
}
System.Console.WriteLine("\nDone");
}
}

Genel bakışa genel bakış


Kod yeniden kullanımını en üst düzeye çıkarmak için genel türleri kullanın, güvenlik ve performans
yazın.
Genel türlerin en yaygın kullanımı koleksiyon sınıfları oluşturmaktır.
.NET Framework sınıf kitaplığı, System.Collections.Generic ad alanında birkaç yeni genel koleksiyon
sınıfı içerir. Bunlar, System.Collections ad alanındaki ArrayList gibi sınıflar yerine mümkün olduğunda
kullanılmalıdır.
Kendi genel arabirimlerinizi, sınıflarınızı, yöntemlerinizi, olaylarınızı ve temsilcilerinizi oluşturabilirsiniz.
Genel sınıflar, belirli veri türlerindeki yöntemlere erişimi etkinleştirmek için kısıtlanabilir.
Genel veri türünde kullanılan türlerle ilgili bilgiler, yansıma kullanılarak çalışma zamanında elde
edilebilir.

İlgili bölümler
Genel Tür Parametreleri
Tür Parametrelerindeki Kısıtlamalar
Genel Sınıflar
Genel Arabirimler
Genel Yöntemler
Genel Temsilciler
C++ Şablonları ve C# Genel Türleri Arasındaki Farklar
Genel Türler ve Yansıma
Çalışma Zamanındaki Genel Türler

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi.

Ayrıca bkz.
System.Collections.Generic
C# Programlama Kılavuzu
Türler
<typeparam >
<typeparamref >
.NET 'teki genel türler
Genel tür parametreleri (C# Programlama Kılavuzu)
31.10.2019 • 2 minutes to read • Edit Online

Genel tür veya yöntem tanımında bir tür parametresi, bir istemcinin genel türün bir örneğini oluşturduklarında
belirttiği belirli bir tür için yer tutucudur. Genel türler 'e girişbölümünde listelenen GenericList<T> gibi genel bir
sınıf, gerçekten bir tür olmadığından olduğu gibi kullanılamaz; Bu, bir tür için şema gibidir. GenericList<T>
kullanmak için, istemci kodu, açılı ayraç içinde bir tür bağımsız değişkeni belirterek oluşturulmuş bir tür
bildirmelidir ve örneklenmelidir. Bu belirli sınıfın tür bağımsız değişkeni, derleyici tarafından tanınan herhangi bir
tür olabilir. Her biri farklı bir tür bağımsız değişkeni kullanılarak oluşturulan herhangi bir sayıda oluşturulmuş tür
örneği oluşturulabilir:

GenericList<float> list1 = new GenericList<float>();


GenericList<ExampleClass> list2 = new GenericList<ExampleClass>();
GenericList<ExampleStruct> list3 = new GenericList<ExampleStruct>();

Bu GenericList<T> örneklerinin her birinde, sınıfındaki T her bir örneği, tür bağımsız değişkeniyle çalışma
zamanında değiştirilir. Bu değiştirme yoluyla, tek bir sınıf tanımı kullanarak üç ayrı tür güvenli ve verimli nesne
oluşturduk. Bu değiştirmenin CLR tarafından nasıl gerçekleştirildiği hakkında daha fazla bilgi için bkz. çalışma
zamanındaki genel türler.

Tür parametresi adlandırma yönergeleri


Genel tür parametrelerini açıklayıcı adlarla adlandırın, tek bir harf adı tamamen kendi kendine açıklayıcı
olamaz ve açıklayıcı bir ad değer eklemez.

public interface ISessionChannel<TSession> { /*...*/ }


public delegate TOutput Converter<TInput, TOutput>(TInput from);
public class List<T> { /*...*/ }

Tek bir harf türü parametresine sahip türler için tür parametre adı olarak T kullanmayı düşünün .

public int IComparer<T>() { return 0; }


public delegate bool Predicate<T>(T item);
public struct Nullable<T> where T : struct { /*...*/ }

Önek açıklayıcı tür parametre adlarını "T" ile yapın .

public interface ISessionChannel<TSession>


{
TSession Session { get; }
}

Parametre adındaki bir tür parametresine yerleştirilmiş olan kısıtlamaları belirtmeyi düşünün . Örneğin,
ISession kısıtlanmış bir parametre TSession çağrılabilir.

Kod Analizi kuralı CA1715 , tür parametrelerinin uygun şekilde adlandırılmış olduğundan emin olmak için
kullanılabilir.

Ayrıca bkz.
System.Collections.Generic
C# Programlama Kılavuzu
Genel Türler
C++ Şablonları ve C# Genel Türleri Arasındaki Farklar
Tür Parametrelerindeki Kısıtlamalar (C#
Programlama Kılavuzu)
27.11.2019 • 14 minutes to read • Edit Online

Kısıtlamalar, derleyicisini bir tür bağımsız değişkeni olması gereken yetenekler hakkında bilgilendirir. Herhangi
bir kısıtlama olmadan tür bağımsız değişkeni herhangi bir tür olabilir. Derleyici yalnızca, tüm .NET türleri için en
son temel sınıf olan System.Objectüyelerini kabul edebilir. Daha fazla bilgi için bkz. kısıtlamaların neden
kullanılması. İstemci kodu bir kısıtlama tarafından izin verilmeyen bir tür kullanarak sınıfınızın örneğini
oluşturmaya çalışırsa, sonuç derleme zamanı hatasıdır. Kısıtlamalar where bağlamsal anahtar sözcüğü
kullanılarak belirtilir. Aşağıdaki tabloda yedi tür kısıtlama listelenmektedir:

KISITLAMASI AÇIKLAMA

where T : struct Tür bağımsız değişkeni null yapılamayan bir değer türü
olmalıdır. Nullable değer türleri hakkında daha fazla bilgi için
bkz. Nullable değer türleri. Tüm değer türlerinde erişilebilir
parametresiz bir Oluşturucu olduğundan, struct kısıtlaması
new() kısıtlamasını gösterir ve new() kısıtlaması ile
birleştirilemez. Ayrıca struct kısıtlamasını unmanaged
kısıtlamasıyla birleştiremezsiniz.

where T : class Tür bağımsız değişkeni bir başvuru türü olmalıdır. Bu


kısıtlama, her sınıf, arabirim, temsilci veya dizi türü için de
geçerlidir.

where T : notnull Tür bağımsız değişkeni null yapılamayan bir tür olmalıdır.
Bağımsız değişken, C# 8,0 veya sonraki bir sürümde null
atanamaz bir başvuru türü veya null yapılamayan bir değer
türü olabilir. Bu kısıtlama, her sınıf, arabirim, temsilci veya dizi
türü için de geçerlidir.

where T : unmanaged Tür bağımsız değişkeni null atanamaz bir yönetilmeyen


türolmalıdır. unmanaged kısıtlaması struct kısıtlamasını
gösterir ve struct ya da new() kısıtlamalarıyla
birleştirilemez.

where T : new() Tür bağımsız değişkeni Ortak parametresiz bir oluşturucuya


sahip olmalıdır. Diğer kısıtlamalarla birlikte kullanıldığında,
new() kısıtlamasının en son belirtilmesi gerekir. new()
kısıtlaması struct ve unmanaged kısıtlamalarıyla
birleştirilemez.

where T : <temel sınıf adı > Tür bağımsız değişkeni belirtilen temel sınıftan olmalıdır veya
türetilmelidir.

where T : <arabirimi adı > Tür bağımsız değişkeni belirtilen arabirimi içermelidir veya
uygulamalıdır. Birden çok arabirim kısıtlaması belirlenebilir.
Kısıtlama arabirimi de genel olabilir.

where T : U T için sağlanan tür bağımsız değişkeni U için sağlanan


bağımsız değişkenden türetilmiş veya türemelidir.
Neden kısıtlama kullanılmalıdır
Tür parametresini kısıtlayan, izin verilen işlem ve metot çağrılarının sayısını kısıtlayan türü tarafından
desteklenenlere ve devralma hiyerarşisindeki tüm türlere göre artırırsınız. Genel sınıfları veya yöntemleri
tasarlarken, Genel Üyeler üzerinde basit atama veya System.Objecttarafından desteklenmeyen yöntemler
çağırma durumunda herhangi bir işlem gerçekleştiriyorsunuz, tür parametresine kısıtlamalar uygulamanız
gerekir. Örneğin, temel sınıf kısıtlaması derleyiciye yalnızca bu türden veya bu türden türetilmiş nesnelerin tür
bağımsız değişkenleri olarak kullanılacağını söyler. Derleyiciye bu garanti verildikten sonra, genel sınıfta bu tür
yöntemlerin çağrılmasına izin verebilir. Aşağıdaki kod örneği, bir temel sınıf kısıtlaması uygulayarak
GenericList<T> sınıfına ekleyebileceğiniz işlevselliği gösterir ( Genel türlere girişolarak).
public class Employee
{
public Employee(string s, int i) => (Name, ID) = (s, i);
public string Name { get; set; }
public int ID { get; set; }
}

public class GenericList<T> where T : Employee


{
private class Node
{
public Node(T t) => (Next, Data) = (null, t);

public Node Next { get; set; }


public T Data { get; set; }
}

private Node head;

public void AddHead(T t)


{
Node n = new Node(t) { Next = head };
head = n;
}

public IEnumerator<T> GetEnumerator()


{
Node current = head;

while (current != null)


{
yield return current.Data;
current = current.Next;
}
}

public T FindFirstOccurrence(string s)
{
Node current = head;
T t = null;

while (current != null)


{
//The constraint enables access to the Name property.
if (current.Data.Name == s)
{
t = current.Data;
break;
}
else
{
current = current.Next;
}
}
return t;
}
}

Kısıtlama, genel sınıfın Employee.Name özelliğini kullanmasını sağlar. Kısıtlama, T türündeki tüm öğelerin
Employee bir nesne veya Employee devralan bir nesne olduğunu belirtir.

Aynı tür parametresine birden çok kısıtlama uygulanabilir ve kısıtlamalar aşağıdaki gibi genel türler olabilir:
class EmployeeList<T> where T : Employee, IEmployee, System.IComparable<T>, new()
{
// ...
}

where T : class kısıtlaması uygulanırken, tür parametresindeki == ve != işleçlerden kaçının, çünkü bu işleçler
yalnızca başvuru kimliğini test edecek, değer eşitlik için değil. Bu davranış, bu işleçler bağımsız değişken olarak
kullanılan bir türde aşırı yüklense bile oluşur. Aşağıdaki kod bu noktayı gösterir; String sınıfı == işlecini aşırı
yüklese de çıkış yanlış olur.

public static void OpEqualsTest<T>(T s, T t) where T : class


{
System.Console.WriteLine(s == t);
}
private static void TestStringEquality()
{
string s1 = "target";
System.Text.StringBuilder sb = new System.Text.StringBuilder("target");
string s2 = sb.ToString();
OpEqualsTest<string>(s1, s2);
}

Derleyici, derleme zamanında T bir başvuru türü olduğunu ve tüm başvuru türleri için geçerli olan varsayılan
işleçleri kullanması gerektiğini bilir. Değer eşitlik için test etmeniz gerekiyorsa, önerilen yol
where T : IEquatable<T> veya where T : IComparable<T> kısıtlamasını de uygulamak ve arayüzü genel sınıfı
oluşturmak için kullanılacak herhangi bir sınıfa uygulamaktır.

Birden çok parametreyi kısıtlama


Aşağıdaki örnekte gösterildiği gibi birden çok parametreye kısıtlama uygulayabilir ve tek bir parametreye birden
çok kısıtlama uygulayabilirsiniz:

class Base { }
class Test<T, U>
where U : struct
where T : Base, new()
{ }

Sınırlandırılmamış tür parametreleri


Ortak sınıf SampleClass<T>{} gibi hiçbir kısıtlaması olmayan tür parametrelerine, sınırlandırılmamış tür
parametreleri denir. Sınırlandırılmamış tür parametreleri aşağıdaki kurallara sahiptir:
Somut tür bağımsız değişkeninin bu işleçleri destekleyeceği garantisi olmadığından != ve == işleçleri
kullanılamıyor.
Bunlara veya System.Object dönüştürülebilir ya da açıkça herhangi bir arabirim türüne dönüştürülebilir.
Bunları nullile karşılaştırabilirsiniz. Sınırlandırılmamış bir parametre null ile karşılaştırıldığında, tür bağımsız
değişkeni bir değer türündeyse karşılaştırma her zaman false döndürür.

Parametreleri kısıtlamalar olarak yazın


Genel tür parametresinin bir kısıtlama olarak kullanılması, aşağıdaki örnekte gösterildiği gibi, kendi tür
parametresine sahip bir üye işlevi bu parametreyi kapsayan türün tür parametresiyle kısıtlamak için yararlıdır:
public class List<T>
{
public void Add<U>(List<U> items) where U : T {/*...*/}
}

Önceki örnekte T , Add yönteminin bağlamındaki bir tür kısıtlamasıdır ve List sınıfının bağlamında sınırsız bir
tür parametresi olur.
Tür parametreleri, genel sınıf tanımlarında kısıtlama olarak da kullanılabilir. Tür parametresi, diğer tür
parametreleriyle birlikte açılı ayraç içinde bildirilmelidir:

//Type parameter V is used as a type constraint.


public class SampleClass<T, U, V> where T : V { }

Derleyici tür parametresi hakkında hiçbir şey System.Object türetilmediği hariç, genel sınıflarla kısıtlamalar
olarak tür parametrelerinin kullanışlılığı sınırlıdır. Tür parametrelerini, iki tür parametresi arasında bir devralma
ilişkisi uygulamak istediğiniz senaryolarda genel sınıflarda kısıtlamalar olarak kullanın.

NotNull kısıtlaması
8,0 ile C# başlayarak, tür bağımsız değişkeninin null yapılamayan bir değer türü veya null yapılamayan bir
başvuru türü olması gerektiğini belirtmek için notnull kısıtlamasını kullanabilirsiniz. notnull kısıtlaması
yalnızca bir nullable enable bağlamında kullanılabilir. notnull kısıtlamasını null yapılabilir bir zorunluluvou
bağlamına eklerseniz derleyici bir uyarı oluşturur.
Diğer kısıtlamaların aksine, bir tür bağımsız değişkeni notnull kısıtlamasını ihlal ettiğinde, bu kod bir
nullable enable bağlamında derlenirse derleyici bir uyarı oluşturur. Kod, null yapılabilir bir zorunluluvou
bağlamında derlenmişse, derleyici hiçbir uyarı veya hata oluşturmaz.

Yönetilmeyen kısıtlama
7,3 ile C# başlayarak, tür parametresinin null atanamaz yönetilmeyen bir türolması gerektiğini belirtmek için
unmanaged kısıtlamasını kullanabilirsiniz. unmanaged kısıtlaması, aşağıdaki örnekte gösterildiği gibi, bellek
blokları olarak işlenebilen türlerle çalışmak için yeniden kullanılabilir yordamlar yazmanızı sağlar:

unsafe public static byte[] ToByteArray<T>(this T argument) where T : unmanaged


{
var size = sizeof(T);
var result = new Byte[size];
Byte* p = (byte*)&argument;
for (var i = 0; i < size; i++)
result[i] = *p++;
return result;
}

Yukarıdaki yöntemin, yerleşik tür olarak bilinen bir tür üzerinde sizeof işlecini kullandığından unsafe
bağlamda derlenmesi gerekir. unmanaged kısıtlaması olmadan sizeof işleci kullanılamaz.
unmanaged kısıtlaması struct kısıtlamasını gösterir ve onunla birleştirilemez. struct kısıtlaması new()
kısıtlamasını gösterdiği için unmanaged kısıtlaması de new() kısıtlaması ile birleştirilemez.

Temsilci kısıtlamaları
Ayrıca, 7,3 C# ile başlayarak temel sınıf kısıtlaması olarak System.Delegate veya System.MulticastDelegate
kullanabilirsiniz. CLR bu kısıtlamaya her zaman izin verilir, ancak C# dil izin vermez. System.Delegate kısıtlaması,
temsilcilerle birlikte, tür açısından güvenli bir şekilde sorunsuz kod yazmanıza olanak sağlar. Aşağıdaki kod, iki
temsilciyi aynı tür olduklarından birleştiren bir genişletme yöntemi tanımlar:

public static TDelegate TypeSafeCombine<TDelegate>(this TDelegate source, TDelegate target)


where TDelegate : System.Delegate
=> Delegate.Combine(source, target) as TDelegate;

Aynı türdeki temsilcileri birleştirmek için yukarıdaki yöntemi kullanabilirsiniz:

Action first = () => Console.WriteLine("this");


Action second = () => Console.WriteLine("that");

var combined = first.TypeSafeCombine(second);


combined();

Func<bool> test = () => true;


// Combine signature ensures combined delegates must
// have the same type.
//var badCombined = first.TypeSafeCombine(test);

Son satırın açıklamasını kaldırırsanız, derlenmez. Hem first hem de test temsilci türleridir, ancak farklı
temsilci türleridir.

Sabit listesi kısıtlamaları


C# 7,3 ' den başlayarak, System.Enum türünü temel sınıf kısıtlaması olarak da belirtebilirsiniz. CLR bu
kısıtlamaya her zaman izin verilir, ancak C# dil izin vermez. System.Enum kullanan genel türler, System.Enum statik
yöntemlerin kullanılmasıyla sonuçları önbelleğe almak için tür kullanımı uyumlu programlama sağlar. Aşağıdaki
örnek, bir sabit listesi türü için geçerli tüm değerleri bulur ve sonra bu değerleri dize gösterimiyle eşleyen bir
sözlük oluşturur.

public static Dictionary<int, string> EnumNamedValues<T>() where T : System.Enum


{
var result = new Dictionary<int, string>();
var values = Enum.GetValues(typeof(T));

foreach (int item in values)


result.Add(item, Enum.GetName(typeof(T), item));
return result;
}

Kullanılan yöntemler, performans etkilerine sahip olan yansıma kullanımını kullanır.Bu yöntemi, yansıma
gerektiren çağrıları yinelemek yerine önbelleğe alınmış ve yeniden kullanılan bir koleksiyon oluşturmak için
çağırabilirsiniz.
Aşağıdaki örnekte gösterildiği gibi, bir sabit listesi oluşturmak ve değerlerini ve adlarını bir sözlüğü oluşturmak
için kullanabilirsiniz:
enum Rainbow
{
Red,
Orange,
Yellow,
Green,
Blue,
Indigo,
Violet
}

var map = EnumNamedValues<Rainbow>();

foreach (var pair in map)


Console.WriteLine($"{pair.Key}:\t{pair.Value}");

Ayrıca bkz.
System.Collections.Generic
C# Programlama Kılavuzu
Genel Türlere Giriş
Genel Sınıflar
new Kısıtlaması
Genel Sınıflar (C# Programlama Kılavuzu)
23.10.2019 • 6 minutes to read • Edit Online

Genel sınıflar, belirli bir veri türüne özgü olmayan işlemleri kapsültir.Genel sınıflar için en yaygın kullanım,
bağlantılı listeler, karma tablolar, yığınlar, kuyruklar, ağaçlar vb. gibi koleksiyonlardır. Koleksiyondan öğe ekleme ve
kaldırma gibi işlemler, depolanan verilerin türüne bakılmaksızın temelde aynı şekilde gerçekleştirilir.
Koleksiyon sınıfları gerektiren çoğu senaryo için önerilen yaklaşım, .NET sınıf kitaplığı 'nda sağlananları
kullanmaktır. Bu sınıfların kullanımı hakkında daha fazla bilgi için bkz. .net 'Teki genel Koleksiyonlar.
Genellikle, mevcut bir somut sınıfla başlayarak genel sınıflar oluşturur ve en iyi Genelleştirme ve kullanılabilirlik
bakiyesine ulaşana kadar, türleri tek seferde tür parametrelerine değiştirerek. Kendi genel sınıflarınızı oluştururken,
önemli noktalara şunlar dahildir:
Tür parametrelerine genelleştiriedilecek türler.
Kural olarak, ne kadar çok tür parametreleştirebilirsiniz, kodunuzun daha esnek ve yeniden kullanılabilir
hale gelmesi de olur. Ancak, çok fazla Genelleştirme, diğer geliştiricilerin okuması veya anlaşılması zor olan
kodlar oluşturabilir.
Varsa tür parametrelerine uygulanacak kısıtlamalar (bkz. tür parametrelerine yönelik kısıtlamalar).
İşlenmesi gereken türleri işleyebilmeniz için mümkün olan en yüksek kısıtlamaları uygulamak iyi bir
kuraldır. Örneğin, genel sınıfınızın yalnızca başvuru türleriyle kullanılması amaçlandığını biliyorsanız, sınıf
kısıtlamasını uygulayın. Bu, sınıfınızın değer türleriyle istenmeden kullanımını engeller ve üzerinde as T
işlecini kullanmanıza olanak sağlar ve null değerler olup olmadığını kontrol eder.
Genel davranışın temel sınıflar ve alt sınıflara göre çarpanının yapılıp yapılmayacağını belirtir.
Genel sınıflar temel sınıf olarak işlev sağladığından, genel olmayan sınıflarda olduğu gibi aynı tasarım
konuları da geçerlidir. Bu konunun ilerleyen kısımlarında genel temel sınıflardan devralma kurallarını
inceleyin.
Bir veya daha fazla genel arabirim uygulanıp etkinleştirilmeyeceğini belirtir.
Örneğin, genel türler tabanlı bir koleksiyonda öğe oluşturmak için kullanılacak bir sınıf tasarlıyorsanız,
sınıfınızın türü olduğu gibi bir arabirim IComparable<T> T uygulamanız gerekebilir.
Basit bir genel sınıf örneği için bkz. Genel türlere giriş.
Tür parametreleri ve kısıtlamaları için kurallar, özellikle devralma ve üye erişilebilirliği ile ilgili genel sınıf davranışı
için çeşitli etkilere sahiptir. Devam etmeden önce bazı terimleri anlamanız gerekir. Bir genel sınıf Node<T>, istemci
kodu için, bir tür bağımsız değişkeni belirterek, kapalı bir oluşturulmuş tür ( Node<int> ) oluşturmak üzere sınıfına
başvurabilir. Alternatif olarak, tür parametresi belirtilmemiş olabilir, örneğin, bir genel temel sınıf belirttiğinizde
açık bir oluşturulan tür ( Node<T> ) oluşturabilirsiniz. Genel sınıflar somut, Kapalı oluşturulmuş veya açık
oluşturulmuş temel sınıflardan kalýtýmla alabilir:
class BaseNode { }
class BaseNodeGeneric<T> { }

// concrete type
class NodeConcrete<T> : BaseNode { }

//closed constructed type


class NodeClosed<T> : BaseNodeGeneric<int> { }

//open constructed type


class NodeOpen<T> : BaseNodeGeneric<T> { }

Genel olmayan, diğer bir deyişle, somut, sınıflar, açık oluşturulmuş sınıflardan veya tür parametrelerinden
devralınabilir, çünkü bu durum, istemci kodu için çalışma zamanında, temel sınıf.

//No error
class Node1 : BaseNodeGeneric<int> { }

//Generates an error
//class Node2 : BaseNodeGeneric<T> {}

//Generates an error
//class Node3 : T {}

Açık oluşturulmuş türlerden devralan genel sınıflar, aşağıdaki kodda gösterildiği gibi, devralan sınıf tarafından
paylaşılmayan herhangi bir temel sınıf türü parametre için tür bağımsız değişkenleri sağlamalıdır:

class BaseNodeMultiple<T, U> { }

//No error
class Node4<T> : BaseNodeMultiple<T, int> { }

//No error
class Node5<T, U> : BaseNodeMultiple<T, U> { }

//Generates an error
//class Node6<T> : BaseNodeMultiple<T, U> {}

Açık oluşturulmuş türlerden devraldığı genel sınıflar, temel türdeki kısıtlamaların bir üst kümesi veya sayısı olan
kısıtlamaları belirtmelidir:

class NodeItem<T> where T : System.IComparable<T>, new() { }


class SpecialNodeItem<T> : NodeItem<T> where T : System.IComparable<T>, new() { }

Genel türler, birden çok tür parametrelerini ve kısıtlamalarını şu şekilde kullanabilir:

class SuperKeyType<K, V, U>


where U : System.IComparable<U>
where V : new()
{ }

Açık oluşturulmuş ve kapalı oluşturulmuş türler, yöntem parametreleri olarak kullanılabilir:


void Swap<T>(List<T> list1, List<T> list2)
{
//code to swap items
}

void Swap(List<int> list1, List<int> list2)


{
//code to swap items
}

Bir genel sınıf bir arabirim uygularsa, bu sınıfın tüm örnekleri bu arabirime eklenebilir.
Genel sınıflar sabit. Diğer bir deyişle, bir giriş parametresi bir List<BaseClass> belirtiyorsa, List<DerivedClass>
sağlamaya çalışırsanız derleme zamanı hatası alırsınız.

Ayrıca bkz.
System.Collections.Generic
C# Programlama Kılavuzu
Genel Türler
Numaralandırıcıların durumunu kaydetme
Devralma bulmaca, birinci bölüm
Genel Arabirimler (C# Programlama Kılavuzu)
23.10.2019 • 5 minutes to read • Edit Online

Genel koleksiyon sınıfları için ya da koleksiyondaki öğeleri temsil eden genel sınıflar için arabirim tanımlamak
genellikle yararlıdır. Genel sınıfların tercihi, değer türlerinde kutulamayı ve kutudan çıkarma işlemlerini önlemek
IComparable<T> için IComparableyerine gibi genel arabirimleri kullanmaktır. .NET Framework sınıf kitaplığı,
System.Collections.Generic ad alanındaki koleksiyon sınıflarıyla kullanılmak üzere birkaç genel arabirimi tanımlar.
Bir arabirim bir tür parametresinde kısıtlama olarak belirtildiğinde, yalnızca arabirimini uygulayan türler
kullanılabilir. Aşağıdaki kod örneğinde GenericList<T> sınıfından türetilen bir SortedList<T> sınıf
gösterilmektedir. Daha fazla bilgi için bkz. Genel türlere giriş. SortedList<T> kısıtlamayı where T : IComparable<T>
ekler. Bu, BubbleSort içindeki SortedList<T> yönteminin List öğelerinde genel CompareTo yöntemini
kullanmasına olanak sağlar. Bu örnekte, liste öğeleri, uygulayan Person IComparable<Person> basit bir sınıftır.

//Type parameter T in angle brackets.


public class GenericList<T> : System.Collections.Generic.IEnumerable<T>
{
protected Node head;
protected Node current = null;

// Nested class is also generic on T


protected class Node
{
public Node next;
private T data; //T as private member datatype

public Node(T t) //T used in non-generic constructor


{
next = null;
data = t;
}

public Node Next


{
get { return next; }
set { next = value; }
}

public T Data //T as return type of property


{
get { return data; }
set { data = value; }
}
}

public GenericList() //constructor


{
head = null;
}

public void AddHead(T t) //T as method parameter type


{
Node n = new Node(t);
n.Next = head;
head = n;
}

// Implementation of the iterator


public System.Collections.Generic.IEnumerator<T> GetEnumerator()
{
{
Node current = head;
while (current != null)
{
yield return current.Data;
current = current.Next;
}
}

// IEnumerable<T> inherits from IEnumerable, therefore this class


// must implement both the generic and non-generic versions of
// GetEnumerator. In most cases, the non-generic method can
// simply call the generic method.
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}

public class SortedList<T> : GenericList<T> where T : System.IComparable<T>


{
// A simple, unoptimized sort algorithm that
// orders list elements from lowest to highest:

public void BubbleSort()


{
if (null == head || null == head.Next)
{
return;
}
bool swapped;

do
{
Node previous = null;
Node current = head;
swapped = false;

while (current.next != null)


{
// Because we need to call this method, the SortedList
// class is constrained on IEnumerable<T>
if (current.Data.CompareTo(current.next.Data) > 0)
{
Node tmp = current.next;
current.next = current.next.next;
tmp.next = current;

if (previous == null)
{
head = tmp;
}
else
{
previous.next = tmp;
}
previous = tmp;
swapped = true;
}
else
{
previous = current;
current = current.next;
}
}
} while (swapped);
}
}

// A simple class that implements IComparable<T> using itself as the


// A simple class that implements IComparable<T> using itself as the
// type argument. This is a common design pattern in objects that
// are stored in generic lists.
public class Person : System.IComparable<Person>
{
string name;
int age;

public Person(string s, int i)


{
name = s;
age = i;
}

// This will cause list elements to be sorted on age values.


public int CompareTo(Person p)
{
return age - p.age;
}

public override string ToString()


{
return name + ":" + age;
}

// Must implement Equals.


public bool Equals(Person p)
{
return (this.age == p.age);
}
}

class Program
{
static void Main()
{
//Declare and instantiate a new generic SortedList class.
//Person is the type argument.
SortedList<Person> list = new SortedList<Person>();

//Create name and age values to initialize Person objects.


string[] names = new string[]
{
"Franscoise",
"Bill",
"Li",
"Sandra",
"Gunnar",
"Alok",
"Hiroyuki",
"Maria",
"Alessandro",
"Raul"
};

int[] ages = new int[] { 45, 19, 28, 23, 18, 9, 108, 72, 30, 35 };

//Populate the list.


for (int x = 0; x < 10; x++)
{
list.AddHead(new Person(names[x], ages[x]));
}

//Print out unsorted list.


foreach (Person p in list)
{
System.Console.WriteLine(p.ToString());
}
System.Console.WriteLine("Done with unsorted list");
//Sort the list.
list.BubbleSort();

//Print out sorted list.


foreach (Person p in list)
{
System.Console.WriteLine(p.ToString());
}
System.Console.WriteLine("Done with sorted list");
}
}

Birden çok arabirim, tek bir tür üzerinde kısıtlamalar olarak belirtilebilir ve aşağıdaki gibi:

class Stack<T> where T : System.IComparable<T>, IEnumerable<T>


{
}

Bir arabirim, aşağıdaki gibi birden fazla tür parametresi tanımlayabilir:

interface IDictionary<K, V>


{
}

Sınıflar için uygulanan devralma kuralları arabirimler için de geçerlidir:

interface IMonth<T> { }

interface IJanuary : IMonth<int> { } //No error


interface IFebruary<T> : IMonth<int> { } //No error
interface IMarch<T> : IMonth<T> { } //No error
//interface IApril<T> : IMonth<T, U> {} //Error

Genel arabirim değişken karşıtı ise genel arabirimler, genel olmayan arabirimlerden devralınabilir, bu da yalnızca
kendi tür parametresini dönüş değeri olarak kullanır. IEnumerable<T> .NET Framework sınıf kitaplığında
öğesinden IEnumerable devralır çünkü IEnumerable<T> yalnızca öğesinin T GetEnumerator dönüş değerinde ve
Current özellik alıcısı içinde kullanılır.
Somut sınıflar, aşağıdaki gibi kapalı oluşturulmuş arabirimler uygulayabilir:

interface IBaseInterface<T> { }

class SampleClass : IBaseInterface<string> { }

Genel sınıflar, sınıf parametresi listesi arabirimin gerektirdiği tüm bağımsız değişkenleri aşağıdaki şekilde sağladığı
sürece genel arabirimleri veya kapalı oluşturulmuş arabirimleri uygulayabilir:

interface IBaseInterface1<T> { }
interface IBaseInterface2<T, U> { }

class SampleClass1<T> : IBaseInterface1<T> { } //No error


class SampleClass2<T> : IBaseInterface2<T, string> { } //No error

Yöntem aşırı yüklemesini denetleyen kurallar, genel sınıflar, genel yapılar veya genel arabirimler içindeki yöntemler
için aynıdır. Daha fazla bilgi için bkz. Genel yöntemler.
Ayrıca bkz.
C# Programlama Kılavuzu
Genel Türlere Giriş
interface
Genel Türler
Genel Yöntemler (C# Programlama Kılavuzu)
23.10.2019 • 3 minutes to read • Edit Online

Genel bir yöntem, tür parametreleriyle belirtilen ve aşağıdaki gibi bir yöntemdir:

static void Swap<T>(ref T lhs, ref T rhs)


{
T temp;
temp = lhs;
lhs = rhs;
rhs = temp;
}

Aşağıdaki kod örneği, tür bağımsız değişkeni için kullanarak int yöntemini çağırmak için bir yol gösterir:

public static void TestSwap()


{
int a = 1;
int b = 2;

Swap<int>(ref a, ref b);


System.Console.WriteLine(a + " " + b);
}

Ayrıca tür bağımsız değişkenini de atlayabilirsiniz, derleyici onu çıkaracaktır. Aşağıdaki çağrısı Swap , önceki
çağrıya eşdeğerdir:

Swap(ref a, ref b);

Tür çıkarımı için aynı kurallar statik yöntemler ve örnek yöntemler için geçerlidir. Derleyici, tür parametrelerini
geçirdiğiniz Yöntem bağımsız değişkenlerine göre çıkarabilir; tür parametreleri yalnızca bir kısıtlamadan veya
dönüş değerinden çıkarılamaz. Bu nedenle tür çıkarımı parametresi olmayan yöntemlerle çalışmaz. Derleyici aşırı
yüklenmiş yöntem imzalarını çözmeyi denemeden önce derleme zamanında tür çıkarımı oluşur. Derleyici, aynı adı
paylaşan tüm genel metotlara tür çıkarımı mantığını uygular. Aşırı yükleme çözümleme adımında, derleyici
yalnızca tür çıkarımı başarılı olan genel yöntemleri içerir.
Genel bir sınıf içinde genel olmayan yöntemler, sınıf düzeyi tür parametrelerine aşağıdaki gibi erişebilir:

class SampleClass<T>
{
void Swap(ref T lhs, ref T rhs) { }
}

İçerilen sınıfla aynı tür parametrelerini alan genel bir yöntem tanımlarsanız, derleyici yöntem kapsamı içinde uyarı
CS0693 oluşturur, iç T için sağlanan bağımsız değişken dıştaki için sağlanan bağımsız değişkeni gizler T . Sınıf
örneği oluşturulurken sağlananlara farklı tür bağımsız değişkenleriyle bir genel sınıf yöntemi çağırma esnekliğine
ihtiyaç duyuyorsanız, yöntemin tür parametresi için aşağıda gösterildiği GenericList2<T> gibi başka bir
tanımlayıcı sağlamayı düşünün örneğinde.
class GenericList<T>
{
// CS0693
void SampleMethod<T>() { }
}

class GenericList2<T>
{
//No warning
void SampleMethod<U>() { }
}

Yöntemlerde tür parametrelerinde daha özelleştirilmiş işlemleri sağlamak için kısıtlamaları kullanın. Artık
adlandırılan Swap<T> SwapIfGreater<T> bu sürümü yalnızca uygulayan IComparable<T>tür bağımsız
değişkenleriyle kullanılabilir.

void SwapIfGreater<T>(ref T lhs, ref T rhs) where T : System.IComparable<T>


{
T temp;
if (lhs.CompareTo(rhs) > 0)
{
temp = lhs;
lhs = rhs;
rhs = temp;
}
}

Genel metotlar çeşitli tür parametrelerinde aşırı yüklenebilir. Örneğin, aşağıdaki yöntemler aynı sınıfta bulunabilir:

void DoWork() { }
void DoWork<T>() { }
void DoWork<T, U>() { }

C# Dil Belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi.

Ayrıca bkz.
System.Collections.Generic
C# Programlama Kılavuzu
Genel Türlere Giriş
Yöntemler
Genel Türler ve Diziler (C# Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

2,0 C# ve üzeri sürümlerde, sıfır alt sınırı olan tek boyutlu diziler otomatik olarak uygulanır IList<T>. Bu, diziler ve
diğer koleksiyon türleri arasında yinelemek için aynı kodu kullanan genel yöntemler oluşturmanızı sağlar. Bu teknik
öncelikle koleksiyonlardaki verileri okumak için yararlıdır. IList<T> Arabirim bir diziye öğe eklemek veya kaldırmak
için kullanılamaz. Bu bağlamdaki bir dizide gibi IList<T> RemoveAt bir yöntemi çağırmaya çalışırsanız bir özel
durum oluşturulur.
Aşağıdaki kod örneği, bir IList<T> giriş parametresi alan tek bir genel yöntemin, bu durumda bir tamsayılar dizisi
olan bir liste ve dizi boyunca nasıl yineleyebileceğinizi göstermektedir.

class Program
{
static void Main()
{
int[] arr = { 0, 1, 2, 3, 4 };
List<int> list = new List<int>();

for (int x = 5; x < 10; x++)


{
list.Add(x);
}

ProcessItems<int>(arr);
ProcessItems<int>(list);
}

static void ProcessItems<T>(IList<T> coll)


{
// IsReadOnly returns True for the array and False for the List.
System.Console.WriteLine
("IsReadOnly returns {0} for this collection.",
coll.IsReadOnly);

// The following statement causes a run-time exception for the


// array, but not for the List.
//coll.RemoveAt(4);

foreach (T item in coll)


{
System.Console.Write(item.ToString() + " ");
}
System.Console.WriteLine();
}
}

Ayrıca bkz.
System.Collections.Generic
C# Programlama Kılavuzu
Genel Türler
Diziler
Genel Türler
Genel Temsilciler (C# Programlama Kılavuzu)
4.11.2019 • 2 minutes to read • Edit Online

Bir temsilci kendi tür parametrelerini tanımlayabilir. Genel temsilciye başvuran kod, aşağıdaki örnekte gösterildiği
gibi, bir genel sınıf örneği oluşturulurken veya genel bir yöntemi çağırırken olduğu gibi kapalı bir oluşturulmuş tür
oluşturmak için tür bağımsız değişkenini belirtebilir:

public delegate void Del<T>(T item);


public static void Notify(int i) { }

Del<int> m1 = new Del<int>(Notify);

C#sürüm 2,0 ' de, somut ve genel temsilci türleri için geçerli olan Yöntem grubu dönüştürmesi adlı yeni bir özellik
vardır ve bu Basitleştirilmiş söz dizimi ile önceki satırı yazmanızı sağlar:

Del<int> m2 = Notify;

Genel bir sınıf içinde tanımlanan temsilciler, sınıf yöntemlerinin olduğu şekilde genel sınıf türü parametrelerini
kullanabilir.

class Stack<T>
{
T[] items;
int index;

public delegate void StackDelegate(T[] items);


}

Temsilciye başvuran kodun, kapsayan sınıfın tür bağımsız değişkenini aşağıdaki gibi belirtmesi gerekir:

private static void DoWork(float[] items) { }

public static void TestStack()


{
Stack<float> s = new Stack<float>();
Stack<float>.StackDelegate d = DoWork;
}

Genel Temsilciler, genellikle gönderen bağımsız değişkeni kesin bir şekilde türlenebilir ve Object'ye ve bu tür bir
ve bundan sonra yayınlanmamalı.
delegate void StackEventHandler<T, U>(T sender, U eventArgs);

class Stack<T>
{
public class StackEventArgs : System.EventArgs { }
public event StackEventHandler<Stack<T>, StackEventArgs> stackEvent;

protected virtual void OnStackChanged(StackEventArgs a)


{
stackEvent(this, a);
}
}

class SampleClass
{
public void HandleStackChange<T>(Stack<T> stack, Stack<T>.StackEventArgs args) { }
}

public static void Test()


{
Stack<double> s = new Stack<double>();
SampleClass o = new SampleClass();
s.stackEvent += o.HandleStackChange;
}

Ayrıca bkz.
System.Collections.Generic
C# Programlama Kılavuzu
Genel Türlere Giriş
Genel Yöntemler
Genel Sınıflar
Genel Arabirimler
Temsilciler
Genel Türler
C++ Şablonları ve C# Genel Türleri Arasındaki Farklar
(C# Programlama Kılavuzu)
23.10.2019 • 3 minutes to read • Edit Online

C#Genel türler C++ ve şablonlar, parametreli türler için destek sağlayan dil özellikleridir.Ancak, ikisi arasında
birçok farklılık vardır. Sözdizimi düzeyinde, C# genel türler C++ şablonların karmaşıklığı olmadan parametreli
türlere daha basit bir yaklaşımdır. Ayrıca, C# C++ şablonların sağladığı tüm işlevleri sağlamayı denemez.
Uygulama düzeyinde, birincil farklılık, genel tür değişimlerin C# çalışma zamanında gerçekleştirildiği ve genel tür
bilgilerinin, bu nedenle örneklenmiş nesneler için korunmasıdır. Daha fazla bilgi için bkz. çalışma zamanındaki
genel türler.
Aşağıdakiler, genel türler ve C# C++ şablonlar arasındaki önemli farklardır:
C#Genel türler, C++ şablonlarla aynı esneklik miktarını sağlamaz. Örneğin, Kullanıcı tanımlı işleçleri
çağırmak mümkün olsa da, genel bir C# sınıfta aritmetik işleçleri çağırmak mümkün değildir.
C#, gibi tür olmayan şablon parametrelerine izin vermez template C<int i> {} .
C#Açık özelleştirmeyi desteklemez; diğer bir deyişle, belirli bir tür için bir şablonun özel bir uygulamasıdır.
C#Kısmi özelleştirmeyi desteklemez: tür bağımsız değişkenlerinin bir alt kümesi için özel bir uygulama.
C#tür parametresinin genel tür için temel sınıf olarak kullanılmasına izin vermez.
C#tür parametrelerinin varsayılan türleri olmasını sağlar.
İçinde C#, bir genel tür parametresi genel olamaz, ancak oluşturulan türler genel türler olarak kullanılabilir.
C++Şablon parametrelerine izin verir.
C++şablondaki tüm tür parametreleri için geçerli olmayan koda izin verir, daha sonra tür parametresi
olarak kullanılan belirli tür için denetlenir. C#, bir sınıftaki kodun, kısıtlamaları karşılayan herhangi bir türle
çalışacak şekilde yazılmasına gerek duyar. Örneğin, içinde C++ aritmetik işleçleri + ve - tür
parametresinin nesnelerini kullanan bir işlev yazmak mümkündür; Bu, bir türü olmayan bir tür ile şablon
örneği oluşturma sırasında bir hata oluşturur. Bu işleçleri destekler. C#Buna izin vermez; izin verilen tek dil
yapıları, kısıtlamalardan çıkarsanolabilecek olanlardır.

Ayrıca bkz.
C# Programlama Kılavuzu
Genel Türlere Giriş
Şablonlar
Çalışma Zamanındaki Genel Türler (C# Programlama
Kılavuzu)
23.10.2019 • 5 minutes to read • Edit Online

Genel bir tür veya yöntem Microsoft ara dil (MSIL ) içinde derlendiğinde, türü parametre varmış gibi tanımlayan
meta veriler içerir. Genel bir tür için MSIL, sağlanan tür parametresinin bir değer türü veya başvuru türü olup
olmadığına göre farklılık gösterir.
Bir genel tür öncelikle parametre olarak bir değer türü ile oluşturulduğunda, çalışma zamanı, MSIL 'de uygun
konumlarda bulunan sağlanan parametre veya parametrelerle birlikte özel genel bir tür oluşturur. Özel genel
türler parametre olarak kullanılan her benzersiz değer türü için bir kez oluşturulur.
Örneğin, program kodunuzun tamsayılar tarafından oluşturulan bir yığın olduğunu varsayalım:

Stack<int> stack;

Bu noktada çalışma zamanı, Stack<T> sınıfının parametresi için uygun tamsayının bulunduğu özelleşmiş bir
sürümünü oluşturur. Artık, program kodunuz bir tamsayılar yığını kullandığında, çalışma zamanı oluşturulan
özelleştirilmiş Stack<T> sınıfı yeniden kullanır. Aşağıdaki örnekte, bir tamsayı yığınının iki örneği oluşturulur ve
Stack<int> kodun tek bir örneğini paylaşır:

Stack<int> stackOne = new Stack<int>();


Stack<int> stackTwo = new Stack<int>();

Ancak, farklı bir değer Stack<T> türüne sahip başka bir sınıfın veya parametresi olarak bir long Kullanıcı tanımlı
yapı, kodunuzun başka bir noktada oluşturulduğunu varsayın. Sonuç olarak, çalışma zamanı genel türün başka
bir sürümünü oluşturur ve MSIL 'de uygun konumlarda long bir koyar. Her bir özel genel sınıf yerel olarak
değer türünü içerdiğinden dönüşümler artık gerekli değildir.
Genel türler, başvuru türleri için biraz farklı şekilde çalışır.Genel bir tür herhangi bir başvuru türüyle
oluşturulduğunda, çalışma zamanı MSIL içindeki parametrelerin yerine nesne başvuruları olan bir özel genel tür
oluşturur. Ardından, türü ne olursa olsun, parametre olarak bir başvuru türü ile oluşturulmuş bir tür her
başlatıldığında, çalışma zamanı, genel türün önceden oluşturulmuş özelleştirilmiş sürümünü yeniden kullanır.
Tüm başvurular aynı boyutta olduğundan bu mümkündür.
Örneğin, bir Customer sınıf Order ve sınıf olmak üzere iki başvuru türüne sahip olduğunuzu ve ayrıca bir
Customer tür yığını oluşturduğunuzu varsayalım:

class Customer { }
class Order { }

Stack<Customer> customers;

Bu noktada, çalışma zamanı, verilerin depolanması yerine daha sonra doldurulacak Stack<T> nesne başvurularını
depolayan sınıfın özelleşmiş bir sürümünü oluşturur. Bir sonraki kod satırının adında Order başka bir başvuru
türünün yığınını oluşturduğunu varsayalım:
Stack<Order> orders = new Stack<Order>();

Değer türlerinden farklı olarak, Stack<T> sınıfın başka bir özelleştirilmiş sürümü Order tür için oluşturulmaz.
Bunun yerine, Stack<T> sınıfının özelleşmiş sürümünün bir örneği oluşturulur orders ve değişken buna
başvuracak şekilde ayarlanır. Daha sonra bir Customer tür yığını oluşturmak için bir kod satırıyla karşılaşdığınızı
varsayalım:

customers = new Stack<Customer>();

Türü kullanılarak oluşturulan Stack<T> sınıfının önceki kullanımıyla birlikte, özel Stack<T> sınıfın başka bir
örneği oluşturulur. Order İçinde bulunan işaretçiler, bir Customer tür boyutunun bellek alanına başvuracak
şekilde ayarlanır. Başvuru türlerinin sayısı program 'dan programa kadar farklılık gösterebildiğinden, genel
türlerin C# uygulanması derleyici tarafından oluşturulan özelleştirilmiş sınıfların sayısını büyük ölçüde azaltır, bu
da genel başvuru sınıfları için türü.
Üstelik, bir genel C# sınıf bir değer türü veya başvuru türü parametresi kullanılarak örneği oluşturulduğunda,
yansıma çalışma zamanında ve hem gerçek türü hem de onun tür parametresi bunun olabilir.

Ayrıca bkz.
System.Collections.Generic
C# Programlama Kılavuzu
Genel Türlere Giriş
Genel Türler
Genel Türler ve Yansıma (C# Programlama Kılavuzu)
23.10.2019 • 4 minutes to read • Edit Online

Ortak dil çalışma zamanı (CLR ) çalışma zamanında genel tür bilgilerine erişime sahip olduğu için, genel türler
hakkında genel türler hakkında bilgi edinmek için yansımayı genel olmayan türler ile aynı şekilde elde edebilirsiniz.
Daha fazla bilgi için bkz. çalışma zamanındaki genel türler.
.NET Framework 2,0 ' de, genel türler için çalışma zamanı bilgilerini etkinleştirmek Type üzere sınıfa birkaç yeni
üye eklenir. Bu yöntemlerin ve özelliklerin nasıl kullanılacağı hakkında daha fazla bilgi için bu sınıfların belgelerine
bakın. Ad System.Reflection.Emit alanı Ayrıca, genel türleri destekleyen yeni üyeler içerir. Bkz . nasıl yapılır:
Yansıma yaymaIle genel bir tür tanımlayın.
Genel yansıma ' de kullanılan koşullara yönelik sabit koşulların bir listesi için, bkz IsGenericType . Özellik
açıklamaları.

SYSTEM. TYPE ÜYE ADI AÇIKLAMA

IsGenericType Bir tür genel ise true döndürür.

GetGenericArguments Oluşturulmuş bir tür için Type sağlanan tür bağımsız


değişkenlerini veya bir genel tür tanımının tür parametrelerini
temsil eden nesne dizisini döndürür.

GetGenericTypeDefinition Geçerli oluşturulmuş tür için temel alınan genel tür tanımını
döndürür.

GetGenericParameterConstraints Geçerli genel tür parametresindeki Type kısıtlamaları temsil


eden nesne dizisini döndürür.

ContainsGenericParameters Türü veya kapsayan türleri ya da metotlarından herhangi biri,


belirli türler sağlanmadığından tür parametreleri içeriyorsa
true değerini döndürür.

GenericParameterAttributes Geçerli genel tür parametresinin


GenericParameterAttributes özel kısıtlamalarını tanımlayan
bayrakların bir birleşimini alır.

GenericParameterPosition Bir tür Type parametresini temsil eden bir nesne için, tür
parametresinin konumunu, genel tür tanımının tür
parametresi listesinde veya tür parametresini tanımlayan
genel yöntem tanımının türü olarak alır.

IsGenericParameter Geçerli Type öğesinin bir genel tür veya yöntem tanımının
tür parametresini temsil ettiğini gösteren bir değer alır.

IsGenericTypeDefinition Geçerli Type öğesinin, diğer genel türlerin üzerinde


oluşturulabilecek genel bir tür tanımını temsil edip etmediğini
belirten bir değer alır. Tür genel bir türün tanımını temsil
ediyorsa, true döndürür.
SYSTEM. TYPE ÜYE ADI AÇIKLAMA

DeclaringMethod Geçerli genel tür parametresini tanımlayan genel yöntemi


veya tür parametresi genel bir yöntem tarafından
tanımlanmamışsa null değerini döndürür.

MakeGenericType Geçerli genel tür tanımının tür parametreleri için bir tür
dizisinin öğelerini değiştirir ve elde edilen oluşturulan türü
temsil eden bir Type nesne döndürür.

Ayrıca, MethodInfo sınıfının üyeleri, genel metotlar için çalışma zamanı bilgilerini etkinleştirir. Genel yöntemleri
yansıtmak için kullanılan koşullara yönelik sabit koşulların bir listesi için bkz. Özellikaçıklamaları.IsGenericMethod

SYSTEM. REFLECTION. MEMBERINFO ÜYE ADI AÇIKLAMA

IsGenericMethod Bir yöntem genel ise, true döndürür.

GetGenericArguments Oluşturulmuş bir genel metodun tür bağımsız değişkenlerini


veya bir genel yöntem tanımının tür parametrelerini temsil
eden nesne türünde bir dizi döndürür.

GetGenericMethodDefinition Geçerli oluşturulan yöntem için temeldeki genel yöntem


tanımını döndürür.

ContainsGenericParameters Yöntem veya kapsayan türlerinden herhangi biri, belirli türler


sağlanmadığından herhangi bir tür parametresi içeriyorsa true
değerini döndürür.

IsGenericMethodDefinition Geçerli MethodInfo bir genel yöntemin tanımını temsil


ediyorsa, true döndürür.

MakeGenericMethod Geçerli genel yöntem tanımının tür parametreleri için bir tür
dizisinin öğelerini değiştirir ve elde edilen oluşturulmuş
yöntemi temsil eden bir MethodInfo nesne döndürür.

Ayrıca bkz.
C# Programlama Kılavuzu
Genel Türler
Yansıma ve Genel Türler
Genel Türler
Genel Türler ve Öznitelikler (C# Programlama
Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Öznitelikler Genel türlere genel olmayan türlerle aynı şekilde uygulanabilir. Öznitelikleri uygulama hakkında daha
fazla bilgi için bkz. öznitelikler.
Özel özniteliklerin yalnızca tür bağımsız değişkenleri sağlanmayan genel türler ve tüm tür parametreleri için
bağımsız değişkenler sağlayan kapalı oluşturulmuş genel türler olan açık Genel türlere başvurmasına izin verilir.
Aşağıdaki örnekler bu özel özniteliği kullanır:

class CustomAttribute : System.Attribute


{
public System.Object info;
}

Bir öznitelik, açık bir genel türe başvurabilir:

public class GenericClass1<T> { }

[CustomAttribute(info = typeof(GenericClass1<>))]
class ClassA { }

Uygun sayıda virgül kullanarak birden çok tür parametresi belirtin. Bu örnekte, GenericClass2 iki tür parametresi
vardır:

public class GenericClass2<T, U> { }

[CustomAttribute(info = typeof(GenericClass2<,>))]
class ClassB { }

Bir öznitelik, Kapalı oluşturulmuş genel bir türe başvurabilir:

public class GenericClass3<T, U, V> { }

[CustomAttribute(info = typeof(GenericClass3<int, double, string>))]


class ClassC { }

Genel tür parametresine başvuran bir öznitelik, derleme zamanı hatasına neden olur:

//[CustomAttribute(info = typeof(GenericClass3<int, T, string>))] //Error


class ClassD<T> { }

Genel bir tür şuradan Attributedevralınabilir:

//public class CustomAtt<T> : System.Attribute {} //Error

Çalışma zamanında genel bir tür veya tür parametresi hakkında bilgi edinmek için, yöntemlerini
System.Reflectionkullanabilirsiniz. Daha fazla bilgi için bkz. Genel türler ve yansıma

Ayrıca bkz.
C# Programlama Kılavuzu
Genel Türler
Öznitelikler
Ad Alanları (C# Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Ad alanları, C# programlamada iki şekilde çok fazla kullanılır. İlk olarak .NET Framework, aşağıdaki gibi birçok
sınıfını düzenlemek için ad alanlarını kullanır:

System.Console.WriteLine("Hello World!");

System bir ad alanıdır ve Console bu ad alanındaki bir sınıftır. using Anahtar sözcüğü, aşağıdaki örnekte olduğu
gibi, tüm adı gerekli olmaması için kullanılabilir:

using System;

Console.WriteLine("Hello");
Console.WriteLine("World!");

Daha fazla bilgi için bkz. using yönergesi.


İkincisi, kendi ad alanlarınızı bildirmek daha büyük programlama projelerindeki sınıf ve yöntem adlarının
kapsamını denetlemenize yardımcı olabilir. Aşağıdaki örnekte olduğu gibi bir ad alanı bildirmek için Namespace
anahtar sözcüğünü kullanın:

namespace SampleNamespace
{
class SampleClass
{
public void SampleMethod()
{
System.Console.WriteLine(
"SampleMethod inside SampleNamespace");
}
}
}

Ad alanının adı geçerli C# bir tanımlayıcı adıolmalıdır.

Ad alanlarına genel bakış


Ad alanları aşağıdaki özelliklere sahiptir:
Büyük kod projelerini düzenler.
. İşleci kullanılarak sınırlandırılır.
using Yönergesi, her sınıf için ad alanının adını belirtmek için gereksinimi obviates.
Ad alanı "root" ad alanıdır: global::System her zaman .net System ad alanına başvurur. global

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin ad alanları bölümüne bakın.
Ayrıca bkz.
C# Programlama Kılavuzu
Ad Alanlarını Kullanma
Nasıl yapılır: My Namespace 'i kullanma
Tanımlayıcı adları
using Yönergesi
:: İşleç
Ad alanlarını kullanmaC# (Programlama Kılavuzu)
23.10.2019 • 6 minutes to read • Edit Online

Ad alanları programlar içinde C# yoğun olarak iki şekilde kullanılır. İlk olarak, .NET Framework sınıfları, birçok
sınıfını düzenlemek için ad alanlarını kullanır. İkinci olarak, kendi ad alanlarınızı bildirmek, sınıf ve yöntem
adlarının kapsamını daha büyük programlama projelerinde denetlemenize yardımcı olabilir.

Ad alanlarına erişme
Çoğu C# uygulama, using yönergelerin bir bölümüyle başlar. Bu bölüm, uygulamanın sıklıkla kullanacağı ad
alanlarını listeler ve içinde yer alan bir yöntemin kullanıldığı her seferinde her defasında tam nitelikli bir ad
belirtmekten tasarruf eder.
Örneğin, satırını dahil ederek:

using System;

Program başlangıcında, Programcı kodu kullanabilir:

Console.WriteLine("Hello, World!");

Onun yerine:

System.Console.WriteLine("Hello, World!");

Ad uzayı diğer adları


Bir ad alanı için bir diğer ad oluşturmak için using yönergesini de kullanabilirsiniz. Diğer ad alanının üyelerine
erişmek için ad alanı diğer :: adı niteleyicisi kullanın. Aşağıdaki örnek, bir ad alanı diğer adının nasıl
oluşturulduğunu ve kullanılacağını gösterir:
using generics = System.Collections.Generic;

namespace AliasExample
{
class TestClass
{
static void Main()
{
generics::Dictionary<string, int> dict = new generics::Dictionary<string, int>()
{
["A"] = 1,
["B"] = 2,
["C"] = 3
};

foreach (string name in dict.Keys)


{
System.Console.WriteLine($"{name} {dict[name]}");
}
// Output:
// A 1
// B 2
// C 3
}
}
}

Kapsamı denetlemek için ad alanlarını kullanma


namespace Anahtar sözcüğü bir kapsamı bildirmek için kullanılır. Projenizin içinde kapsam oluşturma özelliği,
kodun düzenlenmesine yardımcı olur ve küresel olarak benzersiz türler oluşturmanıza olanak sağlar. Aşağıdaki
örnekte, başlıklı SampleClass bir sınıf, diğeri içinde iç içe iki ad alanında tanımlanır. . Üye erişim işleci , hangi
yöntemin çağracağını ayırt etmek için kullanılır.
namespace SampleNamespace
{
class SampleClass
{
public void SampleMethod()
{
System.Console.WriteLine(
"SampleMethod inside SampleNamespace");
}
}

// Create a nested namespace, and define another class.


namespace NestedNamespace
{
class SampleClass
{
public void SampleMethod()
{
System.Console.WriteLine(
"SampleMethod inside NestedNamespace");
}
}
}

class Program
{
static void Main(string[] args)
{
// Displays "SampleMethod inside SampleNamespace."
SampleClass outer = new SampleClass();
outer.SampleMethod();

// Displays "SampleMethod inside SampleNamespace."


SampleNamespace.SampleClass outer2 = new SampleNamespace.SampleClass();
outer2.SampleMethod();

// Displays "SampleMethod inside NestedNamespace."


NestedNamespace.SampleClass inner = new NestedNamespace.SampleClass();
inner.SampleMethod();
}
}
}

Tam nitelikli adlar


Ad alanları ve türler, bir mantıksal hiyerarşiyi gösteren tam nitelikli adlarla tanımlanan benzersiz başlıklara sahiptir.
Örneğin, ifade A.B , ad alanının veya A türün adı olduğunu ve B içinde iç içe geçmiş olduğunu gösterir.
Aşağıdaki örnekte, iç içe geçmiş sınıflar ve ad alanları vardır. Tam nitelikli ad her bir varlıktan sonra bir yorum
olarak belirtilir.
namespace N1 // N1
{
class C1 // N1.C1
{
class C2 // N1.C1.C2
{
}
}
namespace N2 // N1.N2
{
class C2 // N1.N2.C2
{
}
}
}

Önceki kod segmentinde:


Ad alanı N1 , genel ad alanının bir üyesidir. Tam nitelikli adı N1 .
Ad alanı N2 bir N1 üyesidir. Tam nitelikli adı N1.N2 .
Sınıfı C1 öğesinin N1 üyesidir. Tam nitelikli adı N1.C1 .
Sınıf adı C2 Bu kodda iki kez kullanılır. Ancak, tam nitelikli adlar benzersizdir. İlk örneği C2 içinde C1 , bu
nedenle tam adı: N1.C1.C2 . İkinci örneği C2 bir ad alanı N2 içinde bildirilmiştir; bu nedenle tam adı ' dir
N1.N2.C2 .

Önceki kod segmentini kullanarak, ad alanına C3 N1.N2 yeni bir sınıf üyesini aşağıdaki şekilde ekleyebilirsiniz:

namespace N1.N2
{
class C3 // N1.N2.C3
{
}
}

Genel olarak, ad alanı diğer adına başvurmak için ad alanı diğer :: adı niteleyicisi global:: kullanın veya genel
ad alanına başvurmak . ve türleri veya üyeleri nitelemek için kullanın.
Ad alanı yerine bir türe başvuran :: diğer adla birlikte kullanılması hatadır. Örneğin:

using Alias = System.Console;

class TestClass
{
static void Main()
{
// Error
//Alias::WriteLine("Hi");

// OK
Alias.WriteLine("Hi");
}
}

Sözcüğün global önceden tanımlanmış bir diğer ad olmadığını unutmayın; bu nedenle, global.X özel bir anlamı
yoktur. Yalnızca ile :: kullanıldığında özel bir anlam elde edin.
Bir diğer ad değil genel ad alanına başvurduğu için, genel global:: adlı bir diğer ad tanımlarsanız derleyici uyarısı
CS0440 oluşturulur. Örneğin, aşağıdaki satır uyarı oluşturur:

using global = System.Collections; // Warning

Diğer :: adlarla kullanmak iyi bir fikirdir ve ek türlerin beklenmedik şekilde tanıtılmasıyla karşı koruma sağlar.
Örneğin, şu örneği göz önünde bulundurun:

using Alias = System;

namespace Library
{
public class C : Alias::Exception { }
}

Bu işe yarar, ancak adlandırılmış Alias bir tür daha sonra tanıtılmışsa, Alias. bunun yerine bu türe bağlanır.
Kullanmak Alias::Exception Alias , bir ad alanı diğer adı olarak değerlendirilip bir tür için hatalı alınmamasını
sağlar.

Ayrıca bkz.
C# Programlama Kılavuzu
Ad Alanları
. işlecinde
:: işleci
extern diğer adı
Nasıl yapılır: My Namespace (C# Programlama
Kılavuzu) kullanın
23.10.2019 • 2 minutes to read • Edit Online

Ad alanı ( My Visual Basic), bir dizi .NET Framework sınıfa kolay ve sezgisel erişim sağlar ve bu sayede bilgisayar,
uygulama, ayarlar, kaynaklar vb. ile etkileşimde bulunan bir kod yazmanıza olanak tanır.
Microsoft.VisualBasic.MyServices Başlangıçta Visual Basic ile kullanım için tasarlanmış olsa da, MyServices ad
alanı C# uygulamalarda kullanılabilir.
Visual Basic MyServices ad alanını kullanma hakkında daha fazla bilgi için, bkz. ile geliştirme.

Başvuru ekleme
Çözümünüzde MyServices sınıfları kullanabilmeniz için, Visual Basic kitaplığına bir başvuru eklemeniz gerekir.
Visual Basic kitaplığına bir başvuru eklemek için
1. Çözüm Gezgini, Başvurular düğümüne sağ tıklayın ve Başvuru Ekle' yi seçin.
2. Başvurular iletişim kutusu göründüğünde, listeyi aşağı kaydırın ve Microsoft. VisualBasic. dll ' i seçin.
Programınızın başlangıcında using bölümüne aşağıdaki satırı da eklemek isteyebilirsiniz.

using Microsoft.VisualBasic.Devices;

Örnek
Bu örnek, MyServices ad alanında bulunan çeşitli statik yöntemleri çağırır. Bu kodun derlenmesi için projeye
Microsoft. VisualBasic. DLL başvurusunun eklenmesi gerekir.
using System;
using Microsoft.VisualBasic.Devices;

class TestMyServices
{
static void Main()
{
// Play a sound with the Audio class:
Audio myAudio = new Audio();
Console.WriteLine("Playing sound...");
myAudio.Play(@"c:\WINDOWS\Media\chimes.wav");

// Display time information with the Clock class:


Clock myClock = new Clock();
Console.Write("Current day of the week: ");
Console.WriteLine(myClock.LocalTime.DayOfWeek);
Console.Write("Current date and time: ");
Console.WriteLine(myClock.LocalTime);

// Display machine information with the Computer class:


Computer myComputer = new Computer();
Console.WriteLine("Computer name: " + myComputer.Name);

if (myComputer.Network.IsAvailable)
{
Console.WriteLine("Computer is connected to network.");
}
else
{
Console.WriteLine("Computer is not connected to network.");
}
}
}

MyServices Ad alanındaki sınıfların tümü bir C# uygulamadan çağrılabilir: Örneğin, FileSystemProxy sınıfı
uyumlu değildir. Bu durumda, ' ın bir FileSystemparçası olan statik yöntemler bunun yerine VisualBasic. dll içinde
de kullanılabilir. Örneğin, bir dizini yinelemek için bu yöntemin nasıl kullanılacağı aşağıda verilmiştir:

// Duplicate a directory
Microsoft.VisualBasic.FileIO.FileSystem.CopyDirectory(
@"C:\original_directory",
@"C:\copy_of_original_directory");

Ayrıca bkz.
C# Programlama Kılavuzu
Ad Alanları
Ad Alanlarını Kullanma
Güvenli olmayan kod ve işaretçiler (C# Programlama
Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Tür güvenliği ve emniyeti korumak için C# işaretçi aritmetik, varsayılan olarak desteklemez. Kullanarak ancak
güvenli anahtar sözcüğü, işaretçileri kullanılabilecek güvenli olmayan bir bağlam tanımlayabilirsiniz. İşaretçiler
hakkında daha fazla bilgi için bkz. işaretçi türleri.

NOTE
Ortak dil çalışma zamanı (CLR), güvenli olmayan kod, doğrulanamayan kodu adlandırılır. C# güvenli olmayan kod tehlikeli
olmak zorunda değildir; Bu, güvenlik CLR tarafından doğrulanamıyor yalnızca kodudur. Tam olarak güvenilen bir derlemede
ise CLR bu nedenle güvenli olmayan kod yalnızca yürütülür. Güvenli olmayan kod kullanın, kodunuz güvenlik riskleri veya
işaretçi hataları sunmaz sağlamak sizin sorumluluğunuzdadır olur.

Güvenli olmayan koda genel bakış


Güvenli olmayan kod, aşağıdaki özelliklere sahiptir:
Yöntemleri, türleri ve kod blokları güvenli olarak tanımlanabilir.
Bazı durumlarda, güvenli olmayan kod dizi sınırları denetimleri kaldırarak bir uygulamanın performansı
artırabilir.
İşaretçileri gerektiren yerel işlevler çağırdığınızda, güvenli olmayan kod gereklidir.
Güvenli olmayan kod kullanarak güvenlik ve sağlamlık risklerini de beraberinde getirir.
Güvenli olmayan bloklar içeren kod ile derlenmelidir -unsafe derleyici seçeneği.

İlgili bölümler
Daha fazla bilgi için bkz.:
İşaretçi türleri
Sabit boyutlu arabellekler

C# dili belirtimi
Daha fazla bilgi için güvenli olmayan kod konuyu C# dil belirtimi.

Ayrıca bkz.
C# Programlama Kılavuzu
unsafe
Sabit Boyutlu Arabellekler (C# Programlama
Kılavuzu)
29.11.2019 • 4 minutes to read • Edit Online

İçinde C#, bir veri yapısında sabit boyutlu bir diziye sahip bir arabellek oluşturmak için fixed ifadesini
kullanabilirsiniz. Sabit boyutlu arabellekler, diğer dillerdeki veya platformlardaki veri kaynaklarıyla birlikte bulunan
Yöntemler yazdığınızda faydalıdır. Sabit dizi, normal yapı üyeleri için izin verilen herhangi bir özniteliği veya
değiştiricilerini alabilir. Tek kısıtlama, dizi türünün bool , byte , char , short , int , long , sbyte , ushort , uint ,
ulong , float veya double olması gerekir.

private fixed char name[30];

Açıklamalar
Güvenli kodda, dizi içeren C# bir struct dizi öğelerini içermez. Bunun yerine, yapı öğelerine bir başvuru içerir.
Güvenli olmayan bir kod bloğunda kullanıldığında bir yapıda sabit boyutlu bir dizi ekleyebilirsiniz.
Aşağıdaki struct boyutu 8 bayttır. pathName dizi bir başvurudur:

public struct PathArray


{
public char[] pathName;
private int reserved;
}

struct , güvenli olmayan kodda gömülü bir dizi içerebilir. Aşağıdaki örnekte, fixedBuffer dizisinin sabit bir
boyutu vardır. İlk öğe için bir işaretçi oluşturmak üzere bir fixed ifadesini kullanın. Bu işaretçi aracılığıyla dizinin
öğelerine erişirsiniz. fixed ifade fixedBuffer örneği alanını bellekte belirli bir konuma sabitsabitler.
internal unsafe struct MyBuffer
{
public fixed char fixedBuffer[128];
}

internal unsafe class MyClass


{
public MyBuffer myBuffer = default;
}

private static void AccessEmbeddedArray()


{
MyClass myC = new MyClass();

unsafe
{
// Pin the buffer to a fixed location in memory.
fixed (char* charPtr = myC.myBuffer.fixedBuffer)
{
*charPtr = 'A';
}
// Access safely through the index:
char c = myC.myBuffer.fixedBuffer[0];
Console.WriteLine(c);
// modify through the index:
myC.myBuffer.fixedBuffer[0] = 'B';
Console.WriteLine(myC.myBuffer.fixedBuffer[0]);
}

128 öğesi char dizi boyutu 256 bayttır. Sabit boyutlu char arabellekleri, kodlamadan bağımsız olarak her zaman
karakter başına iki bayt alır. Bu, karakter arabellekleri API yöntemlerine veya CharSet = CharSet.Auto ya da
CharSet = CharSet.Ansi yapılar halinde Sıralansa bile geçerlidir. Daha fazla bilgi için bkz. CharSet.

Yukarıdaki örnekte, 7,3 ile C# başlayarak kullanılabilir olan sabitleme olmadan fixed alanlarına erişim
gösterilmektedir.
Diğer bir yaygın sabit boyutlu dizi bool dizidir. Bir bool dizisindeki öğeler her zaman boyuttaki bir bayttır. bool
diziler, bit dizileri veya arabellekleri oluşturmak için uygun değildir.

NOTE
Stackallockullanılarak oluşturulan bellek dışında, C# derleyici ve ortak DIL çalışma zamanı (CLR) herhangi bir güvenlik
arabelleği taşma denetimi gerçekleştirmez. Tüm güvenli olmayan kodlarda olduğu gibi dikkatli olun.

Güvenli olmayan arabellekler aşağıdaki yollarla normal dizilerden farklıdır:


Güvenli olmayan arabellekleri yalnızca güvenli olmayan bir bağlamda kullanabilirsiniz.
Güvenli olmayan arabellekler her zaman vektörlerdir veya tek boyutlu dizilerdir.
Dizi bildirimi, char id[8] gibi bir sayı içermelidir. char id[] kullanamazsınız.
Güvenli olmayan arabellekler yalnızca güvenli olmayan bağlamdaki yapıların örnek alanları olabilir.

Ayrıca bkz.
C# Programlama Kılavuzu
Güvenli Olmayan Kod ve İşaretçiler
fixed Deyimi
Birlikte çalışabilirlik
İşaretçi türleri (C# Programlama Kılavuzu)
4.11.2019 • 5 minutes to read • Edit Online

Güvensiz bir bağlamda, bir işaretçi türü, bir değer türü veya bir başvuru türü bir tür olabilir. Bir işaretçi türü
bildirimi, aşağıdaki biçimlerden birini alır:

type* identifier;
void* identifier; //allowed but not recommended

Bir işaretçi türündeki * önce belirtilen tür, başvurulan türolarak adlandırılır. Yalnızca yönetilmeyen bir tür ,
başvurulan bir tür olabilir.
İşaretçi türleri nesneden devralma ve işaretçi türleri ve object arasında dönüştürme yok. Ayrıca, kutulama ve
kutudan çıkarma işaretçileri desteklemez. Ancak, farklı işaretçi türleri ve işaretçi türleri ve tamsayı türleri arasında
dönüştürme yapabilirsiniz.
Aynı bildirimde birden çok işaretçi bildirdiğinizde, yıldız işareti (*) yalnızca altı çizili türle birlikte yazılır; her bir
işaretçi adı için önek olarak kullanılmaz. Örneğin:

int* p1, p2, p3; // Ok


int *p1, *p2, *p3; // Invalid in C#

Bir işaretçi, bir işaretçiye işaret eden bir nesne başvurusu atık olarak toplanabileceğinden, bir başvuruya veya
başvuru içeren bir yapıya işaret edemez. Çöp toplayıcı, bir nesneye herhangi bir işaretçi türü tarafından işaret
edilip edilmediğini izlemez.
myType* türündeki işaretçi değişkeninin değeri, myType türünde bir değişkenin adresidir. Aşağıda, işaretçi türü
bildirimi örnekleri verilmiştir:

ÖRNEK AÇIKLAMA

int* p p , tamsayıya yönelik bir işaretçidir.

int** p p , tamsayıya yönelik işaretçinin bir işaretçisidir.

int*[] p p , tamsayılara yönelik işaretçilerin tek boyutlu bir dizisidir.

char* p p , Char için bir işaretçidir.

void* p p , bilinmeyen bir türe yönelik bir işaretçidir.

İşaretçi yöneltme işleci *, işaretçi değişkeninin işaret ettiği yerdeki içeriğe erişebilir. Örneğin, aşağıdaki bildirimi
ele alalım:

int* myVariable;

İfade *myVariable , myVariable bulunan adreste bulunan int değişkenini gösterir.


Konular Sabit bildiriminde ve işaretçi dönüştürmelerinde birçok işaretçiyeörnek vardır. Aşağıdaki örnek unsafe
anahtar sözcüğünü ve fixed ifadesini kullanır ve iç işaretçinin nasıl artırılacağını gösterir. Bu kodu çalıştırmak
için bir konsolun Ana işlevine yapıştırabilirsiniz. Bu örneklerin -unsafe derleyici seçenek kümesiyle derlenmesi
gerekir.

// Normal pointer to an object.


int[] a = new int[5] { 10, 20, 30, 40, 50 };
// Must be in unsafe code to use interior pointers.
unsafe
{
// Must pin object on heap so that it doesn't move while using interior pointers.
fixed (int* p = &a[0])
{
// p is pinned as well as object, so create another pointer to show incrementing it.
int* p2 = p;
Console.WriteLine(*p2);
// Incrementing p2 bumps the pointer by four bytes due to its type ...
p2 += 1;
Console.WriteLine(*p2);
p2 += 1;
Console.WriteLine(*p2);
Console.WriteLine("--------");
Console.WriteLine(*p);
// Dereferencing p and incrementing changes the value of a[0] ...
*p += 1;
Console.WriteLine(*p);
*p += 1;
Console.WriteLine(*p);
}
}

Console.WriteLine("--------");
Console.WriteLine(a[0]);

/*
Output:
10
20
30
--------
10
11
12
--------
12
*/

Yöneltme işlecini void* türünde bir işaretçiye uygulayamazsınız. Ancak, boş bir işaretçiyi başka herhangi bir türü
dönüştürmek veya bunun tersini yapmak için bir yayın kullanabilirsiniz.
Bir işaretçi null olabilir. Yönlendirme işlecini bir null işaretçiye uygulamak, uygulama tarafından tanımlanan bir
davranışa neden olur.
Yöntemler arasında işaretçiler geçirmek tanımsız davranışlara neden olabilir. Bir in , out veya ref parametresi
ya da işlev sonucu olarak yerel bir değişkene bir işaretçi döndüren bir yöntem düşünün. İşaretçi sabit bir blokta
ayarlandıysa, işaret ettiği değişken artık sabit olamaz.
Aşağıdaki tabloda, güvenli olmayan bir bağlamda işaretçiler üzerinde işlem yapabilecek işleçler ve deyimler
listelenmektedir:
BIR YÖNETIM GRUBUNA BAĞLANMAK VEYA BAĞLI BIR YÖNETIM
GRUBUNUN ÖZELLIKLERINI DÜZENLEMEK IÇIN YÖNETIM ÇALIŞMA
İŞLEÇ/DEYIM ALANINDA

* İşaretçi yöneltmesi gerçekleştirir.

-> Bir yapının bir üyesine bir işaretçi yoluyla erişir.

[] Bir işaretçiyi dizine ekler.

& Bir değişkenin adresini alır.

++ ve -- İşaretçileri artırır ve azaltır.

+ ve - İşaretçi aritmetiği gerçekleştirir.

== , != , < , > , <= ve >= İşaretçileri karşılaştırır.

stackalloc işleci Yığında bellek ayırır.

fixed ekstresi Adresinin bulunamaması için bir değişkeni geçici olarak


sabitler.

İşaretçi ile ilgili işleçler hakkında daha fazla bilgi için bkz. işaretçi ile ilgili işleçler.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin işaretçi türleri bölümüne bakın.

Ayrıca bkz.
C# Programlama Kılavuzu
Güvenli Olmayan Kod ve İşaretçiler
İşaretçi Dönüştürmeler
Türler
unsafe
İşaretçi Dönüşümleri (C# Programlama Kılavuzu)
4.11.2019 • 2 minutes to read • Edit Online

Aşağıdaki tabloda önceden tanımlanmış örtük işaretçi dönüşümleri gösterilmektedir. Örtük dönüştürmeler,
yöntem çağırma ve atama deyimleri dahil olmak üzere birçok durumda gerçekleşebilir.

Örtük işaretçi dönüşümleri


BAŞLANGIÇ BITIŞ

Herhangi bir işaretçi türü Kağıt

null Herhangi bir işaretçi türü

Açık işaretçi dönüştürmesi, bir atama ifadesi kullanarak örtük dönüştürme olmayan dönüştürmeler
gerçekleştirmek için kullanılır. Aşağıdaki tabloda bu dönüşümler gösterilmektedir.

Açık işaretçi dönüşümleri


BAŞLANGIÇ BITIŞ

Herhangi bir işaretçi türü Diğer herhangi bir işaretçi türü

SByte, Byte, Short, ushort, int, uint, Long veya ulong Herhangi bir işaretçi türü

Herhangi bir işaretçi türü SByte, Byte, Short, ushort, int, uint, Long veya ulong

Örnek
Aşağıdaki örnekte, int bir işaretçi byte işaretçisine dönüştürülür. İşaretçinin, değişkenin en düşük adresli baytını
işaret ettiğini unutmayın. Sonucu büyük ölçüde artırdığınızda, int boyutuna kadar (4 bayt), değişkenin kalan
baytlarını görüntüleyebilirsiniz.

// compile with: -unsafe


class ClassConvert
{
static void Main()
{
int number = 1024;

unsafe
{
// Convert to byte:
byte* p = (byte*)&number;

System.Console.Write("The 4 bytes of the integer:");

// Display the 4 bytes of the int variable:


for (int i = 0 ; i < sizeof(int) ; ++i)
{
System.Console.Write(" {0:X2}", *p);
// Increment the pointer:
p++;
}
System.Console.WriteLine();
System.Console.WriteLine("The value of the integer: {0}", number);

// Keep the console window open in debug mode.


System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
}
}
/* Output:
The 4 bytes of the integer: 00 04 00 00
The value of the integer: 1024
*/

Ayrıca bkz.
C# Programlama Kılavuzu
İşaretçi türleri
Türler
unsafe
fixed Deyimi
stackalloc
Nasıl yapılır: Bir bayt dizisine kopyalamak için
işaretçiler kullanma (C# Programlama Kılavuzu)
23.10.2019 • 3 minutes to read • Edit Online

Aşağıdaki örnek, bayt bir diziden kopyalamak için işaretçiler kullanır.


Bu örnekte güvenli olmayan işaretçiler, kullanmanıza olanak tanıyan anahtar sözcüğü Copy yöntemi. Sabit deyimi,
kaynak ve hedef dizi işaretçileri bildirmek için kullanılır. fixed Deyimi PIN'ler çöp toplamadan taşınmayacak
böylece bellekte konumunu kaynak ve hedef dizi. Bellek bloklarını diziler için ne zaman sabitlenmemiş fixed blok
tamamlandı. Çünkü Copy Bu örnekte kullanmaktadır unsafe anahtar sözcüğü, onu derlenmelidir -unsafe derleyici
seçeneği.
Bu örnekte, ikinci bir yönetilmeyen işaretçi yerine dizinleri hem dizilerin öğelerine erişir. Bildirimi pSource ve
pTarget işaretçileri, dizileri sabitler. Bu özellik, C# 7.3 ile başlayan kullanılabilir.

Örnek
static unsafe void Copy(byte[] source, int sourceOffset, byte[] target,
int targetOffset, int count)
{
// If either array is not instantiated, you cannot complete the copy.
if ((source == null) || (target == null))
{
throw new System.ArgumentException();
}

// If either offset, or the number of bytes to copy, is negative, you


// cannot complete the copy.
if ((sourceOffset < 0) || (targetOffset < 0) || (count < 0))
{
throw new System.ArgumentException();
}

// If the number of bytes from the offset to the end of the array is
// less than the number of bytes you want to copy, you cannot complete
// the copy.
if ((source.Length - sourceOffset < count) ||
(target.Length - targetOffset < count))
{
throw new System.ArgumentException();
}

// The following fixed statement pins the location of the source and
// target objects in memory so that they will not be moved by garbage
// collection.
fixed (byte* pSource = source, pTarget = target)
{
// Copy the specified number of bytes from source to target.
for (int i = 0; i < count; i++)
{
pTarget[targetOffset + i] = pSource[sourceOffset + i];
}
}
}

static void UnsafeCopyArrays()


{
// Create two arrays of the same length.
// Create two arrays of the same length.
int length = 100;
byte[] byteArray1 = new byte[length];
byte[] byteArray2 = new byte[length];

// Fill byteArray1 with 0 - 99.


for (int i = 0; i < length; ++i)
{
byteArray1[i] = (byte)i;
}

// Display the first 10 elements in byteArray1.


System.Console.WriteLine("The first 10 elements of the original are:");
for (int i = 0; i < 10; ++i)
{
System.Console.Write(byteArray1[i] + " ");
}
System.Console.WriteLine("\n");

// Copy the contents of byteArray1 to byteArray2.


Copy(byteArray1, 0, byteArray2, 0, length);

// Display the first 10 elements in the copy, byteArray2.


System.Console.WriteLine("The first 10 elements of the copy are:");
for (int i = 0; i < 10; ++i)
{
System.Console.Write(byteArray2[i] + " ");
}
System.Console.WriteLine("\n");

// Copy the contents of the last 10 elements of byteArray1 to the


// beginning of byteArray2.
// The offset specifies where the copying begins in the source array.
int offset = length - 10;
Copy(byteArray1, offset, byteArray2, 0, length - offset);

// Display the first 10 elements in the copy, byteArray2.


System.Console.WriteLine("The first 10 elements of the copy are:");
for (int i = 0; i < 10; ++i)
{
System.Console.Write(byteArray2[i] + " ");
}
System.Console.WriteLine("\n");
/* Output:
The first 10 elements of the original are:
0 1 2 3 4 5 6 7 8 9

The first 10 elements of the copy are:


0 1 2 3 4 5 6 7 8 9

The first 10 elements of the copy are:


90 91 92 93 94 95 96 97 98 99
*/
}

Ayrıca bkz.
C# Programlama Kılavuzu
Güvenli Olmayan Kod ve İşaretçiler
-unsafe (C# Derleyici Seçenekleri)
Atık Toplama
XML Belgeleri Yorumları (C# Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Visual C#'de, kaynak kodda doğrudan açıklamaların başvurduğu kod bloğunun hemen öncesindeki özel açıklama
alanlarına (üç eğik çizgiyle gösterilir) XML öğeleri ekleyerek, kodunuz için belge oluşturabilirsiniz, örneğin:

/// <summary>
/// This class performs an important function.
/// </summary>
public class MyClass {}

-Doc seçeneğiyle derlerken, derleyici kaynak KODUNDAKI tüm XML etiketlerini arar ve bir XML belge dosyası
oluşturur. Derleyici tarafından oluşturulan dosyayı temel alan son belgeleri oluşturmak için özel bir araç
oluşturabilir veya Docfx veya sandrolegibi bir araç kullanabilirsiniz.
XML öğelerine başvurmak için (örneğin, işleviniz, bir XML belge açıklamasında açıklama eklemek istediğiniz
belirli XML öğelerini işliyorsa), standart tırnak içine alma mekanizmasını ( < ve > ) kullanabilirsiniz. Kod
başvurusu ( cref ) öğelerinde genel tanımlayıcılara başvurmak için, kaçış karakterlerini (örneğin,
cref="List&lt;T&gt;" ) veya küme ayraçlarını ( cref="List{T}" ) kullanabilirsiniz. Özel bir durum olarak, derleyici,
genel tanımlayıcılara başvururken belge açıklamasının yazar için daha az sıkıcı olması için, derleyici tireleri açılı
ayraçlar olarak ayrıştırır.

NOTE
XML belge açıklamaları meta veri değildir; oluşturulan derlemeye dahil edilmezler ve bu nedenle yansıtma üzerinden
erişilemezler.

Bu Bölümde
Belge Açıklamaları için Önerilen Etiketler
XML Dosyasını İşleme
Belge Etiketleri için Sınırlayıcılar
Nasıl yapılır: XML Belgesi Özelliklerini Kullanma

İlgili Bölümler
Daha fazla bilgi için bkz.:
-Doc (Işlem belgeleri açıklamaları)

C# Dil Belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir kaynaktır.

Ayrıca bkz.
C# Programlama Kılavuzu
Belge Açıklamaları için Önerilen Etiketler (C#
Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

C# Derleyici kodunuzda belge açıklamalarını işler ve adı /doc komut satırı SEÇENEĞINDE belirttiğiniz bir
dosyada xml olarak biçimlendirir. Derleyici tarafından oluşturulan dosyayı temel alan son belgeleri oluşturmak
için özel bir araç oluşturabilir veya Docfx veya sandrolegibi bir araç kullanabilirsiniz.
Etiketler, türler ve tür üyeleri gibi kod yapıları üzerinde işlenir.

NOTE
Belge açıklamaları bir ad alanına uygulanamaz.

Derleyici geçerli XML olan herhangi bir etiketi işleyecek. Aşağıdaki Etiketler kullanıcı belgelerinde genel olarak
kullanılan işlevleri sağlar.

Etiketler

<c > <para > <see > *

<code > <param > * <seealso > *

<example > <paramref > <summary>

<exception > * <permission > * <typeparam > *

<include > * <remarks > <typeparamref >

<list > <returns> <value>

(* derleyicinin söz dizimini doğruladığını gösterir.)


Bir belge açıklamasının metninde Açılı ayraçların görünmesini istiyorsanız, < ve > HTML kodlamasını
kullanın &lt; ve &gt; . Bu kodlama aşağıdaki örnekte gösterilmiştir:

/// <summary>
/// This property always returns a value &lt; 1.
/// </summary>

Ayrıca bkz.
C# Programlama Kılavuzu
-Doc (C# derleyici seçenekleri)
XML Belge Açıklamaları
XML Dosyasını İşleme (C# Programlama Kılavuzu)
26.10.2019 • 8 minutes to read • Edit Online

Derleyici, kodunuzda belge oluşturmak için etiketlenmiş her yapı için bir KIMLIK dizesi oluşturur. (Kodunuzu
etiketleme hakkında daha fazla bilgi için bkz. belge açıklamaları Için önerilen Etiketler.) KIMLIK dizesi yapıyı
benzersiz bir şekilde tanımlar. XML dosyasını işleyen programlar, belgelerin uygulandığı karşılık gelen .NET
Framework meta veri/yansıma öğesini tanımlamak için KIMLIK dizesini kullanabilir.
XML dosyası, kodunuzun hiyerarşik bir temsili değildir; her öğe için oluşturulmuş KIMLIĞI olan düz bir liste.
Derleyici, KIMLIK dizelerini oluşturduğunda aşağıdaki kuralları sunar:
Dizede boşluk yok.
KIMLIK dizesinin ilk bölümü, tanımlanmakta olan üyenin türünü, tek bir karakter ve iki nokta üst üste ile
belirler. Aşağıdaki üye türleri kullanılır:

KARAKTER AÇIKLAMA

N ad alanı

Bir ad alanına belge açıklamaları ekleyemezsiniz, ancak bu


kişilere, desteklenmiş olduğu durumlarda bu başvuruları
yapabilirsiniz.

T Tür: Class, Interface, struct, Enum, Delegate

F alan

P Özellik (Dizin oluşturucular veya diğer dizinli özellikler


dahil)

M Yöntem (oluşturucular, işleçler ve benzeri özel yöntemler


dahil)

E olay

! Hata dizesi

Dizenin geri kalanı hata hakkında bilgi sağlar. Derleyici C# ,


çözümlenemeyen bağlantılar için hata bilgileri oluşturur.

Dizenin ikinci bölümü, ad alanının köküden başlayarak öğenin tam nitelikli adıdır. Öğenin adı, kapsayan tür
(ler) ve ad alanı noktalarla ayrılır. Öğenin adında nokta varsa, bunlar karma işareti (' # ') ile değiştirilmiştir.
Hiçbir öğenin doğrudan adında bir karma işareti olmadığı varsayılır. Örneğin, dize oluşturucusunun tam adı
"System. String. #ctor" olacaktır.
Özellikler ve yöntemler için, yöntem için bağımsız değişkenler varsa, parantez içine alınmış bağımsız
değişken listesi aşağıda verilmiştir. Bağımsız değişken yoksa, parantezler yok. Bağımsız değişkenler virgülle
ayrılır. Her bağımsız değişkenin kodlaması, .NET Framework imzasında nasıl kodlandığını doğrudan izler:
Temel türler. Normal türler (ELEMENT_TYPE_CLASS veya ELEMENT_TYPE_VALUETYPE ), türün
tam nitelikli adı olarak gösterilir.
İç türler (örneğin, ELEMENT_TYPE_I4, ELEMENT_TYPE_OBJECT, ELEMENT_TYPE_STRING,
ELEMENT_TYPE_TYPEDBYREF ve ELEMENT_TYPE_VOID ) karşılık gelen tam türün tam adı olarak
gösterilir. Örneğin, System. Int32 veya System. TypedReference.
ELEMENT_TYPE_PTR, değiştirilen türden sonra bir '*' olarak temsil edilir.
ELEMENT_TYPE_BYREF, değiştirilen türden sonra bir '@' olarak temsil edilir.
ELEMENT_TYPE_PINNED, değiştirilen türden sonra bir ' ^ ' olarak temsil edilir. C# Derleyici bunu
hiçbir şekilde oluşturmaz.
ELEMENT_TYPE_CMOD_REQ, değiştirilen türü takip eden|bir ' ' ve değiştirici sınıfının tam adı
olarak temsil edilir. C# Derleyici bunu hiçbir şekilde oluşturmaz.
ELEMENT_TYPE_CMOD_OPT, değiştirilen türden sonra bir '! ' ve değiştirici sınıfının tam adı olarak
temsil edilir.
ELEMENT_TYPE_SZARRAY, dizinin öğe türü takip eden "[]" olarak temsil edilir.
ELEMENT_TYPE_GENERICARRAY, dizinin öğe türü takip eden "[?]" olarak temsil edilir. C# Derleyici
bunu hiçbir şekilde oluşturmaz.
ELEMENT_TYPE_ARRAY, virgül sayısının derece-1 olduğu ve bilinen her boyutun alt sınırları ve
boyutunun ondalık olarak temsil edildiği [küçükharfegöre: size , küçükharfegöre: size ] olarak
gösterilir. Daha düşük bir sınır veya boyut belirtilmemişse, bu yalnızca atlanır. Belirli bir boyutun alt
sınırı ve boyutu atlanırsa, ': ' de atlanır. Örneğin, alt sınır olarak 1 olan 2 boyutlu bir dizi ve
belirtilmemiş boyutlar [1:, 1:].
ELEMENT_TYPE_FNPTR, dönüş türü olan ve imza yöntemin bağımsız değişkenlerinin olduğu "=
FUNC: type (Signature) type " olarak temsil edilir. Bağımsız değişken yoksa, parantezler atlanır. C#
Derleyici bunu hiçbir şekilde oluşturmaz.
Aşağıdaki imza bileşenleri, aşırı yüklenmiş yöntemlerin farklılaştırmaları hiçbir şekilde
kullanıldıklarından temsil edilmez:
çağırma kuralı
Dönüş türü
ELEMENT_TYPE_SENTINEL
Yalnızca dönüştürme işleçleri (op_Implicit ve op_Explicit) için, metodun dönüş değeri, yukarıda kodlanan bir
' ~ ' ve ardından dönüş türü tarafından kodlanır.
Genel türler için, türün adının ardından bir geri değer ve ardından genel tür parametrelerinin sayısını
belirten bir sayı gelmelidir. Örneğin:
<member name="T:SampleClass`2"> , public class SampleClass<T, U> olarak tanımlanan bir türün etikettir.
Genel türleri parametre olarak alan yöntemler için, genel tür parametreleri, geri işaretleri (örneğin `0, `1) ile
önceden ortaya çıkacak sayılar olarak belirtilir. Türün genel parametreleri için sıfır tabanlı dizi gösterimini
temsil eden her bir sayı.

Örnekler
Aşağıdaki örneklerde, bir sınıfa ve üyelerine ait KIMLIK dizelerinin nasıl oluşturulacağı gösterilmektedir:

namespace N
{
/// <summary>
/// Enter description here for class X.
/// Enter description here for class X.
/// ID string generated is "T:N.X".
/// </summary>
public unsafe class X
{
/// <summary>
/// Enter description here for the first constructor.
/// ID string generated is "M:N.X.#ctor".
/// </summary>
public X() { }

/// <summary>
/// Enter description here for the second constructor.
/// ID string generated is "M:N.X.#ctor(System.Int32)".
/// </summary>
/// <param name="i">Describe parameter.</param>
public X(int i) { }

/// <summary>
/// Enter description here for field q.
/// ID string generated is "F:N.X.q".
/// </summary>
public string q;

/// <summary>
/// Enter description for constant PI.
/// ID string generated is "F:N.X.PI".
/// </summary>
public const double PI = 3.14;

/// <summary>
/// Enter description for method f.
/// ID string generated is "M:N.X.f".
/// </summary>
/// <returns>Describe return value.</returns>
public int f() { return 1; }

/// <summary>
/// Enter description for method bb.
/// ID string generated is "M:N.X.bb(System.String,System.Int32@,System.Void*)".
/// </summary>
/// <param name="s">Describe parameter.</param>
/// <param name="y">Describe parameter.</param>
/// <param name="z">Describe parameter.</param>
/// <returns>Describe return value.</returns>
public int bb(string s, ref int y, void* z) { return 1; }

/// <summary>
/// Enter description for method gg.
/// ID string generated is "M:N.X.gg(System.Int16[],System.Int32[0:,0:])".
/// </summary>
/// <param name="array1">Describe parameter.</param>
/// <param name="array">Describe parameter.</param>
/// <returns>Describe return value.</returns>
public int gg(short[] array1, int[,] array) { return 0; }

/// <summary>
/// Enter description for operator.
/// ID string generated is "M:N.X.op_Addition(N.X,N.X)".
/// </summary>
/// <param name="x">Describe parameter.</param>
/// <param name="xx">Describe parameter.</param>
/// <returns>Describe return value.</returns>
/// <returns>Describe return value.</returns>
public static X operator +(X x, X xx) { return x; }

/// <summary>
/// Enter description for property.
/// ID string generated is "P:N.X.prop".
/// </summary>
public int prop { get { return 1; } set { } }

/// <summary>
/// Enter description for event.
/// ID string generated is "E:N.X.d".
/// </summary>
public event D d;

/// <summary>
/// Enter description for property.
/// ID string generated is "P:N.X.Item(System.String)".
/// </summary>
/// <param name="s">Describe parameter.</param>
/// <returns></returns>
public int this[string s] { get { return 1; } }

/// <summary>
/// Enter description for class Nested.
/// ID string generated is "T:N.X.Nested".
/// </summary>
public class Nested { }

/// <summary>
/// Enter description for delegate.
/// ID string generated is "T:N.X.D".
/// </summary>
/// <param name="i">Describe parameter.</param>
public delegate void D(int i);

/// <summary>
/// Enter description for operator.
/// ID string generated is "M:N.X.op_Explicit(N.X)~System.Int32".
/// </summary>
/// <param name="x">Describe parameter.</param>
/// <returns>Describe return value.</returns>
public static explicit operator int(X x) { return 1; }

}
}

Ayrıca bkz.
C# Programlama Kılavuzu
-Doc (C# derleyici seçenekleri)
XML Belge Açıklamaları
Belge Etiketleri için Sınırlayıcılar (C# Programlama
Kılavuzu)
23.10.2019 • 4 minutes to read • Edit Online

XML belgesi açıklamalarının kullanılması, bir belge açıklamasının başladığı ve bittiği derleyicisine işaret eden
sınırlayıcıları gerektirir. XML belge etiketleriyle aşağıdaki tür sınırlayıcıları kullanabilirsiniz:
///
Tek satırlık sınırlayıcı. Bu, belge örneklerinde gösterilen ve görsel C# proje şablonları tarafından kullanılan formdur.
Sınırlayıcıyı izleyen bir boşluk karakteri varsa, bu karakter XML çıktısına dahil edilmez.

NOTE
Visual Studio IDE, akıllı yorum düzenleme adlı, <summary > < ve/Summary > etiketlerini otomatik olarak ekleyen ve kod
düzenleyicisinde /// ayırıcısını yazdıktan sonra imlecinizi bu etiketlerin içinde taşıtan bir özelliğe sahiptir. Seçenekler iletişim
kutusundabu özelliği etkinleştirebilir veya devre dışı bırakabilirsiniz.

/** */
Çok satırlı sınırlayıcılar.
@No__t_0 sınırlayıcılarını kullanırken izlenecek bazı biçimlendirme kuralları vardır.
@No__t_0 sınırlayıcısı içeren satırda, satırın geri kalanı boşluk ise, satır Yorumlar için işlenmez. @No__t_0
sınırlayıcısından sonraki ilk karakter boşluk ise, bu boşluk karakteri yok sayılır ve satırın geri kalanı işlenir.
Aksi takdirde, /** sınırlayıcısından sonra çizginin tüm metni açıklamanın bir parçası olarak işlenir.
@No__t_0 sınırlayıcısı içeren satırda, */ sınırlayıcısına yalnızca beyaz boşluk varsa, bu satır yok sayılır. Aksi
takdirde, */ sınırlayıcısı olan satırdaki metin, açıklama parçası olarak işlenir ve bu, aşağıdaki madde
işaretinde açıklanan desenler ile eşleşen kurallara tabidir.
@No__t_0 sınırlayıcısıyla başlayan satırlar için, derleyici her bir satırın başlangıcında ortak bir model arar. Bu
kalıp, isteğe bağlı boşluk ve bir yıldız işareti ( * ) ve ardından daha isteğe bağlı boşluk içerebilir. Derleyici,
/** sınırlayıcısı veya */ sınırlayıcısıyla başlamayan her satırın başlangıcında ortak bir model bulursa, her
satır için bu kalıbı yoksayar.
Aşağıdaki örneklerde bu kurallar gösterilmektedir.
Aşağıdaki açıklamanın işlenecek tek bir kısmı <summary> ile başlayan satırdır. Üç etiket biçimi aynı
açıklamaları üretir.

/** <summary>text</summary> */

/**
<summary>text</summary>
*/

/**
* <summary>text</summary>
*/

Derleyici, ikinci ve üçüncü çizgilerin başlangıcında "*" ortak bir modelini tanımlar. Bu kalıp çıkışa dahil
değildir.
/**
* <summary>
* text </summary>*/

Derleyici, aşağıdaki açıklamada ortak bir model bulmadığından, üçüncü satırdaki ikinci karakter bir yıldız
işareti değildir. Bu nedenle, ikinci ve üçüncü satırlardaki tüm metinler açıklamanın bir parçası olarak işlenir.

/**
* <summary>
text </summary>
*/

Derleyici, aşağıdaki açıklamada iki nedenden dolayı hiçbir model bulmamalıdır. İlk olarak, yıldız işaretiyle
önceki boşluk sayısı tutarlı değil. İkincisi, beşinci satır boşluk ile eşleşmeyen bir sekme ile başlar. Bu nedenle,
metnin ikinci ile beş arasındaki tüm metinler, açıklamanın bir parçası olarak işlenir.

/**
* <summary>
* text
* text2
* </summary>
*/

Ayrıca bkz.
C# Programlama Kılavuzu
XML Belge Açıklamaları
-Doc (C# derleyici seçenekleri)
XML Belge Açıklamaları
Nasıl yapılır: XML belgeleri özelliklerini kullanma
23.10.2019 • 5 minutes to read • Edit Online

Aşağıdaki örnek, belgelenen bir türe temel bir genel bakış sağlar.

Örnek
// If compiling from the command line, compile with: -doc:YourFileName.xml

/// <summary>
/// Class level summary documentation goes here.
/// </summary>
/// <remarks>
/// Longer comments can be associated with a type or member through
/// the remarks tag.
/// </remarks>
public class TestClass : TestInterface
{
/// <summary>
/// Store for the Name property.
/// </summary>
private string _name = null;

/// <summary>
/// The class constructor.
/// </summary>
public TestClass()
{
// TODO: Add Constructor Logic here.
}

/// <summary>
/// Name property.
/// </summary>
/// <value>
/// A value tag is used to describe the property value.
/// </value>
public string Name
{
get
{
if (_name == null)
{
throw new System.Exception("Name is null");
}
return _name;
}
}

/// <summary>
/// Description for SomeMethod.
/// </summary>
/// <param name="s"> Parameter description for s goes here.</param>
/// <seealso cref="System.String">
/// You can use the cref attribute on any tag to reference a type or member
/// and the compiler will check that the reference exists.
/// </seealso>
public void SomeMethod(string s)
{
}

/// <summary>
/// <summary>
/// Some other method.
/// </summary>
/// <returns>
/// Return values are described through the returns tag.
/// </returns>
/// <seealso cref="SomeMethod(string)">
/// Notice the use of the cref attribute to reference a specific method.
/// </seealso>
public int SomeOtherMethod()
{
return 0;
}

public int InterfaceMethod(int n)


{
return n * n;
}

/// <summary>
/// The entry point for the application.
/// </summary>
/// <param name="args"> A list of command line arguments.</param>
static int Main(System.String[] args)
{
// TODO: Add code to start application here.
return 0;
}
}

/// <summary>
/// Documentation that describes the interface goes here.
/// </summary>
/// <remarks>
/// Details about the interface go here.
/// </remarks>
interface TestInterface
{
/// <summary>
/// Documentation that describes the method goes here.
/// </summary>
/// <param name="n">
/// Parameter n requires an integer argument.
/// </param>
/// <returns>
/// The method returns an integer.
/// </returns>
int InterfaceMethod(int n);
}

Örnek, aşağıdaki içeriklerle bir. xml dosyası oluşturur:

<?xml version="1.0"?>
<doc>
<assembly>
<name>xmlsample</name>
</assembly>
<members>
<member name="T:TestClass">
<summary>
Class level summary documentation goes here.
</summary>
<remarks>
Longer comments can be associated with a type or member through
the remarks tag.
</remarks>
</member>
<member name="F:TestClass._name">
<member name="F:TestClass._name">
<summary>
Store for the Name property.
</summary>
</member>
<member name="M:TestClass.#ctor">
<summary>
The class constructor.
</summary>
</member>
<member name="P:TestClass.Name">
<summary>
Name property.
</summary>
<value>
A value tag is used to describe the property value.
</value>
</member>
<member name="M:TestClass.SomeMethod(System.String)">
<summary>
Description for SomeMethod.
</summary>
<param name="s"> Parameter description for s goes here.</param>
<seealso cref="T:System.String">
You can use the cref attribute on any tag to reference a type or member
and the compiler will check that the reference exists.
</seealso>
</member>
<member name="M:TestClass.SomeOtherMethod">
<summary>
Some other method.
</summary>
<returns>
Return values are described through the returns tag.
</returns>
<seealso cref="M:TestClass.SomeMethod(System.String)">
Notice the use of the cref attribute to reference a specific method.
</seealso>
</member>
<member name="M:TestClass.Main(System.String[])">
<summary>
The entry point for the application.
</summary>
<param name="args"> A list of command line arguments.</param>
</member>
<member name="T:TestInterface">
<summary>
Documentation that describes the interface goes here.
</summary>
<remarks>
Details about the interface go here.
</remarks>
</member>
<member name="M:TestInterface.InterfaceMethod(System.Int32)">
<summary>
Documentation that describes the method goes here.
</summary>
<param name="n">
Parameter n requires an integer argument.
</param>
<returns>
The method returns an integer.
</returns>
</member>
</members>
</doc>
Kodu derleme
Örneği derlemek için aşağıdaki komut satırını yazın:
csc XMLsample.cs /doc:XMLsample.xml

Bu komut, tarayıcınızda görüntüleyebileceğiniz veya TYPE komutunu kullanarak XMLsample. XMLXML dosyasını
oluşturur.

Güçlü programlama
XML belgeleri///ile başlar. Yeni bir proje oluşturduğunuzda, sihirbazlar sizin için bazı başlangıç//satır satırları koyar.
Bu yorumların işlenmesinde bazı kısıtlamalar vardır:
Belgeler düzgün biçimlendirilmiş XML olmalıdır. XML doğru biçimlendirilmediyse bir uyarı oluşturulur ve
belge dosyası bir hata ile karşılaşıldığını bildiren bir açıklama içerir.
Geliştiriciler kendi etiket kümesini oluşturmak ücretsizdir. Önerilen bir etiket kümesi vardır ( belge
açıklamaları Için önerilen etiketlerebakın). Önerilen etiketlerden bazılarının özel anlamları vardır:
@No__t_0param > etiketi parametreleri tanımlamakta kullanılır. Kullanıldıysa, derleyici parametrenin
var olduğunu ve tüm parametrelerin belgelerde açıklandığını doğrular. Doğrulama başarısız olursa,
derleyici bir uyarı verir.
@No__t_0 özniteliği, bir kod öğesine başvuru sağlamak için herhangi bir etikete iliştirilebilir. Derleyici
bu kod öğesinin varolduğunu doğrular. Doğrulama başarısız olursa, derleyici bir uyarı verir. Derleyici,
cref özniteliğinde açıklanan bir türü ararken tüm using deyimlerini uyar.

@No__t_0summary > etiketi, Visual Studio içinde IntelliSense tarafından bir tür veya üyeyle ilgili ek
bilgileri göstermek için kullanılır.

NOTE
XML dosyası, tür ve Üyeler hakkında tam bilgi sağlamaz (örneğin, herhangi bir tür bilgisi içermez). Bir tür veya
üye hakkında tam bilgi almak için, belge dosyasının gerçek tür veya üye üzerinde yansıma ile birlikte
kullanılması gerekir.

Ayrıca bkz.
C# Programlama Kılavuzu
-Doc (C# derleyici seçenekleri)
XML Belge Açıklamaları
DocFX belge işlemcisi
Sandrole belge işlemcisi
<c > (C# Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Sözdizimi
<c>text</c>

Parametreler
text
Kod olarak göstermek istediğiniz metin.

Açıklamalar
@No__t_0c > etiketi, bir açıklama içindeki metnin kod olarak işaretlenmesi gerektiğini göstermek için bir yol sağlar.
Birden çok satırı kod olarak göstermek için <code > kullanın.
Belge açıklamalarını bir dosyaya işlemek için -doc ile derleyin.

Örnek
// compile with: -doc:DocFileName.xml

/// text for class TestClass


public class TestClass
{
/// <summary><c>DoWork</c> is a method in the <c>TestClass</c> class.
/// </summary>
public static void DoWork(int Int1)
{
}

/// text for Main


static void Main()
{
}
}

Ayrıca bkz.
C# Programlama Kılavuzu
Belge Açıklamaları için Önerilen Etiketler
<code > (C# Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Sözdizimi
<code>content</code>

Parametreler
content
Kod olarak işaretlenmesini istediğiniz metin.

Açıklamalar
@No__t_0code > etiketi, kod olarak birden fazla satırı göstermek için bir yol sağlar. Bir açıklama içindeki metnin
kod olarak işaretlenmesi gerektiğini göstermek için <c > kullanın.
Belge açıklamalarını bir dosyaya işlemek için -doc ile derleyin.

Örnek
@No__t_2code > etiketinin nasıl kullanılacağına ilişkin bir örnek için <example > konusuna bakın.

Ayrıca bkz.
C# Programlama Kılavuzu
Belge Açıklamaları için Önerilen Etiketler
cref Özniteliği (C# Programlama Kılavuzu)
23.10.2019 • 3 minutes to read • Edit Online

XML belgesi etiketindeki özniteliği "kod başvurusu" anlamına gelir. cref Etiketin iç metninin tür, yöntem veya
özellik gibi bir kod öğesi olduğunu belirtir. Docfx ve sandrole gibi belge araçları, otomatik cref olarak tür veya
üyenin belgelendiği sayfaya köprüler oluşturmak için öznitelikleri kullanır.

Örnek
Aşağıdaki örnek, cref <bkz. > etiketlerinde kullanılan öznitelikleri gösterir.

// Save this file as CRefTest.cs


// Compile with: csc CRefTest.cs -doc:Results.xml

namespace TestNamespace
{
/// <summary>
/// TestClass contains several cref examples.
/// </summary>
public class TestClass
{
/// <summary>
/// This sample shows how to specify the <see cref="TestClass"/> constructor as a cref attribute.
/// </summary>
public TestClass()
{ }

/// <summary>
/// This sample shows how to specify the <see cref="TestClass(int)"/> constructor as a cref attribute.
/// </summary>
public TestClass(int value)
{ }

/// <summary>
/// The GetZero method.
/// </summary>
/// <example>
/// This sample shows how to call the <see cref="GetZero"/> method.
/// <code>
/// class TestClass
/// {
/// static int Main()
/// {
/// return GetZero();
/// }
/// }
/// </code>
/// </example>
public static int GetZero()
{
return 0;
}

/// <summary>
/// The GetGenericValue method.
/// </summary>
/// <remarks>
/// This sample shows how to specify the <see cref="GetGenericValue"/> method as a cref attribute.
/// </remarks>

public static T GetGenericValue<T>(T para)


public static T GetGenericValue<T>(T para)
{
return para;
}
}

/// <summary>
/// GenericClass.
/// </summary>
/// <remarks>
/// This example shows how to specify the <see cref="GenericClass{T}"/> type as a cref attribute.
/// </remarks>
class GenericClass<T>
{
// Fields and members.
}

class Program
{
static int Main()
{
return TestClass.GetZero();
}
}
}

Derlendiğinde, program aşağıdaki XML dosyasını oluşturur. Yöntemin özniteliği, örneğin, derleyicisinin tarafından
öğesine "M:TestNamespace.TestClass.GetZero" dönüştürüldüğünü unutmayın. cref GetZero "D:" öneki "method"
anlamına gelir ve DocFX ve Sandrole gibi belge araçları tarafından tanınan bir kuraldır. Tüm ön eklerin listesi için
bkz. XML dosyasını işleme.

<?xml version="1.0"?>
<doc>
<assembly>
<name>CRefTest</name>
</assembly>
<members>
<member name="T:TestNamespace.TestClass">
<summary>
TestClass contains cref examples.
</summary>
</member>
<member name="M:TestNamespace.TestClass.#ctor">
<summary>
This sample shows how to specify the <see cref="T:TestNamespace.TestClass"/> constructor as a cref
attribute.
</summary>
</member>
<member name="M:TestNamespace.TestClass.#ctor(System.Int32)">
<summary>
This sample shows how to specify the <see cref="M:TestNamespace.TestClass.#ctor(System.Int32)"/>
constructor as a cref attribute.
</summary>
</member>
<member name="M:TestNamespace.TestClass.GetZero">
<summary>
The GetZero method.
</summary>
<example>
This sample shows how to call the <see cref="M:TestNamespace.TestClass.GetZero"/> method.
<code>
class TestClass
{
static int Main()
{
return GetZero();
}
}
}
</code>
</example>
</member>
<member name="M:TestNamespace.TestClass.GetGenericValue``1(``0)">
<summary>
The GetGenericValue method.
</summary>
<remarks>
This sample shows how to specify the <see
cref="M:TestNamespace.TestClass.GetGenericValue``1(``0)"/> method as a cref attribute.
</remarks>
</member>
<member name="T:TestNamespace.GenericClass`1">
<summary>
GenericClass.
</summary>
<remarks>
This example shows how to specify the <see cref="T:TestNamespace.GenericClass`1"/> type as a cref
attribute.
</remarks>
</member>
</members> <members>
<member name="T:TestNamespace.TestClass">
<summary>
TestClass contains two cref examples.
</summary>
</member>
<member name="M:TestNamespace.TestClass.GetZero">
<summary>
The GetZero method.
</summary>
<example> This sample shows how to call the <see cref="M:TestNamespace.TestClass.GetZero"/>
method.
<code>
class TestClass
{
static int Main()
{
return GetZero();
}
}
</code>
</example>
</member>
<member name="M:TestNamespace.TestClass.GetGenericValue``1(``0)">
<summary>
The GetGenericValue method.
</summary>
<remarks>
This sample shows how to specify the <see
cref="M:TestNamespace.TestClass.GetGenericValue``1(``0)"/> method as a cref attribute.
</remarks>
</member>
<member name="T:TestNamespace.GenericClass`1">
<summary>
GenericClass.
</summary>
<remarks>
This example shows how to specify the <see cref="T:TestNamespace.GenericClass`1"/> type as a cref
attribute.
</remarks>
</member>
</members>
</doc>
Ayrıca bkz.
XML Belge Açıklamaları
Belge Açıklamaları için Önerilen Etiketler
<example > (C# Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Sözdizimi
<example>description</example>

Parametreler
description
Kod örneğinin açıklaması.

Açıklamalar
@No__t_0example > etiketi, bir yöntemin veya diğer kitaplık üyesinin nasıl kullanılacağına ilişkin bir örnek
belirtmenize olanak tanır. Bu genellikle <code > etiketinin kullanılmasını içerir.
Belge açıklamalarını bir dosyaya işlemek için -doc ile derleyin.

Örnek
// Save this file as CRefTest.cs
// Compile with: csc CRefTest.cs -doc:Results.xml

namespace TestNamespace
{
/// <summary>
/// TestClass contains several cref examples.
/// </summary>
public class TestClass
{
/// <summary>
/// This sample shows how to specify the <see cref="TestClass"/> constructor as a cref attribute.
/// </summary>
public TestClass()
{ }

/// <summary>
/// This sample shows how to specify the <see cref="TestClass(int)"/> constructor as a cref attribute.
/// </summary>
public TestClass(int value)
{ }

/// <summary>
/// The GetZero method.
/// </summary>
/// <example>
/// This sample shows how to call the <see cref="GetZero"/> method.
/// <code>
/// class TestClass
/// {
/// static int Main()
/// {
/// return GetZero();
/// }
/// }
/// </code>
/// </code>
/// </example>
public static int GetZero()
{
return 0;
}

/// <summary>
/// The GetGenericValue method.
/// </summary>
/// <remarks>
/// This sample shows how to specify the <see cref="GetGenericValue"/> method as a cref attribute.
/// </remarks>

public static T GetGenericValue<T>(T para)


{
return para;
}
}

/// <summary>
/// GenericClass.
/// </summary>
/// <remarks>
/// This example shows how to specify the <see cref="GenericClass{T}"/> type as a cref attribute.
/// </remarks>
class GenericClass<T>
{
// Fields and members.
}

class Program
{
static int Main()
{
return TestClass.GetZero();
}
}
}

Ayrıca bkz.
C# Programlama Kılavuzu
Belge Açıklamaları için Önerilen Etiketler
<exception > (C# Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Sözdizimi
<exception cref="member">description</exception>

Parametreler
cref = " member "
Geçerli derleme ortamında kullanılabilir bir özel duruma başvuru. Derleyici verilen özel durumun var olduğunu
denetler ve çıkış XML dosyasında kurallı öğe adına member çevirir. member çift tırnak işaretleri ("") içinde yer
almalıdır.
Genel bir türe başvurmak üzere member biçimlendirme hakkında daha fazla bilgi için bkz. XML dosyasını işleme.
description
Özel durumun açıklaması.

Açıklamalar
@No__t_0exception > etiketi hangi özel durumların atılamayacağını belirlemenizi sağlar. Bu etiket Yöntemler,
özellikler, olaylar ve Dizin oluşturucular için tanımlara uygulanabilir.
Belge açıklamalarını bir dosyaya işlemek için -doc ile derleyin.
Özel durum işleme hakkında daha fazla bilgi için bkz. özel durumlar ve özel durum işleme.

Örnek
// compile with: -doc:DocFileName.xml

/// Comment for class


public class EClass : System.Exception
{
// class definition...
}

/// Comment for class


class TestClass
{
/// <exception cref="System.Exception">Thrown when...</exception>
public void DoSomething()
{
try
{
}
catch (EClass)
{
}
}
}
Ayrıca bkz.
C# Programlama Kılavuzu
Belge Açıklamaları için Önerilen Etiketler
<> dahil etC# (Programlama Kılavuzu)
23.10.2019 • 3 minutes to read • Edit Online

Sözdizimi
<include file='filename' path='tagpath[@name="id"]' />

Parametreler
filename
Belgeleri içeren XML dosyasının adı. Dosya adı, kaynak kodu dosyası ile ilişkili bir yol ile nitelenme yapılabilir. Tek
filename tırnak işaretleri (' ') içine alın.

tagpath
İçindeki filename etiketlerin yolu, etikete name yol açar. Yolu tek tırnak işaretleri (' ') içine alın.
name
Yorumlarla önce gelen etiketteki ad Belirleyicisi; name , id olur.
id
Açıklamaların önündeki etiketin KIMLIĞI. KIMLIĞI çift tırnak işareti ("") içine alın.

Açıklamalar
<İçerme > etiketi, kaynak kodunuzda türleri ve üyeleri tanımlayan başka bir dosyadaki açıklamalara başvurmanıza
olanak sağlar. Bu, belge açıklamalarını doğrudan kaynak kodu dosyanıza yerleştirmeye alternatiftir. Belgeler ayrı bir
dosyaya yerleştirilerek, kaynak denetimini belgelere kaynak koddan ayrı olarak uygulayabilirsiniz. Bir kişinin
kaynak kodu dosyası kullanıma alınmış olabilir ve başka birisinin belge dosyası kullanıma alınmış olabilir.
<İçerme > etiketi XML XPath söz dizimini kullanır. <İçerme > kullanımını özelleştirmenin yolları için XPath
belgelerine bakın.

Örnek
Bu çok dosyalı bir örnektir. > <İçeren ilk dosya aşağıda listelenmiştir:
// compile with: -doc:DocFileName.xml

/// <include file='xml_include_tag.doc' path='MyDocs/MyMembers[@name="test"]/*' />


class Test
{
static void Main()
{
}
}

/// <include file='xml_include_tag.doc' path='MyDocs/MyMembers[@name="test2"]/*' />


class Test2
{
public void Test()
{
}
}

İkinci dosya olan xml_include_tag. doc, aşağıdaki belge açıklamalarını içerir:

<MyDocs>

<MyMembers name="test">
<summary>
The summary for this type.
</summary>
</MyMembers>

<MyMembers name="test2">
<summary>
The summary for this other type.
</summary>
</MyMembers>

</MyDocs>

Program çıktısı
Aşağıdaki komut satırı ile test ve test2 sınıflarını derlerken aşağıdaki çıktı oluşturulur: /doc:DocFileName.xml. Visual
Studio 'da, proje Tasarımcısı ' nın Yapı bölmesinde XML belgesi açıklamaları seçeneğini belirtirsiniz. C# Derleyici
<içerme > etiketini gördüğünde, geçerli kaynak dosya yerine xml_include_tag. doc içinde belge açıklamalarını arar.
Daha sonra derleyici DocFileName. xml oluşturur ve bu, son belgeleri oluşturmak için Docfx ve sandrole gibi belge
araçları tarafından tüketilen dosyadır.
<?xml version="1.0"?>
<doc>
<assembly>
<name>xml_include_tag</name>
</assembly>
<members>
<member name="T:Test">
<summary>
The summary for this type.
</summary>
</member>
<member name="T:Test2">
<summary>
The summary for this other type.
</summary>
</member>
</members>
</doc>

Ayrıca bkz.
C# Programlama Kılavuzu
Belge Açıklamaları için Önerilen Etiketler
<list > (C# Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Sözdizimi
<list type="bullet" | "number" | "table">
<listheader>
<term>term</term>
<description>description</description>
</listheader>
<item>
<term>term</term>
<description>description</description>
</item>
</list>

Parametreler
term
@No__t_0 tanımlanacak bir terim.
description
Bir madde işareti veya numaralandırılmış listedeki bir öğe ya da bir term tanımı.

Açıklamalar
@No__t_0listheader > bloğu, bir tablo ya da tanım listesinin başlık satırını tanımlamak için kullanılır. Bir tablo
tanımlarken, yalnızca başlıktaki terim için bir giriş sağlamanız gerekir.
Listedeki her öğe bir <item > bloğu ile belirtilir. Tanım listesi oluştururken hem term hem de description
belirtmeniz gerekir. Ancak, bir tablo, madde işaretli liste veya numaralandırılmış liste için yalnızca description için
bir giriş sağlamanız gerekir.
Bir liste veya tablo, gereken sayıda > blobundan <item sahip olabilir.
Belge açıklamalarını bir dosyaya işlemek için -doc ile derleyin.

Örnek
// compile with: -doc:DocFileName.xml

/// text for class TestClass


public class TestClass
{
/// <summary>Here is an example of a bulleted list:
/// <list type="bullet">
/// <item>
/// <description>Item 1.</description>
/// </item>
/// <item>
/// <description>Item 2.</description>
/// </item>
/// </list>
/// </summary>
static void Main()
{
}
}

Ayrıca bkz.
C# Programlama Kılavuzu
Belge Açıklamaları için Önerilen Etiketler
<para > (C# Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Sözdizimi
<para>content</para>

Parametreler
content
Paragrafın metni.

Açıklamalar
@No__t_0para > etiketi, <summary >, <remarks >veya <returns> gibi bir etiket içinde kullanım içindir ve metne
yapı eklemenizi sağlar.
Belge açıklamalarını bir dosyaya işlemek için -doc ile derleyin.

Örnek
@No__t_2para > kullanma örneği için bkz. <summary > .

Ayrıca bkz.
C# Programlama Kılavuzu
Belge Açıklamaları için Önerilen Etiketler
<param > (C# Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Sözdizimi
<param name="name">description</param>

Parametreler
name
Bir yöntem parametresinin adı. Adı çift tırnak işareti ("") içine alın.
description
Parametresi için bir açıklama.

Açıklamalar
Yöntemin parametrelerinden birini açıklayacak bir yöntem bildirimi için açıklamasında <param > etiketi
kullanılmalıdır. Birden çok parametreyi belgelemek için birden çok <param > etiketi kullanın.
@No__t_0param > etiketinin metni IntelliSense 'de, Nesne Tarayıcısı ve kod yorumu Web raporunda görüntülenir.
Belge açıklamalarını bir dosyaya işlemek için -doc ile derleyin.

Örnek
// compile with: -doc:DocFileName.xml

/// text for class TestClass


public class TestClass
{
// Single parameter.
/// <param name="Int1">Used to indicate status.</param>
public static void DoWork(int Int1)
{
}

// Multiple parameters.
/// <param name="Int1">Used to indicate status.</param>
/// <param name="Float1">Used to specify context.</param>
public static void DoWork(int Int1, float Float1)
{
}

/// text for Main


static void Main()
{
}
}

Ayrıca bkz.
C# Programlama Kılavuzu
Belge Açıklamaları için Önerilen Etiketler
<paramref > (C# Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Sözdizimi
<paramref name="name"/>

Parametreler
name
Başvurabileceğiniz parametrenin adı. Adı çift tırnak işareti ("") içine alın.

Açıklamalar
@No__t_0paramref > etiketi, kod açıklamalarındaki bir sözcüğün bir <summary > veya <remarks > bloğunun bir
parametreye başvurduğunu göstermek için bir yol sağlar. Bu sözcüğü, kalın veya italik yazı tipiyle olduğu gibi farklı
bir şekilde biçimlendirmek için XML dosyası işlenebilir.
Belge açıklamalarını bir dosyaya işlemek için -doc ile derleyin.

Örnek
// compile with: -doc:DocFileName.xml

/// text for class TestClass


public class TestClass
{
/// <summary>DoWork is a method in the TestClass class.
/// The <paramref name="int1"/> parameter takes a number.
/// </summary>
public static void DoWork(int int1)
{
}

/// text for Main


static void Main()
{
}
}

Ayrıca bkz.
C# Programlama Kılavuzu
Belge Açıklamaları için Önerilen Etiketler
<permission > (C# Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Sözdizimi
<permission cref="member">description</permission>

Parametreler
cref = " member "
Geçerli derleme ortamından çağrılabilen bir üyeye veya alana başvuru. Derleyici verilen kod öğesinin var
olduğunu denetler ve çıkış XML dosyasında kurallı öğe adına member çevirir. üye çift tırnak işareti ("") içinde yer
almalıdır.
Genel bir türe cref başvurusu oluşturma hakkında bilgi için bkz. <see >.
description
Üyeye erişim açıklaması.

Açıklamalar
@No__t_0permission > etiketi bir üyenin erişimini belgelemenizi sağlar. @No__t_0 sınıfı, bir üyeye erişim
belirtmenize olanak tanır.
Belge açıklamalarını bir dosyaya işlemek için -doc ile derleyin.

Örnek
// compile with: -doc:DocFileName.xml

class TestClass
{
/// <permission cref="System.Security.PermissionSet">Everyone can access this method.</permission>
public static void Test()
{
}

static void Main()


{
}
}

Ayrıca bkz.
C# Programlama Kılavuzu
Belge Açıklamaları için Önerilen Etiketler
<remarks > (C# Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Sözdizimi
<remarks>description</remarks>

Parametreler
Description
Üyenin açıklaması.

Açıklamalar
@No__t_0remarks > etiketi, <summary >ile belirtilen bilgileri kullanarak bir tür hakkında bilgi eklemek için
kullanılır. Bu bilgiler Nesne Tarayıcısı penceresinde görüntülenir.
Belge açıklamalarını bir dosyaya işlemek için -doc ile derleyin.

Örnek
// compile with: -doc:DocFileName.xml

/// <summary>
/// You may have some primary information about this class.
/// </summary>
/// <remarks>
/// You may have some additional information about this class.
/// </remarks>
public class TestClass
{
/// text for Main
static void Main()
{
}
}

Ayrıca bkz.
C# Programlama Kılavuzu
Belge Açıklamaları için Önerilen Etiketler
<returns > (C# Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Sözdizimi
<returns>description</returns>

Parametreler
description
Dönüş değerinin açıklaması.

Açıklamalar
@No__t_0returns > etiketi, dönüş değerini betimleyen bir yöntem bildiriminin açıklamasında kullanılmalıdır.
Belge açıklamalarını bir dosyaya işlemek için -doc ile derleyin.

Örnek
// compile with: -doc:DocFileName.xml

/// text for class TestClass


public class TestClass
{
/// <returns>Returns zero.</returns>
public static int GetZero()
{
return 0;
}

/// text for Main


static void Main()
{
}
}

Ayrıca bkz.
C# Programlama Kılavuzu
Belge Açıklamaları için Önerilen Etiketler
<bkz. >C# (Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Sözdizimi
<see cref="member"/>

Parametreler
cref = " member "
Geçerli derleme ortamından çağrılabilen bir üyeye veya alana başvuru. Derleyici verilen kod öğesinin var
olduğunu denetler ve çıkış XML dosyasında member öğe adına geçirir. Üyeyi çift tırnak işareti ("") içine koyun.

Açıklamalar
> <Etiketi, metnin içinden bir bağlantı belirtmenize olanak tanır. Ayrıca, metnin See de bir bölümüne
yerleştirilmesi gerektiğini belirtmek için <de seede > kullanın. Kod öğeleri için belge sayfalarına iç köprüler
oluşturmak üzere cref özniteliğini kullanın.
Belge açıklamalarını bir dosyaya işlemek için -doc ile derleyin.
Aşağıdaki örnek bir Özet bölümü <içindeki bir See > etiketini gösterir.

// compile with: -doc:DocFileName.xml

/// text for class TestClass


public class TestClass
{
/// <summary>DoWork is a method in the TestClass class.
/// <para>Here's how you could make a second paragraph in a description. <see
cref="System.Console.WriteLine(System.String)"/> for information about output statements.</para>
/// <seealso cref="TestClass.Main"/>
/// </summary>
public static void DoWork(int Int1)
{
}

/// text for Main


static void Main()
{
}
}

Ayrıca bkz.
C# Programlama Kılavuzu
Belge Açıklamaları için Önerilen Etiketler
<seealso > (C# Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Sözdizimi
<seealso cref="member"/>

Parametreler
cref = " member "
Geçerli derleme ortamından çağrılabilen bir üyeye veya alana başvuru. Derleyici verilen kod öğesinin var
olduğunu denetler ve çıkış XML dosyasında öğe adına member geçirir. member Çift tırnak işaretleri ("") içinde yer
almalıdır.
Genel bir türe cref başvurusu oluşturma hakkında bilgi için bkz. <see >.

Açıklamalar
@No__t_0seealso > etiketi, Ayrıca bkz. bölümünde görünmesini isteyebileceğiniz metni belirtmenize olanak tanır.
Metnin içinden bir bağlantı belirtmek için <see > kullanın.
Belge açıklamalarını bir dosyaya işlemek için -doc ile derleyin.

Örnek
@No__t_2seealso > kullanma örneği için bkz. <summary > .

Ayrıca bkz.
C# Programlama Kılavuzu
Belge Açıklamaları için Önerilen Etiketler
<summary > (C# Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Sözdizimi
<summary>description</summary>

Parametreler
description
Nesnenin Özeti.

Açıklamalar
@No__t_0summary > etiketi bir tür veya tür üyesini tanımlamakta kullanılmalıdır. Bir tür açıklamasına ek bilgi
eklemek için <remarks > kullanın. Kod öğeleri için belge sayfalarına iç köprüler oluşturmak üzere Docfx ve
sandrole gibi belge araçlarını etkinleştirmek için cref özniteliğini kullanın.
@No__t_0summary > etiketinin metni, IntelliSense 'deki türle ilgili tek bilgi kaynağıdır ve ayrıca Nesne Tarayıcısı
penceresinde de görüntülenir.
Belge açıklamalarını bir dosyaya işlemek için -doc ile derleyin. Derleyici tarafından oluşturulan dosyayı temel
alan son belgeleri oluşturmak için özel bir araç oluşturabilir veya Docfx veya sandrolegibi bir araç
kullanabilirsiniz.

Örnek
// compile with: -doc:DocFileName.xml

/// text for class TestClass


public class TestClass
{
/// <summary>DoWork is a method in the TestClass class.
/// <para>Here's how you could make a second paragraph in a description. <see
cref="System.Console.WriteLine(System.String)"/> for information about output statements.</para>
/// <seealso cref="TestClass.Main"/>
/// </summary>
public static void DoWork(int Int1)
{
}

/// text for Main


static void Main()
{
}
}

Önceki örnek aşağıdaki XML dosyasını üretir.


<?xml version="1.0"?>
<doc>
<assembly>
<name>YourNamespace</name>
</assembly>
<members>
<member name="T:DotNetEvents.TestClass">
text for class TestClass
</member>
<member name="M:DotNetEvents.TestClass.DoWork(System.Int32)">
<summary>DoWork is a method in the TestClass class.
<para>Here's how you could make a second paragraph in a description. <see
cref="M:System.Console.WriteLine(System.String)"/> for information about output statements.</para>
<seealso cref="M:DotNetEvents.TestClass.Main"/>
</summary>
</member>
<member name="M:DotNetEvents.TestClass.Main">
text for Main
</member>
</members>
</doc>

Örnek
Aşağıdaki örnek, genel bir türe cref başvurusunun nasıl yapılacağını gösterir.

// compile with: -doc:DocFileName.xml

// the following cref shows how to specify the reference, such that,
// the compiler will resolve the reference
/// <summary cref="C{T}">
/// </summary>
class A { }

// the following cref shows another way to specify the reference,


// such that, the compiler will resolve the reference
// <summary cref="C &lt; T &gt;">

// the following cref shows how to hard-code the reference


/// <summary cref="T:C`1">
/// </summary>
class B { }

/// <summary cref="A">


/// </summary>
/// <typeparam name="T"></typeparam>
class C<T> { }

Önceki örnek aşağıdaki XML dosyasını üretir.


<?xml version="1.0"?>
<doc>
<assembly>
<name>YourNamespace</name>
</assembly>
<members>
<member name="T:ExtensionMethodsDemo1.A">
<summary cref="T:ExtensionMethodsDemo1.C`1">
</summary>
</member>
<member name="T:ExtensionMethodsDemo1.B">
<summary cref="T:C`1">
</summary>
</member>
<member name="T:ExtensionMethodsDemo1.C`1">
<summary cref="T:ExtensionMethodsDemo1.A">
</summary>
<typeparam name="T"></typeparam>
</member>
</members>
</doc>

Ayrıca bkz.
C# Programlama Kılavuzu
Belge Açıklamaları için Önerilen Etiketler
<typeparam > (C# Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Sözdizimi
<typeparam name="name">description</typeparam>

Parametreler
name
Tür parametresinin adı. Adı çift tırnak işareti ("") içine alın.
description
Tür parametresi için bir açıklama.

Açıklamalar
@No__t_0 etiketi, bir tür parametresini betimleyen genel tür veya yöntem bildirimine ilişkin açıklamada
kullanılmalıdır. Genel tür veya metodun her tür parametresi için bir etiket ekleyin.
Daha fazla bilgi için bkz. Genel türler.
@No__t_0 etiketinin metni IntelliSense 'de, nesne tarayıcısı pencere kodu açıklama Web raporunda görüntülenir.
Belge açıklamalarını bir dosyaya işlemek için -doc ile derleyin.

Örnek
// compile with: -doc:DocFileName.xml

/// comment for class


public class TestClass
{
/// <summary>
/// Creates a new array of arbitrary type <typeparamref name="T"/>
/// </summary>
/// <typeparam name="T">The element type of the array</typeparam>
public static T[] mkArray<T>(int n)
{
return new T[n];
}
}

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
Belge Açıklamaları için Önerilen Etiketler
<typeparamref > (C# Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Sözdizimi
<typeparamref name="name"/>

Parametreler
name
Tür parametresinin adı. Adı çift tırnak işareti ("") içine alın.

Açıklamalar
Genel türlerde ve yöntemlerde tür parametreleri hakkında daha fazla bilgi için bkz. Genel türler.
Belge dosyasının tüketicilerini farklı bir şekilde (örneğin, italik) biçimlendirmesini sağlamak için bu etiketi kullanın.
Belge açıklamalarını bir dosyaya işlemek için -doc ile derleyin.

Örnek
// compile with: -doc:DocFileName.xml

/// comment for class


public class TestClass
{
/// <summary>
/// Creates a new array of arbitrary type <typeparamref name="T"/>
/// </summary>
/// <typeparam name="T">The element type of the array</typeparam>
public static T[] mkArray<T>(int n)
{
return new T[n];
}
}

Ayrıca bkz.
C# Programlama Kılavuzu
Belge Açıklamaları için Önerilen Etiketler
<value > (C# Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Sözdizimi
<value>property-description</value>

Parametreler
property-description
Özelliği için bir açıklama.

Açıklamalar
@No__t_0value > etiketi, bir özelliğin temsil ettiği değeri açıklamanıza olanak sağlar. Visual Studio .NET geliştirme
ortamında kod Sihirbazı aracılığıyla bir özellik eklediğinizde, yeni özellik için bir <summary > etiketi ekleneceğini
unutmayın. Sonra özelliğin temsil ettiği değeri tanımlayan bir <value > etiketini el ile eklemeniz gerekir.
Belge açıklamalarını bir dosyaya işlemek için -doc ile derleyin.

Örnek
// compile with: -doc:DocFileName.xml

/// text for class Employee


public class Employee
{
private string _name;

/// <summary>The Name property represents the employee's name.</summary>


/// <value>The Name property gets/sets the value of the string field, _name.</value>

public string Name


{
get
{
return _name;
}
set
{
_name = value;
}
}
}

/// text for class MainClass


public class MainClass
{
/// text for Main
static void Main()
{
}
}
Ayrıca bkz.
C# Programlama Kılavuzu
Belge Açıklamaları için Önerilen Etiketler
Özel Durumlar ve Özel Durum İşleme (C#
Programlama Kılavuzu)
4.11.2019 • 5 minutes to read • Edit Online

C# Dilin özel durum işleme özellikleri, bir program çalışırken oluşan beklenmedik veya olağanüstü durumlarla
ilgilenmenize yardımcı olur. Özel durum işleme, başarılı olmayan eylemleri denemek için try , catch ve
finally anahtar sözcüklerini kullanır, bunu yapmak için makul olduğuna karar verirken sorunları idare edin ve
daha sonra kaynakları temizleyebiliriz. Özel durumlar ortak dil çalışma zamanı (CLR ) tarafından, .NET Framework
veya herhangi bir üçüncü taraf kitaplığı tarafından ya da uygulama kodu tarafından oluşturulabilir. Özel durumlar
throw anahtar sözcüğü kullanılarak oluşturulur.

Çoğu durumda, kodunuzun doğrudan çağırdığı bir yöntem tarafından değil, çağrı yığınında daha sonra başka bir
yöntem tarafından bir özel durum atılır. Bu durumda, CLR, belirli bir özel durum türü için catch bloğuna sahip
bir yöntemi arayarak yığını yeniden yürütür ve bulduğu ilk catch bloğunu yürütür. Çağrı yığınında herhangi bir
yerde uygun catch bloğu bulursa, işlemi sonlandırır ve kullanıcıya bir ileti görüntüler.
Bu örnekte, bir yöntem sıfıra bölme için test eder ve hatayı yakalar. Özel durum işleme olmadan, bu program bir
Dividebysıfırlaması özel durumu ile sonlandırılır ve işlenmemiş bir hatadır.

class ExceptionTest
{
static double SafeDivision(double x, double y)
{
if (y == 0)
throw new System.DivideByZeroException();
return x / y;
}
static void Main()
{
// Input for test purposes. Change the values to see
// exception handling behavior.
double a = 98, b = 0;
double result = 0;

try
{
result = SafeDivision(a, b);
Console.WriteLine("{0} divided by {1} = {2}", a, b, result);
}
catch (DivideByZeroException e)
{
Console.WriteLine("Attempted divide by zero.");
}
}
}

Özel durumlara genel bakış


Özel durumlar aşağıdaki özelliklere sahiptir:
Özel durumlar, sonuçta System.Exception ' dan türetilen türlerdir.
Özel durum oluşturabilecek deyimler etrafında try bloğu kullanın.
try bloğunda bir özel durum oluştuktan sonra Denetim akışı, çağrı yığınında herhangi bir yerde bulunan ilk
ilişkili özel durum işleyicisine atlar. ' C#De, bir özel durum işleyicisini tanımlamak için catch anahtar sözcüğü
kullanılır.
Belirli bir özel durum için özel durum işleyicisi yoksa, program yürütmeyi bir hata iletisiyle sonlandırır.
İşleyebilmediğiniz ve uygulamayı bilinen bir durumda bırakarak bir özel durumu yakalamayın.
System.Exception yakalarsanız catch bloğunun sonundaki throw anahtar sözcüğünü kullanarak yeniden
oluşturun.
Bir catch bloğu bir özel durum değişkeni tanımlıyorsa, oluşan özel durum türü hakkında daha fazla bilgi
edinmek için onu kullanabilirsiniz.
Özel durumlar, throw anahtar sözcüğü kullanılarak açıkça bir program tarafından oluşturulabilir.
Özel durum nesneleri, hata hakkında, çağrı yığınının durumu ve hatanın metin açıklaması gibi ayrıntılı bilgiler
içerir.
Bir özel durum oluşsa bile finally bloğundaki kod yürütülür. Kaynakları serbest bırakmak için finally
bloğu kullanın, örneğin, try bloğunda açılan tüm akışları veya dosyaları kapatın.
.NET Framework yönetilen özel durumlar, Win32 yapılandırılmış özel durum işleme mekanizmasının üzerine
uygulanır. Daha fazla bilgi için, bkz. yapılandırılmış özel durum işlemeC++(C/) ve Win32 yapılandırılmış özel
durum işleme derinlikleri üzerinde çökme kursu.

İlgili Bölümler
Özel durumlar ve özel durum işleme hakkında daha fazla bilgi için aşağıdaki makalelere bakın:
Özel Durumları Kullanma
Özel Durum İşleme
Özel Durumlar Oluşturma ve Atma
Derleyicinin Ürettiği Özel Durumlar
Nasıl yapılır: try/catch kullanarak özel durum Işleme (C# Programlama Kılavuzu)
Nasıl yapılır: Finally Kullanarak Temizleme Kodu Yürütme
Nasıl yapılır: CLS Olmayan Özel Durum Yakalama

C# Dil Belirtimi
Daha fazla bilgi için bkz. C# dil belirtiminde özel durumlar . Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
SystemException
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
throw
try-catch
try-finally
try-catch-finally
Özel Durumlar
Özel Durumlar Kullanma (C# Programlama Kılavuzu)
23.10.2019 • 5 minutes to read • Edit Online

İçinde C#, çalışma zamanında programdaki hatalar, özel durumlar adlı bir mekanizma kullanılarak program
aracılığıyla dağıtılır. Özel durumlar, hata ile karşılaştığında ve hatayı düzeltebileceğiniz kodla yakalanan kodla
oluşturulur. Özel durumlar .NET Framework ortak dil çalışma zamanı (CLR ) veya bir programdaki kodla
oluşturulabilir. Bir özel durum oluşturulduktan sonra, özel durum için bir catch ifade bulunana kadar çağrı yığınını
yayar. Yakalanamayan özel durumlar, bir iletişim kutusu görüntüleyen sistem tarafından sunulan genel bir özel
durum işleyicisi tarafından işlenir.
Özel durumlar, öğesinden Exceptiontüretilmiş sınıflar tarafından temsil edilir. Bu sınıf, özel durum türünü tanımlar
ve özel durumla ilgili ayrıntıları içeren özellikleri içerir. Özel durum oluşturmak, özel durum türetilmiş sınıfın bir
örneğini oluşturmayı, isteğe bağlı olarak özel durumun özelliklerini yapılandırmayı ve sonra throw anahtar
sözcüğünü kullanarak nesneyi oluşturmayı içerir. Örneğin:

class CustomException : Exception


{
public CustomException(string message)
{

}
private static void TestThrow()
{
CustomException ex =
new CustomException("Custom exception in TestThrow()");

throw ex;
}

Bir özel durum oluşturulduktan sonra, çalışma zamanı bir try blok içinde olup olmadığını görmek için geçerli
ifadeyi denetler. Eğer ise, try bloğuyla catch ilişkili herhangi bir blok, özel durumu yakalayıp
yakalayamayacağını görmek için denetlenir. Catch bloklar genellikle özel durum türlerini belirtir; catch bloğun
türü özel durumla aynı türde veya özel durumun catch temel bir sınıfı ise, blok yöntemi işleyebilir. Örneğin:

static void TestCatch()


{
try
{
TestThrow();
}
catch (CustomException ex)
{
System.Console.WriteLine(ex.ToString());
}
}

Bir özel durum oluşturan ifade bir blok içinde try değilse veya try kendisini kapsayan blok eşleşen catch bir
blok içindeyse, çalışma zamanı bir try deyimin ve catch blokların çağırma yöntemini denetler. Çalışma zamanı,
arama yığınını devam ettirir ve uyumlu catch bir blok arar. Blok bulduktan ve yürütüldükten sonra, denetim bu
catch blok sonrasında sonraki ifadeye geçirilir. catch
Bir try ifade, birden fazla catch blok içerebilir. Özel durumu catch işleyebilen ilk deyim yürütülür; uyumlu
olsalar bile aşağıdaki catch deyimler yok sayılır. Bu nedenle, catch blokları her zaman en belirli (veya en çok
türetilen) en azından belirli bir şekilde sıralanmalıdır. Örneğin:

using System;
using System.IO;

public class ExceptionExample


{
static void Main()
{
try
{
using (var sw = new StreamWriter(@"C:\test\test.txt"))
{
sw.WriteLine("Hello");
}
}
// Put the more specific exceptions first.
catch (DirectoryNotFoundException ex)
{
Console.WriteLine(ex);
}
catch (FileNotFoundException ex)
{
Console.WriteLine(ex);
}
// Put the least specific exception last.
catch (IOException ex)
{
Console.WriteLine(ex);
}

Console.WriteLine("Done");
}
}

Blok yürütülmeden önce, çalışma zamanı finally blokları denetler. catch Finally bloklar, programcı 'nin
durdurulmuş try bir bloktan veya herhangi bir dış kaynağın (grafik tutamaçları, veritabanı bağlantıları veya dosya
akışları gibi) çöp kutusu beklemeden serbest bırakılması için herhangi bir belirsiz durumu temizlemesini sağlar
nesneleri sonlandırmak için çalışma zamanında toplayıcı. Örneğin:
static void TestFinally()
{
System.IO.FileStream file = null;
//Change the path to something that works on your machine.
System.IO.FileInfo fileInfo = new System.IO.FileInfo(@"C:\file.txt");

try
{
file = fileInfo.OpenWrite();
file.WriteByte(0xF);
}
finally
{
// Closing the file allows you to reopen it immediately - otherwise IOException is thrown.
if (file != null)
{
file.Close();
}
}

try
{
file = fileInfo.OpenWrite();
System.Console.WriteLine("OpenWrite() succeeded");
}
catch (System.IO.IOException)
{
System.Console.WriteLine("OpenWrite() failed");
}
}

Bir özel durum, çağrılırsa dosyayı yeniden açmaya çalışan ikinci try bloktaki kod başarısız file.Close() olur ve
dosya kilitli kalır. WriteByte() Bir özel durum oluşsa bile finally
bloklaryürütüldüğüiçin,öncekiörnektekiblokdosyanındüzgünşekildekapatılmasınısağlarvebirhatadankaçınmayayard
ımcıolur. finally
Bir özel durum catch oluşturulduktan sonra çağrı yığınında uyumlu bir blok bulunmazsa, üç durumdan biri
oluşur:
Özel durum bir Sonlandırıcı içindeyse Sonlandırıcı iptal edilir ve varsa taban sonlandırıcısı çağırılır.
Çağrı yığını statik bir Oluşturucu içeriyorsa veya bir statik alan Başlatıcısı TypeInitializationException varsa,
özgün özel durum yeni özel durumun InnerException özelliğine atanır.
İş parçacığının başlangıcına ulaşıldığında, iş parçacığı sonlandırılır.

Ayrıca bkz.
C# Programlama Kılavuzu
Özel Durumlar ve Özel Durum İşleme
Özel Durum İşleme (C# Programlama Kılavuzu)
4.11.2019 • 6 minutes to read • Edit Online

TRY bloğu, programcılar tarafından C# bir özel durumdan etkilenebilecek kodu bölümlemek için kullanılır. İlişkili
catch blokları, ortaya çıkan özel durumları işlemek için kullanılır. Finally bloğu, try bloğunda ayrılan kaynakları
serbest bırakma gibi try bloğunda bir özel durumun oluşturulup oluşturulmayacağını bakılmaksızın çalıştırılan
kodu içerir. try bir blok, bir veya daha fazla ilişkili catch bloğunu veya finally bloğunu veya her ikisini de
gerektirir.
Aşağıdaki örneklerde bir try-catch ifadeyi, bir try-finally ifadesini ve try-catch-finally ifadesini gösterir.

try
{
// Code to try goes here.
}
catch (SomeSpecificException ex)
{
// Code to handle the exception goes here.
// Only catch exceptions that you know how to handle.
// Never catch base class System.Exception without
// rethrowing it at the end of the catch block.
}

try
{
// Code to try goes here.
}
finally
{
// Code to execute after the try block goes here.
}

try
{
// Code to try goes here.
}
catch (SomeSpecificException ex)
{
// Code to handle the exception goes here.
}
finally
{
// Code to execute after the try (and possibly catch) blocks
// goes here.
}

catch veya finally bloğu olmayan try bloğu bir derleyici hatasına neden olur.

Catch blokları
catch bloğu, yakalamak için özel durum türünü belirtebilir. Tür belirtimine özel durum filtresidenir. Özel durum
türü Exceptiontüretilmelidir. Genel olarak, try bloğunda oluşturulan tüm özel durumları nasıl işleyebileceğinizi
veya catch blobunun sonuna bir throw bildirisi eklemiş olmanız durumunda özel durum filtresi olarak Exception
belirtmeyin.
Farklı özel durum filtrelerine sahip birden çok catch bloğu birlikte zincirlenebilir. catch blokları kodunuzda
yukarıdan aşağıya değerlendirilir, ancak oluşturulan her özel durum için yalnızca bir catch bloğu yürütülür.
Oluşturulan özel durumun tam türünü veya temel sınıfını belirten ilk catch bloğu yürütülür. catch bloğu eşleşen
bir özel durum filtresi belirtiyorsa, deyimde bir filtre varsa, filtresi olmayan bir catch bloğu seçilir. En belirli (yani,
en türetilmiş) özel durum türleri catch blokları konumlandırmak önemlidir.
Aşağıdaki koşullar doğru olduğunda özel durumları yakalamalı:
Özel durumun neden oluşturulması gerektiği konusunda iyi bir fikir sahibi olabilirsiniz ve bir
FileNotFoundException nesnesi yakalarsanız kullanıcıdan yeni bir dosya adı girmesini isteme gibi belirli bir
kurtarma uygulayabilirsiniz.
Yeni, daha özel bir özel durum oluşturabilir ve silebilirsiniz.

int GetInt(int[] array, int index)


{
try
{
return array[index];
}
catch(System.IndexOutOfRangeException e)
{
throw new System.ArgumentOutOfRangeException(
"Parameter index is out of range.", e);
}
}

Ek işleme için geçirmeden önce bir özel durumu kısmen işlemek istiyorsunuz. Aşağıdaki örnekte, özel
durumu yeniden oluşturmadan önce bir hata günlüğüne giriş eklemek için bir catch bloğu kullanılır.

try
{
// Try to access a resource.
}
catch (System.UnauthorizedAccessException e)
{
// Call a custom error logging procedure.
LogError(e);
// Re-throw the error.
throw;
}

Finally blokları
finally bir blok, bir try bloğunda gerçekleştirilen eylemleri temizlemenize olanak sağlar. Varsa, try bloğundan
ve eşleşen catch bloğundan sonra finally bloğu son yürütülür. Bir özel durumun oluşturulup
oluşturulmayacağını veya özel durum türüyle eşleşen bir catch bloğunun bulunup bulunamadığına bakılmaksızın
finally bloğu her zaman çalışır.

finally bloğu, çalışma zamanındaki çöp toplayıcısının nesneleri son haline getirilmeksizin dosya akışları,
veritabanı bağlantıları ve grafik tutamaçları gibi kaynakları serbest bırakmak için kullanılabilir. Daha fazla bilgi için
bkz. using deyimleri .
Aşağıdaki örnekte, finally bloğu try bloğunda açılan bir dosyayı kapatmak için kullanılır. Dosya tutamacı
durumunun, dosya kapatılmadan önce denetlendiğine dikkat edin. try bloğu dosyayı açmayabilir, dosya tanıtıcısı
yine de null değerine sahiptir ve finally bloğu bunu kapatmayı denemez. Alternatif olarak, try bloğunda
dosya başarılı bir şekilde açılırsa, finally bloğu açık dosyayı kapatır.
System.IO.FileStream file = null;
System.IO.FileInfo fileinfo = new System.IO.FileInfo("C:\\file.txt");
try
{
file = fileinfo.OpenWrite();
file.WriteByte(0xF);
}
finally
{
// Check for null because OpenWrite might have failed.
if (file != null)
{
file.Close();
}
}

C# Dil Belirtimi
Daha fazla bilgi için bkz. C# dil belirtiminde Exceptions ve TRY deyimleri . Dil belirtimi, C# sözdizimi ve kullanımı
için kesin bir kaynaktır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
Özel Durumlar ve Özel Durum İşleme
try-catch
try-finally
try-catch-finally
using Deyimi
Özel Durumlar Oluşturma ve Atma (C# Programlama
Kılavuzu)
4.11.2019 • 6 minutes to read • Edit Online

Özel durumlar, programı çalıştırırken bir hata oluştuğunu göstermek için kullanılır.Bir hatayı tanımlayan özel
durum nesneleri oluşturulur ve throw anahtar sözcüğüyle oluşturulur. Çalışma zamanı, en uyumlu özel durum
işleyicisini arar.
Aşağıdaki koşullardan biri veya daha fazlası doğru olduğunda programcılar özel durumlar atmalıdır:
Yöntem, tanımlı işlevini tamamlayamıyor.
Örneğin, bir yönteme ait bir parametre geçersiz bir değere sahipse:

static void CopyObject(SampleClass original)


{
if (original == null)
{
throw new System.ArgumentException("Parameter cannot be null", "original");
}

Nesne durumuna bağlı olarak bir nesneye uygun olmayan bir çağrı yapılır.
Bir örnek, salt okunurdur bir dosyaya yazmaya çalışıyor olabilir. Bir nesne durumunun bir işleme izin
vermediği durumlarda, bu sınıfın bir türetmesi temelinde InvalidOperationException veya bir nesnesi örneği
oluşturun. Bu, InvalidOperationException nesnesi oluşturan bir yönteme örnektir:

class ProgramLog
{
System.IO.FileStream logFile = null;
void OpenLog(System.IO.FileInfo fileName, System.IO.FileMode mode) {}

void WriteLog()
{
if (!this.logFile.CanWrite)
{
throw new System.InvalidOperationException("Logfile cannot be read-only");
}
// Else write data to the log and return.
}
}

Bir yöntemin bağımsız değişkeni bir özel duruma neden olur.


Bu durumda, özgün özel durumun yakalanmalı ve bir ArgumentException örneğinin oluşturulması gerekir.
Özgün özel durumun InnerException parametresi olarak ArgumentException oluşturucusuna geçirilmesi
gerekir:
static int GetValueFromArray(int[] array, int index)
{
try
{
return array[index];
}
catch (System.IndexOutOfRangeException ex)
{
System.ArgumentException argEx = new System.ArgumentException("Index is out of range", "index",
ex);
throw argEx;
}
}

Özel durumlar StackTraceadlı bir özellik içerir. Bu dize, geçerli çağrı yığınındaki yöntemlerin adını, her yöntem için
özel durumun oluşturulduğu dosya adı ve satır numarasıyla birlikte içerir. Bir StackTrace nesnesi, throw deyimin
noktasındaki ortak dil çalışma zamanı (CLR ) tarafından otomatik olarak oluşturulur. böylece, yığın izlemenin
başlayacağı noktadan özel durumlar oluşturulmalıdır.
Tüm özel durumlar Messageadlı bir özellik içerir. Bu dize, özel durumun nedenini açıklamak için ayarlanmalıdır.
Güvenliğe duyarlı bilgilerin ileti metnine yerleştirilmemelidir. Messageek olarak, ArgumentException, özel
durumun oluşturulmasına neden olan bağımsız değişkenin adı olarak ayarlanması gereken ParamName adlı bir
özellik içerir. Özellik ayarlayıcısı durumunda, ParamName value olarak ayarlanmalıdır.
Ortak ve korumalı Yöntemler, kendilerine amaçlanan işlevleri tamamlanamadığında özel durumlar atmalıdır.
Oluşturulan özel durum sınıfı, hata koşullarına uyan en belirgin özel durum olmalıdır. Bu özel durumlar, sınıf
işlevselliğinin bir parçası olarak belgelenmelidir ve özgün sınıftaki türetilmiş sınıflar veya güncelleştirmeler geriye
dönük uyumluluk için aynı davranışı korurlar.

Özel durumlar oluştururken kaçınmak için gerekenler


Aşağıdaki liste, özel durumlar oluştururken kaçınmak için Yöntemler tanımlar:
Özel durumlar, bir programın akışını sıradan yürütmenin parçası olarak değiştirmek için kullanılmamalıdır.
Özel durumlar yalnızca hata koşullarını raporlamak ve işlemek için kullanılmalıdır.
Özel durumlar, oluşturulması yerine dönüş değeri veya parametresi olarak döndürülmemelidir.
System.Exception, System.SystemException, System.NullReferenceExceptionveya
System.IndexOutOfRangeException kasıtlı olarak kendi kaynak kodınızdan atamayın.
Hata ayıklama modunda, ancak serbest bırakma modunda oluşturulabilecek özel durumlar oluşturmayın.
Geliştirme aşamasında çalışma zamanı hatalarını belirlemek için bunun yerine hata ayıklama onayı kullanın.

Özel durum sınıfları tanımlama


Programlar, System ad alanında önceden tanımlanmış bir özel durum sınıfı oluşturabilir (daha önce belirtilen
durumlar hariç) veya Exceptiontüreterek kendi özel durum sınıflarını oluşturabilir. Türetilmiş sınıflar en az dört
Oluşturucu tanımlamalıdır: tek parametresiz bir Oluşturucu, ileti özelliğini ayarlayan diğeri ve hem Message hem
de InnerException özelliklerini ayarlayan. Dördüncü Oluşturucu özel durumu seri hale getirmek için kullanılır. Yeni
özel durum sınıfları seri hale getirilebilir olmalıdır. Örneğin:
[Serializable()]
public class InvalidDepartmentException : System.Exception
{
public InvalidDepartmentException() : base() { }
public InvalidDepartmentException(string message) : base(message) { }
public InvalidDepartmentException(string message, System.Exception inner) : base(message, inner) { }

// A constructor is needed for serialization when an


// exception propagates from a remoting server to the client.
protected InvalidDepartmentException(System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
}

Yeni özellikler özel durumu çözmek için yararlı olduğunda yalnızca özel durum sınıfına eklenmelidir. Türetilmiş özel
durum sınıfına yeni özellikler eklenirse, eklenen bilgileri döndürmek için ToString() geçersiz kılınmalıdır.

C# Dil Belirtimi
Daha fazla bilgi için bkz. C# dil belirtiminde Exceptions ve throw deyimleri . Dil belirtimi, C# sözdizimi ve kullanımı
için kesin bir kaynaktır.

Ayrıca bkz.
C# Programlama Kılavuzu
Özel Durumlar ve Özel Durum İşleme
Özel durum hiyerarşisi
Özel Durum İşleme
Derleyicinin Ürettiği Özel Durumlar (C# Programlama
Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Bazı özel durumlar, temel işlemler başarısız olduğunda .NET Framework ortak dil çalışma zamanı (CLR ) tarafından
otomatik olarak oluşturulur. Bu özel durumlar ve bunların hata koşulları aşağıdaki tabloda listelenmiştir.

ÖZEL DURUM AÇIKLAMA

ArithmeticException DivideByZeroException VeOverflowExceptiongibi aritmetik


işlemler sırasında oluşan özel durumlar için temel sınıf.

ArrayTypeMismatchException Öğenin gerçek türü dizinin gerçek türüyle uyumlu


olmadığından, bir dizi belirli bir öğeyi depolayamadığı zaman
oluşturulur.

DivideByZeroException İntegral değeri sıfıra bölmek için bir deneme yapıldığında


oluşturulur.

IndexOutOfRangeException Dizin sıfırdan küçükse veya dizinin sınırları dışında bir diziyi
dizinlemek için bir girişim yapıldığında oluşturulur.

InvalidCastException Temel türden bir arabirime ya da türetilmiş bir türe açık bir
dönüştürme çalışma zamanında başarısız olduğunda
oluşturulur.

NullReferenceException Değeri nullolan bir nesneye başvuru yapmaya çalıştığınızda


oluşturulur.

OutOfMemoryException New işlecini kullanarak bellek ayırma girişimi başarısız


olduğunda oluşturulur. Bu, ortak dil çalışma zamanı için
kullanılabilir belleğin tükendiğini gösterir.

OverflowException checked Bağlamdaki aritmetik işlem taştığında oluşturulur.

StackOverflowException Yürütme yığını çok fazla sayıda bekleyen Yöntem çağrısı ile
tükendiğinde oluşturulur; genellikle çok derin veya sonsuz
özyineleme gösterir.

TypeInitializationException Statik bir Oluşturucu bir özel durum oluşturduğunda ve bunu


yakalamak için catch uyumlu bir yan tümce yoksa
oluşturulur.

Ayrıca bkz.
C# Programlama Kılavuzu
Özel Durumlar ve Özel Durum İşleme
Özel Durum İşleme
try-catch
try-finally
try-catch-finally
Nasıl yapılır: Try/catch kullanarak özel durum işleme
(C# Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Try-catch bloğunun amacı, çalışma kodu tarafından oluşturulan bir özel durumu yakalamak ve işleymelidir. Bazı
özel durumlar bir catch blokta işlenebilir ve sorun yeniden oluşturulan özel durum olmadan çözüldü; ancak,
genellikle yapabileceğiniz tek şey uygun özel durumun atılmasından emin olabilir.

Örnek
Bu örnekte, IndexOutOfRangeException en uygun özel durum değildir: ArgumentOutOfRangeException index
hata, çağıran tarafından geçirilen bağımsız değişkenin nedeni olduğundan yöntem için daha anlamlı hale gelir.

class TestTryCatch
{
static int GetInt(int[] array, int index)
{
try
{
return array[index];
}
catch (System.IndexOutOfRangeException e) // CS0168
{
System.Console.WriteLine(e.Message);
// Set IndexOutOfRangeException to the new exception's InnerException.
throw new System.ArgumentOutOfRangeException("index parameter is out of range.", e);
}
}
}

Açıklamalar
Özel duruma neden olan kod try bloğa alınmıştır. Bir catch ifade, gerçekleşirse, işleme
IndexOutOfRangeException hemen sonra eklenir. Bloğu öğesini işler ve bunun yerine daha uygun
ArgumentOutOfRangeException özel durumu oluşturur. IndexOutOfRangeException catch Çağıranı mümkün
olduğunca fazla bilgi sağlamak için, özgün özel durumu yeni özel durum olarak InnerException belirtmeyi göz
önünde bulundurun. Özelliği ReadOnly olduğundan, bunu yeni özel durumun oluşturucusunda atamanız gerekir.
InnerException

Ayrıca bkz.
C# Programlama Kılavuzu
Özel Durumlar ve Özel Durum İşleme
Özel Durum İşleme
Nasıl yapılır: Son kullanılan temizleme kodunu
yürütme (C# Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Bir finally deyimin amacı, genellikle özel bir durum oluşsa bile, genellikle dış kaynakları tutan nesneler olan
nesnelerin gerekli temizleme işleminin hemen gerçekleşmemesini sağlamaktır. Bu tür temizliğin bir örneği, Close
nesnenin ortak FileStream dil çalışma zamanı tarafından çöp toplanmasını beklemek yerine, aşağıdaki gibi, hemen
sonrasında çağrılır:

static void CodeWithoutCleanup()


{
System.IO.FileStream file = null;
System.IO.FileInfo fileInfo = new System.IO.FileInfo("C:\\file.txt");

file = fileInfo.OpenWrite();
file.WriteByte(0xF);

file.Close();
}

Örnek
Önceki kodu bir try-catch-finally ifadeye dönüştürmek için, temizleme kodu, çalışma kodundan aşağıdaki gibi
ayrılır.

static void CodeWithCleanup()


{
System.IO.FileStream file = null;
System.IO.FileInfo fileInfo = null;

try
{
fileInfo = new System.IO.FileInfo("C:\\file.txt");

file = fileInfo.OpenWrite();
file.WriteByte(0xF);
}
catch(System.UnauthorizedAccessException e)
{
System.Console.WriteLine(e.Message);
}
finally
{
if (file != null)
{
file.Close();
}
}
}

Bir özel durum, try OpenWrite() çağrıdan önce blok içinde herhangi bir zamanda olabileceği veya OpenWrite()
çağrının kendisi başarısız olabileceği için, kapatmayı denediğinde dosyanın açık olduğu garanti edilmez. Blok,
Close yöntemi çağırmadan önce FileStream nesnenin olmadığından null emin olmak için bir denetim ekler.
finally Denetim olmadan, NullReferenceExceptionblok kendi kendine oluşturabilir, ancak mümkünse özel
durumların finally atma işlemi mümkünse kaçınılmalıdır. finally null

Veritabanı bağlantısı, bir finally blokta kapanmakta olan başka bir adaydır. Bir veritabanı sunucusuyla izin
verilen bağlantı sayısı bazen sınırlı olduğundan, veritabanı bağlantılarını mümkün olduğunca hızlı bir şekilde
kapatmanız gerekir. Bağlantınızı kapatabilmeniz için önce bir özel durum oluşursa, bu, finally bloğu kullanmanın
çöp toplama beklerken daha iyi bir durumdur.

Ayrıca bkz.
C# Programlama Kılavuzu
Özel Durumlar ve Özel Durum İşleme
Özel Durum İşleme
using Deyimi
try-catch
try-finally
try-catch-finally
Nasıl yapılır: CLS Olmayan Özel Durum
Değerlendirme
23.10.2019 • 2 minutes to read • Edit Online

/CLI dahil C++bazı .NET dilleri, nesnelerin türetmeyen Exceptionözel durumlar oluşturması için izin verir. Bu tür
özel durumlar CLS dışı özel durumlar veya özel durumlarolarak adlandırılır. İçinde C# CLS olmayan özel durumlar
belirtemezsiniz, ancak bunları iki şekilde yakalayabilirsiniz:
Bir catch (RuntimeWrappedException e) blok içinde.
Varsayılan olarak, bir görsel C# derleme CLS olmayan özel durumları sarmalanmış özel durumlar olarak
yakalar. Bu yöntemi, RuntimeWrappedException.WrappedException özelliği aracılığıyla erişilebilen özgün
özel duruma erişmeniz gerekiyorsa kullanın. Bu konu başlığında ilerleyen yordamda, özel durumların bu
şekilde nasıl yakalanacağı açıklanmaktadır.
Genel bir catch bloğu içinde (özel durum türü belirtilmeden bir catch bloğu), diğer catch tüm bloklarından
sonra konur.
CLS olmayan özel durumlara yanıt olarak bazı eylemler (örneğin, bir günlük dosyasına yazma)
gerçekleştirmek istediğinizde ve özel durum bilgilerine erişmeniz gerekmiyorsa bu yöntemi kullanın.
Varsayılan olarak ortak dil çalışma zamanı tüm özel durumları sarmalanır. Bu davranışı devre dışı bırakmak
için, bu derleme düzeyi özniteliğini kodunuzda, genellikle AssemblyInfo.cs dosyasında ekleyin:
[assembly: RuntimeCompatibilityAttribute(WrapNonExceptionThrows = false)] .

CLS olmayan bir özel durumu yakalamak için


Bir catch(RuntimeWrappedException e) blok içinde, RuntimeWrappedException.WrappedException özelliği
aracılığıyla özgün özel duruma erişin.

Örnek
Aşağıdaki örnek,/Cliende C++yazılmış bir sınıf KITAPLıĞıNDAN oluşturulan CLS olmayan bir özel durumun nasıl
yakalanalınacağını gösterir. Bu örnekte, C# istemci kodunun, oluşturulmakta olan özel durum türünün bir
System.Stringolduğunu önceden öğrendiğine unutmayın. Bu tür, kodunuzun
RuntimeWrappedException.WrappedException erişebileceği sürece özelliği özgün türünü geri çevirebilirsiniz.

// Class library written in C++/CLI.


var myClass = new ThrowNonCLS.Class1();

try
{
// throws gcnew System::String(
// "I do not derive from System.Exception!");
myClass.TestThrow();
}
catch (RuntimeWrappedException e)
{
String s = e.WrappedException as String;
if (s != null)
{
Console.WriteLine(s);
}
}
Ayrıca bkz.
RuntimeWrappedException
Özel Durumlar ve Özel Durum İşleme
Dosya Sistemi ve Kayıt Defteri (C# Programlama
Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Aşağıdaki konularda, dosyalar, klasörler ve C# kayıt defteri üzerinde çeşitli temel işlemleri gerçekleştirmek için ve
.NET Framework nasıl kullanılacağı gösterilmektedir.

Bu Bölümde
BAŞLIK AÇIKLAMA

Nasıl yapılır: Dizin ağacı aracılığıyla yineleme Bir dizin ağacında el ile nasıl yineleyemezsiniz gösterir.

Nasıl yapılır: Dosyalar, klasörler ve sürücüler hakkında bilgi Dosyalar, klasörler ve sürücüler hakkında oluşturma süreleri
alın ve boyutu gibi bilgilerin nasıl alınacağını gösterir.

Nasıl yapılır: Dosya veya klasör oluşturma Yeni bir dosya veya klasör oluşturmayı gösterir.

Nasıl yapılır: Dosyaları ve klasörleri kopyalama, silme ve Dosya ve klasörlerin nasıl kopyalanacağını, silineceğini ve
taşıma (C# Programlama Kılavuzu) taşınacağını gösterir.

Nasıl yapılır: Dosya Işlemleri için Ilerleme durumu Iletişim Belirli dosya işlemleri için standart bir Windows ilerleme
kutusu sağlama durumu iletişim kutusunun nasıl görüntüleneceğini gösterir.

Nasıl yapılır: Bir metin dosyasına yaz Bir metin dosyasına nasıl yazılacağını gösterir.

Nasıl yapılır: Bir metin dosyasından okuma Bir metin dosyasından nasıl okunacağını gösterir.

Nasıl yapılır: Bir metin dosyasını tek seferde bir satır okuyun Tek seferde bir dosyadan bir satırdan nasıl metin alınacağını
gösterir.

Nasıl yapılır: Kayıt defterinde anahtar oluşturma Sistem kayıt defterine bir anahtarın nasıl yazılacağını gösterir.

İlgili Bölümler
Dosya ve Akış G/Ç'si
Nasıl yapılır: Dosyaları ve klasörleri kopyalama, silme ve taşıma (C# Programlama Kılavuzu)
C# Programlama Kılavuzu
Dosyalar, klasörler ve sürücüler
System.IO
Nasıl yapılır: Bir dizin ağacında yineleme (C#
Programlama Kılavuzu)
23.10.2019 • 10 minutes to read • Edit Online

"Bir dizin ağacını yineleme" ifadesi, belirtilen kök klasörü altındaki her bir dosyaya her bir dosyanın herhangi bir
derinliğine erişmesi anlamına gelir. Her bir dosyayı açmak zorunda değilsiniz. Dosya veya alt dizinin adını yalnızca
bir string olarak alabilir veya bir System.IO.FileInfo veya System.IO.DirectoryInfo nesnesi biçiminde ek bilgiler
alabilirsiniz.

NOTE
Windows 'da, "Directory" ve "Folder" terimleri birbirinin yerine kullanılır. Çoğu belge ve Kullanıcı arabirimi metni "Folder"
terimini kullanır, ancak .NET Framework sınıf kitaplığı "Dizin" terimini kullanır.

En basit durumda, belirli bir kök altındaki tüm dizinler için erişim izinleriniz olduğunu bildiğiniz,
System.IO.SearchOption.AllDirectories bayrağını kullanabilirsiniz. Bu bayrak, belirtilen Düzenle eşleşen tüm iç içe
geçmiş alt dizinleri döndürür. Aşağıdaki örnek, bu bayrağın nasıl kullanılacağını göstermektedir.

root.GetDirectories("*.*", System.IO.SearchOption.AllDirectories);

Bu yaklaşımdaki zayıflığın, belirtilen kök altındaki alt dizinlerin herhangi biri ya DirectoryNotFoundException
UnauthorizedAccessExceptionda bir bütün yöntemin başarısız olmasına neden olur ve Dizin döndürmez. GetFiles
Yöntemi kullandığınızda aynı değeri de geçerlidir. Bu özel durumları belirli alt klasörlerde işlemeniz gerekiyorsa,
aşağıdaki örneklerde gösterildiği gibi, dizin ağacını el ile ilermalısınız.
Bir dizin ağacını el ile ilerlerinizden önce (ön geçiş öncesi geçiş) veya dosyaları önce (sıra çapraz geçişi), önce alt
dizinleri işleyebilirsiniz. Bir ön sırada çapraz geçiş gerçekleştirirseniz, doğrudan o klasörün içinde olan dosyalara
geçmeden önce geçerli klasörün altındaki tüm ağaca ileredersiniz. Bu belgenin ilerleyen kısımlarında yer değiştiren
örnekler, son düzen çapraz geçişi gerçekleştirir, ancak bunları önceden sıralı çapraz geçiş gerçekleştirmek üzere
kolayca değiştirebilirsiniz.
Diğer bir seçenek de özyineleme veya yığın tabanlı bir geçiş geçişinin kullanılıp kullanılmayacağını belirtir. Bu
belgede daha sonra gelen örneklerde her iki yaklaşım gösterilmektedir.
Dosyalar ve klasörler üzerinde çeşitli işlemler gerçekleştirmeniz gerekiyorsa, işlemi tek bir temsilci kullanarak
çağırabileceğiniz ayrı işlevlere yeniden düzenleyerek bu örnekleri modüle dönüştürebilirsiniz.

NOTE
NTFS dosya sistemleri, birleşme noktaları, Simgesel bağlantılarve sabit bağlantılarbiçiminde yeniden ayrıştırma noktaları
içerebilir. GetFiles VeGetDirectories gibi .NET Framework Yöntemler, yeniden ayrıştırma noktası altında herhangi bir alt dizin
döndürmez. Bu davranış, iki yeniden ayrıştırma noktası birbirine başvururken sonsuz döngüye girme riskiyle karşı koruma
sağlar. Genel olarak, dosyaları istem dışı olarak değiştirmeyin veya sildiğinizden emin olmak için yeniden ayrıştırma
noktalarıyla uğraşdığınızda olağanüstü dikkatli olmanız gerekir. Yeniden ayrıştırma noktaları üzerinde tam denetime ihtiyacınız
varsa, doğrudan ilgili Win32 dosya sistemi yöntemlerini çağırmak için platform çağırma veya yerel kod kullanın.

Örnek
Aşağıdaki örnek, özyineleme kullanarak bir dizin ağacına nasıl yol gösterir. Özyinelemeli yaklaşım zarif, ancak dizin
ağacı büyük ve derin iç içe ise bir yığın taşması özel durumuna neden olur.
İşlenen özel durumlar ve her dosya veya klasör üzerinde gerçekleştirilen belirli eylemler yalnızca örnek olarak
sağlanır. Bu kodu, özel gereksinimlerinizi karşılayacak şekilde değiştirmelisiniz. Daha fazla bilgi için koddaki
açıklamalara bakın.

public class RecursiveFileSearch


{
static System.Collections.Specialized.StringCollection log = new
System.Collections.Specialized.StringCollection();

static void Main()


{
// Start with drives if you have to search the entire computer.
string[] drives = System.Environment.GetLogicalDrives();

foreach (string dr in drives)


{
System.IO.DriveInfo di = new System.IO.DriveInfo(dr);

// Here we skip the drive if it is not ready to be read. This


// is not necessarily the appropriate action in all scenarios.
if (!di.IsReady)
{
Console.WriteLine("The drive {0} could not be read", di.Name);
continue;
}
System.IO.DirectoryInfo rootDir = di.RootDirectory;
WalkDirectoryTree(rootDir);
}

// Write out all the files that could not be processed.


Console.WriteLine("Files with restricted access:");
foreach (string s in log)
{
Console.WriteLine(s);
}
// Keep the console window open in debug mode.
Console.WriteLine("Press any key");
Console.ReadKey();
}

static void WalkDirectoryTree(System.IO.DirectoryInfo root)


{
System.IO.FileInfo[] files = null;
System.IO.DirectoryInfo[] subDirs = null;

// First, process all the files directly under this folder


try
{
files = root.GetFiles("*.*");
}
// This is thrown if even one of the files requires permissions greater
// than the application provides.
catch (UnauthorizedAccessException e)
{
// This code just writes out the message and continues to recurse.
// You may decide to do something different here. For example, you
// can try to elevate your privileges and access the file again.
log.Add(e.Message);
}

catch (System.IO.DirectoryNotFoundException e)
{
Console.WriteLine(e.Message);
}
}

if (files != null)
{
foreach (System.IO.FileInfo fi in files)
{
// In this example, we only access the existing FileInfo object. If we
// want to open, delete or modify the file, then
// a try-catch block is required here to handle the case
// where the file has been deleted since the call to TraverseTree().
Console.WriteLine(fi.FullName);
}

// Now find all the subdirectories under this directory.


subDirs = root.GetDirectories();

foreach (System.IO.DirectoryInfo dirInfo in subDirs)


{
// Resursive call for each subdirectory.
WalkDirectoryTree(dirInfo);
}
}
}
}

Örnek
Aşağıdaki örnek, özyineleme kullanılmadan bir dizin ağacındaki dosyalar ve klasörler arasında nasıl yineleme
yapılacağını gösterir. Bu teknik, son ilk Stack<T> çıkar (LIFO ) yığını olan genel koleksiyon türünü kullanır.
İşlenen özel durumlar ve her dosya veya klasör üzerinde gerçekleştirilen belirli eylemler yalnızca örnek olarak
sağlanır. Bu kodu, özel gereksinimlerinizi karşılayacak şekilde değiştirmelisiniz. Daha fazla bilgi için koddaki
açıklamalara bakın.

public class StackBasedIteration


{
static void Main(string[] args)
{
// Specify the starting folder on the command line, or in
// Visual Studio in the Project > Properties > Debug pane.
TraverseTree(args[0]);

Console.WriteLine("Press any key");


Console.ReadKey();
}

public static void TraverseTree(string root)


{
// Data structure to hold names of subfolders to be
// examined for files.
Stack<string> dirs = new Stack<string>(20);

if (!System.IO.Directory.Exists(root))
{
throw new ArgumentException();
}
dirs.Push(root);

while (dirs.Count > 0)


{
string currentDir = dirs.Pop();
string[] subDirs;
try
{
subDirs = System.IO.Directory.GetDirectories(currentDir);
}
}
// An UnauthorizedAccessException exception will be thrown if we do not have
// discovery permission on a folder or file. It may or may not be acceptable
// to ignore the exception and continue enumerating the remaining files and
// folders. It is also possible (but unlikely) that a DirectoryNotFound exception
// will be raised. This will happen if currentDir has been deleted by
// another application or thread after our call to Directory.Exists. The
// choice of which exceptions to catch depends entirely on the specific task
// you are intending to perform and also on how much you know with certainty
// about the systems on which this code will run.
catch (UnauthorizedAccessException e)
{
Console.WriteLine(e.Message);
continue;
}
catch (System.IO.DirectoryNotFoundException e)
{
Console.WriteLine(e.Message);
continue;
}

string[] files = null;


try
{
files = System.IO.Directory.GetFiles(currentDir);
}

catch (UnauthorizedAccessException e)
{

Console.WriteLine(e.Message);
continue;
}

catch (System.IO.DirectoryNotFoundException e)
{
Console.WriteLine(e.Message);
continue;
}
// Perform the required action on each file here.
// Modify this block to perform your required task.
foreach (string file in files)
{
try
{
// Perform whatever action is required in your scenario.
System.IO.FileInfo fi = new System.IO.FileInfo(file);
Console.WriteLine("{0}: {1}, {2}", fi.Name, fi.Length, fi.CreationTime);
}
catch (System.IO.FileNotFoundException e)
{
// If file was deleted by a separate application
// or thread since the call to TraverseTree()
// then just continue.
Console.WriteLine(e.Message);
continue;
}
}

// Push the subdirectories onto the stack for traversal.


// This could also be done before handing the files.
foreach (string str in subDirs)
dirs.Push(str);
}
}
}

Uygulamanızın onu açma iznine sahip olup olmadığını anlamak için her klasörü sınamak genellikle çok zaman alır.
Bu nedenle, kod örneği işlemin yalnızca bu parçasını bir try/catch blokta barındırır. Bir klasöre erişim izni catch
reddedildiğinde, izinlerinizi yükseltmeyi ve sonra yeniden erişmeyi deneyerek engellemeyi değiştirebilirsiniz. Bir
kural olarak, yalnızca uygulamanızı bilinmeyen bir durumda bırakmadan işleyebilmeniz için bu özel durumları
yakalayın.
Bir dizin ağacının içeriğini bellekte veya diskte depolamanız gerekirse, en iyi seçenek her bir dosya için yalnızca
FullName özelliğini (türü string ) saklamalıdır. Daha sonra bu dizeyi, gerektiğinde yeni FileInfo bir veya
DirectoryInfo nesne oluşturmak veya ek işlem gerektiren herhangi bir dosyayı açmak için kullanabilirsiniz.

Güçlü Programlama
Sağlam dosya yineleme kodu, dosya sisteminin birçok karmaşıklıklarını dikkate almalıdır. Windows dosya sistemi
hakkında daha fazla bilgi için bkz. NTFS 'ye genel bakış.

Ayrıca bkz.
System.IO
LINQ ve Dosya Dizinleri
Dosya sistemi ve kayıt defteri (C# Programlama Kılavuzu)
Nasıl yapılır: Dosyalar, klasörler ve sürücüler hakkında
bilgi edinme (C# Programlama Kılavuzu)
23.10.2019 • 3 minutes to read • Edit Online

.NET Framework, aşağıdaki sınıfları kullanarak dosya sistemi bilgilerine erişebilirsiniz:


System.IO.FileInfo
System.IO.DirectoryInfo
System.IO.DriveInfo
System.IO.Directory
System.IO.File
FileInfo VeDirectoryInfo sınıfları bir dosya veya dizini temsil eder ve NTFS dosya sistemi tarafından desteklenen
dosya özniteliklerinin çoğunu açığa çıkaran özellikler içerir. Ayrıca dosya ve klasörleri açma, kapatma, taşıma ve
silme yöntemleri de bulunur. Oluşturucuya dosya, klasör veya sürücü adını temsil eden bir dize geçirerek, bu
sınıfların örneklerini oluşturabilirsiniz:

System.IO.DriveInfo di = new System.IO.DriveInfo(@"C:\");

Ayrıca, DirectoryInfo.GetDirectories DirectoryInfo.GetFilesve


içinyapılançağrılarıkullanarakdosyaların,klasörlerinveyasürücülerinadlarınıeldeedebilirsiniz.DriveInfo.RootDirectory
System.IO.Directory VeSystem.IO.File sınıfları, dizinler ve dosyalar hakkında bilgi almak için statik yöntemler
sağlar.

Örnek
Aşağıdaki örnek dosya ve klasörlerle ilgili bilgilere erişmek için çeşitli yollar gösterir.

class FileSysInfo
{
static void Main()
{
// You can also use System.Environment.GetLogicalDrives to
// obtain names of all logical drives on the computer.
System.IO.DriveInfo di = new System.IO.DriveInfo(@"C:\");
Console.WriteLine(di.TotalFreeSpace);
Console.WriteLine(di.VolumeLabel);

// Get the root directory and print out some information about it.
System.IO.DirectoryInfo dirInfo = di.RootDirectory;
Console.WriteLine(dirInfo.Attributes.ToString());

// Get the files in the directory and print out some information about them.
System.IO.FileInfo[] fileNames = dirInfo.GetFiles("*.*");

foreach (System.IO.FileInfo fi in fileNames)


{
Console.WriteLine("{0}: {1}: {2}", fi.Name, fi.LastAccessTime, fi.Length);
}
// Get the subdirectories directly that is under the root.
// See "How to: Iterate Through a Directory Tree" for an example of how to
// iterate through an entire tree.
System.IO.DirectoryInfo[] dirInfos = dirInfo.GetDirectories("*.*");

foreach (System.IO.DirectoryInfo d in dirInfos)


{
Console.WriteLine(d.Name);
}

// The Directory and File classes provide several static methods


// for accessing files and directories.

// Get the current application directory.


string currentDirName = System.IO.Directory.GetCurrentDirectory();
Console.WriteLine(currentDirName);

// Get an array of file names as strings rather than FileInfo objects.


// Use this method when storage space is an issue, and when you might
// hold on to the file name reference for a while before you try to access
// the file.
string[] files = System.IO.Directory.GetFiles(currentDirName, "*.txt");

foreach (string s in files)


{
// Create the FileInfo object only when needed to ensure
// the information is as current as possible.
System.IO.FileInfo fi = null;
try
{
fi = new System.IO.FileInfo(s);
}
catch (System.IO.FileNotFoundException e)
{
// To inform the user and continue is
// sufficient for this demonstration.
// Your application may require different behavior.
Console.WriteLine(e.Message);
continue;
}
Console.WriteLine("{0} : {1}",fi.Name, fi.Directory);
}

// Change the directory. In this case, first check to see


// whether it already exists, and create it if it does not.
// If this is not appropriate for your application, you can
// handle the System.IO.IOException that will be raised if the
// directory cannot be found.
if (!System.IO.Directory.Exists(@"C:\Users\Public\TestFolder\"))
{
System.IO.Directory.CreateDirectory(@"C:\Users\Public\TestFolder\");
}

System.IO.Directory.SetCurrentDirectory(@"C:\Users\Public\TestFolder\");

currentDirName = System.IO.Directory.GetCurrentDirectory();
Console.WriteLine(currentDirName);

// Keep the console window open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}

Güçlü Programlama
Kullanıcı tarafından belirtilen yol dizelerini işlerken aşağıdaki koşullarda özel durumları da işlemeniz gerekir:
Dosya adı hatalı biçimlendirilmiş. Örneğin, geçersiz karakterler veya yalnızca boşluk içeriyor.
Dosya adı null.
Dosya adı sistem tarafından tanımlanan uzunluk üst sınırından daha uzun.
Dosya adı iki nokta üst üste (:)) sahiptir.
Uygulama, belirtilen dosyayı okumak için yeterli izinlere sahip değilse, Exists Yöntem bir yolun var olup
olmadığına bakılmaksızın döndürülür false ; Yöntem bir özel durum oluşturmaz.

Ayrıca bkz.
System.IO
C# Programlama Kılavuzu
Dosya sistemi ve kayıt defteri (C# Programlama Kılavuzu)
Nasıl yapılır: Dosya veya klasör oluşturma (C#
Programlama Kılavuzu)
23.10.2019 • 4 minutes to read • Edit Online

Bilgisayarınızda program aracılığıyla bir klasör oluşturabilir, bir alt klasör oluşturabilir, alt klasörde bir dosya
oluşturabilir ve verileri dosyaya yazabilirsiniz.

Örnek
public class CreateFileOrFolder
{
static void Main()
{
// Specify a name for your top-level folder.
string folderName = @"c:\Top-Level Folder";

// To create a string that specifies the path to a subfolder under your


// top-level folder, add a name for the subfolder to folderName.
string pathString = System.IO.Path.Combine(folderName, "SubFolder");

// You can write out the path name directly instead of using the Combine
// method. Combine just makes the process easier.
string pathString2 = @"c:\Top-Level Folder\SubFolder2";

// You can extend the depth of your path if you want to.
//pathString = System.IO.Path.Combine(pathString, "SubSubFolder");

// Create the subfolder. You can verify in File Explorer that you have this
// structure in the C: drive.
// Local Disk (C:)
// Top-Level Folder
// SubFolder
System.IO.Directory.CreateDirectory(pathString);

// Create a file name for the file you want to create.


string fileName = System.IO.Path.GetRandomFileName();

// This example uses a random string for the name, but you also can specify
// a particular name.
//string fileName = "MyNewFile.txt";

// Use Combine again to add the file name to the path.


pathString = System.IO.Path.Combine(pathString, fileName);

// Verify the path that you have constructed.


Console.WriteLine("Path to my file: {0}\n", pathString);

// Check that the file doesn't already exist. If it doesn't exist, create
// the file and write integers 0 - 99 to it.
// DANGER: System.IO.File.Create will overwrite the file if it already exists.
// This could happen even with random file names, although it is unlikely.
if (!System.IO.File.Exists(pathString))
{
using (System.IO.FileStream fs = System.IO.File.Create(pathString))
{
for (byte i = 0; i < 100; i++)
{
fs.WriteByte(i);
}
}
}
}
else
{
Console.WriteLine("File \"{0}\" already exists.", fileName);
return;
}

// Read and display the data from your file.


try
{
byte[] readBuffer = System.IO.File.ReadAllBytes(pathString);
foreach (byte b in readBuffer)
{
Console.Write(b + " ");
}
Console.WriteLine();
}
catch (System.IO.IOException e)
{
Console.WriteLine(e.Message);
}

// Keep the console window open in debug mode.


System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
// Sample output:

// Path to my file: c:\Top-Level Folder\SubFolder\ttxvauxe.vv0

//0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
//30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
// 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 8
//3 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
}

Klasör zaten varsa, CreateDirectory hiçbir şey yapmaz ve hiçbir özel durum oluşturulmaz. Ancak, File.Create
varolan bir dosyayı yeni bir dosya ile değiştirir. Örnek, varolan bir if dosyanın değiştirilmesini engellemek için bir
- else ifade kullanır.
Örnekte aşağıdaki değişiklikleri yaparak, belirli bir ada sahip bir dosyanın zaten mevcut olup olmadığına bağlı
olarak farklı sonuçlar belirtebilirsiniz. Böyle bir dosya yoksa, kod bir tane oluşturur. Böyle bir dosya varsa, kod bu
dosyaya veri ekler.
Rastgele olmayan bir dosya adı belirtin.

// Comment out the following line.


//string fileName = System.IO.Path.GetRandomFileName();

// Replace that line with the following assignment.


string fileName = "MyNewFile.txt";

İfadesini aşağıdaki koddaki ifadesiyledeğiştirin. using if - else

using (System.IO.FileStream fs = new System.IO.FileStream(pathString, FileMode.Append))


{
for (byte i = 0; i < 100; i++)
{
fs.WriteByte(i);
}
}
Her seferinde verilerin dosyaya eklendiğini doğrulamak için örneği birkaç kez çalıştırın.
Deneyebileceğiniz daha FileMode fazla değer için bkz FileMode.
Aşağıdaki koşullar özel bir duruma neden olabilir:
Klasör adı hatalı biçimlendirilmiş. Örneğin, geçersiz karakterler içeriyor veya yalnızca boşluk
(ArgumentException sınıf) içeriyor. Geçerli yol adları oluşturmak için sınıfınıkullanın.Path
Oluşturulacak klasörün üst klasörü salt okunurdur (IOException sınıf).
Klasör adı null (ArgumentNullException sınıf).
Klasör adı çok uzun (PathTooLongException sınıf).
Klasör adı yalnızca bir iki nokta üst üste, ":"PathTooLongException (sınıf).

.NET Framework Güvenliği


Kısmi güven durumlarında SecurityException sınıfın bir örneği oluşturulabilir.
Klasörü oluşturma izniniz yoksa, örnek UnauthorizedAccessException sınıfının bir örneğini oluşturur.

Ayrıca bkz.
System.IO
C# Programlama Kılavuzu
Dosya sistemi ve kayıt defteri (C# Programlama Kılavuzu)
Nasıl yapılır: Dosyaları ve klasörleri kopyalama, silme
ve taşıma (C# Programlama Kılavuzu)
23.10.2019 • 4 minutes to read • Edit Online

Aşağıdaki System.IO.Fileörneklerde, adSystem.IO alanından System.IO.FileInfo, System.IO.Directory, ve


System.IO.DirectoryInfo sınıfları kullanarak dosya ve klasörleri zaman uyumlu bir şekilde kopyalama, taşıma ve
silme işlemlerinin nasıl yapılacağı gösterilmektedir. Bu örnekler, bir ilerleme çubuğu veya başka bir kullanıcı
arabirimi sağlamaz. Standart ilerleme durumu iletişim kutusu sağlamak istiyorsanız, bkz . nasıl yapılır: Dosya
IşlemleriIçin bir Ilerleme durumu iletişim kutusu belirtin.
Birden System.IO.FileSystemWatcher çok dosya üzerinde çalışırken ilerlemeyi hesaplamanıza olanak sağlayacak
olayları sağlamak için kullanın. Diğer bir yaklaşım, Windows kabuğu 'nda dosyayla ilgili ilgili yöntemleri çağırmak
için platform çağırma kullanmaktır. Bu dosya işlemlerini zaman uyumsuz olarak gerçekleştirme hakkında daha
fazla bilgi için bkz. zaman uyumsuz dosya g/ç.

Örnek
Aşağıdaki örnek, dosyaların ve dizinlerin nasıl kopyalanacağını gösterir.
// Simple synchronous file copy operations with no user interface.
// To run this sample, first create the following directories and files:
// C:\Users\Public\TestFolder
// C:\Users\Public\TestFolder\test.txt
// C:\Users\Public\TestFolder\SubDir\test.txt
public class SimpleFileCopy
{
static void Main()
{
string fileName = "test.txt";
string sourcePath = @"C:\Users\Public\TestFolder";
string targetPath = @"C:\Users\Public\TestFolder\SubDir";

// Use Path class to manipulate file and directory paths.


string sourceFile = System.IO.Path.Combine(sourcePath, fileName);
string destFile = System.IO.Path.Combine(targetPath, fileName);

// To copy a folder's contents to a new location:


// Create a new target folder.
// If the directory already exists, this method does not create a new directory.
System.IO.Directory.CreateDirectory(targetPath);

// To copy a file to another location and


// overwrite the destination file if it already exists.
System.IO.File.Copy(sourceFile, destFile, true);

// To copy all the files in one directory to another directory.


// Get the files in the source folder. (To recursively iterate through
// all subfolders under the current directory, see
// "How to: Iterate Through a Directory Tree.")
// Note: Check for target path was performed previously
// in this code example.
if (System.IO.Directory.Exists(sourcePath))
{
string[] files = System.IO.Directory.GetFiles(sourcePath);

// Copy the files and overwrite destination files if they already exist.
foreach (string s in files)
{
// Use static Path methods to extract only the file name from the path.
fileName = System.IO.Path.GetFileName(s);
destFile = System.IO.Path.Combine(targetPath, fileName);
System.IO.File.Copy(s, destFile, true);
}
}
else
{
Console.WriteLine("Source path does not exist!");
}

// Keep console window open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}

Örnek
Aşağıdaki örnek, dosyaların ve dizinlerin nasıl taşınacağını gösterir.
// Simple synchronous file move operations with no user interface.
public class SimpleFileMove
{
static void Main()
{
string sourceFile = @"C:\Users\Public\public\test.txt";
string destinationFile = @"C:\Users\Public\private\test.txt";

// To move a file or folder to a new location:


System.IO.File.Move(sourceFile, destinationFile);

// To move an entire directory. To programmatically modify or combine


// path strings, use the System.IO.Path class.
System.IO.Directory.Move(@"C:\Users\Public\public\test\", @"C:\Users\Public\private");
}
}

Örnek
Aşağıdaki örnek, dosyaların ve dizinlerin nasıl silineceğini gösterir.

// Simple synchronous file deletion operations with no user interface.


// To run this sample, create the following files on your drive:
// C:\Users\Public\DeleteTest\test1.txt
// C:\Users\Public\DeleteTest\test2.txt
// C:\Users\Public\DeleteTest\SubDir\test2.txt

public class SimpleFileDelete


{
static void Main()
{
// Delete a file by using File class static method...
if(System.IO.File.Exists(@"C:\Users\Public\DeleteTest\test.txt"))
{
// Use a try block to catch IOExceptions, to
// handle the case of the file already being
// opened by another process.
try
{
System.IO.File.Delete(@"C:\Users\Public\DeleteTest\test.txt");
}
catch (System.IO.IOException e)
{
Console.WriteLine(e.Message);
return;
}
}

// ...or by using FileInfo instance method.


System.IO.FileInfo fi = new System.IO.FileInfo(@"C:\Users\Public\DeleteTest\test2.txt");
try
{
fi.Delete();
}
catch (System.IO.IOException e)
{
Console.WriteLine(e.Message);
}

// Delete a directory. Must be writable or empty.


try
{
System.IO.Directory.Delete(@"C:\Users\Public\DeleteTest");
}
catch (System.IO.IOException e)
{
Console.WriteLine(e.Message);
}
// Delete a directory and all subdirectories with Directory static method...
if(System.IO.Directory.Exists(@"C:\Users\Public\DeleteTest"))
{
try
{
System.IO.Directory.Delete(@"C:\Users\Public\DeleteTest", true);
}

catch (System.IO.IOException e)
{
Console.WriteLine(e.Message);
}
}

// ...or with DirectoryInfo instance method.


System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(@"C:\Users\Public\public");
// Delete this dir and all subdirs.
try
{
di.Delete(true);
}
catch (System.IO.IOException e)
{
Console.WriteLine(e.Message);
}

}
}

Ayrıca bkz.
System.IO
C# Programlama Kılavuzu
Dosya sistemi ve kayıt defteri (C# Programlama Kılavuzu)
Nasıl yapılır: Dosya Işlemleri için Ilerleme durumu Iletişim kutusu sağlama
Dosya ve Akış G/Ç'si
Ortak G/Ç Görevleri
Nasıl yapılır: Dosya Işlemleri için Ilerleme durumu
Iletişim kutusu sağlama (C# Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Microsoft.VisualBasic Ad alanında CopyFile(String, String, UIOption) yöntemini kullanırsanız, Windows 'daki


dosya işlemlerinde ilerleme durumunu gösteren bir standart iletişim kutusu sağlayabilirsiniz.

NOTE
Bilgisayarınız, aşağıdaki yönergelerde yer alan Visual Studio kullanıcı arabirimi öğelerinden bazıları için farklı adlar veya
konumlar gösterebilir. Sahip olduğunuz Visual Studio sürümü ve kullandığınız ayarlar bu öğeleri belirler. Daha fazla bilgi için
IDE'yi kişiselleştirme.

Visual Studio 'da bir başvuru eklemek için


1. Menü çubuğunda Proje, Başvuru Ekle' yi seçin.
Başvuru Yöneticisi iletişim kutusu görüntülenir.
2. Derlemeler alanında, zaten seçili değilse Framework ' ü seçin.
3. Ad listesinde, Microsoft. VisualBasic onay kutusunu seçin ve ardından iletişim kutusunu kapatmak için
Tamam düğmesini seçin.

Örnek
Aşağıdaki kod, sourcePath belirten dizinini belirten destinationPath dizine kopyalar. Bu kod ayrıca, işlem
tamamlanmadan önce kalan tahmini süreyi gösteren standart bir iletişim kutusu sağlar.

// The following using directive requires a project reference to Microsoft.VisualBasic.


using Microsoft.VisualBasic.FileIO;

class FileProgress
{
static void Main()
{
// Specify the path to a folder that you want to copy. If the folder is small,
// you won't have time to see the progress dialog box.
string sourcePath = @"C:\Windows\symbols\";
// Choose a destination for the copied files.
string destinationPath = @"C:\TestFolder";

FileSystem.CopyDirectory(sourcePath, destinationPath,
UIOption.AllDialogs);
}
}

Ayrıca bkz.
Dosya sistemi ve kayıt defteri (C# Programlama Kılavuzu)
Nasıl yapılır: Metin dosyasına yazma (C#
Programlama Kılavuzu)
23.10.2019 • 3 minutes to read • Edit Online

Bu örnekler bir metin dosyasına yazmanın çeşitli yollarını göstermektedir. İlk iki örnek, bir metin dosyasına bir
System.IO.File IEnumerable<string> ve dizesinin her bir öğesini yazmak için sınıfında statik kolay yöntemler
kullanır. Örnek 3 ' te, dosyaya yazarken her satırı ayrı olarak işlemek gerektiğinde bir dosyaya nasıl metin
ekleneceği gösterilmektedir. Örnekler 1-3 dosyadaki tüm varolan içeriğin üzerine yazılır, ancak örnek 4 ' te varolan
bir dosyaya nasıl metin ekleneceği gösterilmektedir.
Bu örneklerin tümü dosyalara dize değişmez değerleri yazar. Dosyaya yazılmış metni biçimlendirmek isterseniz,
Format yöntemi veya C# dize ilişkilendirme özelliğini kullanın.

Örnek
class WriteTextFile
{
static void Main()
{

// These examples assume a "C:\Users\Public\TestFolder" folder on your machine.


// You can modify the path if necessary.

// Example #1: Write an array of strings to a file.


// Create a string array that consists of three lines.
string[] lines = { "First line", "Second line", "Third line" };
// WriteAllLines creates a file, writes a collection of strings to the file,
// and then closes the file. You do NOT need to call Flush() or Close().
System.IO.File.WriteAllLines(@"C:\Users\Public\TestFolder\WriteLines.txt", lines);

// Example #2: Write one string to a text file.


string text = "A class is the most powerful data type in C#. Like a structure, " +
"a class defines the data and behavior of the data type. ";
// WriteAllText creates a file, writes the specified string to the file,
// and then closes the file. You do NOT need to call Flush() or Close().
System.IO.File.WriteAllText(@"C:\Users\Public\TestFolder\WriteText.txt", text);

// Example #3: Write only some strings in an array to a file.


// The using statement automatically flushes AND CLOSES the stream and calls
// IDisposable.Dispose on the stream object.
// NOTE: do not use FileStream for text files because it writes bytes, but StreamWriter
// encodes the output as text.
using (System.IO.StreamWriter file =
new System.IO.StreamWriter(@"C:\Users\Public\TestFolder\WriteLines2.txt"))
{
foreach (string line in lines)
{
// If the line doesn't contain the word 'Second', write the line to the file.
if (!line.Contains("Second"))
{
file.WriteLine(line);
}
}
}

// Example #4: Append new text to an existing file.


// The using statement automatically flushes AND CLOSES the stream and calls
// The using statement automatically flushes AND CLOSES the stream and calls
// IDisposable.Dispose on the stream object.
using (System.IO.StreamWriter file =
new System.IO.StreamWriter(@"C:\Users\Public\TestFolder\WriteLines2.txt", true))
{
file.WriteLine("Fourth line");
}
}
}
//Output (to WriteLines.txt):
// First line
// Second line
// Third line

//Output (to WriteText.txt):


// A class is the most powerful data type in C#. Like a structure, a class defines the data and behavior of
the data type.

//Output to WriteLines2.txt after Example #3:


// First line
// Third line

//Output to WriteLines2.txt after Example #4:


// First line
// Third line
// Fourth line

Güçlü Programlama
Aşağıdaki koşullar özel bir duruma neden olabilir:
Dosya mevcut ve salt okunur.
Yol adı çok uzun olabilir.
Disk dolu olabilir.

Ayrıca bkz.
C# Programlama Kılavuzu
Dosya sistemi ve kayıt defteri (C# Programlama Kılavuzu)
Örnekli Bir koleksiyonu uygulama depolamasına kaydetme
Nasıl yapılır: Metin dosyasından okuma (C#
Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Bu örnek, statik yöntemleri ReadAllText ve ReadAllLines System.IO.File sınıfından kullanarak bir metin dosyasının
içeriğini okur.
Tarafından kullanılan StreamReaderbir örnek için bkz . nasıl yapılır: Bir metin dosyasını tek seferde bir satır okur.

NOTE
Bu örnekte kullanılan dosyalar, konusunda nasıl yapılır: Bir metin dosyasınayazın.

Örnek
class ReadFromFile
{
static void Main()
{
// The files used in this example are created in the topic
// How to: Write to a Text File. You can change the path and
// file name to substitute text files of your own.

// Example #1
// Read the file as one string.
string text = System.IO.File.ReadAllText(@"C:\Users\Public\TestFolder\WriteText.txt");

// Display the file contents to the console. Variable text is a string.


System.Console.WriteLine("Contents of WriteText.txt = {0}", text);

// Example #2
// Read each line of the file into a string array. Each element
// of the array is one line of the file.
string[] lines = System.IO.File.ReadAllLines(@"C:\Users\Public\TestFolder\WriteLines2.txt");

// Display the file contents by using a foreach loop.


System.Console.WriteLine("Contents of WriteLines2.txt = ");
foreach (string line in lines)
{
// Use a tab to indent each line of the file.
Console.WriteLine("\t" + line);
}

// Keep the console window open in debug mode.


Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
}

Kod Derleniyor
Kodu kopyalayın ve bir C# konsol uygulamasına yapıştırın.
Metin dosyalarını şu şekilde kullanarak kullanmıyorsanız: Bir metin dosyasınayazın, ReadAllText bağımsız
değişkenini ReadAllLines bilgisayarınızdaki uygun yol ve dosya adıyla değiştirin.
Güçlü Programlama
Aşağıdaki koşullar özel bir duruma neden olabilir:
Dosya yok veya belirtilen konumda yok. Dosya adının yolunu ve yazımını denetleyin.

.NET Framework Güvenliği


Dosyanın içeriğini belirlemekte bir dosyanın adına güvenmeyin. Örneğin, dosya myFile.cs bir C# kaynak dosyası
olmayabilir.

Ayrıca bkz.
System.IO
C# Programlama Kılavuzu
Dosya sistemi ve kayıt defteri (C# Programlama Kılavuzu)
Nasıl yapılır: Bir Defada bir Satır Olarak bir Metin
Dosyasını Okuma (Visual C#)
23.10.2019 • 2 minutes to read • Edit Online

Bu örnek, bir metin dosyasının içeriğini, tek seferde bir satırı, ReadLine StreamReader sınıfının yöntemini
kullanarak bir dizeye okur. Her metin satırı, dizede line depolanır ve ekranda görüntülenir.

Örnek
int counter = 0;
string line;

// Read the file and display it line by line.


System.IO.StreamReader file =
new System.IO.StreamReader(@"c:\test.txt");
while((line = file.ReadLine()) != null)
{
System.Console.WriteLine(line);
counter++;
}

file.Close();
System.Console.WriteLine("There were {0} lines.", counter);
// Suspend the screen.
System.Console.ReadLine();

Kod Derleniyor
Kodu kopyalayın ve konsol uygulamasının Main yöntemine yapıştırın.
Gerçek "c:\test.txt" dosya adıyla değiştirin.

Güçlü Programlama
Aşağıdaki koşullar özel bir duruma neden olabilir:
Dosya mevcut olmayabilir.

.NET Framework Güvenliği


Dosya adına dayanarak dosyanın içeriği ile ilgili kararlar vermeyin. Örneğin, dosya myFile.cs bir C# kaynak
dosyası olmayabilir.

Ayrıca bkz.
System.IO
C# Programlama Kılavuzu
Dosya sistemi ve kayıt defteri (C# Programlama Kılavuzu)
Nasıl yapılır: Kayıt Defterinde Anahtar Oluşturma
(Visual C#)
23.10.2019 • 2 minutes to read • Edit Online

Bu örnek, "ad" ve "Isabella" değer çiftini geçerli kullanıcının kayıt defterine, "adlar" anahtarı altında ekler.

Örnek
Microsoft.Win32.RegistryKey key;
key = Microsoft.Win32.Registry.CurrentUser.CreateSubKey("Names");
key.SetValue("Name", "Isabella");
key.Close();

Kod Derleniyor
Kodu kopyalayın ve konsol uygulamasının Main yöntemine yapıştırın.
Parametresini, Names doğrudan kayıt defterinin HKEY_CURRENT_USER düğümünün altında bulunan bir
anahtarın adıyla değiştirin.
Name Parametresini doğrudan Names düğümünün altında bulunan bir değerin adıyla değiştirin.

Güçlü Programlama
Anahtarınız için uygun bir konum bulmak üzere kayıt defteri yapısını inceleyin. Örneğin, geçerli kullanıcının yazılım
anahtarını açmak ve şirketinizin adıyla bir anahtar oluşturmak isteyebilirsiniz. Ardından kayıt defteri değerlerini
şirketinizin anahtarına ekleyin.
Aşağıdaki koşullar özel bir duruma neden olabilir:
Anahtarın adı null.
Kullanıcının kayıt defteri anahtarları oluşturma izni yok.
Anahtar adı 255 karakterlik sınırı aşıyor.
Anahtar kapalıdır.
Kayıt defteri anahtarı salt okunurdur.

.NET Framework Güvenliği


Microsoft.Win32.Registry.CurrentUser Yerel Microsoft.Win32.Registry.LocalMachine bilgisayar yerine, Kullanıcı
klasörüne veri yazmak daha güvenlidir —.
Bir kayıt defteri değeri oluşturduğunuzda, bu değer zaten varsa ne yapılacağını belirlemeniz gerekir. Belki de kötü
amaçlı olan bir işlem, değeri zaten oluşturmuş ve ona erişime sahip olabilir. Verileri kayıt defteri değerine
yerleştirdiğinizde, veriler diğer işlem tarafından kullanılabilir. Bunu engellemek için kullanın.
Overload:Microsoft.Win32.RegistryKey.GetValue yöntemidir. Anahtar zaten mevcut değilse null değerini döndürür.

Kayıt defteri anahtarı erişim denetim listeleriyle (ACL ) korunuyorsa bile, parolalar gibi gizli dizileri, kayıt defterinde
düz metin olarak depolamak güvenli değildir.
Ayrıca bkz.
System.IO
C# Programlama Kılavuzu
Dosya sistemi ve kayıt defteri (C# Programlama Kılavuzu)
İle kayıt defterinden okuma, yazma ve silmeC#
Birlikte Çalışabilirlik (C# Programlama Kılavuzu)
4.11.2019 • 2 minutes to read • Edit Online

Birlikte çalışabilirlik, yönetilmeyen koddaki mevcut yatırımlardan korunmanızı ve avantajlarını yapmanızı sağlar.
Ortak dil çalışma zamanının (CLR ) denetimi altında çalışan koda yönetilen kodadı verılır ve CLR dışında çalışan
koda yönetilmeyen koddenir. COM, COM+, C++ bileşenler, ActiveX bileşenleri ve MICROSOFT Windows API,
yönetilmeyen kod örnekleridir.
.NET Framework platform çağırma Hizmetleri, System.Runtime.InteropServices ad alanı, C++ birlikte
ÇALıŞABILIRLIK ve com birlikte ÇALıŞABILIRLIĞI (com birlikte çalışma) aracılığıyla yönetilmeyen kodla birlikte
çalışabilirliğe izin verebilir.

Bu Bölümde
Birlikte Çalışabilirliğe Genel Bakış
Yönetilen kod ve yönetilmeyen kod C# arasında birlikte çalışma yöntemlerini açıklar.
Nasıl yapılır: Visual C# Özelliklerini Kullanarak Office Birlikte Çalışma Nesnelerine Erişim
Office programlama işlemini kolaylaştırmak için görselde C# tanıtılan özellikleri açıklar.
Nasıl yapılır: COM Birlikte Çalışma Programlamada Dizin Oluşturulmuş Özellikleri Kullanma
Parametreleri olan COM özelliklerine erişmek için dizinlenmiş özelliklerin nasıl kullanılacağını açıklar.
Nasıl yapılır: Wave Dosyasını Oynatmak için Platform Çağırma Kullanma
Windows işletim sisteminde bir. wav ses dosyası oynatmak için platform çağırma Hizmetleri ' nin nasıl
kullanılacağını açıklar.
İzlenecek yol: Office programlama
Çalışma kitabının bir bağlantısını içeren bir Excel çalışma kitabı ve Word belgesi oluşturmayı gösterir.
Örnek COM Sınıfı
Bir C# SıNıFıN bir com nesnesi olarak nasıl kullanıma sunuleceğini gösterir.

C# Dil Belirtimi
Daha fazla bilgi için bkz. C# dil belirtiminde temel kavramlar . Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
Marshal.ReleaseComObject
C# Programlama Kılavuzu
Yönetilmeyen Kod ile Birlikte Çalışma
İzlenecek yol: Office programlama
Birlikte Çalışabilirliğe Genel Bakış (C# Programlama
Kılavuzu)
23.10.2019 • 5 minutes to read • Edit Online

Bu konu, yönetilen kod ve yönetilmeyen kod C# arasında birlikte çalışabilirliği etkinleştirme yöntemlerini açıklar.

Platform çağırma
Platform çağırma , yönetilen kodun, MICROSOFT Windows API 'dakiler gibi dinamik bağlantı kitaplıkları (dll 'ler)
içinde uygulanan yönetilmeyen işlevleri çağırmasına olanak sağlayan bir hizmettir. İçe aktarılmış bir işlevi bulur ve
çağırır ve bağımsız değişkenlerini (tamsayılar, dizeler, diziler, yapılar vb.) gerektiğinde birlikte çalışma sınırında
sıralar.
Daha fazla bilgi için bkz. yönetilmeyen DLL işlevlerini kullanma ve nasıl yapılır: Bir Wave dosyasınıoynatmak için
platform çağırma 'yi kullanın.

NOTE
Ortak dil çalışma zamanı (CLR) sistem kaynaklarına erişimi yönetir. CLR dışındaki yönetilmeyen kodu çağırmak bu güvenlik
mekanizmasını atlar ve bu nedenle bir güvenlik riski oluşturur. Örneğin, yönetilmeyen kod, CLR Güvenlik mekanizmalarını
atlayarak doğrudan yönetilmeyen koddaki kaynakları çağırabilir. Daha fazla bilgi için bkz. .net 'Teki güvenlik.

C++ Birlikte Çalışma


Yerel bir sınıfı C++ , C++ C# ya da başka bir .NET Framework dilde yazılmış kodla tüketilebilmesi için, yerel bir
sınıfı kaydırmak IÇIN de bilinen birlikte çalışma (IJW ) seçeneğini kullanabilirsiniz. Bunu yapmak için, yerel bir C++
dll veya com bileşenini kaydırmak üzere kod yazarsınız. Diğer .NET Framework dillerinin aksine, Visual C++ ,
yönetilen ve yönetilmeyen kodun aynı uygulamada ve hatta aynı dosyada yer almasını sağlayan, birlikte
çalışabilirlik desteğine sahiptir. Daha sonra, C++ bir yönetilen derleme üretmek için /clr derleyici anahtarını
kullanarak kodu derleyebilirsiniz. Son olarak, C# projenizdeki derlemeye bir başvuru ekler ve sarmalanmış
nesneleri diğer yönetilen sınıfları kullandığınız gibi kullanırsınız.

COM bileşenlerini C 'ye gösterme#


Bir C# projeden com bileşeni kullanabilirsiniz. Genel adımlar aşağıdaki gibidir:
1. Kullanmak için bir COM bileşeni bulun ve kaydedin. Bir COM DLL kaydını kaydetmek veya kaydını silmek
için Regsvr32. exe ' yi kullanın.
2. Projeye COM bileşenine veya tür kitaplığına başvuru ekleyin.
Başvuruyu eklediğinizde, Visual Studio bir .NET Framework birlikte çalışma derlemesini çıkarmak için giriş
olarak bir tür kitaplığı alan Tlbimp. exe (tür kitaplığı alma)kullanır. Ayrıca, çalışma zamanı çağrılabilir
sarmalayıcı (RCW ) adlı derleme, tür kitaplığındaki COM sınıflarını ve arabirimlerini sarmalayan yönetilen
sınıfları ve arabirimleri içerir. Visual Studio, oluşturulan derleme için projeye bir başvuru ekler.
3. RCW 'da tanımlanan bir sınıfın örneğini oluşturun. Bu, sırasıyla COM nesnesinin bir örneğini oluşturur.
4. Nesneyi diğer yönetilen nesneleri kullandığınız şekilde kullanın. Nesne çöp toplama tarafından geri
kazanılır, COM nesnesinin örneği de bellekten serbest bırakılır.
Daha fazla bilgi için bkz. com bileşenlerini .NET Framework gösterme.

COM C# 'a gösterme


COM istemcileri, doğru C# şekilde açığa çıkarılan türleri tüketebilir. Türleri açığa çıkarmak C# için temel adımlar
şunlardır:
1. C# Projeye birlikte çalışma özniteliklerini ekleyin.
Visual C# Project özelliklerini değiştirerek BIR derlemeyi com görünebilir hale getirebilirsiniz. Daha fazla
bilgi için bkz. derleme bilgileri Iletişim kutusu.
2. Bir COM tür kitaplığı oluşturun ve bunu COM kullanımı için kaydedin.
Visual C# Project özelliklerini DEĞIŞTIREREK, com birlikte çalışma için C# derlemeyi otomatik olarak
kaydedebilirsiniz. Visual Studio, bir tür kitaplığı oluşturmak için yönetilen bir derlemeyi giriş olarak alan
/tlb komut satırı anahtarını kullanarak Regasm. exe ' yi (derleme kayıt aracı)kullanır. Bu tür kitaplığı
derlemedeki public türleri açıklar ve com istemcilerinin yönetilen sınıflar oluşturabilmesi için kayıt defteri
girişleri ekler.
Daha fazla bilgi için bkz. COM ve örnek com sınıfına .NET Framework bileşenleri gösterme .

Ayrıca bkz.
Birlikte çalışma performansını iyileştirme
COM ve .NET arasında birlikte çalışabilirliğe giriş
Visual Basic COM birlikte çalışabilirliğine giriş
Yönetilen ve yönetilmeyen kod arasında sıralama
Yönetilmeyen Kod ile Birlikte Çalışma
C# Programlama Kılavuzu
Nasıl yapılır: Visual C# Özelliklerini Kullanarak Office
Birlikte Çalışma Nesnelerine Erişim (C# Programlama
Kılavuzu)
4.11.2019 • 18 minutes to read • Edit Online

Görselde C# Office API nesnelerine erişimi basitleştiren özellikler vardır. Yeni özellikler adlandırılmış ve isteğe
bağlı bağımsız değişkenler, dynamic adlı yeni bir tür ve COM yöntemlerindeki başvuru parametrelerine bağımsız
değişkenleri değer parametreleri gibi geçirme özelliği içerir.
Bu konu başlığında, Microsoft Office bir Excel çalışma sayfası oluşturan ve görüntüleyen kod yazmak için yeni
özellikleri kullanacaksınız. Daha sonra, Excel çalışma sayfasına bağlı bir simge içeren bir Office Word belgesi
eklemek için kod yazacaksınız.
Bu yönergeyi tamamlamak için, bilgisayarınızda yüklü Microsoft Office Excel 2007 ve Microsoft Office Word
2007 veya sonraki sürümlerin olması gerekir.

NOTE
Bilgisayarınız, aşağıdaki yönergelerde yer alan Visual Studio kullanıcı arabirimi öğelerinden bazıları için farklı adlar veya
konumlar gösterebilir. Sahip olduğunuz Visual Studio sürümü ve kullandığınız ayarlar bu öğeleri belirler. Daha fazla bilgi için
IDE'yi kişiselleştirme.

Yeni bir konsol uygulaması oluşturmak için


1. Visual Studio 'Yu başlatın.
2. Dosya menüsünde, Yeni' nin üzerine gelin ve ardından Proje' ye tıklayın. Yeni proje iletişim kutusu
görüntülenir.
3. Yüklü şablonlar bölmesinde, görsel C# ' i genişletin ve ardından Windows' a tıklayın.
4. .NET Framework 4 ' ün (veya sonraki bir sürüm) hedef çerçeve olarak seçildiğinden emin olmak Için Yeni
proje iletişim kutusunun üst kısmına bakın.
5. Şablonlar bölmesinde konsol uygulaması' na tıklayın.
6. Ad alanına projeniz için bir ad yazın.
7. Tamam'a tıklayın.
Yeni proje Çözüm Gezginigörüntülenir.

Başvuru eklemek için


1. Çözüm Gezgini, projenizin adına sağ tıklayın ve ardından Başvuru Ekle' ye tıklayın. Başvuru Ekle
iletişim kutusu görüntülenir.
2. Derlemeler sayfasında, bileşen adı listesinde Microsoft. Office. Interop. Word ' ü seçin ve ardından
CTRL tuşunu basılı tutarak Microsoft. Office. Interop. Excel' i seçin. Derlemeleri görmüyorsanız
bunların yüklendiğinden ve görüntülendiğinden emin olmanız gerekebilir. Bkz. nasıl yapılır: Office birincil
birlikte çalışma derlemelerini yüklemek.
3. Tamam'a tıklayın.

Gerekli yönergeleri kullanarak ekleme


1. Çözüm Gezgini, program.cs dosyasına sağ tıklayın ve ardından kodu görüntüle' ye tıklayın.
2. Kod dosyasının en üstüne aşağıdaki using yönergelerini ekleyin:

using Excel = Microsoft.Office.Interop.Excel;


using Word = Microsoft.Office.Interop.Word;

Banka hesaplarının bir listesini oluşturmak için


1. Aşağıdaki sınıf tanımını Program sınıfının altındaki program.csiçine yapıştırın.

public class Account


{
public int ID { get; set; }
public double Balance { get; set; }
}

2. İki hesap içeren bir bankAccounts listesi oluşturmak için Main yöntemine aşağıdaki kodu ekleyin.

// Create a list of accounts.


var bankAccounts = new List<Account> {
new Account {
ID = 345678,
Balance = 541.27
},
new Account {
ID = 1230221,
Balance = -127.44
}
};

Excel 'e hesap bilgilerini veren bir yöntem bildirmek için


1. Bir Excel çalışma sayfası ayarlamak için aşağıdaki yöntemi Program sınıfına ekleyin.
Add yöntemi, belirli bir şablonu belirtmek için isteğe bağlı bir parametreye sahiptir. 4 ' te C# yeni olan
isteğe bağlı parametreler, parametrenin varsayılan değerini kullanmak istiyorsanız bu parametreye ilişkin
bağımsız değişkeni atlamanızı sağlar. Aşağıdaki kodda bir bağımsız değişken gönderilmediğinden, Add
varsayılan şablonu kullanır ve yeni bir çalışma kitabı oluşturur. Önceki sürümlerindeki denk ifade, bir yer
C# tutucu bağımsız değişkeni gerektirir: ExcelApp.Workbooks.Add(Type.Missing) .
static void DisplayInExcel(IEnumerable<Account> accounts)
{
var excelApp = new Excel.Application();
// Make the object visible.
excelApp.Visible = true;

// Create a new, empty workbook and add it to the collection returned


// by property Workbooks. The new workbook becomes the active workbook.
// Add has an optional parameter for specifying a praticular template.
// Because no argument is sent in this example, Add creates a new workbook.
excelApp.Workbooks.Add();

// This example uses a single workSheet. The explicit type casting is


// removed in a later procedure.
Excel._Worksheet workSheet = (Excel.Worksheet)excelApp.ActiveSheet;
}

2. DisplayInExcel sonuna aşağıdaki kodu ekleyin. Kod, çalışma sayfasının ilk satırının ilk iki sütununa değer
ekler.

// Establish column headings in cells A1 and B1.


workSheet.Cells[1, "A"] = "ID Number";
workSheet.Cells[1, "B"] = "Current Balance";

3. DisplayInExcel sonuna aşağıdaki kodu ekleyin. foreach döngüsü, hesap listesindeki bilgileri, çalışma
sayfasının Art arda gelen satırlarının ilk iki sütununa koyar.

var row = 1;
foreach (var acct in accounts)
{
row++;
workSheet.Cells[row, "A"] = acct.ID;
workSheet.Cells[row, "B"] = acct.Balance;
}

4. Sütun genişliklerini içeriğe uyacak şekilde ayarlamak için DisplayInExcel sonuna aşağıdaki kodu ekleyin.

workSheet.Columns[1].AutoFit();
workSheet.Columns[2].AutoFit();

Önceki sürümleri bu C# işlemler için açık atama gerektirir çünkü ExcelApp.Columns[1] bir Object
döndürdüğünden AutoFit bir Excel Range yöntemidir. Aşağıdaki satırlarda atama gösterilmektedir.

((Excel.Range)workSheet.Columns[1]).AutoFit();
((Excel.Range)workSheet.Columns[2]).AutoFit();

C#4 ve sonraki sürümlerde, derleme -Link derleyici seçeneği tarafından başvuruluyorsa veya equivalently,
Excel birlikte çalışma türleri özelliği true olarak ayarlandıysa, döndürülen Object otomatik olarak
dynamic dönüştürür. True, bu özellik için varsayılan değerdir.

Projeyi çalıştırmak için


1. Main sonuna aşağıdaki satırı ekleyin.
// Display the list in an Excel spreadsheet.
DisplayInExcel(bankAccounts);

2. CTRL + F5 tuşlarına basın.


İki hesaptan gelen verileri içeren bir Excel çalışma sayfası görüntülenir.

Word belgesi eklemek için


1. C# 4 ve sonraki sürümlerin, Office programlama 'yi geliştiren ek yollarını göstermek için aşağıdaki kod bir
Word uygulaması açar ve Excel çalışma sayfasına bağlanan bir simge oluşturur.
Bu adımda daha sonra belirtilen CreateIconInWordDoc yöntemi Program sınıfına yapıştırın.
CreateIconInWordDoc , Add ve PasteSpecialmetot çağrılarının karmaşıklığını azaltmak için adlandırılmış ve
isteğe bağlı bağımsız değişkenleri kullanır. Bu çağrılar, başvuru parametrelerine sahip COM yöntemlerine
yapılan C# çağrıları kolaylaştıran 4 ' te tanıtılan iki yeni özelliği dahil ediyor. İlk olarak, başvuru
parametrelerine bağımsız değişkenleri değer parametreleriniz gibi gönderebilirsiniz. Diğer bir deyişle, her
başvuru parametresi için bir değişken oluşturmadan doğrudan değerleri gönderebilirsiniz. Derleyici
bağımsız değişken değerlerini tutacak geçici değişkenler oluşturur ve çağrıdan geri döndüğünüzde
değişkenleri atar. İkinci olarak, bağımsız değişken listesindeki ref anahtar sözcüğünü atlayabilirsiniz.
Add yönteminin tümü isteğe bağlı dört başvuru parametresi vardır. C# 4,0 ve sonraki sürümlerde,
varsayılan değerlerini kullanmak istiyorsanız parametrelerin herhangi biri veya tümü için bağımsız
değişkenleri atlayabilirsiniz. C# 3,0 ve önceki sürümlerde, her bir parametre için bir bağımsız değişken
sağlanmalı ve parametreler başvuru parametreleri olduğundan bağımsız değişken bir değişken olmalıdır.
PasteSpecial yöntemi panonun içeriğini ekler. Yönteminde, hepsi isteğe bağlı yedi başvuru parametresi
vardır. Aşağıdaki kod, bunların ikisi için bağımsız değişkenler belirtir: Link , pano içeriklerinin kaynağına
bir bağlantı oluşturmak ve bağlantıyı bir simge olarak göstermek için DisplayAsIcon . C# 4,0 ve sonraki
sürümlerde, bu ikisi için adlandırılmış bağımsız değişkenleri kullanabilir ve diğerlerini atlayabilirsiniz.
Bunlar başvuru parametreleri olsa da, ref anahtar sözcüğünü kullanmanız veya bağımsız değişken olarak
gönderilmek üzere değişkenler oluşturmanız gerekmez. Değerleri doğrudan gönderebilirsiniz. C# 3,0 ve
önceki sürümlerde, her başvuru parametresi için bir değişken bağımsız değişkeni sağlamanız gerekir.

static void CreateIconInWordDoc()


{
var wordApp = new Word.Application();
wordApp.Visible = true;

// The Add method has four reference parameters, all of which are
// optional. Visual C# allows you to omit arguments for them if
// the default values are what you want.
wordApp.Documents.Add();

// PasteSpecial has seven reference parameters, all of which are


// optional. This example uses named arguments to specify values
// for two of the parameters. Although these are reference
// parameters, you do not need to use the ref keyword, or to create
// variables to send in as arguments. You can send the values directly.
wordApp.Selection.PasteSpecial( Link: true, DisplayAsIcon: true);
}

Dilin C# 3,0 ve önceki sürümlerinde, aşağıdaki daha karmaşık kod gereklidir.


static void CreateIconInWordDoc2008()
{
var wordApp = new Word.Application();
wordApp.Visible = true;

// The Add method has four parameters, all of which are optional.
// In Visual C# 2008 and earlier versions, an argument has to be sent
// for every parameter. Because the parameters are reference
// parameters of type object, you have to create an object variable
// for the arguments that represents 'no value'.

object useDefaultValue = Type.Missing;

wordApp.Documents.Add(ref useDefaultValue, ref useDefaultValue,


ref useDefaultValue, ref useDefaultValue);

// PasteSpecial has seven reference parameters, all of which are


// optional. In this example, only two of the parameters require
// specified values, but in Visual C# 2008 an argument must be sent
// for each parameter. Because the parameters are reference parameters,
// you have to contruct variables for the arguments.
object link = true;
object displayAsIcon = true;

wordApp.Selection.PasteSpecial( ref useDefaultValue,


ref link,
ref useDefaultValue,
ref displayAsIcon,
ref useDefaultValue,
ref useDefaultValue,
ref useDefaultValue);
}

2. Main sonuna aşağıdaki ifadeyi ekleyin.

// Create a Word document that contains an icon that links to


// the spreadsheet.
CreateIconInWordDoc();

3. DisplayInExcel sonuna aşağıdaki ifadeyi ekleyin. Copy yöntemi, çalışma sayfasını panoya ekler.

// Put the spreadsheet contents on the clipboard. The Copy method has one
// optional parameter for specifying a destination. Because no argument
// is sent, the destination is the Clipboard.
workSheet.Range["A1:B3"].Copy();

4. CTRL + F5 tuşlarına basın.


Bir simge içeren bir Word belgesi görüntülenir. Çalışma sayfasını ön plana getirmek için simgeye çift
tıklayın.

Birlikte çalışma türlerini katıştır özelliğini ayarlamak için


1. Çalışma zamanında birincil birlikte çalışma derlemesi (PIA) gerektirmeyen bir COM türünü çağırdığınızda
ek geliştirmeler yapılabilir. PIA 'ların bağımlılığını kaldırmak sürüm bağımsızlık ve daha kolay dağıtıma
neden olur. PIA olmadan programlamanın avantajları hakkında daha fazla bilgi için bkz. Izlenecek yol:
yönetilen derlemelerden tür ekleme.
Ayrıca, gerekli ve COM yöntemleri tarafından döndürülen türler Object yerine dynamic türü kullanılarak
gösterilebildiğinden programlama kolaylaşır. Tür dynamic olan değişkenler çalışma zamanına kadar
değerlendirilmez, bu da açık atama gereksinimini ortadan kaldırır. Daha fazla bilgi için bkz. dinamik tür
kullanımı.
4 C# ' te, PIA kullanımı yerine tür bilgilerini katıştırma varsayılan davranıştır. Bu varsayılan nedenle, açık
atama gerekli olmadığından önceki örneklerden bazıları basitleştirilmiştir. Örneğin, DisplayInExcel
worksheet bildirimi Excel._Worksheet workSheet = (Excel.Worksheet)excelApp.ActiveSheet yerine
Excel._Worksheet workSheet = excelApp.ActiveSheet olarak yazılmıştır. Aynı yöntemde AutoFit yapılan
çağrılar, ExcelApp.Columns[1] bir Object döndürdüğünden ve AutoFit bir Excel yöntemi olduğundan,
varsayılan olmadan açık atama gerektirir. Aşağıdaki kod, atama gösterir.

((Excel.Range)workSheet.Columns[1]).AutoFit();
((Excel.Range)workSheet.Columns[2]).AutoFit();

2. Tür bilgilerini gömmek yerine varsayılan değer değiştirmek ve PIA 'leri kullanmak için, Çözüm Gezgini '
deki Başvurular düğümünü genişletin ve ardından Microsoft. Office. Interop. Excel veya Microsoft.
Office. Interop. Wordöğesini seçin.
3. Özellikler penceresini göremiyorsanız F4tuşuna basın.
4. Özellik listesine birlikte çalışma türlerini katıştır ' ı bulun ve değerini falseolarak değiştirin.
Equivalently, bir komut isteminde -Link yerine -Reference derleyici seçeneğini kullanarak derleyebilirsiniz.

Tabloya ek biçimlendirme eklemek için


1. Aşağıdaki ifadesiyle DisplayInExcel AutoFit iki çağrısı değiştirin.

// Call to AutoFormat in Visual C# 2010.


workSheet.Range["A1", "B3"].AutoFormat(
Excel.XlRangeAutoFormat.xlRangeAutoFormatClassic2);

AutoFormat yöntemi, hepsi isteğe bağlı yedi değer parametresine sahiptir. Adlandırılmış ve isteğe bağlı
bağımsız değişkenler hiçbiri, bazıları veya tümü için bağımsız değişkenler sağlamanıza olanak tanır. Önceki
ifadede, Format parametrelerden yalnızca biri için bir bağımsız değişken sağlanır. Format parametre
listesindeki ilk parametre olduğundan, parametre adını belirtmeniz gerekmez. Ancak, aşağıdaki kodda
gösterildiği gibi, deyimin parametre adının dahil edilip edilmediğini anlamak daha kolay olabilir.

// Call to AutoFormat in Visual C# 2010.


workSheet.Range["A1", "B3"].AutoFormat(Format:
Excel.XlRangeAutoFormat.xlRangeAutoFormatClassic2);

2. Sonucu görmek için CTRL + F5 tuşlarına basın. Diğer biçimler XlRangeAutoFormat numaralandırmasında
listelenmiştir.
3. Adım 1 ' deki ifadesini, C# 3,0 ve önceki sürümlerde gerekli olan bağımsız değişkenleri gösteren aşağıdaki
kodla karşılaştırın.

// The AutoFormat method has seven optional value parameters. The


// following call specifies a value for the first parameter, and uses
// the default values for the other six.

// Call to AutoFormat in Visual C# 2008. This code is not part of the


// current solution.
excelApp.get_Range("A1", "B4").AutoFormat(Excel.XlRangeAutoFormat.xlRangeAutoFormatTable3,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing);
Örnek
Aşağıdaki kod, tüm örneği göstermektedir.

using System;
using System.Collections.Generic;
using System.Linq;
using Excel = Microsoft.Office.Interop.Excel;
using Word = Microsoft.Office.Interop.Word;

namespace OfficeProgramminWalkthruComplete
{
class Walkthrough
{
static void Main(string[] args)
{
// Create a list of accounts.
var bankAccounts = new List<Account>
{
new Account {
ID = 345678,
Balance = 541.27
},
new Account {
ID = 1230221,
Balance = -127.44
}
};

// Display the list in an Excel spreadsheet.


DisplayInExcel(bankAccounts);

// Create a Word document that contains an icon that links to


// the spreadsheet.
CreateIconInWordDoc();
}

static void DisplayInExcel(IEnumerable<Account> accounts)


{
var excelApp = new Excel.Application();
// Make the object visible.
excelApp.Visible = true;

// Create a new, empty workbook and add it to the collection returned


// by property Workbooks. The new workbook becomes the active workbook.
// Add has an optional parameter for specifying a praticular template.
// Because no argument is sent in this example, Add creates a new workbook.
excelApp.Workbooks.Add();

// This example uses a single workSheet.


Excel._Worksheet workSheet = excelApp.ActiveSheet;

// Earlier versions of C# require explicit casting.


//Excel._Worksheet workSheet = (Excel.Worksheet)excelApp.ActiveSheet;

// Establish column headings in cells A1 and B1.


workSheet.Cells[1, "A"] = "ID Number";
workSheet.Cells[1, "B"] = "Current Balance";

var row = 1;
foreach (var acct in accounts)
{
row++;
workSheet.Cells[row, "A"] = acct.ID;
workSheet.Cells[row, "B"] = acct.Balance;
}
workSheet.Columns[1].AutoFit();
workSheet.Columns[2].AutoFit();

// Call to AutoFormat in Visual C#. This statement replaces the


// two calls to AutoFit.
workSheet.Range["A1", "B3"].AutoFormat(
Excel.XlRangeAutoFormat.xlRangeAutoFormatClassic2);

// Put the spreadsheet contents on the clipboard. The Copy method has one
// optional parameter for specifying a destination. Because no argument
// is sent, the destination is the Clipboard.
workSheet.Range["A1:B3"].Copy();
}

static void CreateIconInWordDoc()


{
var wordApp = new Word.Application();
wordApp.Visible = true;

// The Add method has four reference parameters, all of which are
// optional. Visual C# allows you to omit arguments for them if
// the default values are what you want.
wordApp.Documents.Add();

// PasteSpecial has seven reference parameters, all of which are


// optional. This example uses named arguments to specify values
// for two of the parameters. Although these are reference
// parameters, you do not need to use the ref keyword, or to create
// variables to send in as arguments. You can send the values directly.
wordApp.Selection.PasteSpecial(Link: true, DisplayAsIcon: true);
}
}

public class Account


{
public int ID { get; set; }
public double Balance { get; set; }
}
}

Ayrıca bkz.
Type.Missing
dynamic
Tür dinamiği kullanma
Adlandırılmış ve İsteğe Bağlı Bağımsız Değişkenler
Nasıl yapılır: Office Programlamada Adlandırılmış ve İsteğe Bağlı Bağımsız Değişkenleri Kullanma
Nasıl yapılır: COM Birlikte Çalışma Programlamada
Dizin Oluşturulmuş Özellikleri Kullanma (C#
Programlama Kılavuzu)
4.11.2019 • 3 minutes to read • Edit Online

Dizinli Özellikler , programlama içinde C# parametreleri olan com özelliklerinin hangi şekilde tüketildiğini geliştirir.
Dizinli Özellikler C#, Microsoft Office programlamayı geliştirmek için adlandırılmış ve isteğe bağlı bağımsız
değişkenler, yeni bir tür (dinamik) ve katıştırılmış tür bilgilerigibi görseldeki diğer özelliklerle birlikte çalışır.
Önceki sürümlerinde C#, yöntemler yalnızca get yönteminin parametresi yoksa ve set yöntemi bir ve yalnızca
bir değer parametresi içeriyorsa özellikler olarak erişilebilir. Ancak, tüm COM özellikleri bu kısıtlamaları
karşılamıyor. Örneğin, Excel Range[Object, Object] özelliğinin, Aralık adı için bir parametre gerektiren bir get
erişimcisi vardır. Geçmişte, Range özelliğine doğrudan erişemediği için, aşağıdaki örnekte gösterildiği gibi, bunun
yerine get_Range yöntemini kullanmanız gerekiyordu.

// Visual C# 2008 and earlier.


var excelApp = new Excel.Application();
// . . .
Excel.Range targetRange = excelApp.get_Range("A1", Type.Missing);

Dizini oluşturulmuş Özellikler bunun yerine aşağıdakini yazmanızı sağlar:

// Visual C# 2010.
var excelApp = new Excel.Application();
// . . .
Excel.Range targetRange = excelApp.Range["A1"];

NOTE
Önceki örnek ayrıca, Type.Missing atlamanızı sağlayan isteğe bağlı bağımsız değişkenler özelliğini de kullanır.

Benzer şekilde, C# 3,0 ve önceki sürümlerde bir Range nesnesinin Value özelliğinin değerini ayarlamak için iki
bağımsız değişken gereklidir. Bir, Aralık değerinin türünü belirten isteğe bağlı bir parametre için bağımsız
değişken sağlar. Diğeri Value özelliği için değer sağlar. Aşağıdaki örneklerde bu teknikler gösterilmektedir. Her
ikisi de a1 hücresinin değerini Name olarak ayarlayın.

// Visual C# 2008.
targetRange.set_Value(Type.Missing, "Name");
// Or
targetRange.Value2 = "Name";

Dizini oluşturulmuş Özellikler bunun yerine aşağıdaki kodu yazmanızı sağlar.

// Visual C# 2010.
targetRange.Value = "Name";

Kendinizinkini dizinli Özellikler oluşturamazsınız. Özelliği yalnızca var olan dizinli özelliklerin kullanımını destekler.
Örnek
Aşağıdaki kod, bir örnek gösterir. Office API 'sine erişen bir projeyi ayarlama hakkında daha fazla bilgi için bkz.
nasıl yapılır: Visual C# özelliklerini kullanarak Office birlikte çalışma nesnelerine erişme.

// You must add a reference to Microsoft.Office.Interop.Excel to run


// this example.
using System;
using Excel = Microsoft.Office.Interop.Excel;

namespace IndexedProperties
{
class Program
{
static void Main(string[] args)
{
CSharp2010();
//CSharp2008();
}

static void CSharp2010()


{
var excelApp = new Excel.Application();
excelApp.Workbooks.Add();
excelApp.Visible = true;

Excel.Range targetRange = excelApp.Range["A1"];


targetRange.Value = "Name";
}

static void CSharp2008()


{
var excelApp = new Excel.Application();
excelApp.Workbooks.Add(Type.Missing);
excelApp.Visible = true;

Excel.Range targetRange = excelApp.get_Range("A1", Type.Missing);


targetRange.set_Value(Type.Missing, "Name");
// Or
//targetRange.Value2 = "Name";

}
}
}

Ayrıca bkz.
Adlandırılmış ve İsteğe Bağlı Bağımsız Değişkenler
dynamic
Tür dinamiği kullanma
Nasıl yapılır: Office Programlamada Adlandırılmış ve İsteğe Bağlı Bağımsız Değişkenleri Kullanma
Nasıl yapılır: Visual C# Özelliklerini Kullanarak Office Birlikte Çalışma Nesnelerine Erişim
İzlenecek yol: Office programlama
Nasıl yapılır: Wave Dosyasını Oynatmak için Platform
Çağırma Kullanma (C# Programlama Kılavuzu)
30.10.2019 • 3 minutes to read • Edit Online

Aşağıdaki C# kod örneği, Windows işletim sisteminde bir Wave ses dosyası oynatmak için platform çağırma
hizmetleri 'ni nasıl kullanacağınızı göstermektedir.

Örnek
Bu örnek kod, winmm.dll``PlaySound yöntem giriş noktasını Form1 PlaySound() olarak içeri aktarmak için
DllImportAttribute kullanır. Örnekte, bir düğme içeren basit bir Windows formu vardır. Düğmeye tıkladığınızda
yürütmek üzere bir dosyayı açabilmek için standart bir Windows OpenFileDialog iletişim kutusu açılır. Bir dalga
dosyası seçildiğinde, winmm. dll kitaplığının PlaySound() yöntemi kullanılarak oynatılır. Bu yöntem hakkında daha
fazla bilgi için bkz. PlaySound Işlevini Waveform ses dosyalarıyla kullanma. . Wav uzantılı bir dosyaya gözatıp
seçin ve ardından Aç ' a tıklayarak Wave dosyasını platform Invoke kullanarak yürütün. Bir metin kutusu seçili
dosyanın tam yolunu gösterir.
Dosyaları Aç iletişim kutusu, filtre ayarları aracılığıyla yalnızca. wav uzantılı dosyaları gösterecek şekilde
filtrelenmiştir:

dialog1.Filter = "Wav Files (*.wav)|*.wav";


using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WinSound
{
public partial class Form1 : Form
{
private TextBox textBox1;
private Button button1;

public Form1() // Constructor.


{
InitializeComponent();
}

[DllImport("winmm.DLL", EntryPoint = "PlaySound", SetLastError = true, CharSet = CharSet.Unicode,


ThrowOnUnmappableChar = true)]
private static extern bool PlaySound(string szSound, System.IntPtr hMod, PlaySoundFlags flags);

[System.Flags]
public enum PlaySoundFlags : int
{
SND_SYNC = 0x0000,
SND_ASYNC = 0x0001,
SND_NODEFAULT = 0x0002,
SND_LOOP = 0x0008,
SND_NOSTOP = 0x0010,
SND_NOWAIT = 0x00002000,
SND_FILENAME = 0x00020000,
SND_RESOURCE = 0x00040004
}

private void button1_Click(object sender, System.EventArgs e)


{
var dialog1 = new OpenFileDialog();

dialog1.Title = "Browse to find sound file to play";


dialog1.InitialDirectory = @"c:\";
dialog1.Filter = "Wav Files (*.wav)|*.wav";
dialog1.FilterIndex = 2;
dialog1.RestoreDirectory = true;

if (dialog1.ShowDialog() == DialogResult.OK)
{
textBox1.Text = dialog1.FileName;
PlaySound(dialog1.FileName, new System.IntPtr(), PlaySoundFlags.SND_SYNC);
}
}

private void Form1_Load(object sender, EventArgs e)


{
// Including this empty method in the sample because in the IDE,
// when users click on the form, generates code that looks for a default method
// with this name. We add it here to prevent confusion for those using the samples.
}
}
}

Kodu derleme
1. Visual Studio 'da C# yeni bir Windows Forms uygulama projesi oluşturun ve WinSoundolarak adlandırın.
2. Yukarıdaki kodu kopyalayın ve Form1.cs dosyasının içeriğinin üzerine yapıştırın.
3. Aşağıdaki kodu kopyalayın ve mevcut koddan sonra InitializeComponent() yönteminde Form1.Designer.cs
dosyasına yapıştırın.

this.button1 = new System.Windows.Forms.Button();


this.textBox1 = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(192, 40);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(88, 24);
this.button1.TabIndex = 0;
this.button1.Text = "Browse";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(8, 40);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(168, 20);
this.textBox1.TabIndex = 1;
this.textBox1.Text = "FIle path";
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.Text = "Platform Invoke WinSound C#";
this.ResumeLayout(false);
this.PerformLayout();

4. Kodu derleyin ve çalıştırın.

Ayrıca bkz.
C# Programlama Kılavuzu
Birlikte Çalışabilirliğe Genel Bakış
Platform çağırma ' ye daha yakından bakış
Platform Çağırma ile Veri Hazırlama
İzlenecek yol: Office Programlama (C# ve Visual
Basic)
4.11.2019 • 19 minutes to read • Edit Online

Visual Studio, C# ve Visual Basic Microsoft Office programlamayı geliştiren özellikler sunar. Yardımcı C# özellikler,
adlandırılmış ve isteğe bağlı bağımsız değişkenleri ve dynamic türünde dönüş değerlerini içerir. COM
programlamada ref anahtar sözcüğünü atlayabilir ve dizinli özelliklere erişim elde edebilirsiniz. Visual Basic
Özellikler otomatik olarak uygulanan özellikler, Lambda ifadelerinde deyimler ve koleksiyon başlatıcıları içerir.
Her iki dil de, birincil birlikte çalışma derlemelerini (PIA 'lar) kullanıcının bilgisayarına dağıtmaksızın COM
bileşenleriyle etkileşen derlemelerin dağıtımına izin veren tür bilgilerinin gömülmesini sağlar. Daha fazla bilgi için
bkz. Izlenecek yol: yönetilen derlemelerden tür ekleme.
Bu izlenecek yol, Office programlama bağlamında bu özellikleri gösterir, ancak bu özelliklerin birçoğu genel
programlamada de yararlıdır. İzlenecek yolda, Excel çalışma kitabı oluşturmak için bir Excel eklenti uygulaması
kullanırsınız. Sonra, çalışma kitabının bağlantısını içeren bir Word belgesi oluşturursunuz. Son olarak, PIA
bağımlılığını etkinleştirmeyi ve devre dışı bırakmayı görürsünüz.

Prerequisites
Bu yönergeyi tamamlamak için bilgisayarınızda Microsoft Office Excel ve Microsoft Office Word yüklü olmalıdır.

NOTE
Bilgisayarınız, aşağıdaki yönergelerde yer alan Visual Studio kullanıcı arabirimi öğelerinden bazıları için farklı adlar veya
konumlar gösterebilir. Sahip olduğunuz Visual Studio sürümü ve kullandığınız ayarlar bu öğeleri belirler. Daha fazla bilgi için
IDE'yi kişiselleştirme.

Excel eklenti uygulaması ayarlamak için


1. Visual Studio 'Yu başlatın.
2. Dosya menüsünde, Yeni' nin üzerine gelin ve ardından Proje' ye tıklayın.
3. Yüklü şablonlar bölmesinde, Visual Basic veya Visual C# ' i genişletin, Office' i genişletin ve ardından
Office ürününün sürüm yılına tıklayın.
4. Şablonlar bölmesinde, Excel <version > eklentisi' ne tıklayın.
5. .NET Framework 4veya sonraki bir sürümün hedef Framework kutusunda göründüğünden emin olmak
için Şablonlar bölmesinin en üstüne bakın.
6. İsterseniz, ad kutusuna projeniz için bir ad yazın.
7. Tamam'a tıklayın.
8. Yeni proje Çözüm Gezginigörüntülenir.
Başvuru eklemek için
1. Çözüm Gezgini, projenizin adına sağ tıklayın ve ardından Başvuru Ekle' ye tıklayın. Başvuru Ekle
iletişim kutusu görüntülenir.
2. Derlemeler sekmesinde, Microsoft. Office. Interop. Excel, sürüm <version>.0.0.0 (Office ürün sürüm
numaralarına bir anahtar Için, bkz. Microsoft sürümleri), bileşen adı listesinde, ve ardından CTRL tuşunu
basılı tutun ve Microsoft. Office. Interop. Word, version <version>.0.0.0 seçin. Derlemeleri
görmüyorsanız bunların yüklendiğinden ve görüntülendiklerinden emin olmanız gerekebilir (bkz. nasıl
yapılır: Office birincil birlikte çalışma derlemelerini yükleme).
3. Tamam'a tıklayın.
Gerekli Içeri aktarmalar deyimlerini eklemek veya yönergeleri kullanmak için
1. Çözüm Gezgini, ThisAddIn. vb veya ThisAddIn.cs dosyasına sağ tıklayın ve ardından kodu görüntüle'
ye tıklayın.
2. Zaten mevcut değilse, aşağıdaki Imports deyimlerini (Visual Basic) veya using C#yönergeleri () kod
dosyasının en üstüne ekleyin.

using System.Collections.Generic;
using Excel = Microsoft.Office.Interop.Excel;
using Word = Microsoft.Office.Interop.Word;

Imports Microsoft.Office.Interop

Banka hesaplarının bir listesini oluşturmak için


1. Çözüm Gezgini, projenizin adına sağ tıklayın, Ekle' ye ve ardından sınıf' a tıklayın. Kullanıyorsanız, Visual
Basic veya Account.cs kullanıyorsanız,. vb sınıfını adlandırın C#. Ekle'yi tıklatın.
2. Account sınıfının tanımını aşağıdaki kodla değiştirin. Sınıf tanımları Otomatik uygulanan özelliklerikullanır.
Daha fazla bilgi için bkz. Otomatik uygulanan özellikler.

class Account
{
public int ID { get; set; }
public double Balance { get; set; }
}

Public Class Account


Property ID As Integer = -1
Property Balance As Double
End Class

3. İki hesap içeren bir bankAccounts listesi oluşturmak için, ThisAddIn. vb veya ThisAddIn.csiçindeki
ThisAddIn_Startup yöntemine aşağıdaki kodu ekleyin. Liste bildirimleri koleksiyon başlatıcılarıkullanır.
Daha fazla bilgi için bkz. koleksiyon başlatıcıları.

var bankAccounts = new List<Account>


{
new Account
{
ID = 345,
Balance = 541.27
},
new Account
{
ID = 123,
Balance = -127.44
}
};
Dim bankAccounts As New List(Of Account) From {
New Account With {
.ID = 345,
.Balance = 541.27
},
New Account With {
.ID = 123,
.Balance = -127.44
}
}

Excel 'e veri aktarmak için


1. Aynı dosyada, ThisAddIn sınıfına aşağıdaki yöntemi ekleyin. Yöntemi bir Excel çalışma kitabı ayarlar ve
verileri buna dışa aktarır.

void DisplayInExcel(IEnumerable<Account> accounts,


Action<Account, Excel.Range> DisplayFunc)
{
var excelApp = this.Application;
// Add a new Excel workbook.
excelApp.Workbooks.Add();
excelApp.Visible = true;
excelApp.Range["A1"].Value = "ID";
excelApp.Range["B1"].Value = "Balance";
excelApp.Range["A2"].Select();

foreach (var ac in accounts)


{
DisplayFunc(ac, excelApp.ActiveCell);
excelApp.ActiveCell.Offset[1, 0].Select();
}
// Copy the results to the Clipboard.
excelApp.Range["A1:B3"].Copy();
}

Sub DisplayInExcel(ByVal accounts As IEnumerable(Of Account),


ByVal DisplayAction As Action(Of Account, Excel.Range))

With Me.Application
' Add a new Excel workbook.
.Workbooks.Add()
.Visible = True
.Range("A1").Value = "ID"
.Range("B1").Value = "Balance"
.Range("A2").Select()

For Each ac In accounts


DisplayAction(ac, .ActiveCell)
.ActiveCell.Offset(1, 0).Select()
Next

' Copy the results to the Clipboard.


.Range("A1:B3").Copy()
End With
End Sub

Bu yöntemde C# iki yeni özellik kullanılır. Bu özelliklerin her ikisi de Visual Basic zaten var.
Add yöntemi belirli bir şablonu belirtmek için isteğe bağlı bir parametreye sahiptir. 4 ' te C# yeni
olan isteğe bağlı parametreler, parametrenin varsayılan değerini kullanmak istiyorsanız bu
parametreye ilişkin bağımsız değişkeni atlamanızı sağlar. Önceki örnekte hiçbir bağımsız değişken
gönderilmediğinden, Add varsayılan şablonu kullanır ve yeni bir çalışma kitabı oluşturur. Önceki
sürümlerindeki denk ifade, bir yer C# tutucu bağımsız değişkeni gerektirir:
excelApp.Workbooks.Add(Type.Missing) .

Daha fazla bilgi için bkz. adlandırılmış ve Isteğe bağlı bağımsız değişkenler.
Range nesnesinin Range ve Offset özellikleri dizinli Özellikler özelliğini kullanır. Bu özellik,
aşağıdaki tipik C# sözdizimini kullanarak bu özellikleri com türlerinden kullanmanıza olanak sağlar.
Dizinli Özellikler Ayrıca, Value2 özelliğini kullanma gereksinimini ortadan kaldıran Range
nesnesinin Value özelliğini kullanmanıza olanak sağlar. Value özelliği dizine alınmış, ancak dizin
isteğe bağlıdır. İsteğe bağlı bağımsız değişkenler ve dizinli özellikler, aşağıdaki örnekte birlikte çalışır.

// Visual C# 2010 provides indexed properties for COM programming.


excelApp.Range["A1"].Value = "ID";
excelApp.ActiveCell.Offset[1, 0].Select();

Dilin önceki sürümlerinde aşağıdaki özel sözdizimi gereklidir.

// In Visual C# 2008, you cannot access the Range, Offset, and Value
// properties directly.
excelApp.get_Range("A1").Value2 = "ID";
excelApp.ActiveCell.get_Offset(1, 0).Select();

Kendinizinkini dizinli Özellikler oluşturamazsınız. Özelliği yalnızca var olan dizinli özelliklerin
kullanımını destekler.
Daha fazla bilgi için bkz. nasıl yapılır: com birlikte çalışma programlamada dizinli özellikleri
kullanma.
2. Sütun genişliklerini içeriğe uyacak şekilde ayarlamak için DisplayInExcel sonuna aşağıdaki kodu ekleyin.

excelApp.Columns[1].AutoFit();
excelApp.Columns[2].AutoFit();

' Add the following two lines at the end of the With statement.
.Columns(1).AutoFit()
.Columns(2).AutoFit()

Bu eklemeler, ' deki başka C#bir özelliği gösterir. Bu, OFFICE gibi com konaklarından döndürülen Object
değerlerini dinamiktür olarak kabul ediyor. Bu, derleme -bağlantı derleyici seçeneği tarafından
başvuruluyorsa, birlikte çalışma türleri ekle , True veya equivalently gibi varsayılan değere
ayarlandığında bu otomatik olarak gerçekleşir. Tür dynamic , geç bağlamaya izin verir, Visual Basic zaten
kullanılabilir ve C# 3,0 ve önceki dil sürümlerinde gerekli olan açık dönüştürmeyi önler.
Örneğin, excelApp.Columns[1] bir Object döndürür ve AutoFit bir Excel Range yöntemidir. dynamic
olmadan, yöntem AutoFit çağrılmadan önce excelApp.Columns[1] tarafından Range örneği olarak
döndürülen nesneyi atamalısınız.

// Casting is required in Visual C# 2008.


((Excel.Range)excelApp.Columns[1]).AutoFit();

// Casting is not required in Visual C# 2010.


excelApp.Columns[1].AutoFit();
Birlikte çalışma türlerini katıştırma hakkında daha fazla bilgi için, bu konunun devamındaki "PIA
başvurusunu bulmak Için" ve "PIA bağımlılığını geri yüklemek için" yordamlarına bakın. dynamic hakkında
daha fazla bilgi için bkz. dinamik veya tür dinamik kullanma.
DisplayInExcel 'i çağırmak için
1. ThisAddIn_StartUp yönteminin sonuna aşağıdaki kodu ekleyin. DisplayInExcel çağrısı iki bağımsız
değişken içerir. İlk bağımsız değişken işlenecek hesapların listesinin adıdır. İkinci bağımsız değişken,
verilerin nasıl işleneceğini tanımlayan çok satırlı bir lambda ifadesidir. Her bir hesabın ID ve balance
değerleri bitişik hücrelerde görüntülenir ve bakiye sıfırdan küçükse satır kırmızı renkte görüntülenir. Daha
fazla bilgi için bkz. lambda ifadeleri.

DisplayInExcel(bankAccounts, (account, cell) =>


// This multiline lambda expression sets custom processing rules
// for the bankAccounts.
{
cell.Value = account.ID;
cell.Offset[0, 1].Value = account.Balance;
if (account.Balance < 0)
{
cell.Interior.Color = 255;
cell.Offset[0, 1].Interior.Color = 255;
}
});

DisplayInExcel(bankAccounts,
Sub(account, cell)
' This multiline lambda expression sets custom
' processing rules for the bankAccounts.
cell.Value = account.ID
cell.Offset(0, 1).Value = account.Balance

If account.Balance < 0 Then


cell.Interior.Color = RGB(255, 0, 0)
cell.Offset(0, 1).Interior.Color = RGB(255, 0, 0)
End If
End Sub)

2. Programı çalıştırmak için F5 'e basın. Hesaplardan verileri içeren bir Excel çalışma sayfası görüntülenir.
Word belgesi eklemek için
1. Excel çalışma kitabına bir bağlantı içeren bir Word belgesi oluşturmak için, ThisAddIn_StartUp yönteminin
sonuna aşağıdaki kodu ekleyin.

var wordApp = new Word.Application();


wordApp.Visible = true;
wordApp.Documents.Add();
wordApp.Selection.PasteSpecial(Link: true, DisplayAsIcon: true);

Dim wordApp As New Word.Application


wordApp.Visible = True
wordApp.Documents.Add()
wordApp.Selection.PasteSpecial(Link:=True, DisplayAsIcon:=True)

Bu kod, içindeki C#yeni özelliklerden birkaçını gösterır: com programlama, adlandırılmış bağımsız
değişkenler ve isteğe bağlı bağımsız değişkenlerle ref anahtar sözcüğünü atlama özelliği. Bu özellikler
Visual Basic zaten var. PasteSpecial yönteminde yedi parametre bulunur ve bunların tümü isteğe bağlı
başvuru parametresi olarak tanımlanır. Adlandırılmış ve isteğe bağlı bağımsız değişkenler, ad ile erişmek
istediğiniz parametreleri tanımlamanızı ve yalnızca bu parametrelere bağımsız değişkenler göndermenizi
sağlar. Bu örnekte, panodaki çalışma kitabına bir bağlantının oluşturulması gerektiğini göstermek için
bağımsız değişkenler gönderilir (Parameter Link ) ve bağlantının Word belgesinde bir simge olarak
görüntülenmek (parametre DisplayAsIcon ). Görsel C# Ayrıca bu bağımsız değişkenlerin ref anahtar
sözcüğünü atlamanızı sağlar.
Uygulamayı çalıştırmak için
1. Uygulamayı çalıştırmak için F5 tuşuna basın. Excel başlatılır ve bankAccounts iki hesaptan bilgileri içeren bir
tablo görüntüler. Daha sonra Excel tablosuna bir bağlantı içeren bir Word belgesi görüntülenir.
Tamamlanmış projeyi temizlemek için
1. Visual Studio 'da Yapı menüsünde Çözümü Temizle ' ye tıklayın. Aksi takdirde, eklenti, bilgisayarınızda Excel
'i her açışınızda çalışacaktır.
PIA başvurusunu bulmak için
1. Uygulamayı yeniden çalıştırın, ancak Çözümü Temizle' yi tıklamayın.
2. Başlat' ı seçin. Microsoft Visual Studio <version > bulun ve bir geliştirici komut istemi açın.
3. Visual Studio için Geliştirici Komut İstemi penceresine ildasm yazın ve ardından ENTER tuşuna basın. Il
DADSM penceresi görüntülenir.
4. Il DAVSM penceresindeki Dosya menüsünde Dosya > Aç' ı seçin. Visual Studio <version > çift tıklayın
ve ardından Projeler' e çift tıklayın. Projeniz için klasörü açın ve Proje adı. dll 'niz için bin/Debug klasörüne
bakın. Proje adı. dll ' ye çift tıklayın. Yeni bir pencere, diğer modüller ve derlemelere başvurulara ek olarak
projenizin özniteliklerini görüntüler. Ad alanlarının Microsoft.Office.Interop.Excel ve
Microsoft.Office.Interop.Word derlemeye dahil edildiğini unutmayın. Visual Studio 'da varsayılan olarak,
derleyici başvurulan bir PIA 'ten sizin için gerekli olan türleri derlemenizin içine aktarır.
Daha fazla bilgi için bkz. nasıl yapılır: derleme Içeriğini görüntüleme.
5. Bildirim simgesine çift tıklayın. Proje tarafından başvurulan öğeleri içeren derlemelerin listesini içeren bir
pencere görüntülenir. Microsoft.Office.Interop.Excel ve Microsoft.Office.Interop.Word listeye dahil
edilmez. Projenizin gerektirdiği türler derlemenizin içine aktarıldığından, bir PIA başvuruları gerekli
değildir. Bu, dağıtımı kolaylaştırır. PIA 'Lerin kullanıcının bilgisayarında mevcut olması gerekmez ve bir
uygulama bir PIA 'ın belirli bir sürümünün dağıtımını gerektirmediğinden, uygulamalar, gerekli API 'Lerin
tüm sürümlerde bulunması şartıyla, Office 'in birden çok sürümü ile çalışacak şekilde tasarlanabilir. .
PIA dağıtımı artık gerekli olmadığından, önceki sürümler dahil olmak üzere birden fazla Office sürümüyle
birlikte çalışarak Gelişmiş senaryolarda bir uygulama oluşturabilirsiniz. Ancak, bu yalnızca kodunuz,
çalıştığınız Office sürümünde kullanılamayan API 'Leri kullanmıyorsa çalışır. Belirli bir API 'nin önceki bir
sürümde kullanılabilir olup olmadığını her zaman temizlemez ve bu nedenle Office 'in önceki sürümleriyle
çalışma için önerilmez.

NOTE
Office, Office 2003 öncesi PIA 'Ları yayımlamadı. Bu nedenle, Office 2002 veya önceki sürümleri için birlikte çalışma
derlemesi oluşturmanın tek yolu COM başvurusunu içeri aktarmadır.

6. Bildirim penceresini ve derleme penceresini kapatın.


PIA bağımlılığını geri yüklemek için
1. Çözüm Gezgini, tüm dosyaları göster düğmesine tıklayın. Başvurular klasörünü genişletin ve
Microsoft. Office. Interop. Excel' i seçin. Özellikler penceresini göstermek için F4 tuşuna basın.
2. Özellikler penceresinde, birlikte çalışma türlerini katıştır özelliğini true değerinden falsedeğerine
değiştirin.
3. Microsoft.Office.Interop.Word için bu yordamda 1 ve 2. adımları tekrarlayın.
4. İçinde C#, DisplayInExcel yönteminin sonundaki Autofit için iki çağrısı olduğunu açıklama.
5. Projenin hala doğru şekilde çalıştığını doğrulamak için F5 tuşuna basın.
6. Önceki yordamdan derleme penceresini açmak için 1-3 arasındaki adımları yineleyin.
Microsoft.Office.Interop.Word ve Microsoft.Office.Interop.Excel artık gömülü derlemeler listesinde
olmadığına dikkat edin.
7. Bildirim simgesine çift tıklayın ve başvurulan derlemeler listesinde gezinin. Microsoft.Office.Interop.Word
ve Microsoft.Office.Interop.Excel her ikisi de listede bulunur. Uygulama Excel ve Word PIAlerine
başvurduğundan ve birlikte çalışma türlerini katıştır özelliği falseolarak ayarlandığından, her iki
derlemenin de son kullanıcının bilgisayarında bulunması gerekir.
8. Visual Studio 'da, tamamlanmış projeyi temizlemek için derleme menüsündeki Çözümü Temizle ' ye
tıklayın.

Ayrıca bkz.
Otomatik uygulanan Özellikler (Visual Basic)
Otomatik uygulanan Özellikler (C#)
Öğe Başlatıcıları
Nesne ve Koleksiyon Başlatıcıları
İsteğe Bağlı Parametreler
Bağımsız Değişkenleri Konuma ve Ada Göre Geçirme
Adlandırılmış ve İsteğe Bağlı Bağımsız Değişkenler
Erken ve Geç Bağlama
dynamic
Tür dinamiği kullanma
Lambda Ifadeleri (Visual Basic)
Lambda Ifadeleri (C#)
Nasıl yapılır: COM Birlikte Çalışma Programlamada Dizin Oluşturulmuş Özellikleri Kullanma
İzlenecek yol: Visual Studio’da Microsoft Office Bütünleştirilmiş Kodlarından Tür Bilgilerini Katıştırma
İzlenecek yol: Yönetilen Bütünleştirilmiş Kodlardan Türler Katıştırma
İnceleme: Excel için İlk VSTO Eklentinizi Oluşturma
COM Birlikte Çalışma
Birlikte çalışabilirlik
Örnek COM Sınıfı (C# Programlama Kılavuzu)
23.10.2019 • 2 minutes to read • Edit Online

Aşağıda bir COM nesnesi olarak kullanıma sunabileceğiniz bir sınıf örneği verilmiştir. Bu kod bir. cs dosyasına
yerleştirildikten ve projenize eklendikten sonra, com birlikte çalışma özelliğini kaydet özelliğini doğruolarak
ayarlayın. Daha fazla bilgi için nasıl yapılır: COM birlikte çalışmasıiçin bir bileşeni kaydedin.
Visual C# Objects 'i com 'a göstermek için bir sınıf arabirimi, gerekliyse bir olay arabirimi ve sınıfın kendisi için
bildirim gerekir. Sınıf üyelerinin COM 'a görünür olması için bu kuralları izlemesi gerekir:
Sınıf ortak olmalıdır.
Özellikler, Yöntemler ve olaylar ortak olmalıdır.
Özellikler ve Yöntemler sınıf arabiriminde bildirilmelidir.
Olaylar olay arabiriminde bildirilmelidir.
Bu arabirimlerde bildirilmemiş olan sınıftaki diğer genel Üyeler COM 'a görünmez, ancak diğer .NET Framework
nesneleri tarafından görülecektir.
Özellikleri ve yöntemleri com 'a sunmak için, bunları sınıf arabiriminde bildirmeniz ve bir DispId özniteliğiyle
işaretlemeniz ve bunları sınıfında uygulamanız gerekir. Üyelerin arabirimde bildirildiği sıra, COM vtable için
kullanılan sıradır.
Sınıfınızdan olayları göstermek için bunları olaylar arabiriminde bildirmeniz ve bir DispId özniteliğiyle
işaretlemeniz gerekir. Sınıf bu arabirimi uygulamamalıdır.
Sınıfı sınıfı arabirimini uygular; birden fazla arabirim uygulayabilir, ancak ilk uygulama varsayılan sınıf arabirimi
olur. COM 'a sunulan yöntemleri ve özellikleri buraya uygulayın. Bunların ortak olarak işaretlenmesi ve sınıf
arabirimindeki bildirimlerle eşleşmesi gerekir. Ayrıca, burada sınıf tarafından oluşturulan olayları bildirin. Bunların
ortak olarak işaretlenmesi ve olaylar arabirimindeki bildirimlerle eşleşmesi gerekir.

Örnek
using System.Runtime.InteropServices;

namespace project_name
{
[Guid("EAA4976A-45C3-4BC5-BC0B-E474F4C3C83F")]
public interface ComClass1Interface
{
}

[Guid("7BD20046-DF8C-44A6-8F6B-687FAA26FA71"),
InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface ComClass1Events
{
}

[Guid("0D53A3E8-E51A-49C7-944E-E72A2064F938"),
ClassInterface(ClassInterfaceType.None),
ComSourceInterfaces(typeof(ComClass1Events))]
public class ComClass1 : ComClass1Interface
{
}
}

Ayrıca bkz.
C# Programlama Kılavuzu
Birlikte çalışabilirlik
Derleme Sayfası, Proje Tasarımcısı (C#)
C#başvurunun
27.11.2019 • 5 minutes to read • Edit Online

Bu bölümde, anahtar sözcükler, C# işleçler, özel karakterler, Önişlemci yönergeleri, derleyici


seçenekleri ve derleyici hataları ve uyarıları hakkında başvuru malzemeleri sağlanmaktadır.

Bu bölümde
C# Anahtar Sözcükleri
Anahtar sözcükler ve sözdizimi hakkında C# bilgi için bağlantılar sağlar.
C# İşleçleri
İşleçler ve sözdizimi hakkında C# bilgi için bağlantılar sağlar.
C# Özel Karakterleri
' Deki C# özel bağlamsal karakterler ve kullanımları hakkındaki bilgilerin bağlantılarını sağlar.
C# Ön İşlemci Yönergeleri
C# Kaynak koda ekleme için derleyici komutları hakkındaki bilgilere bağlantılar sağlar.
C# Derleyici Seçenekleri
Derleyici seçenekleri ve bunların nasıl kullanılacağı hakkında bilgi içerir.
C# Derleyici Hataları
C# Derleyici hatalarının ve uyarılarının nedenini ve düzeltmesini gösteren kod parçacıkları
içerir.
C#Dil belirtimi
C# 6,0 dil belirtimi. Bu, C# 6,0 diline yönelik taslak bir önersahiptir. Bu belge, ECMA C#
standartları Komitesi ile çalışma aracılığıyla iyileştirilcektir. Sürüm 5,0, standart ECMA-334 5
sürümü belgesi olarak 2017 Aralık 'ta yayımlanmıştır.
6,0 sonrası C# sürümlerde uygulanan özellikler, dil belirtimi tekliflerinde temsil edilir. Bu
belgeler, bu yeni özellikleri eklemek için dil belirtimine yönelik değişimleri ' i anlatmaktadır.
Bunlar taslak teklif formundadır. Bu belirtimler, resmi İnceleme için ECMA standartları
Komitesi ve kurulduğu 'in C# gelecekteki bir sürümüne gönderilir.
C#7,0 belirtim teklifleri
7,0 ' de C# uygulanan çeşitli yeni özellikler vardır. Bunlar, model eşleştirme, yerel işlevler,
çıkış değişkeni bildirimleri, throw ifadeleri, ikili sabit değerler ve basamak ayırıcıları içerirler.
Bu klasör, bu özelliklerin her biri için belirtimleri içerir.
C#7,1 belirtim teklifleri
7,1 ' C# ye eklenen yeni özellikler vardır. İlk olarak, Task veya Task<int> döndüren bir Main
yöntemi yazabilirsiniz. Bu, Main``async değiştiricisini eklemenize olanak sağlar. default
ifadesi, türün çıkarsanbileceği konumlarda bir tür olmadan kullanılabilir. Ayrıca demet üye
adları da çıkarsanamıyor. Son olarak, bir model eşleştirme, genel türler ile kullanılabilir.
C#7,2 belirtim teklifleri
C#7,2 çok sayıda küçük özellik ekledi. in anahtar sözcüğünü kullanarak, ReadOnly
başvuruya göre bağımsız değişkenler geçirebilirsiniz. Span ve ilgili türler için derleme
zamanı güvenliğini desteklemeye yönelik bir dizi alt düzey değişiklik vardır. Bazı durumlarda,
sonraki bağımsız değişkenlerin konumsal olduğu adlandırılmış bağımsız değişkenleri
kullanabilirsiniz. private protected erişim değiştiricisi, arayanların aynı derlemede
uygulanan türetilmiş türlerle sınırlı olduğunu belirtmenizi sağlar. ?: işleci, bir değişkene bir
başvuruya çözüm verebilir. Ayrıca, baştaki basamak ayırıcısını kullanarak onaltılık ve ikili
sayıları biçimlendirebilirsiniz.
C#7,3 belirtim teklifleri
C#7,3, birkaç küçük güncelleştirme içeren başka bir nokta sürümüdür. Yeni kısıtlamaları genel
tür parametreleri üzerinde kullanabilirsiniz. Diğer değişiklikler, stackalloc ayırmaları
kullanma dahil fixed alanlarla çalışmayı kolaylaştırır. ref anahtar sözcüğüyle belirtilen
yerel değişkenler, yeni depolama birimine başvuracak şekilde yeniden atanabilir. Öznitelikleri,
derleyicinin ürettiği yedekleme alanını hedefleyen otomatik uygulanan özelliklere
yerleştirebilirsiniz. , Başlatıcılarda ifade değişkenleri kullanılabilir. Tanımlama grupları, eşitlik
(veya eşitsizlik) için karşılaştırılabilir. Aşırı yükleme çözümlemesi için bazı geliştirmeler de
vardır.
C#8,0 belirtim teklifleri
C#8,0, .NET Core 3,0 ile kullanılabilir. Özellikler, null yapılabilir başvuru türleri, özyinelemeli
model eşleştirme, varsayılan arabirim yöntemleri, zaman uyumsuz akışlar, aralıklar ve
dizinler, using bildirimleri kullanarak ve using bildirimlerini, null birleştirme atamasını ve salt
okunur örnek üyelerini içerir.

İlgili Bölümler
C# için Visual Studio Geliştirme Ortamını Kullanma
IDE ve düzenleyiciyi tanımlayan kavramsal ve görev konularına bağlantılar sağlar.
C# Programlama Kılavuzu
C# Programlama dilinin kullanımı hakkındaki bilgileri içerir.
C#dil sürümü oluşturma
23.10.2019 • 5 minutes to read • Edit Online

En son C# derleyici, projenizin hedef çerçevesine veya çerçevelerine göre varsayılan dil sürümünü belirler.
Bunun nedeni, C# dilin her .NET uygulamasında kullanılamayan türleri veya çalışma zamanı bileşenlerini
kullanan özelliklere sahip olması olabilir. Bu Ayrıca, projenizin her türlü hedefi için varsayılan olarak en yüksek
uyumlu dil sürümünü almanızı sağlar.
Bu makaledeki kurallar, Visual Studio 2019 veya .NET Core 3,0 SDK ile sunulan derleyici için geçerlidir.Visual
C# Studio 2017 yüklemesinin parçası olan derleyiciler veya daha önceki .NET Core SDK sürümleri, varsayılan
olarak C# 7,0 ' dir.

Varsayılanları
Derleyici, bu kurallara göre bir varsayılan değer belirler:

HEDEF ÇERÇEVE SÜRÜM C#DIL SÜRÜMÜ VARSAYILANI

.NET Core 3.x C# 8.0

.NET Core 2.x C# 7.3

.NET Standard 2,1 C# 8.0

.NET Standard 2,0 C# 7.3

.NET Standard 'in C# 7.3

.NET Framework tüm C# 7.3

Önizlemeler için varsayılan


Projeniz karşılık gelen önizleme dili sürümüne sahip bir önizleme çerçevesini hedefliyorsa, kullanılan dil
sürümü önizleme dili sürümüdür. Bu, yayımlanmış bir .NET Core sürümünü hedefleyen projelerinizi
etkilemeden, herhangi bir ortamda bu önizleme ile çalışmak için garanti edilen en son özellikleri kullanmanızı
sağlar.

Varsayılanı geçersiz kıl


C# Sürümünüzü açıkça belirtmeniz gerekiyorsa, bunu birkaç şekilde yapabilirsiniz:
Proje dosyanızıel ile düzenleyin.
Bir alt dizinde birden çok proje içindil sürümünü ayarlayın.
@No__t-1 derleyici seçeneğini yapılandırma
Proje dosyasını düzenleme
Proje dosyanızdaki dil sürümünü ayarlayabilirsiniz. Örneğin, önizleme özelliklerine açıkça erişim istiyorsanız,
şöyle bir öğe ekleyin:
<PropertyGroup>
<LangVersion>preview</LangVersion>
</PropertyGroup>

@No__t-0 değeri, derleyicinizin desteklediği en son C# önizleme dili sürümünü kullanır.


Birden çok proje yapılandırma
Birden çok dizini yapılandırmak için <LangVersion> öğesini içeren bir Dizin. Build. props dosyası
oluşturabilirsiniz. Bunu genellikle çözüm dizininizde yapabilirsiniz. Aşağıdakileri çözüm dizininizde bir Dizin.
Build. props dosyasına ekleyin:

<Project>
<PropertyGroup>
<LangVersion>preview</LangVersion>
</PropertyGroup>
</Project>

Şimdi, bu dosyayı içeren dizinin her alt dizinindeki derlemeler Önizleme C# sürümünü kullanacaktır. Daha fazla
bilgi için, yapınızı özelleştirmebaşlıklı makaleye bakın.

C#dil sürümü başvurusu


Aşağıdaki tabloda tüm geçerli C# dil sürümleri gösterilmektedir. Daha eskiyse, derleyicisinin her değeri
anlayamayabilir. .NET Core 3,0 ' i yüklerseniz, listelenen her şeye erişim sahibi olursunuz.

DEĞER AÇIKLAMA

Önizleme Derleyici, en son önizleme sürümündeki tüm geçerli dil


sözdizimini kabul eder.

sürümü Derleyici derleyicinin en son yayınlanan sürümünden (ikincil


sürüm dahil) söz dizimini kabul eder.

Latestana Derleyici derleyicinin en son yayınlanan ana sürümünden


söz dizimini kabul eder.

8.0 Derleyici yalnızca C# 8,0 veya daha düşük bir sözdiziminde


bulunan sözdizimini kabul eder.

7,3 Derleyici yalnızca C# 7,3 veya daha düşük bir sözdiziminde


bulunan sözdizimini kabul eder.

7,2 Derleyici yalnızca C# 7,2 veya daha düşük bir sözdiziminde


bulunan sözdizimini kabul eder.

7,1 Derleyici yalnızca C# 7,1 veya daha düşük bir sözdiziminde


bulunan sözdizimini kabul eder.

7 Derleyici yalnızca C# 7,0 veya daha düşük bir sözdiziminde


bulunan sözdizimini kabul eder.

6 Derleyici yalnızca C# 6,0 veya daha düşük bir sözdiziminde


bulunan sözdizimini kabul eder.
DEĞER AÇIKLAMA

5 Derleyici yalnızca C# 5,0 veya daha düşük bir sözdiziminde


bulunan sözdizimini kabul eder.

4 Derleyici yalnızca C# 4,0 veya daha düşük bir sözdiziminde


bulunan sözdizimini kabul eder.

3 Derleyici yalnızca C# 3,0 veya daha düşük bir sözdiziminde


bulunan sözdizimini kabul eder.

ISO-2 Derleyici yalnızca ISO/ıEC 23270:2006 C# (2,0) içinde


bulunan söz dizimini kabul eder

ISO-1 Derleyici yalnızca ISO/ıEC 23270:2003 C# (1.0/1.2) içinde


bulunan söz dizimini kabul eder
C# Anahtar Sözcükleri
29.11.2019 • 2 minutes to read • Edit Online

Anahtar sözcükler, derleyiciye özel anlamlara sahip olan önceden tanımlanmış, ayrılmış
tanımlayıcılardır. Ön ek olarak @ eklemediğiniz sürece, programınızda tanımlayıcı olarak kullanılamaz.
Örneğin, @if geçerli bir tanımlayıcıdır, ancak if if bir anahtar sözcüktür.
Bu konudaki ilk tablo, bir programın herhangi bir C# bölümünde ayrılmış tanımlayıcılar olan anahtar
sözcükleri listeler. Bu konudaki ikinci tablo, içindeki C#bağlamsal anahtar sözcükleri listeler. Bağlamsal
anahtar sözcüklerde yalnızca sınırlı program bağlamında özel anlamı vardır ve bu bağlamın dışında
tanımlayıcılar olarak kullanılabilir. Genellikle, C# dile yeni anahtar sözcükler eklendikçe, önceki
sürümlerde yazılmış programları bozmamak için bağlamsal anahtar sözcükler olarak eklenirler.

abstract as base bool

break byte case yakalaya

char checked class const

continue decimal default delegate

do double değilse enum

event explicit extern false

finally Düzenle float for

Foreach goto kullandıysanız implicit

in int interface internal

is lock long namespace

new null object operator

out override params private

protected public readonly ref

return sbyte sealed short

sizeof stackalloc static string

struct switch this throw

true almaya typeof uint

ulong unchecked unsafe ushort


using statik kullanma virtual void

volatile while

Bağlamsal anahtar sözcükler


Bağlam anahtar sözcüğü, kodda belirli bir anlamı sağlamak için kullanılır, ancak içinde C#ayrılmış bir
sözcük değildir. partial ve where gibi bazı bağlamsal anahtar sözcükler, iki veya daha fazla bağlamda
özel anlamlara sahiptir.

add ek ascending

async await by

descending dynamic equals

Kaynak get global

grubu into ayrılma

atalım nameof on

OrderBy Kısmi (tür) partial (Yöntem)

remove seçin set

yönetilmeyen (genel tür kısıtlaması) value var

when (filtre koşulu) where (genel tür kısıtlaması) WHERE (sorgu yan tümcesi)

yield

Ayrıca bkz.
C#başvurunun
Değer türleri (C# başvuru)
29.11.2019 • 4 minutes to read • Edit Online

İki tür değer türü vardır:


Yapılar
Sabit Listeleri

Değer türlerinin ana özellikleri


Değer türünde bir değişken, türün bir değerini içerir. Örneğin, int türünün bir değişkeni 42 değerini
içerebilir. Bu, bir nesne olarak da bilinen tür örneğine başvuru içeren bir başvuru türü değişkeninden
farklıdır. Değer türünde bir değişkene yeni bir değer atadığınızda, bu değer kopyalanır. Başvuru türündeki bir
değişkene yeni bir değer atadığınızda, başvuru nesnenin kendisi değil, kopyalanır.
Tüm değer türleri örtük olarak System.ValueTypetüretilir.
Başvuru türlerinden farklı olarak, bir değer türünden yeni bir tür türemezsiniz. Ancak, başvuru türleri gibi
yapılar, arabirimler uygulayabilir.
Değer türü değişkenleri varsayılan olarak null olamaz. Ancak, karşılık gelen null yapılabilir değer türlerinin
değişkenleri null olabilir.
Her değer türünün, bu türün varsayılan değerini Başlatan örtük parametresiz bir Oluşturucusu vardır. Değer
türlerinin varsayılan değerleri hakkında daha fazla bilgi için bkz. varsayılan değerler tablosu.

Basit türler
Basit türler tarafından C# sunulan önceden tanımlanmış bir yapı türleri kümesidir ve aşağıdaki türleri içerir:
Integral türleri: tamsayı sayısal türleri ve char türü
Kayan nokta türleri
bool
Basit türler anahtar sözcükler aracılığıyla tanımlanır, ancak bu anahtar sözcükler yalnızca System ad
alanındaki önceden tanımlanmış yapı türleri için diğer adlardır. Örneğin, int bir System.Int32diğer adıdır.
Diğer adların tam listesi için bkz. Yerleşik türler tablosu.
Basit türler, bazı ek işlemlere izin veren diğer yapı türlerinden farklıdır:
Basit türler, değişmez değerler kullanılarak başlatılabilir.Örneğin, 'A' türü char bir değişmez
değerdir ve 2001 int türü bir değişmez değerdir.
Const anahtar sözcüğüyle basit türlerin sabitlerini bildirebilirsiniz. Diğer yapı türlerinin sabitlerinin
olması mümkün değildir.
İşlenenleri hepsi basit tür sabitleri olan sabit ifadeler, derleme zamanında değerlendirilir.
Daha fazla bilgi için, C# dil belirtiminin basit türler bölümüne bakın.

Değer türlerini başlatma


Yerel değişkenlerin kullanılmadan C# önce başlatılması gerekir. Örneğin, aşağıdaki örnekte olduğu gibi,
başlatma olmadan yerel bir değişken bildirebilirsiniz:

int myInt;

Bunu, başlamadan önce kullanamazsınız. Aşağıdaki ifadeyi kullanarak başlatabilirsiniz:

myInt = new int(); // Invoke parameterless constructor for int type.

Bu ifade aşağıdaki ifadeye eşdeğerdir:

myInt = 0; // Assign an initial value, 0 in this example.

Tabii ki, bildirimi ve başlatmayı aşağıdaki örneklerle aynı bildirimde bulabilirsiniz:

int myInt = new int();

–veya–

int myInt = 0;

New işlecini kullanmak, belirli türde parametresiz oluşturucuyu çağırır ve varsayılan değeri değişkenine atar.
Önceki örnekte, parametresiz Oluşturucu değeri myInt``0 atanır. Parametresiz oluşturucular çağırarak
atanan değerler hakkında daha fazla bilgi için bkz. varsayılan değerler tablosu.
Kullanıcı tanımlı türlerle, parametresiz oluşturucuyu çağırmak için Yeni ' yi kullanın. Örneğin, aşağıdaki ifade
Point yapısının parametresiz oluşturucusunu çağırır:

var p = new Point(); // Invoke parameterless constructor for the struct.

Bu çağrıdan sonra yapının kesin olarak atanması kabul edilir; diğer bir deyişle, tüm üyeleri varsayılan
değerlerine başlatılır.
new işleci hakkında daha fazla bilgi için, bkz. Yeni.
Sayısal türlerin çıkışını biçimlendirme hakkında daha fazla bilgi için bkz. sayısal sonuçlar tablosunu
biçimlendirme.

Ayrıca bkz.
C#başvurunun
C# anahtar sözcükleri
Başvuru türleri
Null yapılabilir değer türleri
Integral sayısal türleri (C# başvuru)
30.10.2019 • 5 minutes to read • Edit Online

İntegral sayısal türleri basit türlerin bir alt kümesidir ve değişmez değerlerile
başlatılabilir. Tüm integral türleri de değer türlerdir. Tüm integral sayısal türler
Aritmetik, bit düzeyinde mantıksal, karşılaştırmave eşitlik işleçlerini destekler.

İntegral türlerinin özellikleri


C#aşağıdaki önceden tanımlanmış integral türlerini destekler:

C#TÜR/ANAHTAR
SÖZCÜK ARALIK BOYUT .NET TÜRÜ

sbyte -128-127 İmzalanan 8 bit System.SByte


tamsayı

byte 0-255 İşaretsiz 8 bit System.Byte


tamsayı

short -32.768-32.767 İmzalanan 16 bit System.Int16


tamsayı

ushort 0-65.535 İşaretsiz 16 bit System.UInt16


tamsayı

int -2.147.483.648- İmzalanan 32 bit System.Int32


2.147.483.647 tamsayı

uint 0-4.294.967.295 İşaretsiz 32 bit System.UInt32


tamsayı

long - İmzalanan 64 bit System.Int64


922337203685477 tamsayı
5808-
9.223.372.036.854.
775.807

ulong 0- İşaretsiz 64 bit System.UInt64


184467440737095 tamsayı
51615

Yukarıdaki tabloda, en soldaki sütundan C# her tür anahtar sözcüğü karşılık gelen
.NET türü için bir diğer addır. Bunlar arasında değiştirilebilir. Örneğin, aşağıdaki
bildirimler aynı türdeki değişkenleri bildirir:

int a = 123;
System.Int32 b = 123;

Her integral türünün varsayılan değeri sıfırdır 0 . İntegral türlerinin her biri, bu türün
en düşük ve en büyük değerini sağlayan MinValue ve MaxValue sabitlerini içerir.
Büyük veya alt sınır olmadan işaretli bir tamsayıyı temsil etmek için
System.Numerics.BigInteger yapısını kullanın.

Tamsayı sabit değerleri


Tamsayı sabit değerleri
Decimal: herhangi bir ön ek olmadan
onaltılı: 0x veya 0X ön eki ile
ikili: 0b veya 0B önekiyle ( C# 7,0 ve üzeri sürümlerde mevcuttur)
Aşağıdaki kod, her birine bir örnek gösterir:

var decimalLiteral = 42;


var hexLiteral = 0x2A;
var binaryLiteral = 0b_0010_1010;

Yukarıdaki örnek ayrıca, 7,0 ile C# başlayarak desteklenen bir rakam ayırıcısıolarak
_ kullanımını da gösterir. Rakam ayırıcısını her türlü sayısal sabit değer ile
kullanabilirsiniz.
Bir tamsayı sabit değerinin türü, soneki tarafından aşağıdaki şekilde belirlenir:
Değişmez değer için bir sonek yoksa, türü, değerinin gösterilebileceği
aşağıdaki türlerin birincsahiptir: int , uint , long , ulong .
Sabit değer U veya u ile sondiçeriyorsa, türü, değeri gösterilebileceği
aşağıdaki türlerin birincsahiptir: uint , ulong .
Sabit değer L veya l ile sondiçeriyorsa, türü, değeri gösterilebileceği
aşağıdaki türlerin birincsahiptir: long , ulong .

NOTE
Küçük harf l bir sonek olarak kullanabilirsiniz. Ancak, harf l 1 basamak ile
karıştırıabileceğinden bu bir derleyici uyarısı oluşturur. Açıklık için L kullanın.

Sabit değer UL , Ul , uL , ul , LU , Lu , lU veya lu tarafından


düzeltildiğinde, türü ulong olur.
Bir tamsayı değişmez değeri ile temsil edilen değer UInt64.MaxValue aşarsa, bir
derleyici hatası CS1021 oluşur.
Bir tamsayı değişmez değerinin belirlenen türü int ise ve değişmez değer
tarafından temsil edilen değer hedef türün aralığı içindeyse, değer örtük olarak
sbyte , byte , short , ushort dönüştürülebilir , uint veya ulong :

byte a = 17;
byte b = 300; // CS0031: Constant value '300' cannot be converted to a 'byte'

Yukarıdaki örnekte gösterildiği gibi, değişmez değerin değeri hedef türü Aralık içinde
değilse, bir derleyici hatası CS0031 oluşur.
Ayrıca, bir tamsayı değişmez değeri ile temsil edilen değeri, değişmez değerin
belirlenen türü dışında bir türe dönüştürmek için bir cast kullanabilirsiniz:
var signedByte = (sbyte)42;
var longVariable = (long)42;

Dönüşümler
Herhangi bir integral sayısal türü diğer tüm integral sayısal türlerine
dönüştürebilirsiniz. Hedef türü kaynak türünün tüm değerlerini depolayabiliyorsanız,
dönüştürme örtük olur. Aksi takdirde, açık bir dönüştürme çağırmak için () cast
işlecini kullanmanız gerekir. Daha fazla bilgi için bkz. yerleşik sayısal dönüştürmeler.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtimininaşağıdaki bölümlerine bakın:
Integral türleri
Tamsayı sabit değerleri

Ayrıca bkz.
C#başvurunun
Yerleşik türler tablosu
Kayan nokta türleri
Sayısal sonuçlar tablosunu biçimlendirme
.NET Sayısal Değerleri
Kayan nokta sayısal türleri (C# başvuru)
29.11.2019 • 5 minutes to read • Edit Online

Kayan nokta türleri basit türlerin bir alt kümesidir ve değişmez değerlerile başlatılabilir. Tüm kayan
nokta türleri de değer türlerdir. Tüm kayan nokta sayısal türleri Aritmetik, karşılaştırmave eşitlik işleçlerini
destekler.

Kayan nokta türlerinin özellikleri


C#aşağıdaki önceden tanımlanmış kayan nokta türlerini destekler:

C#TÜR/ANAHTAR
SÖZCÜK YAKLAŞIK ARALIK DUYARLIK BOYUT .NET TÜRÜ

float ± 1,5 x 10− 45 ila ± ~ 6-9 basamak 4 bayt System.Single


3,4 x 1038

double ± 5,0 × 10− 324 ila ~ 15-17 basamak 8 bayt System.Double


± 1,7 × 10308

decimal ± 1,0 x 10-28 ila ± 28-29 basamak 16 bayt System.Decimal


7,9228 x 1028

Yukarıdaki tabloda, en soldaki sütundan C# her tür anahtar sözcüğü karşılık gelen .NET türü için bir diğer
addır. Bunlar arasında değiştirilebilir. Örneğin, aşağıdaki bildirimler aynı türdeki değişkenleri bildirir:

double a = 12.3;
System.Double b = 12.3;

Her kayan nokta türünün varsayılan değeri sıfırdır 0 . Kayan nokta türlerinin her biri, bu türün minimum
ve maksimum sonlu değerini sağlayan MinValue ve MaxValue sabitlerini içerir. float ve double türleri,
sayı olmayan ve sonsuz değerleri temsil eden sabitleri de sağlar. Örneğin, double türü şu sabitleri sağlar:
Double.NaN, Double.NegativeInfinityve Double.PositiveInfinity.
decimal türü daha fazla kesinlik ve float ve double daha küçük bir aralığa sahip olduğundan, finansal
ve parasal hesaplamalar için uygundur.
Bir ifadede integral türlerini ve kayan nokta türlerini karıştırabilirsiniz. Bu durumda, integral türler kayan
nokta türlerine dönüştürülür. İfadenin değerlendirmesi aşağıdaki kurallara göre gerçekleştirilir:
Kayan nokta türlerinden biri double , ifade double veya ilişkisel ve eşitlik karşılaştırmalarında bool
olarak değerlendirilir.
İfadede double tür yoksa, ifade float veya ilişkisel ve eşitlik karşılaştırmalarında bool olarak
değerlendirilir.
Kayan nokta ifadesi aşağıdaki değer kümelerini içerebilir:
Pozitif ve negatif sıfır
Pozitif ve negatif sonsuzluk
Sayı olmayan değer (NaN )
Sınırlı olmayan değerler kümesi
Bu değerler hakkında daha fazla bilgi için, IEEE Web sitesinde kullanılabilen Ikili kayan nokta
ARITMETIĞI Için IEEE Standard ' a bakın.
Kayan noktalı bir değeri biçimlendirmek için Standart sayısal biçim dizelerini veya özel sayısal biçim
dizelerini kullanabilirsiniz.

Gerçek sabit değerler


Gerçek bir sabit değerin türü, soneki tarafından aşağıdaki şekilde belirlenir:
Sonek olmadan veya d ya da D sonekine sahip sabit değer double türündedir
f veya F sonekine sahip sabit değer float türündedir
m veya M sonekine sahip sabit değer decimal türündedir

Aşağıdaki kod, her birine bir örnek gösterir:

double d = 3D;
d = 4d;
d = 3.934_001;

float f = 3_000.5F;
f = 5.4f;

decimal myMoney = 3_000.5m;


myMoney = 400.75M;

Yukarıdaki örnek ayrıca, 7,0 ile C# başlayarak desteklenen bir rakam ayırıcısıolarak _ kullanımını da
gösterir. Rakam ayırıcısını her türlü sayısal sabit değer ile kullanabilirsiniz.
Ayrıca, aşağıdaki örnekte gösterildiği gibi bilimsel gösterim kullanabilirsiniz, yani gerçek bir sabit değerin
üs bir kısmını belirtebilirsiniz:

double d = 0.42e2;
Console.WriteLine(d); // output 42;

float f = 134.45E-2f;
Console.WriteLine(f); // output: 1.3445

decimal m = 1.5E6m;
Console.WriteLine(m); // output: 1500000

Dönüşümler
Kayan nokta sayısal türleri arasında yalnızca bir örtük dönüşüm vardır: float 'den double . Ancak,
herhangi bir kayan nokta türünü açık atamaile başka bir kayan nokta türüne dönüştürebilirsiniz. Daha
fazla bilgi için bkz. yerleşik sayısal dönüştürmeler.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtimininaşağıdaki bölümlerine bakın:
Kayan nokta türleri
Ondalık tür
Gerçek sabit değerler

Ayrıca bkz.
C#başvurunun
Yerleşik türler tablosu
Integral türleri
Sayısal sonuçlar tablosunu biçimlendirme
Standart sayısal biçim dizeleri
.NET Sayısal Değerleri
System.Numerics.Complex
Yerleşik sayısal dönüşümler (C# başvuru)
24.10.2019 • 7 minutes to read • Edit Online

C#integral ve kayan nokta sayısal türleri kümesi sağlar. Örtük veya açık olmak üzere iki sayısal tür arasında bir
dönüştürme var. Açık bir dönüştürme çağırmak için () cast işlecini kullanmanız gerekir.

Örtük Sayısal dönüştürmeler


Aşağıdaki tabloda, yerleşik sayısal türler arasında önceden tanımlanmış örtük dönüştürmeler gösterilmektedir:

BAŞLANGIÇ BITIŞ

sbyte short , int , long , float , double veya decimal

byte short , ushort , int , uint , long , ulong , float ,


double veya decimal

short int , long , float , double veya decimal

ushort int , uint , long , ulong , float , double veya


decimal

int long , float , double veya decimal

uint long , ulong , float , double veya decimal

long float , double veya decimal

ulong float , double veya decimal

float double

NOTE
int , uint , long ya da ulong 'den float ve long ulong ya da double arasında örtük dönüştürmeler, duyarlık
kaybına neden olabilir, ancak hiçbir şekilde bir büyüklük kaybı olmaz. Diğer örtük sayısal dönüştürmeler hiçbir bilgiyi hiçbir
şekilde kaybetmez.

Ayrıca,
Tüm integral sayısal türleri örtük olarak herhangi bir kayan nokta sayısal türünedönüştürülebilir.
byteve sbyte türlerine örtük dönüştürmeler yok. double ve decimal türlerinden örtük
dönüştürmeler yok.
decimal türü ile float veya double türleri arasında örtük dönüştürme yok.
int türünde sabit bir ifadenin değeri (örneğin, bir tamsayı değişmez değeri ile temsil edilen bir değer),
hedef türün aralığı içindeyse örtülü olarak sbyte , byte , short , ushort , uint veya ulong
dönüştürülebilir :
byte a = 13;
byte b = 300; // CS0031: Constant value '300' cannot be converted to a 'byte'

Yukarıdaki örnekte gösterildiği gibi, sabit değer hedef türünün aralığı içinde değilse, bir derleyici hatası
CS0031 oluşur.

Açık sayısal dönüştürmeler


Aşağıdaki tabloda, örtük dönüştürmeolmayan yerleşik sayısal türler arasında önceden tanımlanmış açık
dönüştürmeler gösterilmektedir:

BAŞLANGIÇ BITIŞ

sbyte byte , ushort , uint veya ulong

byte sbyte

short sbyte , byte , ushort , uint veya ulong

ushort sbyte , byte veya short

int sbyte , byte , short , ushort , uint veya ulong

uint sbyte , byte , short , ushort veya int

long sbyte , byte , short , ushort , int , uint veya


ulong

ulong sbyte , byte , short , ushort , int , uint veya long

float sbyte , byte , short , ushort , int , uint , long ,


ulong veya decimal

double sbyte , byte , short , ushort , int , uint , long ,


ulong , float veya decimal

decimal sbyte , byte , short , ushort , int , uint , long ,


ulong , float veya double

NOTE
Açık bir sayısal dönüştürme, veri kaybına neden olabilir veya genellikle bir OverflowExceptionözel durum oluşturabilir.

Ayrıca,
İntegral türdeki bir değeri başka bir integral türüne dönüştürdüğünüzde, sonuç taşma Denetim
bağlamınabağlıdır. Denetlenen bir bağlamda, kaynak değer hedef türünün aralığı içindeyse dönüştürme
başarılı olur. Aksi takdirde, bir OverflowException oluşturulur. İşaretlenmemiş bir bağlamda, dönüştürme
her zaman başarılı olur ve şu şekilde devam eder:
Kaynak türü hedef türünden büyükse, "ekstra" en önemli bitleri atarak kaynak değer kesilir. Sonuç
daha sonra hedef türünün bir değeri olarak değerlendirilir.
Kaynak türü hedef türünden küçükse, hedef türle aynı boyutta olması için, kaynak değeri ya imza
veya sıfır genişletilmiş ya da sıfır genişletilmiş olur. Kaynak türü imzalanmışsa, oturum açma
uzantısı kullanılır; Kaynak türü işaretsiz ise sıfır uzantı kullanılır. Sonuç daha sonra hedef türünün
bir değeri olarak değerlendirilir.
Kaynak türü hedef türle aynı boyutta ise, kaynak değer hedef türün bir değeri olarak
değerlendirilir.
Bir decimal değerini bir integral türüne dönüştürdüğünüzde, bu değer en yakın tamsayı değerine sıfır
doğru yuvarlanır. Elde edilen integral değeri, hedef türü aralığının dışındaysa bir OverflowException
oluşturulur.
Bir double veya float değerini bir integral türüne dönüştürdüğünüzde, bu değer en yakın tamsayı
değerine sıfır doğru yuvarlanır. Elde edilen integral değeri, hedef türü aralığının dışındaysa sonuç, taşma
denetimi bağlamınabağlıdır. Denetlenen bir bağlamda, bir OverflowException atılır, ancak işaretlenmemiş
bir bağlamda sonuç, hedef türünün belirtilmeyen bir değeridir.
double dönüştürdüğünüzde double değeri en yakın float değerine yuvarlanır. double değeri
float
çok küçük veya float türüne sığmayacak kadar büyükse, sonuç sıfır veya sonsuzluk olur.
float veya double decimal 'e dönüştürdüğünüzde, kaynak değer decimal gösterimine dönüştürülür
ve gerekirse 28 ondalık haneli, en yakın sayıya yuvarlanır. Kaynak değerin değerine bağlı olarak,
aşağıdaki sonuçlardan biri meydana gelebilir:
Kaynak değeri decimal olarak gösterilemeyecek kadar küçükse, sonuç sıfır olur.
Kaynak değeri NaN (sayı değil), sonsuz veya decimal olarak temsil edilebilmesi için çok büyük ise,
bir OverflowException oluşturulur.
decimal veya
float double dönüştürdüğünüzde, kaynak değer sırasıyla en yakın float veya double
değere yuvarlanır.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtimininaşağıdaki bölümlerine bakın:
Örtük Sayısal dönüştürmeler
Açık sayısal dönüştürmeler

Ayrıca bkz.
C#başvurunun
Atama ve tür dönüşümleri
bool (C# başvuru)
29.11.2019 • 2 minutes to read • Edit Online

bool Type anahtar sözcüğü, true veya false olabilen bir Boolean değeri temsil eden .NET System.Boolean yapı
türü için bir diğer addır.
bool türünün değerleriyle mantıksal işlemler gerçekleştirmek için, Boolean mantıksal işleçler kullanın. bool türü
karşılaştırma ve eşitlik işleçlerinin sonuç türüdür. bool ifade, IF, Do, whileve for deyimlerinde ve koşullu işleç ?:
bir denetim koşullu ifadesi olabilir.
bool türünün varsayılan değeri false .

Sabit değerler
bool değişkenini başlatmak veya bir bool değeri geçirmek için true ve false değişmez değerleri
kullanabilirsiniz:

bool check = true;


Console.WriteLine(check ? "Checked" : "Not checked"); // output: Checked

Console.WriteLine(false ? "Checked" : "Not checked"); // output: Not checked

Dönüşümler
C# bool türünü içeren yalnızca iki dönüştürme sağlar. Bunlar, karşılık gelen null yapılabilir bool? türüne örtülü bir
dönüşümtür ve bool? türünden açık bir dönüştürme. Ancak, .NET bool türüne dönüştürmek için
kullanabileceğiniz ek yöntemler sağlar. Daha fazla bilgi için, System.Boolean API başvurusu sayfasının Boole
değerlerine dönüştürme bölümüne bakın.

Üç değerli Boole mantığı


Üç değerli mantığı desteketmeniz gerekiyorsa (örneğin, üç değerli bir Boolean türünü destekleyen veritabanlarıyla
çalışırken) null yapılabilir bool? türünü kullanın. bool? işlenenleri için, önceden tanımlanmış & ve | işleçleri üç
değerli mantığı destekler. Daha fazla bilgi için, Boole mantıksal işleçler makalesinin Nullable Boolean mantıksal
işleçler bölümüne bakın.
Null yapılabilir değer türleri hakkında daha fazla bilgi için bkz. Nullable değer türleri.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin bool türü bölümüne bakın.

Ayrıca bkz.
C#başvurunun
Yerleşik türler tablosu
true ve false işleçleri
Char (C# başvuru)
29.11.2019 • 2 minutes to read • Edit Online

char Type anahtar sözcüğü, bir Unicode UTF -16 karakteri temsil eden .NET System.Char yapı türü için bir
diğer addır.

TÜR ARALIK BOYUT .NET TÜRÜ

char U + 0000-U + FFFF 16 bit System.Char

char türünün varsayılan değeri \0 , yani U + 0000.


Dize türü, metni char değerleri dizisi olarak temsil eder.

Sabit değerler
İle bir char değeri belirtebilirsiniz:
bir karakter sabit değeri.
bir karakter kodunun dört basamaklı onaltılı temsili \u bir Unicode kaçış sırası.
\x bir karakter kodunun onaltılı gösterimi tarafından izlenen bir onaltılık kaçış sırası.

var chars = new[]


{
'j',
'\u006A',
'\x006A',
(char)106,
};
Console.WriteLine(string.Join(" ", chars)); // output: j j j j

Yukarıdaki örnekte gösterildiği gibi, bir karakter kodunun değerini de karşılık gelen char değerine
çevirebilirsiniz.

NOTE
Unicode kaçış sırası söz konusu olduğunda, dört onaltılık basamağı de belirtmeniz gerekir. Yani, \u006A geçerli bir kaçış
sırası, \u06A ve \u6A geçerli değildir.
Onaltılı kaçış sırası söz konusu olduğunda, öndeki sıfırları atlayabilirsiniz. Diğer bir deyişle, \x006A , \x06A ve \x6A
kaçış dizileri geçerlidir ve aynı karaktere karşılık gelir.

Dönüşümler
char türü örtük olarak şu integral türlerine dönüştürülebilir: ushort , int , uint , long ve. Ayrıca
ulong
yerleşik kayan nokta sayısal türlerine örtülü olarak dönüştürülebilir: float , double ve decimal . sbyte , byte
ve short integral türlerine açıkça dönüştürülebilir.
Diğer türlerden char türüne örtük dönüştürme yok. Ancak, herhangi bir integral veya kayan nokta sayısal türü
char açıkça dönüştürülebilir.
C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin Integral türler bölümüne bakın.

Ayrıca bkz.
C#başvurunun
Yerleşik türler tablosu
Dizeler
2 minutes to read
struct (C# Başvurusu)
4.11.2019 • 2 minutes to read • Edit Online

struct türü, genellikle bir dikdörtgenin koordinatları veya Stoktaki bir öğenin özellikleri gibi
ilgili değişkenlerin küçük gruplarını kapsüllemek için kullanılan bir değer türüdür. Aşağıdaki
örnek, basit bir struct bildirimini göstermektedir:

public struct Book


{
public decimal price;
public string title;
public string author;
}

Açıklamalar
Yapılar, birçok üye olsa da, oluşturucular, sabitler, alanlar, Yöntemler, Özellikler, Dizin
oluşturucular, işleçler, Olaylarve iç içe türleriçerebilir. gerekli, bunun yerine bir sınıf yazmanız
gerekir.
Örnekler için bkz. yapıları kullanma.
Yapılar bir arabirim uygulayabilir, ancak başka bir struct 'tan devralınabilir.Bu nedenle, yapı
üyeleri protected olarak bildirilemez.
Daha fazla bilgi için bkz. yapılar.

Örnekler
Örnekler ve daha fazla bilgi için bkz. yapıları kullanma.

C# dili belirtimi
Örnekler için bkz. yapıları kullanma.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
Varsayılan Değerler Tablosu
Yerleşik Türler Tablosu
Türler
Değer Türleri
class
interface
Sınıflar ve Yapılar
Nullable değer türleri (C# başvuru)
8.11.2019 • 11 minutes to read • Edit Online

Null olabilen bir değer türü T? temel alınan değer T türünün tüm değerlerini ve ek bir null değeri temsil
eder. Örneğin, aşağıdaki üç değerden herhangi birini bir bool? değişkenine atayabilirsiniz: true , false
veya null . Temel alınan değer türü T , null yapılabilir bir değer türü olamaz.

NOTE
C#8,0, Nullable başvuru türleri özelliğini tanıtır. Daha fazla bilgi için bkz. Nullable başvuru türleri. Null yapılabilir değer
türleri 2 ile C# başlayarak kullanılabilir.

Herhangi bir null yapılabilir değer türü, genel System.Nullable<T> yapısının bir örneğidir. Aşağıdaki
değiştirilebilir formlardan herhangi birinde T , temel alınan bir tür ile null olabilen bir değer türüne
başvurabilirsiniz: Nullable<T> veya T? .
Genellikle, temel alınan bir değer türünün tanımsız değerini temsil etmeniz gerektiğinde null yapılabilen bir
değer türü kullanırsınız. Örneğin, bir Boolean veya bool , değişken yalnızca true ya da false olabilir.
Ancak bazı uygulamalarda bir değişken değeri tanımsız veya eksik olabilir. Örneğin, bir veritabanı alanı
true veya false içerebilir veya hiçbir değer içeremez, diğer bir deyişle, NULL . Bu senaryodaki bool?
türünü kullanabilirsiniz.

Bildirim ve atama
Değer türü, karşılık gelen null yapılabilir değer türüne örtük olarak dönüştürülebilir olduğundan, onun
temel alınan değer türü için yaptığınız gibi, null olabilen değer türünde bir değişkene bir değer
atayabilirsiniz. null değerini de atayabilirsiniz. Örneğin:

double? pi = 3.14;
char? letter = 'a';

int m2 = 10;
int? m = m2;

bool? flag = null;

// An array of a nullable type:


int?[] arr = new int?[10];

Null olabilen bir değer türünün varsayılan değeri null temsil eder, diğer bir deyişle, Nullable<T>.HasValue
özelliği false döndüren bir örneğidir.

Null yapılabilir bir değer türünün örneğinin incelenmesi


7,0 ile C# başlayarak, is işlecini bir tür düzeniyle birlikte kullanarak null için null yapılabilir değer
türünün bir örneğini inceleyebilir ve temel alınan bir türün değerini alabilirsiniz:
int? a = 42;
if (a is int valueOfA)
{
Console.WriteLine($"a is {valueOfA}");
}
else
{
Console.WriteLine("a does not have a value");
}
// Output:
// a is 42

Her zaman, null olabilen bir değer türü değişkeninin değerini incelemek ve almak için aşağıdaki salt
okunurdur özelliklerini kullanabilirsiniz:
Nullable<T>.HasValue, null yapılabilir bir değer türünün bir örneğinin temel alınan türü bir değere
sahip olup olmadığını gösterir.
Nullable<T>.Value, HasValue true bir temel alınan türün değerini alır. HasValue false , Value
özelliği bir InvalidOperationExceptionoluşturur.
Aşağıdaki örnek, değişkenin görüntülemeden önce bir değer içerip içermediğini test etmek için HasValue
özelliğini kullanır:

int? b = 10;
if (b.HasValue)
{
Console.WriteLine($"b is {b.Value}");
}
else
{
Console.WriteLine("b does not have a value");
}
// Output:
// b is 10

Ayrıca, aşağıdaki örnekte gösterildiği gibi, null olabilen bir değer türünün değişkenini HasValue özelliğini
kullanmak yerine null ile karşılaştırabilirsiniz:

int? c = 7;
if (c != null)
{
Console.WriteLine($"c is {c.Value}");
}
else
{
Console.WriteLine("c does not have a value");
}
// Output:
// c is 7

Null yapılabilir bir değer türünden temel alınan bir türe


dönüştürme
Null olabilen bir değer türünün değerini null yapılamayan bir değer türü değişkenine atamak istiyorsanız,
null yerine atanacak değeri belirtmeniz gerekebilir. Bunu yapmak için null birleşim işleci ?? kullanın (aynı
amaçla Nullable<T>.GetValueOrDefault(T) yöntemini de kullanabilirsiniz):
int? a = 28;
int b = a ?? -1;
Console.WriteLine($"b is {b}"); // output: b is 28

int? c = null;
int d = c ?? -1;
Console.WriteLine($"d is {d}"); // output: d is -1

null yerine temel alınan değer türünün varsayılan değerini kullanmak istiyorsanız
Nullable<T>.GetValueOrDefault() yöntemini kullanın.
Ayrıca, aşağıdaki örnekte gösterildiği gibi, null olabilen bir değer türünü null yapılamayan bir türe açıkça
çevirebilirsiniz:

int? n = null;

//int m1 = n; // Doesn't compile


int n2 = (int)n; // Compiles, but throws an exception if n is null

Çalışma zamanında, null yapılabilir bir değer türünün değeri null , açık atama bir
InvalidOperationExceptionoluşturur.
Null yapılamayan bir değer türü T , örtük olarak karşılık gelen null değer türü T? türüne dönüştürülebilir.

Yükseltilmemiş işleçleri
Önceden tanımlanmış birli ve ikili işleçler veya T bir değer türü tarafından desteklenen aşırı yüklenmiş
işleçler, karşılık gelen null yapılabilir değer türü T? tarafından da desteklenir. Yükseltilmemiş işleçleriolarak
da bilinen bu işleçler, bir veya her iki işlenen de null``null üretir; Aksi takdirde, işleç sonucu hesaplamak
için işlenenlerinin kapsanan değerlerini kullanır. Örneğin:

int? a = 10;
int? b = null;
int? c = 10;

a++; // a is 11
a = a * c; // a is 110
a = a + b; // a is null

NOTE
bool? türü için, önceden tanımlanmış & ve | işleçleri bu bölümde açıklanan kurallara uymalıdır: işleçlerden biri
null olsa bile bir operatör değerlendirmesinin sonucu null olmamalıdır. Daha fazla bilgi için, Boole mantıksal işleçler
makalesinin Nullable Boolean mantıksal işleçler bölümüne bakın.

< , > , <= ve >= karşılaştırma işleçleri için, bir veya her iki işlenen de null , sonuç false olur; Aksi
takdirde, kapsanan işlenen değerleri karşılaştırılır. Belirli bir karşılaştırma (örneğin, <= ) false
döndürdüğünden, zıt karşılaştırma ( > ) true döndürdüğünü varsaymayın. Aşağıdaki örnek, 10 ' un
olduğunu gösterir
null büyük veya eşit değil
null ve küçüktür
int? a = 10;
Console.WriteLine($"{a} >= null is {a >= null}");
Console.WriteLine($"{a} < null is {a < null}");
Console.WriteLine($"{a} == null is {a == null}");
// Output:
// 10 >= null is False
// 10 < null is False
// 10 == null is False

int? b = null;
int? c = null;
Console.WriteLine($"null >= null is {b >= c}");
Console.WriteLine($"null == null is {b == c}");
// Output:
// null >= null is False
// null == null is True

Yukarıdaki örnek ayrıca, null her ikisi de true değerlendirilen iki null yapılabilir değer türü örneğinin
eşitlik karşılaştırmasını gösterir.
İki değer türü arasında Kullanıcı tanımlı bir dönüştürme varsa, aynı dönüştürme karşılık gelen null
atanabilir değer türleri arasında da kullanılabilir.

Kutulama ve kutudan çıkarma


Null yapılabilir bir değer türü örneği, T? aşağıdaki gibi kutulanır :
HasValue false döndürürse, null başvuru üretilir.
HasValue true döndürürse, temel alınan değer T türünün karşılık gelen değeri Nullable<T>örneği
değil kutulanır.
Aşağıdaki örnekte gösterildiği gibi, bir değer türünün paketlenmiş değerini, karşılık gelen null değer türü
T?``T bırakabilirsiniz:

int a = 41;
object aBoxed = a;
int? aNullable = (int?)aBoxed;
Console.WriteLine($"Value of aNullable: {aNullable}");

object aNullableBoxed = aNullable;


if (aNullableBoxed is int valueOfA)
{
Console.WriteLine($"aNullableBoxed is boxed int: {valueOfA}");
}
// Output:
// Value of aNullable: 41
// aNullableBoxed is boxed int: 41

Null yapılabilir değer türünü belirleme


Aşağıdaki örnek, bir System.Type örneğinin oluşturulmuş bir null yapılabilir değer türünü (yani, belirtilen
tür parametresine sahip System.Nullable<T> türü) temsil edip etmediğini gösterir T :
Console.WriteLine($"int? is {(IsNullable(typeof(int?)) ? "nullable" : "non nullable")} type");
Console.WriteLine($"int is {(IsNullable(typeof(int)) ? "nullable" : "non-nullable")} type");

bool IsNullable(Type type) => Nullable.GetUnderlyingType(type) != null;

// Output:
// int? is nullable type
// int is non-nullable type

Örnekte gösterildiği gibi, bir System.Type örneği oluşturmak için typeof işlecini kullanırsınız.
Bir örneğin, null yapılabilir bir değer türünde olup olmadığını anlamak istiyorsanız, yukarıdaki kodla test
edilecek bir Type örneğini almak için Object.GetType yöntemini kullanmayın. Null olabilen değer türünün
bir örneğinde Object.GetType yöntemini çağırdığınızda, örnek Objectolarak paketlenmelidir . Null olabilen
bir değer türünün null olmayan bir örneğinin kutulenmesi, temel alınan türün bir değer kutulamasında
eşdeğerdir GetType, null olabilen bir değer türünün temel türünü temsil eden bir Type örneği döndürür:

int? a = 17;
Type typeOfA = a.GetType();
Console.WriteLine(typeOfA.FullName);
// Output:
// System.Int32

Ayrıca, bir örneğin null yapılabilir değer türünde olup olmadığını anlamak için , işleç kullanmayın. Aşağıdaki
örnekte gösterildiği gibi, null olabilen bir değer türü örneği ve temel alınan tür örneğini is işleçle ayırt
edemezsiniz:

int? a = 14;
if (a is int)
{
Console.WriteLine("int? instance is compatible with int");
}

int b = 17;
if (b is int?)
{
Console.WriteLine("int instance is compatible with int?");
}
// Output:
// int? instance is compatible with int
// int instance is compatible with int?

Bir örneğin null yapılabilir bir değer türünde olup olmadığını anlamak için aşağıdaki örnekte sunulan kodu
kullanabilirsiniz:

int? a = 14;
Console.WriteLine(IsOfNullableType(a)); // output: True

int b = 17;
Console.WriteLine(IsOfNullableType(b)); // output: False

bool IsOfNullableType<T>(T o)
{
var type = typeof(T);
return Nullable.GetUnderlyingType(type) != null;
}
NOTE
Bu bölümde açıklanan yöntemler, null yapılabilir başvuru türleridurumunda geçerli değildir.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtimininaşağıdaki bölümlerine bakın:
Null yapılabilir türler
Yükseltilmemiş işleçleri
Örtük null yapılabilir dönüşümler
Açık boş değer atanabilir dönüşümler
Yükseltilmemiş dönüştürme işleçleri

Ayrıca bkz.
C#başvurunun
' Yükseltilmemiş ' tam olarak ne anlama geliyor?
System.Nullable<T>
System.Nullable
Nullable.GetUnderlyingType
Boş değer atanabilir başvuru türleri
Başvuru türleri (C# başvuru)
4.11.2019 • 2 minutes to read • Edit Online

C#'de iki çeşit tür vardır: başvuru türleri ve değer türleri. Başvuru türlerinin değişkenleri başvuruları kendi
verilerine (nesneler) depolarken, değer türlerinin değişkenleri kendi verilerini doğrudan içerir. Başvuru türleri
ile, iki değişken aynı nesneye başvurabilir; bu nedenle, bir değişken üzerinde yapılan işlemler diğer
değişkenin başvurduğu nesneyi etkileyebilir. Değer türleriyle, her değişken kendi verilerinin kopyasına
sahiptir ve bir değişkende diğer işlemler (ın, ref ve out parametre değişkenleri hariç) için bir değişken
üzerinde işlemler yapılamaz; bkz. ın, ref ve Out parametre değiştiricisi.
Aşağıdaki anahtar sözcükler, başvuru türlerini bildirmek için kullanılır:
class
interface
delegate
C# ayrıca aşağıdaki yerleşik başvuru türlerini de sağlar:
dynamic
object
string

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
Türler
Değer Türleri
Yerleşik başvuru türleri (C# başvuru)
25.11.2019 • 10 minutes to read • Edit Online

C#, çeşitli yerleşik başvuru türlerine sahiptir. .NET kitaplığındaki bir tür için eş anlamlı anahtar
sözcükler veya operatörler vardır.

Nesne türü
object türü, .NET System.Object için bir diğer addır. Birleşik tür sisteminde C#, tüm türler,
önceden tanımlanmış ve Kullanıcı tanımlı, başvuru türleri ve değer türleri,
System.Objectdoğrudan veya dolaylı olarak devralınır. object türündeki değişkenlere herhangi
bir tür değeri atayabilirsiniz. Herhangi bir object değişken varsayılan değeri, değişmez null
kullanılarak atanabilir. Değer türünde bir değişken nesnesine dönüştürüldüğünde,
kutulanmışolarak kabul edilir. Nesne türündeki bir değişken bir değer türüne
dönüştürüldüğünde, kutulanmamışolarak kabul edilir. Daha fazla bilgi için bkz. kutulama ve
kutudançıkarma.

Dize türü
string türü, sıfır veya daha fazla Unicode karakter dizisini temsil eder. string , .NET
System.String için bir diğer addır.
string bir başvuru türü olsa da, eşitlik işleçleri == ve != , başvuruları değil string
nesnelerinin değerlerini karşılaştırmak için tanımlanmıştır. Bu, dize eşitlik sınamasını daha
sezgisel hale getirir. Örneğin:

string a = "hello";
string b = "h";
// Append to contents of 'b'
b += "ello";
Console.WriteLine(a == b);
Console.WriteLine(object.ReferenceEquals(a, b));

Bu, dizelerin içeriği eşdeğer olduğu, ancak a ve b aynı dize örneğine başvurmadığından
"true" ve ardından "false" değerlerini görüntüler.
+ İşleci dizeleri art arda ekler:

string a = "good " + "morning";

Bu, "iyi sabah" içeren bir dize nesnesi oluşturur.


Dizeler sabittir--dize nesnesinin içeriği nesne oluşturulduktan sonra değiştirilemez, ancak söz
konusu sözdizimi bunu yapabilse gibi görünür. Örneğin, bu kodu yazdığınızda, derleyici aslında
yeni karakter dizisini tutmak için yeni bir dize nesnesi oluşturur ve bu yeni nesne b atanır. b
için ayrılan bellek ("h" dizesini içeriyorsa), daha sonra çöp toplama için uygun hale gelir.

string b = "h";
b += "ello";
[] işleci , bir string tek tek karakterleri için salt okunur erişim için kullanılabilir. Geçerli
değerler 0 başlar ve string uzunluğundan küçük olmalıdır:

string str = "test";


char x = str[2]; // x = 's';

Benzer şekilde, [] işleci, string her bir karakter üzerinde yineleme için de kullanılabilir:

string str = "test";

for (int i = 0; i < str.Length; i++)


{
Console.Write(str[i] + " ");
}
// Output: t e s t

Dize sabit değerleri string türündedir ve tırnak işaretleri ve @ tırnak içine alınmış iki biçimde
yazılabilir. Tırnak işaretli dize sabit değerleri çift tırnak işareti (") içine alınır:

"good morning" // a string literal

Dize sabit değerleri, herhangi bir karakter sabit değeri içerebilir. Kaçış dizileri dahil edilir.
Aşağıdaki örnek, eğik çizgi için \\ kaçış sırası kullanır, f harfi için \u0066 ve yeni satır için \n .

string a = "\\\u0066\n F";


Console.WriteLine(a);
\\ Output:
\\ \f
\\ F

NOTE
Kaçış kodu \udddd ( dddd dört basamaklı bir sayıdır), U + dddd Unicode karakterini temsil eder. Sekiz
basamaklı Unicode kaçış kodları da tanınmalıdır: \Udddddddd .

Tam dize sabit değerleri @ ile başlar ve ayrıca çift tırnak işaretleri içine alınır. Örneğin:

@"good morning" // a string literal

Tam dizelerin avantajı, kaçış dizilerinin işlenmediği , örneğin tam nitelikli bir Windows dosya
adını yazmayı kolaylaştırır.

@"c:\Docs\Source\a.txt" // rather than "c:\\Docs\\Source\\a.txt"

Bir @-quoted dizesinde çift tırnak işareti eklemek için, bu iki katına geçin:

@"""Ahoy!"" cried the captain." // "Ahoy!" cried the captain.

Temsilci türü
Bir temsilci türünün bildirimi, yöntem imzasına benzerdir. Dönüş değerine ve herhangi bir
türde parametreye sahiptir:

public delegate void MessageDelegate(string message);


public delegate int AnotherDelegate(MyType m, long num);

.NET ' te, System.Action ve System.Func türleri birçok ortak temsilci için genel tanımlar sağlar.
Muhtemelen yeni özel temsilci türleri tanımlamanız gerekmez. Bunun yerine, belirtilen genel
türlerin örneklemesini oluşturabilirsiniz.
delegate , adlandırılmış veya anonim bir yöntemi kapsüllemek için kullanılabilecek bir başvuru
türüdür. Temsilciler, içindeki C++işlev işaretçilerine benzerdir; Ancak, temsilciler tür açısından
güvenli ve güvenlidir. Temsilcilerin uygulamaları için bkz. Temsilciler ve Genel Temsilciler.
Temsilciler, olaylarıntemelini oluşturur. Bir temsilci, adlandırılmış ya da anonim bir yöntemle
ilişkilendirerek oluşturulabilir.
Temsilci, uyumlu bir dönüş türü ve giriş parametrelerine sahip bir yöntem veya lambda
ifadesiyle oluşturulmalıdır. Yöntem imzasında izin verilen varyans derecesi hakkında daha fazla
bilgi için bkz. temsilcilerin varyansı. Anonim yöntemlerle kullanılmak üzere, ile ilişkilendirilecek
temsilci ve kod birlikte bildirilmiştir.

Dinamik tür
dynamic türü, değişkenin, derleme zamanı tür denetimini atlayan üyelerine ve başvurularını
kullanacağını gösterir. Bunun yerine, bu işlemler çalışma zamanında çözümlenir. dynamic türü,
Office Otomasyonu API 'leri, IronPython kitaplıkları gibi dinamik API 'ler ve HTML Belge
Nesne Modeli (DOM ) gibi COM API 'Lerine erişimi basitleştirir.
Tür dynamic , çoğu durumda object türü gibi davranır. Özellikle, null olmayan herhangi bir
ifade dynamic türüne dönüştürülebilir. dynamic türü, dynamic türü ifadeler içeren işlemlere
object farklıdır veya derleyici tarafından denetlenen tür. Derleyici, işlem hakkındaki bilgileri
birlikte paketler ve bu bilgiler daha sonra çalışma zamanında işlemi değerlendirmek için
kullanılır. İşlemin bir parçası olarak dynamic türündeki değişkenler object türündeki
değişkenlere derlenir. Bu nedenle, dynamic yalnızca derleme zamanında mevcuttur, çalışma
zamanında değil.
Aşağıdaki örnek, dynamic türünde bir değişkenini object türünde bir değişkene karşıttır.
Derleme zamanında her değişkenin türünü doğrulamak için, WriteLine deyimlerine dyn veya
obj üzerine fare işaretçisini koyun. Aşağıdaki kodu IntelliSense 'in kullanılabildiği bir
düzenleyiciye kopyalayın. IntelliSense, obj için dinamik dyn ve nesne gösterir.

class Program
{
static void Main(string[] args)
{
dynamic dyn = 1;
object obj = 1;

// Rest the mouse pointer over dyn and obj to see their
// types at compile time.
System.Console.WriteLine(dyn.GetType());
System.Console.WriteLine(obj.GetType());
}
}

WriteLine deyimleri dyn ve obj çalışma zamanı türlerini görüntüler. Bu noktada, her ikisi de
aynı tür, tamsayı olmalıdır. Aşağıdaki çıktı üretilir:
System.Int32
System.Int32

Derleme zamanında dyn ve obj arasındaki farkı görmek için, önceki örnekteki bildirimler ve
WriteLine deyimleri arasına aşağıdaki iki satırı ekleyin.

dyn = dyn + 3;
obj = obj + 3;

Bir tamsayı ve ifadedeki bir nesne obj + 3 ekleme denemesi için bir derleyici hatası bildirilir.
Ancak dyn + 3 için bir hata bildirilmedi. dyn türü dynamic olduğundan, dyn içeren ifade
derleme sırasında denetlenmez.
Aşağıdaki örnek, dynamic çeşitli bildirimlerde kullanır. Main yöntemi, derleme zamanı tür
denetimini çalışma zamanı tür denetlemesi ile de karşıtlıkları.
using System;

namespace DynamicExamples
{
class Program
{
static void Main(string[] args)
{
ExampleClass ec = new ExampleClass();
Console.WriteLine(ec.exampleMethod(10));
Console.WriteLine(ec.exampleMethod("value"));

// The following line causes a compiler error because exampleMethod


// takes only one argument.
//Console.WriteLine(ec.exampleMethod(10, 4));

dynamic dynamic_ec = new ExampleClass();


Console.WriteLine(dynamic_ec.exampleMethod(10));

// Because dynamic_ec is dynamic, the following call to exampleMethod


// with two arguments does not produce an error at compile time.
// However, it does cause a run-time error.
//Console.WriteLine(dynamic_ec.exampleMethod(10, 4));
}
}

class ExampleClass
{
static dynamic field;
dynamic prop { get; set; }

public dynamic exampleMethod(dynamic d)


{
dynamic local = "Local variable";
int two = 2;

if (d is int)
{
return local;
}
else
{
return two;
}
}
}
}
// Results:
// Local variable
// 2
// Local variable

Ayrıca bkz.
C#Başvurunun
C# Anahtar Sözcükleri
Olaylar
Tür dinamiği kullanma
Dizeleri Kullanmak için En İyi Uygulamalar
Temel Dize İşlemleri
Yeni Dizeler Oluşturma
Tür testi ve atama işleçleri
Model eşleştirmeyi ve as ve işleç işleçlerini kullanarak güvenli bir şekilde atama
İzlenecek yol: dinamik nesneler oluşturma ve kullanma
System.Object
System.String
System.Dynamic.DynamicObject
class (C# Başvurusu)
23.10.2019 • 4 minutes to read • Edit Online

Sınıflar, aşağıdaki örnekte gösterildiği gibi class anahtar sözcüğü kullanılarak bildirilmiştir:

class TestClass
{
// Methods, properties, fields, events, delegates
// and nested classes go here.
}

Açıklamalar
İçinde C#yalnızca tekli devralmaya izin verilir. Diğer bir deyişle, bir sınıf yalnızca bir temel
sınıftan uygulamayı devralınabilir. Ancak, bir sınıf birden fazla arabirim uygulayabilir.
Aşağıdaki tabloda sınıf devralma ve arabirim uygulama örnekleri gösterilmektedir:

DEVRALMA ÖRNEK

Yok. class ClassA { }

Tek class DerivedClass: BaseClass { }

Hiçbiri, iki arabirim uygular class ImplClass: IFace1, IFace2 { }

Tek, bir arabirim uygular class ImplDerivedClass: BaseClass, IFace1


{ }

Diğer sınıflarda iç içe değil, bir ad alanı içinde doğrudan bildirdiğiniz sınıflar ortak veya
içolabilir. Sınıflar varsayılan internal olarak ' dir.
İç içe geçmiş sınıflar dahil olmak üzere sınıf üyeleri ortak, korumalı dahili, korunan, dahili,
özelveya özel korumalıolabilir. Üyeler varsayılan private olarak ' dir.
Daha fazla bilgi için bkz. erişim değiştiricileri.
Tür parametrelerine sahip genel sınıfları bildirebilirsiniz. Daha fazla bilgi için bkz. genel
sınıflar.
Bir sınıf, aşağıdaki üyelerin bildirimlerini içerebilir:
Oluşturucular
Sabitler
Alanlar
Sonlandırıcılar
Yöntemler
Özellikler
Dizin Oluşturucular
İşleçler
Olaylar
Temsilciler
Sınıflar
Arabirimler
Yapılar
Sabit Listeleri

Örnek
Aşağıdaki örnek, sınıf alanları, oluşturucular ve yöntemlerinin bildirimini gösterir. Ayrıca,
nesne örneğini oluşturmayı ve örnek verilerini yazdırmayı gösterir. Bu örnekte, iki sınıf
bildirilmiştir. İlk sınıf Child olan, iki özel alan ( name ve age ), iki ortak Oluşturucu ve bir
genel yöntem içerir. İkinci sınıfı StringTest , öğesini içermesi Main için kullanılır.
class Child
{
private int age;
private string name;

// Default constructor:
public Child()
{
name = "N/A";
}

// Constructor:
public Child(string name, int age)
{
this.name = name;
this.age = age;
}

// Printing method:
public void PrintChild()
{
Console.WriteLine("{0}, {1} years old.", name, age);
}
}

class StringTest
{
static void Main()
{
// Create objects by using the new operator:
Child child1 = new Child("Craig", 11);
Child child2 = new Child("Sally", 10);

// Create an object using the default constructor:


Child child3 = new Child();

// Display results:
Console.Write("Child #1: ");
child1.PrintChild();
Console.Write("Child #2: ");
child2.PrintChild();
Console.Write("Child #3: ");
child3.PrintChild();
}
}
/* Output:
Child #1: Craig, 11 years old.
Child #2: Sally, 10 years old.
Child #3: N/A, 0 years old.
*/

Açıklamalar
Önceki örnekte özel alanlara ( name ve age ) yalnızca Child sınıfın genel yöntemiyle
erişildiğine dikkat edin. Örneğin, aşağıdaki gibi bir ifade kullanarak alt öğenin adını Main
yöntemden yazdıramazsınız:

Console.Write(child1.name); // Error

' In Child Main özel üyelerine erişim, yalnızca sınıfının bir üyesi Main ise mümkün
olacaktır.
Bir erişim değiştiricisi private olmayan bir sınıf içinde bildirildiği türler, bu nedenle bu
örnekteki veri üyeleri anahtar sözcüğünün kaldırılmakta olması private durumunda olmaya
devam eder.
Son olarak, parametresiz Oluşturucu ( child3 ) kullanılarak oluşturulan nesne için age ,
alanın varsayılan olarak sıfıra başlatıldığını fark edersiniz.

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı
için kesin bir kaynaktır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
Başvuru Türleri
interface (C# Başvurusu)
23.10.2019 • 3 minutes to read • Edit Online

Arabirim yalnızca yöntemlerin, özelliklerin, olayların veya Dizin oluşturucularınimzalarını içerir. Ara
birimi uygulayan bir sınıfın veya yapının, ara birim tanımında belirtilen ara birim üyelerini uygulaması
gerekir. Aşağıdaki örnekte ImplementationClass sınıfının, parametresi olmayan ve SampleMethod 'i
döndüren void adlı bir yöntemi uygulaması gerekir.
Daha fazla bilgi ve örnek için bkz. arabirimler.

Örnek
interface ISampleInterface
{
void SampleMethod();
}

class ImplementationClass : ISampleInterface


{
// Explicit interface member implementation:
void ISampleInterface.SampleMethod()
{
// Method implementation.
}

static void Main()


{
// Declare an interface instance.
ISampleInterface obj = new ImplementationClass();

// Call the member.


obj.SampleMethod();
}
}

Ara birim, bir ad alanının veya bir sınıfın üyesi olabilir ve aşağıdaki üyelerin imzalarını içerebilir:
Yöntemler
Özellikler
Dizin Oluşturucular
Olaylar
Bir ara birim, bir veya daha fazla temel ara birimden devralınabilir.
Bir temel tür listesi temel bir sınıfı ve ara birimleri içerdiğinde, temel sınıfın listede ilk sırada olması
gerekir.
Bir ara birimi uygulayan bir sınıf, o ara birimin üyelerini açıkça uygulayabilir. Açıkça uygulanan bir üyeye,
bir sınıfın örneği üzerinden erişilemez, yalnızca ara birimin bir örneği üzerinden erişilebilir.
Açık arabirim uygulamasındaki diğer ayrıntılar ve kod örnekleri için bkz. Açık arabirim uygulama.

Örnek
Aşağıdaki örnek, ara birim uygulamasını gösterir. Bu örnekte, ara birim özellik bildirimini, sınıf ise
uygulamayı içerir. IPoint öğesini uygulayan bir sınıfın herhangi bir örneği x ve y tamsayı
özelliklerine sahiptir.

interface IPoint
{
// Property signatures:
int x
{
get;
set;
}

int y
{
get;
set;
}
}

class Point : IPoint


{
// Fields:
private int _x;
private int _y;

// Constructor:
public Point(int x, int y)
{
_x = x;
_y = y;
}

// Property implementation:
public int x
{
get
{
return _x;
}

set
{
_x = value;
}
}

public int y
{
get
{
return _y;
}
set
{
_y = value;
}
}
}

class MainClass
{
static void PrintPoint(IPoint p)
{
Console.WriteLine("x={0}, y={1}", p.x, p.y);
}
static void Main()
{
IPoint p = new Point(2, 3);
Console.Write("My Point: ");
PrintPoint(p);
}
}
// Output: My Point: x=2, y=3

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
Başvuru Türleri
Arabirimler
Özellikleri Kullanma
Dizin Oluşturucular Kullanma
class
struct
Arabirimler
void (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

Bir yöntem için dönüş türü olarak kullanıldığında void yöntemi bir değer döndürmediğini belirtir.
void bir yöntemin parametre listesinde izin verilmez. Hiçbir parametre almayan ve hiçbir değer döndürmeyen
bir yöntem şu şekilde bildirilir:

public void SampleMethod()


{
// Body of the method.
}

void Ayrıca güvenli olmayan bir bağlamda, bir işaretçi türü bilinmiyor bildirmek için kullanılır. Daha fazla bilgi
için işaretçi türleri.
void .NET Framework için bir diğer addır System.Void türü.

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir kaynaktır.

Ayrıca bkz.
C# başvurusu
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
Başvuru Türleri
Değer Türleri
Yöntemler
Güvenli Olmayan Kod ve İşaretçiler
var (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

Visual C# 3.0 içinde başlayarak, yöntem kapsamda bildirilen değişkenler örtük bir "type" olabilir var .
Bir türü örtük olarak belirlenmiş yerel değişken alacağı yalnızca kendiniz türü bildirilen, ancak
derleyicinin türü belirler kesin. Aşağıdaki iki bildirimlerini i işlevsel olarak eşdeğerdir:

var i = 10; // Implicitly typed.


int i = 10; // Explicitly typed.

Daha fazla bilgi için örtük olarak yazılan yerel değişkenler ve LINQ Sorgu işlemlerinde tür ilişkileri.

Örnek
Aşağıdaki örnek, iki sorgu ifadeleri gösterir. İlk ifadede, kullanımını var izin verilir, ancak sorgu sonuç
türü olarak açıkça belirtilebilir gerekli olmadığından bir IEnumerable<string> . Ancak, ikinci ifadede, var
anonim türlerin koleksiyonunu olacak şekilde sonuç verir ve bu tür adı derleyici için dışında erişilemez.
Kullanım var sonucu için yeni bir sınıf oluşturma gereksinimini ortadan kaldırır. Örnek # 2'de
unutmayın foreach yineleme değişkeni item de dolaylı olarak yazılmalıdır.

// Example #1: var is optional when


// the select clause specifies a string
string[] words = { "apple", "strawberry", "grape", "peach", "banana" };
var wordQuery = from word in words
where word[0] == 'g'
select word;

// Because each element in the sequence is a string,


// not an anonymous type, var is optional here also.
foreach (string s in wordQuery)
{
Console.WriteLine(s);
}

// Example #2: var is required because


// the select clause specifies an anonymous type
var custQuery = from cust in customers
where cust.City == "Phoenix"
select new { cust.Name, cust.Phone };

// var must be used because each item


// in the sequence is an anonymous type
foreach (var item in custQuery)
{
Console.WriteLine("Name={0}, Phone={1}", item.Name, item.Phone);
}

Ayrıca bkz.
C# başvurusu
C# Programlama Kılavuzu
Örtülü Olarak Yazılan Yerel Değişkenler
Yönetilmeyen türler (C# başvuru)
27.11.2019 • 2 minutes to read • Edit Online

Bir tür, aşağıdaki türlerden biri ise, yönetilmeyen bir türdür :


sbyte , byte , short , ushort , int , uint , long , ulong , char , float , double , decimal veya bool
Herhangi bir numaralandırma türü
Herhangi bir işaretçi türü
Yalnızca yönetilmeyen türlerin ve 7,3 ve önceki sürümlerde bulunan C# alanları içeren Kullanıcı tanımlı
herhangi bir yapı türü, oluşturulmuş bir tür değildir (en az bir tür bağımsız değişkeni içeren bir tür)
7,3 ile C# başlayarak, bir tür parametresinin işaretçi olmayan, null atanamaz yönetilmeyen bir tür olduğunu
belirtmek için unmanaged kısıtlamasını kullanabilirsiniz.
8,0 ' C# den başlayarak, aşağıdaki örnekte gösterildiği gibi, yalnızca yönetilmeyen türlerin alanlarını içeren
oluşturulmuş bir yapı türü de yönetilmez:

using System;

public struct Coords<T>


{
public T X;
public T Y;
}

public class UnmanagedTypes


{
public static void Main()
{
DisplaySize<Coords<int>>();
DisplaySize<Coords<double>>();
}

private unsafe static void DisplaySize<T>() where T : unmanaged


{
Console.WriteLine($"{typeof(T)} is unmanaged and its size is {sizeof(T)} bytes");
}
}
// Output:
// Coords`1[System.Int32] is unmanaged and its size is 8 bytes
// Coords`1[System.Double] is unmanaged and its size is 16 bytes

Genel bir yapı, yönetilmeyen ve yönetilmeyen oluşturulmuş türlerin kaynağı olabilir. Yukarıdaki örnek,
Coords<T> genel bir struct tanımlar ve yönetilmeyen oluşturulmuş türlerin örneklerini gösterir. Yönetilmeyen
tür olmayan örnek Coords<object> . Yönetilmeyen olmayan object türünde alanlar içerdiğinden, yönetilmeyen
değildir. Oluşturulan Tüm türlerin yönetilmeyen türler olmasını istiyorsanız, genel bir yapının tanımındaki
unmanaged kısıtlamasını kullanın:

public struct Coords<T> where T : unmanaged


{
public T X;
public T Y;
}
C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin işaretçi türleri bölümüne bakın.

Ayrıca bkz.
C#başvurunun
İşaretçi türleri
Bellek ve aralıkla ilgili türler
sizeof işleci
stackalloc işleci
Yerleşik türler tablosu (C# başvuru)
29.11.2019 • 2 minutes to read • Edit Online

Aşağıdaki tabloda, System ad alanında önceden tanımlanmış türlerin diğer C# adları olan yerleşik türler için
anahtar sözcükler gösterilmektedir:

C#TÜRÜYLE .NET TÜRÜ

bool System.Boolean

byte System.Byte

sbyte System.SByte

char System.Char

decimal System.Decimal

double System.Double

float System.Single

int System.Int32

uint System.UInt32

long System.Int64

ulong System.UInt64

object System.Object

short System.Int16

ushort System.UInt16

string System.String

Açıklamalar
Tablodaki tüm türler, object ve string hariç, basit türler olarak adlandırılır.
.NET türleri ve bunların C# tür anahtar sözcük diğer adları değiştirilebilir. Örneğin, aşağıdaki bildirimlerden
birini kullanarak bir tamsayı değişkeni bildirebilirsiniz:

int x = 123;
System.Int32 y = 123;

Belirtilen türü temsil eden System.Type örneğini almak için typeof işlecini kullanın:
Type stringType = typeof(string);
Console.WriteLine(stringType.FullName);

Type doubleType = typeof(System.Double);


Console.WriteLine(doubleType.FullName);

// Output:
// System.String
// System.Double

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
Değer türleri
Başvuru türleri
Varsayılan değerler tablosu
dynamic
Değer türleri tablosu (C# başvuru)
29.11.2019 • 2 minutes to read • Edit Online

Aşağıdaki tabloda C# değer türleri gösterilmektedir:

DEĞER TÜRÜ KATEGORI

bool Boole değeri

byte İşaretsiz, sayısal, integral

char İşaretsiz, sayısal, integral

decimal Sayısal, kayan nokta

double Sayısal, kayan nokta

enum Listeleme

float Sayısal, kayan nokta

int İmzalanan, sayısal, integral

long İmzalanan, sayısal, integral

sbyte İmzalanan, sayısal, integral

short İmzalanan, sayısal, integral

struct Kullanıcı tanımlı yapı

uint İşaretsiz, sayısal, integral

ulong İşaretsiz, sayısal, integral

ushort İşaretsiz, sayısal, integral

Ayrıca bkz.
C#başvurunun
Varsayılan değerler tablosu
Değer türleri
Sayısal sonuçlar tablosunu biçimlendirme
Varsayılan değerler tablosu (C# başvuru)
29.11.2019 • 2 minutes to read • Edit Online

Aşağıdaki tabloda, C# türlerin varsayılan değerleri gösterilmektedir:

TÜR VARSAYILAN DEĞER

Herhangi bir başvuru türü null

Herhangi bir yerleşik integral sayısal türü 0 (sıfır)

Herhangi bir yerleşik kayan nokta sayısal türü 0 (sıfır)

bool false

char '\0' (U + 0000)

enum İfade tarafından üretilen değer (E)0 , burada E enum


tanımlayıcısıdır.

struct Tüm değer türü alanları varsayılan değerlerine ve tüm


başvuru türü alanlarına ayarlanarak oluşturulan değer
null .

Herhangi bir Nullable değer türü HasValue özelliği false ve Value özelliği tanımsız bir
örnek. Bu varsayılan değer null olabilen bir değer türünün
null değeri olarak da bilinir.

Aşağıdaki örnekte gösterildiği gibi, bir türün varsayılan değerini oluşturmak için varsayılan işleci kullanın:

int a = default(int);

7,1 ' C# den başlayarak, türü varsayılan değeri olan bir değişkeni başlatmak için default değişmez değerini
kullanabilirsiniz:

int a = default;

Bir değer türü için, örtük parametresiz Oluşturucu, aşağıdaki örnekte gösterildiği gibi türün varsayılan
değerini de üretir:

var n = new System.Numerics.Complex();


Console.WriteLine(n); // output: (0, 0)

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtimininaşağıdaki bölümlerine bakın:
Varsayılan değerler
Varsayılan oluşturucular

Ayrıca bkz.
C#başvurunun
C# anahtar sözcükleri
Yerleşik türler tablosu
Oluşturucular
Sayısal sonuçlar tablosunu biçimlendirme (C#
başvuru)
4.11.2019 • 2 minutes to read • Edit Online

Aşağıdaki tabloda sayısal sonuçları biçimlendirmek için desteklenen biçim belirticileri gösterilmektedir. Son
sütundaki biçimlendirilen sonuç, "en-US" CultureInfokarşılık gelir.

BIÇIM BELIRTECI AÇIKLAMA ÖRNEKLER SONUÇ

C veya c Para Birimi string s = $"{2.5:C}"; $2,50

string s = $"{-2.5:C}"; ($2,50)

D veya d Ondalık string s = $"{25:D5}"; 00025

E veya e Simge string s = $" 2.50 e + 005


{250000:E2}";

F veya f Sabit nokta string s = $"{2.5:F2}"; 2,50

string s = $"{2.5:F0}"; 3

G veya g Genel string s = $"{2.5:G}"; 2,5

N veya n rakamlardan string s = $" 2.500.000,00


{2500000:N}";

P veya p Yüzde string s = $"{0.25:P}"; % 25,00

R veya r Gidiş string s = $"{2.5:R}"; 2,5

X veya x Onaltılık string s = $"{250:X}"; BELIRLEDIĞINIZ

string s = $" 'DIR


{0xffff:X}";

Açıklamalar
Bir biçim dizesi oluşturmak için Biçim belirleyicisi kullanın. Biçim dizesi şu biçimdedir: Axx , burada
A , sayısal değere uygulanan biçimlendirme türünü denetleyen biçim belirticisidir.
xx , biçimlendirilen çıktıda basamak sayısını etkileyen duyarlık belirticisidir. Duyarlık belirticisinin değeri, 0 ile
99 aralığındadır.
Ondalık ("D" veya "d") ve onaltılı ("X" veya "x") biçim belirticileri yalnızca integral türler için desteklenir. Gidiş
dönüş ("R" veya "r") Biçim belirleyicisi yalnızca Single, Doubleve BigInteger türleri için desteklenir.
Standart sayısal biçim dizeleri şunları destekler:
Tüm sayısal türlerde ToString yönteminin bazı aşırı yüklemeleri. Örneğin, Int32.ToString(String) ve
Int32.ToString(String, IFormatProvider) yöntemlerine bir sayısal biçim dizesi sağlayabilirsiniz.
Örneğin String.Format yöntemi tarafından desteklenen .NET Bileşik biçimlendirme özelliği.
Enterpolasyonlu dizeler.
Daha fazla bilgi için bkz. Standart sayısal biçim dizeleri.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
Biçimlendirme türleri
Bileşik biçimlendirme
Dize ilişkilendirme
string
Erişim Değiştiricileri (C# Başvurusu)
4.11.2019 • 2 minutes to read • Edit Online

Erişim değiştiriciler, bir üyenin veya bir türün belirtilen erişilebilirliğini belirtmek için kullanılan anahtar
kelimelerdir. Bu bölüm dört erişim değiştiricilerini tanıtır:
public
protected
internal
private

Aşağıdaki altı erişilebilirlik düzeyi erişim değiştiricilerini kullanarak belirtilebilir:


public : erişim kısıtlı değil.
protected : erişim, kapsayan sınıftan türetilmiş olan sınıf veya türlerle sınırlıdır.
internal : erişim geçerli derleme ile sınırlıdır.
protected internal : erişim, geçerli derleme veya içeren sınıftan türetilmiş türlerle sınırlıdır.
private : erişim, kapsayan tür ile sınırlıdır.
private protected : erişim, geçerli derleme içindeki içeren sınıftan türetilmiş içeren sınıf veya türlerle
sınırlıdır.
Bu bölüm ayrıca şunları da tanıtır:
Erişilebilirlik düzeyleri: altı erişilebilirlik düzeyi tanımlamak için dört erişim değiştiricilerini kullanma.
Erişilebilirlik etki alanı: program bölümlerinde bir üyeye başvurulduğunu belirtir.
Erişilebilirlik düzeylerini kullanma kısıtlamaları: belirtilen erişilebilirlik düzeylerini kullanma
kısıtlamalarının Özeti.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
Erişim Değiştiricileri
Erişim Anahtar Sözcükleri
Değiştiriciler
Erişilebilirlik Düzeyleri (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

Üyeler için aşağıdaki tanımlanmış erişilebilirlik public düzeylerinden birini internal belirtmek için private ,,,
veya erişim değiştiricilerini protected kullanın.

TANIMLANAN ERIŞILEBILIRLIK AÇIKLAMA

public Erişim kısıtlı değil.

protected Erişim, kapsayan sınıftan türetilmiş kapsayan sınıf veya


türlerle sınırlıdır.

internal Erişim, geçerli derleme ile sınırlıdır.

protected internal Erişim, geçerli derleme veya kapsayan sınıftan türetilmiş


türlerle sınırlıdır.

private Erişim, kapsayan tür ile sınırlıdır.

private protected Erişim, geçerli derleme içindeki içeren sınıftan türetilmiş


kapsayan sınıf veya türlerle sınırlıdır. 7,2 sürümünden C#
itibaren kullanılabilir.

protected internal Veya private protected kombinasyonlarını kullandığınızda, bir üye veya tür için yalnızca
bir erişim değiştiricisine izin verilir.
Ad alanlarında erişim değiştiricilerine izin verilmez. Ad alanlarının erişim kısıtlamaları yoktur.
Üye bildiriminin gerçekleştiği içeriğe bağlı olarak, yalnızca belirli olarak tanımlanmış erişilebilirlik izin verilir.
Üye bildiriminde erişim değiştiricisi belirtilmemişse, varsayılan bir erişilebilirlik kullanılır.
Diğer türlerde iç içe olmayan en üst düzey türler yalnızca internal veya public erişilebilirliği olabilir. Bu
türlerin internal varsayılan erişilebilirliği.
Diğer türlerin üyeleri olan iç içe türler, aşağıdaki tabloda gösterildiği gibi, erişilebilir olarak bildirilebilecek.

ÜYELERI VARSAYILAN ÜYE ERIŞILEBILIRLIĞI ÜYENIN IZIN VERILEN ERIŞILEBILIRLIĞI

enum public Yok.

class private public

protected

internal

private

protected internal

private protected
ÜYELERI VARSAYILAN ÜYE ERIŞILEBILIRLIĞI ÜYENIN IZIN VERILEN ERIŞILEBILIRLIĞI

interface public Yok.

struct private public

internal

private

İç içe bir türün erişilebilirliği, hem belirtilen üyenin hem de hem de hem de kapsayan türdeki erişilebilirlik etki
alanı tarafından belirlenen erişilebilirlik etki alanınabağlıdır. Ancak, iç içe geçmiş bir türün erişilebilirlik etki alanı,
kapsayan türden bu türü aşamaz.

C# Dil Belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
Erişim Değiştiricileri
Erişilebilirlik Etki Alanı
Erişilebilirlik Düzeylerinin Kullanılmasındaki Kısıtlamalar
Erişim Değiştiricileri
public
private
protected
internal
Erişilebilirlik Etki Alanı (C# Başvurusu)
23.10.2019 • 3 minutes to read • Edit Online

Üyenin erişilebilirlik etki alanı bir üyenin hangi program bölümlerine başvurduğunu belirtir. Üye başka bir tür
içinde iç içe ise, erişilebilirlik etki alanı hem üyenin Erişilebilirlik düzeyine hem de hemen kapsayan türdeki
erişilebilirlik etki alanına göre belirlenir.
Üst düzey bir türün erişilebilirlik etki alanı, en azından içinde bildirildiği projenin program metni. Diğer bir
deyişle, etki alanı bu projenin tüm kaynak dosyalarını içerir. İç içe bir türün erişilebilirlik etki alanı, bildirildiği türün
en az program metniyle. Diğer bir deyişle, etki alanı tüm iç içe geçmiş türleri içeren tür gövdesidir. İç içe bir türün
erişilebilirlik etki alanı, kendisini kapsayan türden hiçbir şekilde aşamaz. Bu kavramlar aşağıdaki örnekte
gösterilmiştir.

Örnek
Bu örnek, en üst düzey bir tür, T1 ve iki iç içe geçmiş M1 sınıf M2 içerir. Sınıflar, farklı tanımlanmış erişilebilir
alanlara sahip alanlar içerir. Main Yönteminde, her üyenin erişilebilirlik etki alanını göstermek için her deyimin bir
açıklaması. Erişilemeyen üyelere başvuruda bulunan deyimlerin açıklama olarak oluşturulduğuna dikkat edin.
Erişilemeyen bir üyeye başvuruda bulunarak oluşan derleyici hatalarını görmek isterseniz, açıklamaları tek
seferde kaldırın.

public class T1
{
public static int publicInt;
internal static int internalInt;
private static int privateInt = 0;
static T1()
{
// T1 can access public or internal members
// in a public or private (or internal) nested class.
M1.publicInt = 1;
M1.internalInt = 2;
M2.publicInt = 3;
M2.internalInt = 4;

// Cannot access the private member privateInt


// in either class:
// M1.privateInt = 2; //CS0122
}

public class M1
{
public static int publicInt;
internal static int internalInt;
private static int privateInt = 0;
}

private class M2
{
public static int publicInt = 0;
internal static int internalInt = 0;
private static int privateInt = 0;
}
}

class MainClass
{
static void Main()
static void Main()
{
// Access is unlimited.
T1.publicInt = 1;

// Accessible only in current assembly.


T1.internalInt = 2;

// Error CS0122: inaccessible outside T1.


// T1.privateInt = 3;

// Access is unlimited.
T1.M1.publicInt = 1;

// Accessible only in current assembly.


T1.M1.internalInt = 2;

// Error CS0122: inaccessible outside M1.


// T1.M1.privateInt = 3;

// Error CS0122: inaccessible outside T1.


// T1.M2.publicInt = 1;

// Error CS0122: inaccessible outside T1.


// T1.M2.internalInt = 2;

// Error CS0122: inaccessible outside M2.


// T1.M2.privateInt = 3;

// Keep the console open in debug mode.


System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
}

C# Dil Belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir kaynaktır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
Erişim Değiştiricileri
Erişilebilirlik Düzeyleri
Erişilebilirlik Düzeylerinin Kullanılmasındaki Kısıtlamalar
Erişim Değiştiricileri
public
private
protected
internal
Erişilebilirlik düzeylerini kullanma kısıtlamaları (C#
başvuru)
23.10.2019 • 4 minutes to read • Edit Online

Bir bildirimde bir tür belirttiğinizde, türün erişilebilirlik düzeyinin bir üyenin ya da başka bir türün erişilebilirlik
düzeyine bağımlı olup olmadığını kontrol edin. Örneğin, doğrudan temel sınıfı en azından türetilmiş sınıf olarak
erişilebilir olmalıdır. Aşağıdaki bildirimler bir derleyici hatasına neden olur çünkü temel sınıf BaseClass şundan
MyClass daha az erişilebilir:

class BaseClass {...}


public class MyClass: BaseClass {...} // Error

Aşağıdaki tablo, belirtilen erişilebilirlik düzeyleri üzerindeki kısıtlamaları özetler.

BAĞLAM AÇIKLAMALAR

Sınıflar Bir sınıf türünün doğrudan temel sınıfı en azından sınıf


türünün kendisi kadar erişilebilir olmalıdır.

Arabirimler Arabirim türünün açık temel arabirimleri en az arabirim


türünün kendisi kadar erişilebilir olmalıdır.

Temsilciler Bir temsilci türünün dönüş türü ve parametre türleri en


azından temsilci türünün kendisi kadar erişilebilir olmalıdır.

Sabitler Bir sabit türü en az sabit değer olarak erişilebilir olmalıdır.

Alanlar Alanın türü en azından alanın kendisi kadar erişilebilir olmalıdır.

Yöntemler Bir yöntemin dönüş türü ve parametre türleri en az yöntemin


kendisi olarak erişilebilir olmalıdır.

Özellikler Özelliğin türü en az özelliğin kendisi olarak erişilebilir olmalıdır.

Olaylar Bir olayın türü en az olayın kendisi olarak erişilebilir olmalıdır.

Dizin Oluşturucular Bir dizin oluşturucunun türü ve parametre türleri en azından


dizin oluşturucunun kendisi olarak erişilebilir olmalıdır.

İşleçler Bir işlecin dönüş türü ve parametre türleri en az işlecin kendisi


olarak erişilebilir olmalıdır.

Oluşturucular Bir oluşturucunun parametre türleri en az oluşturucunun


kendisi olarak erişilebilir olmalıdır.

Örnek
Aşağıdaki örnek farklı türlerin hatalı bildirimlerini içerir. Her bildirimi izleyen yorum, beklenen derleyici hatasını
gösterir.
// Restrictions on Using Accessibility Levels
// CS0052 expected as well as CS0053, CS0056, and CS0057
// To make the program work, change access level of both class B
// and MyPrivateMethod() to public.

using System;

// A delegate:
delegate int MyDelegate();

class B
{
// A private method:
static int MyPrivateMethod()
{
return 0;
}
}

public class A
{
// Error: The type B is less accessible than the field A.myField.
public B myField = new B();

// Error: The type B is less accessible


// than the constant A.myConst.
public readonly B myConst = new B();

public B MyMethod()
{
// Error: The type B is less accessible
// than the method A.MyMethod.
return new B();
}

// Error: The type B is less accessible than the property A.MyProp


public B MyProp
{
set
{
}
}

MyDelegate d = new MyDelegate(B.MyPrivateMethod);


// Even when B is declared public, you still get the error:
// "The parameter B.MyPrivateMethod is not accessible due to
// protection level."

public static B operator +(A m1, B m2)


{
// Error: The type B is less accessible
// than the operator A.operator +(A,B)
return new B();
}

static void Main()


{
Console.Write("Compiled successfully");
}
}

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir kaynaktır.
Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
Erişim Değiştiricileri
Erişilebilirlik Etki Alanı
Erişilebilirlik Düzeyleri
Erişim Değiştiricileri
public
private
protected
internal
internal (C# Başvurusu)
4.11.2019 • 3 minutes to read • Edit Online

internal anahtar sözcüğü, türler ve tür üyeleri için bir erişim değiştiricisidir .

Bu sayfa internal erişimi içerir. internal anahtar sözcüğü ayrıca protected internal erişim
değiştiricisinin bir parçasıdır.

İç türlere veya üyelere, bu örnekte olduğu gibi, yalnızca aynı derlemede bulunan dosyalar içinde
erişilebilir:

public class BaseClass


{
// Only accessible within the same assembly.
internal static int x = 0;
}

Diğer erişim değiştiricilerine sahip internal bir karşılaştırması için bkz. Erişilebilirlik düzeyleri ve erişim
değiştiricileri.
Derlemeler hakkında daha fazla bilgi için bkz. .net 'Teki derlemeler.
İç erişimin yaygın olarak kullanılması bileşen tabanlı geliştirmede olduğundan, bir grup bileşenin,
uygulama kodunun geri kalanında gösterilmeksizin özel bir biçimde birlikte çalışabilmesine olanak sağlar.
Örneğin, grafik kullanıcı arabirimleri oluşturmak için bir çerçeve, iç erişimi olan üyeleri kullanarak birlikte
çalışan Control ve Form sınıfları sağlayabilir. Bu Üyeler iç olduğundan, Framework kullanan koda
gösterilmez.
Bir tür ya da bir üyeye, tanımlandıkları derlemenin dışında iç erişimle başvurulmaları hatadır.

Örnek
Bu örnek, Assembly1.cs ve Assembly1_a.cs iki dosya içerir. İlk dosya, BaseClass iç temel sınıf içerir. İkinci
dosyada BaseClass örneğini oluşturma girişimi bir hata oluşturacaktır.

// Assembly1.cs
// Compile with: /target:library
internal class BaseClass
{
public static int intM = 0;
}

// Assembly1_a.cs
// Compile with: /reference:Assembly1.dll
class TestAccess
{
static void Main()
{
var myBase = new BaseClass(); // CS0122
}
}
Örnek
Bu örnekte, örnek 1 ' de kullandığınız dosyaları kullanın ve BaseClass erişilebilirlik düzeyini public olarak
değiştirin. Ayrıca üye intM erişilebilirlik düzeyini internal olarak değiştirin. Bu durumda, sınıfının
örneğini oluşturabilirsiniz, ancak iç üyeye erişemezsiniz.

// Assembly2.cs
// Compile with: /target:library
public class BaseClass
{
internal static int intM = 0;
}

// Assembly2_a.cs
// Compile with: /reference:Assembly2.dll
public class TestAccess
{
static void Main()
{
var myBase = new BaseClass(); // Ok.
BaseClass.intM = 444; // CS0117
}
}

C# Dil Belirtimi
Daha fazla bilgi için bkz. C# dil belirtiminde Erişilebilirlik bildirimi . Dil belirtimi, C# sözdizimi ve kullanımı
için kesin bir kaynaktır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
Erişim Değiştiricileri
Erişilebilirlik Düzeyleri
Değiştiriciler
public
private
protected
private (C# Başvurusu)
4.11.2019 • 2 minutes to read • Edit Online

private anahtar sözcüğü bir üye erişim değiştiricisidir.

Bu sayfa private erişimi içerir. private anahtar sözcüğü ayrıca private protected erişim
değiştiricisinin bir parçasıdır.

Özel erişim en az izin veren erişim düzeyidir. Özel üyelere, bu örnekte olduğu gibi, yalnızca sınıfın
gövdesinde veya bildirildiği yapı içinde erişilebilir:

class Employee
{
private int i;
double d; // private access by default
}

Aynı gövdedeki iç içe türler Ayrıca bu özel üyelere de erişebilir.


Bu, sınıf veya bildirildiği yapı dışında özel bir üyeye başvuruda bulunmak için derleme zamanı
hatasıdır.
Diğer erişim değiştiricilerine sahip private bir karşılaştırması için bkz. Erişilebilirlik düzeyleri ve
erişim değiştiricileri.

Örnek
Bu örnekte, Employee sınıfı iki özel veri üyesi içerir, name ve salary . Özel Üyeler olarak, üye
yöntemleri dışında erişilemez. GetName ve Salary adlı ortak Yöntemler, Özel üyelere denetimli
erişime izin verecek şekilde eklenir. name üyesine ortak bir yöntem yoluyla erişilir ve salary üyesine
ortak bir salt okunurdur özelliği tarafından erişilir. (Daha fazla bilgi için bkz. Özellikler .)
class Employee2
{
private string name = "FirstName, LastName";
private double salary = 100.0;

public string GetName()


{
return name;
}

public double Salary


{
get { return salary; }
}
}

class PrivateTest
{
static void Main()
{
var e = new Employee2();

// The data members are inaccessible (private), so


// they can't be accessed like this:
// string n = e.name;
// double s = e.salary;

// 'name' is indirectly accessed via method:


string n = e.GetName();

// 'salary' is indirectly accessed via property


double s = e.Salary;
}
}

C# dili belirtimi
Daha fazla bilgi için bkz. C# dil belirtiminde Erişilebilirlik bildirimi . Dil belirtimi, C# sözdizimi ve
kullanımı için kesin bir kaynaktır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
Erişim Değiştiricileri
Erişilebilirlik Düzeyleri
Değiştiriciler
public
protected
internal
protected (C# Başvurusu)
4.11.2019 • 2 minutes to read • Edit Online

protected anahtar sözcüğü bir üye erişim değiştiricisidir.

Bu sayfa protected erişimi içerir. protected anahtar sözcüğü ayrıca protected internal ve
private protected erişim değiştiricilerinden de bir parçasıdır.

Korunan bir üyeye kendi sınıfı içinde ve türetilmiş sınıf örnekleri tarafından erişilebilir.
Diğer erişim değiştiricilerine sahip protected bir karşılaştırması için bkz. Erişilebilirlik düzeyleri.

Örnek
Bir temel sınıfın korunan üyesine, yalnızca erişim türetilmiş sınıf türü aracılığıyla gerçekleşirse türetilmiş
bir sınıfta erişilebilir. Örneğin, aşağıdaki kod kesimini göz önünde bulundurun:

class A
{
protected int x = 123;
}

class B : A
{
static void Main()
{
var a = new A();
var b = new B();

// Error CS1540, because x can only be accessed by


// classes derived from A.
// a.x = 10;

// OK, because this class derives from A.


b.x = 10;
}
}

a.x = 10 ifade, B sınıfının bir örneği değil, Main yöntemi içinde yapıldığından bir hata oluşturur.
Struct devralınamadığı için yapı üyeleri korunamaz.

Örnek
Bu örnekte, DerivedPoint sınıfı Point türetilir. Bu nedenle, doğrudan türetilmiş sınıftan temel sınıfın
korunan üyelerine erişebilirsiniz.
class Point
{
protected int x;
protected int y;
}

class DerivedPoint: Point


{
static void Main()
{
var dpoint = new DerivedPoint();

// Direct access to protected members.


dpoint.x = 10;
dpoint.y = 15;
Console.WriteLine($"x = {dpoint.x}, y = {dpoint.y}");
}
}
// Output: x = 10, y = 15

x ve y erişim düzeylerini özelolarak değiştirirseniz, derleyici hata iletilerini verebilir:


'Point.y' is inaccessible due to its protection level.

'Point.x' is inaccessible due to its protection level.

C# dili belirtimi
Daha fazla bilgi için bkz. C# dil belirtiminde Erişilebilirlik bildirimi . Dil belirtimi, C# sözdizimi ve kullanımı
için kesin bir kaynaktır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
Erişim Değiştiricileri
Erişilebilirlik Düzeyleri
Değiştiriciler
public
private
internal
İç sanal anahtar sözcüklere yönelik güvenlik sorunları
public (C# Başvurusu)
4.11.2019 • 2 minutes to read • Edit Online

public anahtar sözcüğü, türler ve tür üyeleri için bir erişim değiştiricisidir. Genel erişim en çok izin
veren erişim düzeyidir. Şu örnekte olduğu gibi genel üyelere erişim konusunda kısıtlama yoktur:

class SampleClass
{
public int x; // No access restrictions.
}

Daha fazla bilgi için bkz. erişim değiştiriciler ve Erişilebilirlik düzeyleri .

Örnek
Aşağıdaki örnekte, PointTest ve MainClass iki sınıf bildirilmiştir. PointTest x ve y ortak üyelere
doğrudan MainClass erişilir.

class PointTest
{
public int x;
public int y;
}

class MainClass4
{
static void Main()
{
var p = new PointTest();
// Direct access to public members.
p.x = 10;
p.y = 15;
Console.WriteLine($"x = {p.x}, y = {p.y}");
}
}
// Output: x = 10, y = 15

public erişim düzeyini özel veya korumalıolarak değiştirirseniz, şu hata iletisini alırsınız:
' PointTest. y ', koruma düzeyi nedeniyle erişilebilir değil.

C# dili belirtimi
Daha fazla bilgi için bkz. C# dil belirtiminde Erişilebilirlik bildirimi . Dil belirtimi, C# sözdizimi ve
kullanımı için kesin bir kaynaktır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
Erişim Değiştiricileri
C# Anahtar Sözcükleri
Erişim Değiştiricileri
Erişilebilirlik Düzeyleri
Değiştiriciler
private
protected
internal
korumalı iç (C# başvuru)
4.11.2019 • 2 minutes to read • Edit Online

protected internal anahtar sözcük birleşimi bir üye erişim değiştiricisidir. Korunan bir iç üyeye geçerli
derlemeden veya kapsayan sınıftan türetilmiş türlerden erişilebilir. Diğer erişim değiştiricilerine sahip
protected internal bir karşılaştırması için bkz. Erişilebilirlik düzeyleri.

Örnek
Bir temel sınıfın korunan iç üyesine, kendisini içeren derleme içindeki herhangi bir türden erişilebilir. Ayrıca,
başka bir derlemede bulunan türetilmiş bir sınıfta, yalnızca erişim türetilmiş sınıf türünün bir değişkeniyle
gerçekleşirse erişilebilir. Örneğin, aşağıdaki kod kesimini göz önünde bulundurun:

// Assembly1.cs
// Compile with: /target:library
public class BaseClass
{
protected internal int myValue = 0;
}

class TestAccess
{
void Access()
{
var baseObject = new BaseClass();
baseObject.myValue = 5;
}
}

// Assembly2.cs
// Compile with: /reference:Assembly1.dll
class DerivedClass : BaseClass
{
static void Main()
{
var baseObject = new BaseClass();
var derivedObject = new DerivedClass();

// Error CS1540, because myValue can only be accessed by


// classes derived from BaseClass.
// baseObject.myValue = 10;

// OK, because this class derives from BaseClass.


derivedObject.myValue = 10;
}
}

Bu örnek, Assembly1.cs ve Assembly2.cs iki dosya içerir. İlk dosya, TestAccess bir ortak temel sınıf,
BaseClass ve başka bir sınıf içerir. BaseClass , TestAccess türü tarafından erişilen korumalı bir dahili üyeye
sahip myValue sahip. İkinci dosyada, bir BaseClass örneği üzerinden myValue erişme girişimi bir hata üretir,
bu üyeye türetilmiş bir sınıfın bir örneği aracılığıyla erişim elde edilir DerivedClass başarılı olur.
Struct devralınamadığı için yapı üyeleri protected internal olamaz.
C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
Erişim Değiştiricileri
Erişilebilirlik Düzeyleri
Değiştiriciler
public
private
internal
İç sanal anahtar sözcüklere yönelik güvenlik sorunları
özel korumalı (C# başvuru)
4.11.2019 • 2 minutes to read • Edit Online

private protected anahtar sözcük birleşimi bir üye erişim değiştiricisidir. Özel korumalı bir üyeye, kapsayan
sınıftan türetilmiş türler tarafından erişilebilir, ancak yalnızca kendi kapsayıcı bütünleştirilmiş kodu içinde
erişilebilir. Diğer erişim değiştiricilerine sahip private protected bir karşılaştırması için bkz. Erişilebilirlik
düzeyleri.

NOTE
private protected erişim değiştiricisi C# sürüm 7,2 ve üzeri sürümlerde geçerlidir.

Örnek
Bir temel sınıfın özel korumalı bir üyesine, yalnızca değişkenin statik türü türetilmiş sınıf türü ise, kendisini
kapsayan derlemede bulunan türetilmiş türlerden erişilebilir. Örneğin, aşağıdaki kod kesimini göz önünde
bulundurun:

// Assembly1.cs
// Compile with: /target:library
public class BaseClass
{
private protected int myValue = 0;
}

public class DerivedClass1 : BaseClass


{
void Access()
{
var baseObject = new BaseClass();

// Error CS1540, because myValue can only be accessed by


// classes derived from BaseClass.
// baseObject.myValue = 5;

// OK, accessed through the current derived class instance


myValue = 5;
}
}

// Assembly2.cs
// Compile with: /reference:Assembly1.dll
class DerivedClass2 : BaseClass
{
void Access()
{
// Error CS0122, because myValue can only be
// accessed by types in Assembly1
// myValue = 10;
}
}

Bu örnek, Assembly1.cs ve Assembly2.cs iki dosya içerir. İlk dosya, bir ortak temel sınıf, BaseClass ve ondan
türetilmiş bir tür içerir, DerivedClass1 . BaseClass , myValue``DerivedClass1 iki şekilde erişmeye çalıştığı özel
korumalı bir üyeye sahip. Bir BaseClass örneği üzerinden myValue ilk kez erişme girişimi bir hata üretir.
Ancak, bunu DerivedClass1 devralınmış üye olarak kullanma girişimi başarılı olur. İkinci dosyada,
DerivedClass2 devralınmış bir myValue erişme girişimi yalnızca Assembly1 içindeki türetilmiş türler
tarafından erişilebilir olduğundan bir hata üretir.
Struct devralınamadığı için yapı üyeleri private protected olamaz.

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
Erişim Değiştiricileri
Erişilebilirlik Düzeyleri
Değiştiriciler
public
private
internal
İç sanal anahtar sözcüklere yönelik güvenlik sorunları
abstract (C# Başvurusu)
4.11.2019 • 5 minutes to read • Edit Online

abstract değiştirici, değiştirilmekte olan bir uygulamanın eksik veya tamamlanmamış bir uygulamasına
sahip olduğunu gösterir. Soyut değiştirici sınıflar, Yöntemler, özellikler, Dizin oluşturucular ve olaylar ile
kullanılabilir. Bir sınıfın yalnızca diğer sınıfların temel sınıfı olduğunu göstermek için bir sınıf bildiriminde
abstract değiştiricisini kullanın, kendi kendine örneği değildir. Soyut olarak işaretlenen Üyeler soyut
sınıftan türetilen soyut olmayan sınıflar tarafından uygulanmalıdır.

Örnek
Bu örnekte, sınıf Square , Shape türettiği için GetArea uygulamasını sağlamalıdır:

abstract class Shape


{
public abstract int GetArea();
}

class Square : Shape


{
int side;

public Square(int n) => side = n;

// GetArea method is required to avoid a compile-time error.


public override int GetArea() => side * side;

static void Main()


{
var sq = new Square(12);
Console.WriteLine($"Area of the square = {sq.GetArea()}");
}
}
// Output: Area of the square = 144

Soyut sınıflar aşağıdaki özelliklere sahiptir:


Soyut bir sınıf örneği oluşturulamıyor.
Soyut bir sınıf, Soyut yöntemler ve erişimciler içerebilir.
İki değiştiricinin ters anlamları olduğundan, soyut değiştirici içeren bir soyut sınıfı değiştirmek
mümkün değildir. sealed değiştiricisi bir sınıfın devralınmasını engeller ve abstract değiştiricisi
bir sınıfın devralınmasını gerektirir.
Soyut bir sınıftan türetilmiş soyut olmayan bir sınıf, devralınan tüm soyut yöntemlerin ve
erişimcilerinin gerçek uygulamalarını içermelidir.
Yöntemin veya özelliğin uygulama içermediğini belirtmek için bir yöntem veya özellik bildiriminde
abstract değiştiricisini kullanın.

Soyut yöntemler aşağıdaki özelliklere sahiptir:


Soyut bir yöntem örtük olarak sanal bir yöntemdir.
Soyut yöntem bildirimlerine yalnızca soyut sınıflarda izin verilir.
Soyut bir yöntem bildirimi gerçek uygulama sunmadığından, hiçbir Yöntem gövdesi yoktur;
Yöntem bildirimi yalnızca noktalı virgül ile sona erer ve imzadan sonra küme ayracı ({}) yoktur.
Örneğin:

public abstract void MyMethod();

Uygulama, soyut olmayan bir sınıfın üyesi olan bir yöntem geçersiz kılmatarafından sağlanır.
Soyut bir yöntem bildiriminde statik veya sanal değiştiricilerin kullanılması hatadır.
Özet özellikler, bildirim ve çağırma söz dizimi farklılıkları dışında soyut yöntemler gibi davranır.
Statik bir özellik üzerinde abstract değiştiricisinin kullanılması hatadır.
Bir soyut devralınmış özellik, geçersiz kılma değiştiricisini kullanan bir özellik bildirimi eklenerek,
türetilmiş bir sınıfta geçersiz kılınabilir.
Soyut sınıflar hakkında daha fazla bilgi için bkz. soyut ve korumalı sınıflar ve sınıf üyeleri.
Soyut bir sınıf tüm arabirim üyeleri için uygulama sağlamalıdır.
Arabirim uygulayan bir soyut sınıf, arabirim yöntemlerini soyut yöntemlerle eşleyebilir. Örneğin:

interface I
{
void M();
}
abstract class C : I
{
public abstract void M();
}

Örnek
Bu örnekte, sınıf DerivedClass BaseClass soyut bir sınıftan türetilir. Soyut sınıf soyut bir yöntem,
AbstractMethod ve iki soyut özellik içerir X ve Y .
abstract class BaseClass // Abstract class
{
protected int _x = 100;
protected int _y = 150;
public abstract void AbstractMethod(); // Abstract method
public abstract int X { get; }
public abstract int Y { get; }
}

class DerivedClass : BaseClass


{
public override void AbstractMethod()
{
_x++;
_y++;
}

public override int X // overriding property


{
get
{
return _x + 10;
}
}

public override int Y // overriding property


{
get
{
return _y + 10;
}
}

static void Main()


{
var o = new DerivedClass();
o.AbstractMethod();
Console.WriteLine($"x = {o.X}, y = {o.Y}");
}
}
// Output: x = 111, y = 161

Yukarıdaki örnekte, aşağıdaki gibi bir ifade kullanarak soyut sınıfı örneğini oluşturmaya çalışırsanız:

BaseClass bc = new BaseClass(); // Error

Derleyicinin ' BaseClass ' soyut sınıfının bir örneğini oluşturkullanılamadığını belirten bir hata alırsınız.

C# Dil Belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
Değiştiriciler
virtual
override
C# Anahtar Sözcükleri
async (C# Başvurusu)
23.10.2019 • 7 minutes to read • Edit Online

Bir yöntem, lambda ifadesiveya anonim yöntemin zaman uyumsuz olduğunu belirtmek için
değiştiricisinikullanın. async Bu değiştiriciyi bir yöntem veya ifadede kullanırsanız, zaman uyumsuz bir
yöntemolarak adlandırılır. Aşağıdaki örnek adlı ExampleMethodAsync bir zaman uyumsuz metodu tanımlar:

public async Task<int> ExampleMethodAsync()


{
// . . . .
}

Zaman uyumsuz programlamaya yeni başladıysanız veya zaman uyumsuz bir yöntemin, çağıranın iş
parçacığını engellemeden uzun süre çalışan bir iş yapmak için await işlecini nasıl kullandığını
anladıysanız, ile zaman uyumsuz programlamaya giriş Async ve await. Aşağıdaki kod zaman uyumsuz
bir yöntem içinde bulunur ve HttpClient.GetStringAsync yöntemini çağırır:

string contents = await httpClient.GetStringAsync(requestUrl);

Zaman uyumsuz bir yöntem, ilk await ifadesine ulaşana dek zaman uyumlu olarak çalışır ve bu noktada,
beklenen görev tamamlanana kadar yöntem askıya alınır. Bu arada, denetim, bir sonraki bölümdeki
örnekte gösterildiği gibi yöntemi çağırana döner.
async Anahtar sözcüğünün değiştirdiği Yöntem bir await ifade veya deyim içermiyorsa, yöntem zaman
uyumlu olarak yürütülür. Bir derleyici uyarısı, deyimi içermeyen await herhangi bir zaman uyumsuz
metotlarda sizi uyarır, çünkü bu durum bir hata gösteriyor olabilir. Bkz. Derleyici Uyarısı (düzey 1)
CS4014.
async Anahtar sözcüğü, yalnızca bir metodu, bir lambda ifadesini veya anonim bir yöntemi
değiştirdiğinde anahtar kelimedir. Tüm diğer bağlamlarda bu, tanımlayıcı olarak yorumlanır.

Örnek
Aşağıdaki örnek, zaman uyumsuz olay işleyicisi, StartButton_Click ve zaman uyumsuz bir
ExampleMethodAsync yöntem arasındaki denetimin yapısını ve akışını gösterir. Zaman uyumsuz yöntemin
sonucu bir Web sayfasının karakter sayısıdır. Kod, Visual Studio 'da oluşturduğunuz bir Windows
Presentation Foundation (WPF ) uygulamasına veya Windows Mağazası uygulamasına uygundur;
uygulamayı ayarlamaya yönelik kod açıklamalarını inceleyin.
Bu kodu, Visual Studio 'da bir Windows Presentation Foundation (WPF ) uygulaması veya bir Windows
Mağazası uygulaması olarak çalıştırabilirsiniz. Adlı StartButton bir düğme denetimine ve adlı
ResultsTextBox TextBox denetimine ihtiyacınız vardır. Adları ve işleyiciyi şuna benzer olacak şekilde
ayarlamayı unutmayın:

<Button Content="Button" HorizontalAlignment="Left" Margin="88,77,0,0" VerticalAlignment="Top"


Width="75"
Click="StartButton_Click" Name="StartButton"/>
<TextBox HorizontalAlignment="Left" Height="137" Margin="88,140,0,0" TextWrapping="Wrap"
Text="&lt;Enter a URL&gt;" VerticalAlignment="Top" Width="310" Name="ResultsTextBox"/>
Kodu WPF uygulaması olarak çalıştırmak için:
Bu kodu MainWindow MainWindow.xaml.cs içindeki sınıfa yapıştırın.
System .net. http öğesine bir başvuru ekleyin.
System .net using . http için bir yönerge ekleyin.
Kodu bir Windows Mağazası uygulaması olarak çalıştırmak için:
Bu kodu MainPage MainPage.xaml.cs içindeki sınıfa yapıştırın.
System .net. http ve System. Threading. Tasks için using yönergelerini ekleyin.

private async void StartButton_Click(object sender, RoutedEventArgs e)


{
// ExampleMethodAsync returns a Task<int>, which means that the method
// eventually produces an int result. However, ExampleMethodAsync returns
// the Task<int> value as soon as it reaches an await.
ResultsTextBox.Text += "\n";

try
{
int length = await ExampleMethodAsync();
// Note that you could put "await ExampleMethodAsync()" in the next line where
// "length" is, but due to when '+=' fetches the value of ResultsTextBox, you
// would not see the global side effect of ExampleMethodAsync setting the text.
ResultsTextBox.Text += String.Format("Length: {0:N0}\n", length);
}
catch (Exception)
{
// Process the exception if one occurs.
}
}

public async Task<int> ExampleMethodAsync()


{
var httpClient = new HttpClient();
int exampleInt = (await httpClient.GetStringAsync("http://msdn.microsoft.com")).Length;
ResultsTextBox.Text += "Preparing to finish ExampleMethodAsync.\n";
// After the following return statement, any method that's awaiting
// ExampleMethodAsync (in this case, StartButton_Click) can get the
// integer result.
return exampleInt;
}
// The example displays the following output:
// Preparing to finish ExampleMethodAsync.
// Length: 53292

IMPORTANT
Görevler ve bir görevi beklerken yürütülen kod hakkında daha fazla bilgi için bkz. Async ve await Ile zaman
uyumsuz programlama. Benzer öğeleri kullanan tam bir WPF örneği için bkz . İzlenecek yol: Async ve
awaitkullanarak Web 'e erişme.

Dönüş Türleri
Zaman uyumsuz bir yöntem aşağıdaki dönüş türlerine sahip olabilir:
Task
Task<TResult>
void. async void yöntemler genellikle olay işleyicileri dışındaki kod için önerilmez çünkü çağıranlar
await bu yöntemlere izin vermez ve başarılı tamamlamayı veya hata koşullarını raporlamak için
farklı bir mekanizma uygulamalıdır.
7,0 ile C# başlayarak, erişilebilir GetAwaiter bir yöntemi olan herhangi bir tür. Bu
System.Threading.Tasks.ValueTask<TResult> tür bir uygulama. NuGet paketi
System.Threading.Tasks.Extensions eklenerek kullanılabilir.

Async yöntemi içindeherhangi bir ref veya Out parametresi bildiremez ve Başvuru dönüş değerinesahip
olabilir, ancak bu parametrelere sahip yöntemleri çağırabilir.
Metodun Task<TResult> Return ifadesinde TResult bir işlenen belirtiyorsa, zaman uyumsuz bir
yöntemin dönüş türü olarak belirtirsiniz. Yöntem tamamlandığında Task anlamlı bir değer
döndürülmezse kullanırsınız. Diğer bir deyişle, yöntemine yapılan bir Task çağrı bir döndürür, ancak
Task tamamlandığında, Task sonucunu void bekleyen tüm await ifadeler.

Dönüş türünü öncelikle void bu dönüş türü gerektiren olay işleyicilerini tanımlamak için kullanırsınız.
Döndüren zaman uyumsuz bir void yöntemi çağıran, bunu bekler ve yöntemin oluşturduğu özel
durumları yakalayamaz.
7,0 ' C# den başlayarak, kodun performans açısından kritik bölümlerinde bellek ayırmalarını en aza
indirmek için bir GetAwaiter yöntemine sahip olan, genellikle bir değer türü olan başka bir tür
döndürüyorsunuz.
Daha fazla bilgi ve örnek için bkz. zaman uyumsuz dönüş türleri.

Ayrıca bkz.
AsyncStateMachineAttribute
await
İzlenecek yol: Async ve await kullanarak Web 'e erişme
Async ve Await ile Zaman Uyumsuz Programlama
const (C# Başvurusu)
4.11.2019 • 3 minutes to read • Edit Online

const anahtar sözcüğünü kullanarak sabit bir alan veya sabit bir yerel değer bildirebilirsiniz. Sabit alanlar ve
Yereller değişken değildir ve değiştirilemeyebilir. Sabitler sayı, Boole değeri, dize veya null başvuru olabilir.
İstediğiniz zaman değiştirilmesini düşündüğünüz bilgileri temsil etmek için bir sabit oluşturmayın. Örneğin, bir
hizmetin fiyatını, ürün sürüm numarasını veya şirketin marka adını depolamak için sabit bir alan kullanmayın. Bu
değerler zaman içinde değişebilir ve derleyiciler yaydığı için, kitaplıklarınız ile derlenen diğer kodun değişiklikleri
görmek için yeniden derlenmesi gerekir. Ayrıca bkz. ReadOnly anahtar sözcüğü. Örneğin:

const int X = 0;
public const double GravitationalConstant = 6.673e-11;
private const string ProductName = "Visual C#";

Açıklamalar
Sabit bir bildirimin türü, bildirimin sunmakta olduğu üyelerin türünü belirtir. Sabit bir yerel veya sabit alanın
başlatıcısı, hedef türe örtük olarak dönüştürülemeyen bir sabit ifade olmalıdır.
Sabit bir ifade, derleme zamanında tam olarak değerlendirilebilen bir ifadedir. Bu nedenle, başvuru türlerinin
sabitleri için tek olası değerler string ve null bir başvurudur.
Sabit bildirimi, şöyle birçok sabit bildirebilir:

public const double X = 1.0, Y = 2.0, Z = 3.0;

Sabit bildiriminde static değiştiriciye izin verilmez.


Bir sabit, aşağıdaki gibi bir sabit ifadeye katılabilir:

public const int C1 = 5;


public const int C2 = C1 + 100;

NOTE
ReadOnly anahtar sözcüğü const anahtar sözcüğünden farklıdır. Bir const alanı yalnızca alanın bildiriminde başlatılabilir.
readonly alan, bildirimde veya bir oluşturucuda başlatılabilir. Bu nedenle, readonly alanlar kullanılan oluşturucuya bağlı
olarak farklı değerlere sahip olabilir. Ayrıca, bir const alanı bir derleme zamanı sabiti olsa da, readonly alanı şu satırda
olduğu gibi çalışma zamanı sabitleri için kullanılabilir: public static readonly uint l1 = (uint)DateTime.Now.Ticks;

Örnek
public class ConstTest
{
class SampleClass
{
public int x;
public int y;
public const int C1 = 5;
public const int C2 = C1 + 5;

public SampleClass(int p1, int p2)


{
x = p1;
y = p2;
}
}

static void Main()


{
var mC = new SampleClass(11, 22);
Console.WriteLine($"x = {mC.x}, y = {mC.y}");
Console.WriteLine($"C1 = {SampleClass.C1}, C2 = {SampleClass.C2}");
}
}
/* Output
x = 11, y = 22
C1 = 5, C2 = 10
*/

Örnek
Bu örnek, sabitlerin yerel değişkenler olarak nasıl kullanılacağını gösterir.

public class SealedTest


{
static void Main()
{
const int C = 707;
Console.WriteLine($"My local constant = {C}");
}
}
// Output: My local constant = 707

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir kaynaktır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
Değiştiriciler
readonly
event (C# Başvurusu)
4.11.2019 • 4 minutes to read • Edit Online

event anahtar sözcüğü bir yayımcı sınıfında bir olay bildirmek için kullanılır.

Örnek
Aşağıdaki örnek, temel alınan temsilci türü olarak EventHandler kullanan bir olayın nasıl bildirilemeyeceğini ve
tetiklemeyeceğini gösterir. Ayrıca, genel EventHandler<TEventArgs> temsilci türünü kullanmayı ve bir olaya
abone olmayı ve olay işleyicisi yöntemini oluşturmayı gösteren tüm kod örneği için bkz. nasıl yapılır: .NET
Framework yönergelerine uygun olan olayları yayımlama.

public class SampleEventArgs


{
public SampleEventArgs(string s) { Text = s; }
public String Text { get; } // readonly
}

public class Publisher


{
// Declare the delegate (if using non-generic pattern).
public delegate void SampleEventHandler(object sender, SampleEventArgs e);

// Declare the event.


public event SampleEventHandler SampleEvent;

// Wrap the event in a protected virtual method


// to enable derived classes to raise the event.
protected virtual void RaiseSampleEvent()
{
// Raise the event in a thread-safe manner using the ?. operator.
SampleEvent?.Invoke(this, new SampleEventArgs("Hello"));
}
}

Olaylar, yalnızca bildirildiği sınıf veya yapı içinden çağrılabilir olan özel bir çok noktaya yayın temsilcisi türüdür
(yayımcı sınıfı). Diğer sınıflar veya yapılar olaya abone olursa, yayımcı sınıfı olayı harekete geçirirse olay
işleyicisi yöntemleri çağırılır. Daha fazla bilgi ve kod örnekleri için bkz. Olaylar ve Temsilciler.
Olaylar ortak, özel, korunan, dahili, korunan iç veya özel korumalıolarak işaretlenebilir. Bu erişim değiştiricileri,
sınıfın kullanıcılarının olaya nasıl erişekullanabileceğinizi tanımlar. Daha fazla bilgi için bkz. erişim değiştiricileri.

Anahtar sözcükler ve olaylar


Aşağıdaki anahtar sözcükler olaylar için geçerlidir.

SÖZCÜKLE AÇIKLAMA DAHA FAZLA BILGI IÇIN

static Sınıfın bir örneği mevcut olmasa bile, Statik Sınıflar ve Statik Sınıf Üyeleri
olayı her zaman çağıranlar için
kullanılabilir hale getirir.
SÖZCÜKLE AÇIKLAMA DAHA FAZLA BILGI IÇIN

virtual Türetilmiş sınıfların, override anahtar Devralma


sözcüğünü kullanarak olay davranışını
geçersiz kılmasına izin verir.

sealed Türetilmiş sınıflar için artık sanal


olmadığını belirtir.

abstract Derleyici add ve remove olay


erişimcisi bloklarını oluşturmaz ve bu
nedenle türetilen sınıfların kendi
uygulamasını sağlaması gerekir.

Static anahtar sözcüğü kullanılarak bir olay statik olay olarak bildirilemez. Bu, sınıfın bir örneği mevcut olmasa
bile herhangi bir zamanda olayı çağıranlar için kullanılabilir hale getirir. Daha fazla bilgi için bkz. statik sınıflar ve
statik sınıf üyeleri.
Bir olay sanal anahtar sözcüğü kullanılarak sanal bir olay olarak işaretlenebilir. Bu, türetilmiş sınıfların override
anahtar sözcüğünü kullanarak olay davranışını geçersiz kılmasını sağlar. Daha fazla bilgi için bkz. Devralma.
Sanal bir olayı geçersiz kılan bir olay, türetilmiş sınıflar için artık sanal olmadığını belirten mühürlüda olabilir.
Son olarak, bir olay soyutolarak bildirilmelidir, bu da derleyicinin add ve remove olay erişimci bloklarını
üretmeyeceği anlamına gelir. Bu nedenle türetilen sınıfların kendi uygulamasını sağlaması gerekir.

C# Dil Belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
add
remove
Değiştiriciler
Nasıl yapılır: temsilcileri birleştirme (çok noktaya yayın temsilcileri)
extern (C# Başvurusu)
4.11.2019 • 3 minutes to read • Edit Online

extern değiştiricisi dışarıdan uygulanan bir yöntemi bildirmek için kullanılır. Yönetilmeyen koda çağrı yapmak için
birlikte çalışma Hizmetleri kullandığınızda extern değiştiricisinin yaygın olarak kullanılması DllImport
özniteliğidir. Bu durumda, aşağıdaki örnekte gösterildiği gibi, yöntemi de static olarak bildirilmelidir:

[DllImport("avifil32.dll")]
private static extern void AVIFileInit();

extern anahtar sözcüğü ayrıca bir dış derleme diğer adı tanımlayabilir, bu da aynı bileşenin farklı sürümlerine tek
bir bütünleştirilmiş kod içinden başvuruda bulunmak mümkün hale gelir. Daha fazla bilgi için bkz. extern diğer ad.
Aynı üyeyi değiştirmek için soyut ve extern değiştiricilerini kullanmak hatadır. extern değiştiricisinin
kullanılması yöntemin dışında C# uygulandığı anlamına gelir, ancak abstract değiştiricinin kullanılması, yöntem
uygulamasının sınıfta sağlanmadığı anlamına gelir.
extern anahtar sözcüğünün kullanımları, C++'a göre C#'de daha fazladır. C# anahtar sözcüğünü C++ anahtar
sözcüğüyle karşılaştırmak için, C++ Dilinde Bağlantı Belirtmek için extern Kullanma Başvurusu'na bakın.

Örnek 1
Bu örnekte, Program kullanıcıdan bir dize alır ve iletiyi bir ileti kutusu içinde görüntüler. Program, User32. dll
kitaplığından içeri aktarılan MessageBox yöntemini kullanır.

//using System.Runtime.InteropServices;
class ExternTest
{
[DllImport("User32.dll", CharSet=CharSet.Unicode)]
public static extern int MessageBox(IntPtr h, string m, string c, int type);

static int Main()


{
string myString;
Console.Write("Enter your message: ");
myString = Console.ReadLine();
return MessageBox((IntPtr)0, myString, "My Message Box", 0);
}

Örnek 2
Bu örnek, bir C# C kitaplığına (yerel dll) çağıran bir programı gösterir.
1. Aşağıdaki C dosyasını oluşturun ve cmdll.c adlandırın:
// cmdll.c
// Compile with: -LD
int __declspec(dllexport) SampleMethod(int i)
{
return i*10;
}

2. Visual Studio yükleme dizininden bir Visual Studio x64 (veya x32) yerel araçlar komut Istemi penceresi açın
ve komut istemine CL -ld Cmdll. c yazarak cmdll.c dosyasını derleyin.
3. Aynı dizinde aşağıdaki C# dosyayı oluşturun ve cm.cs olarak adlandırın:

// cm.cs
using System;
using System.Runtime.InteropServices;
public class MainClass
{
[DllImport("Cmdll.dll")]
public static extern int SampleMethod(int x);

static void Main()


{
Console.WriteLine("SampleMethod() returns {0}.", SampleMethod(5));
}
}

4. Visual Studio yükleme dizininden bir Visual Studio x64 (veya x32) yerel araçlar komut Istemi penceresi açın
ve cm.cs dosyasını şunu yazarak derleyin:

csc cm.cs (x64 komut istemi için) — veya — csc-platform: x86 cm.cs (x32 komut istemi için)

Bu işlem yürütülebilir dosya cm.exe oluşturur.


5. cm.exe 'i çalıştırın. SampleMethod yöntemi, 5 değerini, 10 ile çarpılan değeri döndüren DLL dosyasına
geçirir. Program aşağıdaki çıktıyı üretir:

SampleMethod() returns 50.

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir kaynaktır.

Ayrıca bkz.
System.Runtime.InteropServices.DllImportAttribute
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
Değiştiriciler
in (Genel Değiştirici) (C# Başvurusu)
4.11.2019 • 3 minutes to read • Edit Online

Genel tür parametreleri için in anahtar sözcüğü tür parametresinin değişken karşıtı olduğunu belirtir. Genel
arabirimlerde ve temsilcilerde in anahtar sözcüğünü kullanabilirsiniz.
Değişken Varyans, genel parametre ile belirtilenden daha az türetilmiş bir tür kullanmanıza olanak sağlar. Bu,
değişken karşıtı arabirimler uygulayan sınıfların örtük dönüştürülmesini ve temsilci türlerinin örtük
dönüştürülmesini sağlar. Genel tür parametrelerindeki Kovaryans ve değişken Varyans, başvuru türleri için
desteklenir, ancak değer türleri için desteklenmez.
Bir tür, genel bir arabirimde veya bir yöntemin dönüş türü değil, bir yöntemin parametrelerinin türünü tanımlıyorsa
yalnızca bir veya temsilcisinde değişken karşıtı olarak bildirilemez. In , ref ve out parametreleri sabit olmalıdır,
yani bunlar birlikte değişken veya değişken karşıtı değil.
Değişken karşıtı tür parametresine sahip bir arabirim, yöntemlerinin, arabirim türü parametresi tarafından
belirtilenden daha az türetilmiş türlerin bağımsız değişkenlerini kabul etmesine olanak tanır. Örneğin,
IComparer<T> arabiriminde T yazın, IComparer<Person> türünün bir nesnesini IComparer<Employee> türünün bir
nesnesine Employee devr Person alırsa herhangi bir özel dönüştürme yöntemini kullanmadan atayabilirsiniz.
Değişken karşıtı bir temsilciye aynı türde başka bir temsilci atanabilir, ancak daha az türetilmiş bir genel tür
parametresi olabilir.
Daha fazla bilgi için bkz. Kovaryans ve değişken varyans.

Değişken karşıtı genel arabirim


Aşağıdaki örnek, bir değişken karşıtı genel arabirimin nasıl bildirileceği, genişletileceği ve uygulanacağını gösterir.
Ayrıca, bu arabirimi uygulayan sınıflar için örtük dönüştürmeyi nasıl kullanabileceğinizi gösterir.

// Contravariant interface.
interface IContravariant<in A> { }

// Extending contravariant interface.


interface IExtContravariant<in A> : IContravariant<A> { }

// Implementing contravariant interface.


class Sample<A> : IContravariant<A> { }

class Program
{
static void Test()
{
IContravariant<Object> iobj = new Sample<Object>();
IContravariant<String> istr = new Sample<String>();

// You can assign iobj to istr because


// the IContravariant interface is contravariant.
istr = iobj;
}
}

Değişken karşıtı genel temsilci


Aşağıdaki örnek, bir değişken karşıtı genel temsilcinin nasıl bildirilemeyeceğini, örneklendirilemeyeceğini ve
çağıralınacağını gösterir. Ayrıca, bir temsilci türünü örtülü olarak nasıl dönüştürebileceğiniz de gösterilmektedir.

// Contravariant delegate.
public delegate void DContravariant<in A>(A argument);

// Methods that match the delegate signature.


public static void SampleControl(Control control)
{ }
public static void SampleButton(Button button)
{ }

public void Test()


{

// Instantiating the delegates with the methods.


DContravariant<Control> dControl = SampleControl;
DContravariant<Button> dButton = SampleButton;

// You can assign dControl to dButton


// because the DContravariant delegate is contravariant.
dButton = dControl;

// Invoke the delegate.


dButton(new Button());
}

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir kaynaktır.

Ayrıca bkz.
out
Kovaryans ve Kontravaryans
Değiştiriciler
Yeni değiştirici (C# başvuru)
4.11.2019 • 5 minutes to read • Edit Online

Bir bildirim değiştiricisi olarak kullanıldığında, new anahtar sözcüğü bir taban sınıftan devralınan bir üyeyi
açıkça gizler. Devralınmış bir üyeyi gizlediğinizde, üyenin türetilmiş sürümü temel sınıf sürümünün yerini alır.
new değiştiricisini kullanmadan üyeleri gizleyebilseniz de bir derleyici uyarısı alırsınız. Bir üyeyi açıkça
gizlemek için new kullanıyorsanız, bu uyarıyı bastırır.
Ayrıca, bir tür örneği veya genel tür kısıtlamasıoluşturmak için new anahtar sözcüğünü kullanabilirsiniz.
Devralınan bir üyeyi gizlemek için, aynı üye adını kullanarak türetilmiş sınıfta bildirin ve new anahtar
sözcüğüyle değiştirin. Örneğin:

public class BaseC


{
public int x;
public void Invoke() { }
}
public class DerivedC : BaseC
{
new public void Invoke() { }
}

Bu örnekte, BaseC.Invoke DerivedC.Invoke gizlenir. x alan, benzer bir adla gizlenmediği için etkilenmez.
Devralma yoluyla ad gizleme aşağıdaki biçimlerden birini alır:
Genellikle, bir sınıfta veya yapıda tanıtılan bir sabit, alan, özellik veya tür, adını paylaşan tüm temel sınıf
üyelerini gizler. Özel durumlar vardır. Örneğin, adı N olan yeni bir alanı, çağrılamayan bir türe sahip
olacak şekilde bildirirseniz ve temel tür bir yöntem olarak N bildirirse, yeni alan, çağırma
sözdiziminde temel bildirimi gizlemez. Daha fazla bilgi için, C# dil belirtiminin üye arama bölümüne
bakın.
Bir sınıf veya yapı içinde tanıtılan bir yöntem, temel sınıfta bu adı paylaşan özellikleri, alanları ve türleri
gizler. Aynı imzaya sahip tüm temel sınıf yöntemlerini de gizler.
Bir sınıf veya yapı içinde tanıtılan bir Dizin Oluşturucu, aynı imzaya sahip olan tüm temel sınıf dizin
oluşturucularının gizlenmesini gösterir.
İki değiştiricinin birbirini dışlamalı anlamları olduğundan hem new hem de aynı üye üzerinde geçersiz
kılmak için bir hatadır. new değiştiricisi aynı ada sahip yeni bir üye oluşturur ve orijinal üyenin gizli hale
gelmesine neden olur. override değiştiricisi devralınan bir üyenin uygulamasını genişletir.
Devralınan bir üyeyi gizlemez bir bildirimde new değiştiricisinin kullanılması bir uyarı oluşturur.

Örnek
Bu örnekte, bir temel sınıf, BaseC ve türetilmiş bir sınıf DerivedC , devralınan alanın değerini gizleyen x aynı
alan adını kullanır. Örnek, new değiştiricinin kullanımını gösterir. Ayrıca, temel sınıfın gizli üyelerine tam
nitelikli adlarını kullanarak nasıl erişileceğini gösterir.
public class BaseC
{
public static int x = 55;
public static int y = 22;
}

public class DerivedC : BaseC


{
// Hide field 'x'.
new public static int x = 100;

static void Main()


{
// Display the new value of x:
Console.WriteLine(x);

// Display the hidden value of x:


Console.WriteLine(BaseC.x);

// Display the unhidden member y:


Console.WriteLine(y);
}
}
/*
Output:
100
55
22
*/

Örnek
Bu örnekte, iç içe yerleştirilmiş bir sınıf, temel sınıfta aynı ada sahip bir sınıfı gizler. Örnek, uyarı iletisini
ortadan kaldırmak ve tam nitelikli adlarını kullanarak gizli sınıf üyelerine erişmek için new değiştiricisinin
nasıl kullanılacağını gösterir.
public class BaseC
{
public class NestedC
{
public int x = 200;
public int y;
}
}

public class DerivedC : BaseC


{
// Nested type hiding the base type members.
new public class NestedC
{
public int x = 100;
public int y;
public int z;
}

static void Main()


{
// Creating an object from the overlapping class:
NestedC c1 = new NestedC();

// Creating an object from the hidden class:


BaseC.NestedC c2 = new BaseC.NestedC();

Console.WriteLine(c1.x);
Console.WriteLine(c2.x);
}
}
/*
Output:
100
200
*/

new değiştiricisini kaldırırsanız, program derleme ve çalıştırmaya devam eder, ancak şu uyarıyı alırsınız:

The keyword new is required on 'MyDerivedC.x' because it hides inherited member 'MyBaseC.x'.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin Yeni değiştirici bölümüne bakın.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
Değiştiriciler
Geçersiz Kılma ve Yeni Anahtar Sözcüklerle Sürüm Oluşturma
Geçersiz Kılmanın ve Yeni Anahtar Sözcüklerin Ne Zaman Kullanılacağını Bilme
Out (genel değiştirici) (C# başvuru)
4.11.2019 • 4 minutes to read • Edit Online

Genel tür parametreleri için out anahtar sözcüğü, tür parametresinin birlikte değişken olduğunu belirtir. Genel
arabirimlerde ve temsilcilerde out anahtar sözcüğünü kullanabilirsiniz.
Kovaryans, genel parametre ile belirtilenden daha fazla türetilmiş bir tür kullanmanıza olanak sağlar. Bu, covaryant
arabirimlerini uygulayan sınıfların örtük dönüştürülmesini ve temsilci türlerinin örtük dönüştürülmesini sağlar.
Kovaryans ve değişken Varyans, başvuru türleri için desteklenir, ancak değer türleri için desteklenmez.
Covaryant türü parametresine sahip bir arabirim, yöntemlerinin tür parametresiyle belirtenlerden daha fazla
türetilmiş tür döndürmesini sağlar. Örneğin, .NET Framework 4 ' te, IEnumerable<T>' de T yazın ve bir özel
dönüştürme yöntemi kullanmadan IEnumerable(Of String) türünün bir nesnesini IEnumerable(Of Object) türünün
bir nesnesine atayabilirsiniz.
Birlikte değişken temsilcisine aynı türde başka bir temsilci atanabilir, ancak daha türetilmiş bir genel tür
parametresi olabilir.
Daha fazla bilgi için bkz. Kovaryans ve değişken varyans.

Örnek-birlikte değişken genel arabirimi


Aşağıdaki örnek, bir covaryant genel arabiriminin nasıl bildirileceği, genişletileceği ve uygulanacağını gösterir.
Ayrıca, birlikte değişken arabirimi uygulayan sınıflar için örtük dönüştürmeyi nasıl kullanacağınızı gösterir.

// Covariant interface.
interface ICovariant<out R> { }

// Extending covariant interface.


interface IExtCovariant<out R> : ICovariant<R> { }

// Implementing covariant interface.


class Sample<R> : ICovariant<R> { }

class Program
{
static void Test()
{
ICovariant<Object> iobj = new Sample<Object>();
ICovariant<String> istr = new Sample<String>();

// You can assign istr to iobj because


// the ICovariant interface is covariant.
iobj = istr;
}
}

Bir genel arabirimde, bir tür parametresi aşağıdaki koşullara uygunsa birlikte değişken olarak bildirilemez:
Tür parametresi yalnızca Arabirim yöntemlerinin dönüş türü olarak kullanılır ve Yöntem bağımsız
değişkenlerinin türü olarak kullanılmaz.
NOTE
Bu kural için bir özel durum var. Bir covaryant arayüzünde bir yöntem parametresi olarak bir değişken karşıtı genel
temsilciniz varsa, bu temsilci için ortak tür parametresi olarak covaryant türü ' ni kullanabilirsiniz. Covaryant ve
değişken karşıtı genel Temsilciler hakkında daha fazla bilgi için bkz. Temsilcilerde varyans ve Func ve eylem genel
temsilcileri için varyans kullanma.

Tür parametresi, arabirim yöntemleri için genel kısıtlama olarak kullanılmaz.

Örnek-birlikte değişken genel temsilcisi


Aşağıdaki örnek, bir covaryant genel temsilcisinin nasıl bildirilemeyeceğini, örneklendirilemeyeceğini ve
çağıralınacağını gösterir. Ayrıca, temsilci türlerini örtük olarak nasıl dönüştürebileceğiniz gösterilmektedir.

// Covariant delegate.
public delegate R DCovariant<out R>();

// Methods that match the delegate signature.


public static Control SampleControl()
{ return new Control(); }

public static Button SampleButton()


{ return new Button(); }

public void Test()


{
// Instantiate the delegates with the methods.
DCovariant<Control> dControl = SampleControl;
DCovariant<Button> dButton = SampleButton;

// You can assign dButton to dControl


// because the DCovariant delegate is covariant.
dControl = dButton;

// Invoke the delegate.


dControl();
}

Genel bir temsilcisinde, bir tür yalnızca bir yöntem dönüş türü olarak kullanılıyorsa ve Yöntem bağımsız
değişkenleri için kullanılmazsa, birlikte değişken olarak bildirilemez.

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir kaynaktır.

Ayrıca bkz.
Genel Arabirimlerde Varyans
in
Değiştiriciler
override (C# Başvurusu)
4.11.2019 • 3 minutes to read • Edit Online

overridedeğiştirici, devralınan bir metodun, özelliğin, dizin oluşturucunun veya olayın soyut veya sanal
uygulamasını genişletmek ya da değiştirmek için gereklidir.

Örnek
Bu örnekte Square sınıfı, GetArea soyut Shape sınıfından devralındığından, geçersiz kılınan bir
GetArea uygulamasını sağlamalıdır:

abstract class Shape


{
public abstract int GetArea();
}

class Square : Shape


{
int side;

public Square(int n) => side = n;

// GetArea method is required to avoid a compile-time error.


public override int GetArea() => side * side;

static void Main()


{
var sq = new Square(12);
Console.WriteLine($"Area of the square = {sq.GetArea()}");
}
}
// Output: Area of the square = 144

override yöntemi, temel sınıftan devralınan bir üyenin yeni bir uygulamasını sağlar. Bir override
bildirimi tarafından geçersiz kılınan yöntem, geçersiz kılınan temel yöntem olarak bilinir. Geçersiz kılınan
temel yöntemin override yöntemiyle aynı imzaya sahip olması gerekir. Devralma hakkında daha fazla
bilgi için bkz. Devralma.
Sanal olmayan veya statik bir yöntemi geçersiz kılamazsınız. Geçersiz kılınan taban yöntemi virtual ,
abstract veya override olmalıdır.

override bildirimi virtual yönteminin erişilebilirliğini değiştiremiyor. Hem override yöntemi hem de
virtual yöntemi aynı erişim düzeyi değiştiricisinesahip olmalıdır.
override bir yöntemi değiştirmek için new , static veya virtual değiştiricilerini kullanamazsınız.
Geçersiz kılma özelliği bildirimi, devralınan özellik olarak tam olarak aynı erişim değiştiricisini, türü ve
adı belirtmeli ve geçersiz kılınan Özellik virtual , abstract veya override olmalıdır.
override anahtar sözcüğünü kullanma hakkında daha fazla bilgi için bkz. geçersiz kılma ve yeni anahtar
sözcüklerle sürüm oluşturma ve geçersiz kılma ve yeni anahtar sözcüklerin ne zaman kullanılacağını
bilme.

Örnek
Bu örnek, Employee adlı bir temel sınıfı ve SalesEmployee adlı türetilmiş bir sınıfı tanımlar. SalesEmployee
sınıfı ek bir alan içerir, salesbonus ve bunu hesaba almak için CalculatePay yöntemi geçersiz kılar.
class TestOverride
{
public class Employee
{
public string name;

// Basepay is defined as protected, so that it may be


// accessed only by this class and derived classes.
protected decimal basepay;

// Constructor to set the name and basepay values.


public Employee(string name, decimal basepay)
{
this.name = name;
this.basepay = basepay;
}

// Declared virtual so it can be overridden.


public virtual decimal CalculatePay()
{
return basepay;
}
}

// Derive a new class from Employee.


public class SalesEmployee : Employee
{
// New field that will affect the base pay.
private decimal salesbonus;

// The constructor calls the base-class version, and


// initializes the salesbonus field.
public SalesEmployee(string name, decimal basepay,
decimal salesbonus) : base(name, basepay)
{
this.salesbonus = salesbonus;
}

// Override the CalculatePay method


// to take bonus into account.
public override decimal CalculatePay()
{
return basepay + salesbonus;
}
}

static void Main()


{
// Create some new employees.
var employee1 = new SalesEmployee("Alice",
1000, 500);
var employee2 = new Employee("Bob", 1200);

Console.WriteLine("Employee4 " + employee1.name +


" earned: " + employee1.CalculatePay());
Console.WriteLine("Employee4 " + employee2.name +
" earned: " + employee2.CalculatePay());
}
}
/*
Output:
Employee4 Alice earned: 1500
Employee4 Bob earned: 1200
*/
C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
Devralma
C# Anahtar Sözcükleri
Değiştiriciler
abstract
virtual
Yeni (değiştirici)
Çok biçimlilik
readonly (C# Başvurusu)
4.11.2019 • 9 minutes to read • Edit Online

readonly anahtar sözcüğü dört bağlamda kullanılabilecek bir değiştiricisidir:


Alan bildiriminde readonly , alana atamanın yalnızca bildirimin bir parçası olarak veya aynı sınıftaki bir
oluşturucuda kullanılabileceğini gösterir. Salt okunur bir alan, alan bildirimi ve Oluşturucu içinde birden
çok kez atanabilir ve yeniden atanabilir.
Oluşturucu çıktıktan sonra bir readonly alanı atanamaz. Bu kural, değer türleri ve başvuru türleri için
farklı etkilere sahiptir:
Değer türleri doğrudan verilerini içerdiğinden, readonly değer türü olan bir alan sabittir.
Başvuru türleri, verilerine yönelik bir başvuru içerdiğinden, readonly başvuru türü olan bir alan her
zaman aynı nesneye başvurmalıdır. Bu nesne sabit değildir. readonly değiştiricisi, alanın farklı bir
başvuru türü örneğiyle değiştirilmesini önler. Ancak, değiştirici alanın örnek verilerinin salt okunurdur
alanı aracılığıyla değiştirilmesini engellemez.

WARNING
Değişebilir bir başvuru türü olan bir dışarıdan görünür salt okunurdur alanı içeren dışarıdan görünen bir tür, bir
güvenlik açığı olabilir ve uyarı CA2104 : "salt okuma kesilebilir başvuru türleri bildiremiyor" olarak tetiklenebilir.

readonly struct tanımında, readonly struct sabit olduğunu gösterir.


readonly üye tanımında, readonly bir struct üyesinin yapının iç durumunu muiçermediğini belirtir.
ref readonly bir yöntemde döndürülen readonly değiştirici, yöntemin bir başvuru döndürdüğünü ve bu
başvuruya yazma izni bulunmadığını gösterir.
readonly struct ve ref readonly bağlamları 7,2 ' C# ye eklenmiştir. 8,0 ' de C# readonly struct üyeleri eklendi

ReadOnly alan örneği


Bu örnekte, year alan değeri, sınıf oluşturucusunda bir değer atanmış olsa da, ChangeYear yönteminde
değiştirilemez:

class Age
{
readonly int year;
Age(int year)
{
this.year = year;
}
void ChangeYear()
{
//year = 1967; // Compile error if uncommented.
}
}

Bir readonly alanına yalnızca aşağıdaki bağlamlarda bir değer atayabilirsiniz:


Bildirimde bir değişken başlatıldığında, örneğin:
public readonly int y = 5;

Örnek alan bildirimini içeren sınıfın örnek oluşturucusunda.


Statik alan bildirimini içeren sınıfın statik oluşturucusunda.
Bu Oluşturucu bağlamları aynı zamanda bir readonly alanını Out veya ref parametresi olarak geçirmek için
geçerli olduğu tek bağlamlardır.

NOTE
readonly anahtar sözcüğü const anahtar sözcüğünden farklıdır. Bir const alanı yalnızca alanın bildiriminde başlatılabilir.
readonly alan, alan bildiriminde ve herhangi bir oluşturucuda birden çok kez atanabilir. Bu nedenle, readonly alanlar
kullanılan oluşturucuya bağlı olarak farklı değerlere sahip olabilir. Ayrıca, bir const alanı bir derleme zamanı sabiti olsa da,
readonly alanı aşağıdaki örnekte olduğu gibi çalışma zamanı sabitleri için kullanılabilir:

public static readonly uint timeStamp = (uint)DateTime.Now.Ticks;

class SampleClass
{
public int x;
// Initialize a readonly field
public readonly int y = 25;
public readonly int z;

public SampleClass()
{
// Initialize a readonly instance field
z = 24;
}

public SampleClass(int p1, int p2, int p3)


{
x = p1;
y = p2;
z = p3;
}

public static void Main()


{
SampleClass p1 = new SampleClass(11, 21, 32); // OK
Console.WriteLine($"p1: x={p1.x}, y={p1.y}, z={p1.z}");
SampleClass p2 = new SampleClass();
p2.x = 55; // OK
Console.WriteLine($"p2: x={p2.x}, y={p2.y}, z={p2.z}");
}
/*
Output:
p1: x=11, y=21, z=32
p2: x=55, y=25, z=24
*/
}

Yukarıdaki örnekte, aşağıdaki örnekte olduğu gibi bir ifade kullanıyorsanız:

p2.y = 66; // Error

Derleyici hata iletisini alırsınız:


A readonly field cannot be assigned to (except in a constructor or a variable initializer)

ReadOnly struct örneği


struct tanımında readonly değiştiricisi yapının sabitolduğunu bildirir. Aşağıdaki örnekte gösterildiği gibi
struct her örnek alanı readonly işaretlenmelidir:

public readonly struct Point


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

public Point(double x, double y) => (X, Y) = (x, y);

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


}

Önceki örnek, depolama alanını bildirmek için salt okunur otomatik özellikleri kullanır. Bu, derleyiciye bu
özellikler için readonly yedekleme alanı oluşturmasını söyler. Ayrıca, readonly alanları doğrudan de
bildirebilirsiniz:

public readonly struct Point


{
public readonly double X;
public readonly double Y;

public Point(double x, double y) => (X, Y) = (x, y);

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


}

readonly işaretlenmemiş bir alan eklendiğinde CS8340 derleyici hatası oluşturulur: "ReadOnly yapıların örnek
alanları ReadOnly olmalıdır."

ReadOnly üye örnekleri


Diğer zamanlarda, mutasyonu destekleyen bir yapı oluşturabilirsiniz. Bu durumlarda, örnek üyelerinden birkaçı
büyük olasılıkla yapının iç durumunu değiştirmez. Bu örnek üyelerini readonly değiştiricisiyle bildirebilirsiniz.
Derleyici amacınızı zorluyor. Bu üye, durumu doğrudan değiştirir veya readonly değiştiricisi ile de bildirilmeyen
bir üyeye eriştiğinde sonuç, derleme zamanı hatasıdır. readonly değiştiricisi class veya interface üye
bildirimlerinde değil struct üyelerinde geçerlidir.
Geçerli struct yöntemlerine readonly değiştiricisini uygulayarak iki avantaja sahip olursunuz. En önemlisi,
derleyici amacınızı zorluyor. Durumu değiştiren kod readonly yönteminde geçerli değildir. Derleyici,
performans iyileştirmelerini etkinleştirmek için readonly değiştiricisinden da kullanabilir. Büyük struct türleri
in başvurusuyla geçirildiğinde, yapının durumu değiştirilemiyorsa derleyicinin bir savunma kopyası
oluşturması gerekir. Yalnızca readonly üyelerine erişilirse, derleyici savunma kopyasını oluşturmayabilir.
readonly değiştiricisi, System.Objecttarafından belirtilen yöntemleri geçersiz kılan yöntemler de dahil olmak
üzere struct çoğu üye üzerinde geçerlidir. Bazı kısıtlamalar vardır:
readonly statik üye bildiremezsiniz.
readonly oluşturucuları bildiremezsiniz.
readonly değiştiricisini bir özellik veya Dizin Oluşturucu bildirimine ekleyebilirsiniz:
readonly public int Counter
{
get { return 0; }
set {} // not useful, but legal
}

readonly değiştiricisini bir özelliğin veya dizin oluşturucunun tek tek get veya set erişimcilerine de
ekleyebilirsiniz:

public int Counter


{
readonly get { return _counter; }
set { _counter = value; }
}
int _counter;

readonly değiştiricisini hem özelliğe hem de aynı özelliğin erişimcilerine bir veya daha fazlasına
ekleyemeyebilirsiniz. Aynı kısıtlama, Dizin oluşturucular için geçerlidir.
Derleyici, derleyicinin uyguladığı kodun durumu değiştirmediğinden otomatik uygulanan özelliklere readonly
değiştiricisini örtülü olarak uygular. Aşağıdaki bildirimlerle eşdeğerdir:

public readonly int Index { get; }


// Or:
public int Number { readonly get; }
public string Message { readonly get; set; }

readonly değiştiricisini bu konumlara ekleyebilirsiniz, ancak anlamlı bir etkiye sahip olmaz. readonly
değiştiricisini otomatik uygulanan bir özellik ayarlayıcısına veya okuma/yazma otomatik uygulanan özelliğine
ekleyemezsiniz.

Ref ReadOnly dönüş örneği


ref return readonly değiştiricisi döndürülen başvurunun değiştirilemeyeceğini gösterir. Aşağıdaki örnek,
kaynağına bir başvuru döndürür. Çağıranların kaynağı değiştiremeyeceğini belirtmek için readonly
değiştiricisini kullanır:

private static readonly Point origin = new Point(0, 0);


public static ref readonly Point Origin => ref origin;

Döndürülen türün bir readonly struct olması gerekmez. ref tarafından döndürülebilecek herhangi bir tür,
ref readonly tarafından döndürülebilir.

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.
Dil belirtimi tekliflerini de görebilirsiniz:
ReadOnly ref ve ReadOnly yapısı
ReadOnly struct üyeleri

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
Değiştiriciler
const
Alanlar
sealed (C# Başvurusu)
5.11.2019 • 3 minutes to read • Edit Online

Bir sınıfa uygulandığında sealed değiştiricisi diğer sınıfların bundan devralınmasını önler. Aşağıdaki
örnekte, sınıf B sınıf A devralır, ancak sınıf B sınıfından hiçbir sınıf devralamıyor.

class A {}
sealed class B : A {}

Bir temel sınıftaki sanal bir yöntemi veya özelliği geçersiz kılan bir yöntem veya özellik üzerinde sealed
değiştiricisini de kullanabilirsiniz. Bu, sınıfların sınıfınızdan türetmesine izin verir ve belirli sanal
yöntemlerin veya özelliklerin geçersiz kılınmasını önler.

Örnek
Aşağıdaki örnekte, Z Y devralır, ancak Z X ve mühürlenen F sanal işlevi geçersiz kılamaz. Y

class X
{
protected virtual void F() { Console.WriteLine("X.F"); }
protected virtual void F2() { Console.WriteLine("X.F2"); }
}

class Y : X
{
sealed protected override void F() { Console.WriteLine("Y.F"); }
protected override void F2() { Console.WriteLine("Y.F2"); }
}

class Z : Y
{
// Attempting to override F causes compiler error CS0239.
// protected override void F() { Console.WriteLine("Z.F"); }

// Overriding F2 is allowed.
protected override void F2() { Console.WriteLine("Z.F2"); }
}

Bir sınıfta yeni yöntemler veya özellikler tanımladığınızda, türetilen sınıfların bunları sanalolarak
bildirmeyerek geçersiz kılmasını engelleyebilirsiniz.
Soyut bir sınıf, soyut yöntemlerin veya özelliklerin bir uygulamasını sağlayan bir sınıf tarafından
devralınamadığı için Sealed bir sınıf ile soyut değiştiricinin kullanılması hatadır.
Bir yönteme veya özelliğe uygulandığında, sealed değiştiricisi her zaman geçersiz kılmaile
kullanılmalıdır.
Yapılar örtük olarak mühürlenmediğinden devralınamaz.
Daha fazla bilgi için bkz. Devralma.
Daha fazla örnek için bkz. soyut ve korumalı sınıflar ve sınıf üyeleri.

Örnek
sealed class SealedClass
{
public int x;
public int y;
}

class SealedTest2
{
static void Main()
{
var sc = new SealedClass();
sc.x = 110;
sc.y = 150;
Console.WriteLine($"x = {sc.x}, y = {sc.y}");
}
}
// Output: x = 110, y = 150

Önceki örnekte, aşağıdaki ifadeyi kullanarak Sealed sınıfından devralmayı deneyebilirsiniz:


class MyDerivedC: SealedClass {} // Error

Sonuç bir hata iletisidir:


'MyDerivedC': cannot derive from sealed type 'SealedClass'

Açıklamalar
Bir sınıfın, yöntemin veya özelliğin mühürlendirilip zorlanmayacağını anlamak için genellikle aşağıdaki iki
noktayı dikkate almalısınız:
Sınıfların türetireceği olası avantajlar, sınıfınızı özelleştirme özelliği aracılığıyla elde edebilir.
Sınıfları Türetmenin olasılığı, sınıflarınızı daha sonra düzgün şekilde veya beklendiği gibi
çalışmayacak şekilde değiştirebilir.

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
Statik Sınıflar ve Statik Sınıf Üyeleri
Soyut ve Korumalı Sınıflar ve Sınıf Üyeleri
Erişim Değiştiricileri
Değiştiriciler
override
virtual
static (C# Başvurusu)
4.11.2019 • 4 minutes to read • Edit Online

Belirli bir nesne yerine türüne ait olan statik bir üye bildirmek için static değiştiricisini kullanın.
static değiştiricisi sınıflar, alanlar, Yöntemler, özellikler, işleçler, olaylar ve oluşturucularla birlikte
kullanılabilir, ancak sınıf dışındaki Dizin oluşturucular, sonlandırıcılar veya türler ile kullanılamaz. Daha
fazla bilgi için bkz. statik sınıflar ve statik sınıf üyeleri.

Örnek
Aşağıdaki sınıf static olarak bildirilmiştir ve yalnızca static yöntemleri içerir:

static class CompanyEmployee


{
public static void DoSomething() { /*...*/ }
public static void DoSomethingElse() { /*...*/ }
}

Sabit veya tür bildirimi örtük olarak statik bir üyedir.


Statik üyeye bir örnek üzerinden başvurulamaz. Bunun yerine tür adı ile başvurulur. Örneğin, aşağıdaki
sınıfı göz önünde bulundurun:

public class MyBaseC


{
public struct MyStruct
{
public static int x = 100;
}
}

Statik üye başvurmak için, üyenin aynı kapsamdan erişilebilir olmadığı müddetçe,
x
MyBaseC.MyStruct.x tam adı kullanın:

Console.WriteLine(MyBaseC.MyStruct.x);

Bir sınıf örneği, sınıfının tüm örnek alanlarının ayrı bir kopyasını içerdiğinde, her statik alanın yalnızca
bir kopyası vardır.
Statik yöntemlere veya özellik erişimcilerine başvurmak için bunu kullanmak mümkün değildir.
static anahtar sözcüğü bir sınıfa uygulanırsa, sınıfın tüm üyeleri statik olmalıdır.
Sınıflar ve statik sınıfların statik oluşturucuları olabilir. Statik oluşturucular, programın başladığı ve
sınıfın örneği oluşturulan bir noktada çağrılır.

NOTE
static anahtar sözcüğü, öğesinden daha sınırlı kullanımları vardır C++. Anahtar sözcükle karşılaştırmak için
bkz. Depolama sınıfları (C++). C++
Statik üyeleri göstermek için, bir şirket çalışanını temsil eden bir sınıf düşünün. Sınıfın çalışanları
saymak için bir yöntem ve çalışanların sayısını depolamak için bir alan içerdiğini varsayın. Hem yöntem
hem de alan herhangi bir örnek çalışana ait değildir. Bunun yerine, şirket sınıfına ait olurlar. Bu nedenle,
sınıfın statik üyeleri olarak bildirilmelidir.

Örnek
Bu örnek, yeni bir çalışanın adını ve KIMLIĞINI okur, bir çalışan sayacını bir artırır ve yeni çalışana ait
bilgileri ve yeni çalışanların sayısını görüntüler. Kolaylık olması için, bu program klavyeden geçerli
çalışan sayısını okur. Gerçek bir uygulamada, bu bilgiler bir dosyadan okunmalıdır.
public class Employee4
{
public string id;
public string name;

public Employee4()
{
}

public Employee4(string name, string id)


{
this.name = name;
this.id = id;
}

public static int employeeCounter;

public static int AddEmployee()


{
return ++employeeCounter;
}
}

class MainClass : Employee4


{
static void Main()
{
Console.Write("Enter the employee's name: ");
string name = Console.ReadLine();
Console.Write("Enter the employee's ID: ");
string id = Console.ReadLine();

// Create and configure the employee object.


Employee4 e = new Employee4(name, id);
Console.Write("Enter the current number of employees: ");
string n = Console.ReadLine();
Employee4.employeeCounter = Int32.Parse(n);
Employee4.AddEmployee();

// Display the new information.


Console.WriteLine($"Name: {e.name}");
Console.WriteLine($"ID: {e.id}");
Console.WriteLine($"New Number of Employees: {Employee4.employeeCounter}");
}
}
/*
Input:
Matthias Berndt
AF643G
15
*
Sample Output:
Enter the employee's name: Matthias Berndt
Enter the employee's ID: AF643G
Enter the current number of employees: 15
Name: Matthias Berndt
ID: AF643G
New Number of Employees: 16
*/

Örnek
Bu örnek, henüz bildirilmemiş başka bir statik alanı kullanarak bir statik alanı başlatabilmenize karşın,
statik alana açıkça bir değer atayana kadar sonuçlar tanımsız olacaktır.
class Test
{
static int x = y;
static int y = 5;

static void Main()


{
Console.WriteLine(Test.x);
Console.WriteLine(Test.y);

Test.x = 99;
Console.WriteLine(Test.x);
}
}
/*
Output:
0
5
99
*/

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
Değiştiriciler
Statik Sınıflar ve Statik Sınıf Üyeleri
unsafe (C# Başvurusu)
4.11.2019 • 2 minutes to read • Edit Online

unsafe anahtar sözcüğü, işaretçileri içeren tüm işlemler için gerekli olan güvenli olmayan bir bağlamı
gösterir. Daha fazla bilgi için bkz. güvenli olmayan kod ve işaretçiler.
unsafe değiştiricisini bir tür veya üye bildiriminde kullanabilirsiniz. Türün veya üyenin metinsel kapsamı, bu
nedenle güvenli olmayan bir bağlam olarak değerlendirilir. Örneğin, aşağıda unsafe değiştiriciyle belirtilen
bir yöntem verilmiştir:

unsafe static void FastCopy(byte[] src, byte[] dst, int count)


{
// Unsafe context: can use pointers here.
}

Güvenli olmayan bağlamın kapsamı parametre listesinden yönteminin sonuna kadar uzanır, bu nedenle
işaretçiler parametre listesinde de kullanılabilir:

unsafe static void FastCopy ( byte* ps, byte* pd, int count ) {...}

Güvenli olmayan bir blok, bu blok içinde güvenli olmayan bir kod kullanımını etkinleştirmek için de
kullanabilirsiniz. Örneğin:

unsafe
{
// Unsafe context: can use pointers here.
}

Güvenli olmayan kod derlemek için -unsafe derleyici seçeneğini belirtmeniz gerekir. Güvenli olmayan kod,
ortak dil çalışma zamanı tarafından doğrulanabilir değil.

Örnek
// compile with: -unsafe
class UnsafeTest
{
// Unsafe method: takes pointer to int.
unsafe static void SquarePtrParam(int* p)
{
*p *= *p;
}

unsafe static void Main()


{
int i = 5;
// Unsafe method: uses address-of operator (&).
SquarePtrParam(&i);
Console.WriteLine(i);
}
}
// Output: 25
C# dili belirtimi
Daha fazla bilgi için bkz. C# dil belirtiminde güvenli olmayan kod . Dil belirtimi, C# sözdizimi ve kullanımı
için kesin bir kaynaktır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
fixed Deyimi
Güvenli Olmayan Kod ve İşaretçiler
Sabit Boyutlu Arabellekler
virtual (C# Başvurusu)
23.10.2019 • 4 minutes to read • Edit Online

@No__t-0 anahtar sözcüğü, bir yöntemi, özelliği, Dizin Oluşturucuyu veya olay bildirimini değiştirmek ve
bir türetilmiş sınıfta geçersiz kılınabilmesi için kullanılır. Örneğin, bu yöntem onu devralan herhangi bir
sınıf tarafından geçersiz kılınabilir:

public virtual double Area()


{
return x * y;
}

Bir sanal üyenin uygulanması türetilmiş bir sınıftaki geçersiz kılan bir üye tarafından değiştirilebilir.
@No__t-0 anahtar sözcüğünü kullanma hakkında daha fazla bilgi için bkz. geçersiz kılma ve Yeni anahtar
sözcüklerle sürüm oluşturma ve geçersiz kılma ve yeni anahtar sözcüklerin ne zaman kullanılacağını
bilme.

Açıklamalar
Bir sanal yöntem çağrıldığında, nesnenin çalışma zamanı türü geçersiz kılan üye için denetlenir. Türetilmiş
bir sınıf üye tarafından geçersiz kılınmamışsa, en çok türetilen sınıftaki geçersiz kılan üye çağrılır, bu,
özgün üye olabilir.
Varsayılan olarak, metotlar sanal değildir. Sanal olmayan bir yöntemi geçersiz kılamazsınız.
@No__t-0 değiştiricisini static , abstract , private veya override değiştiricisiyle kullanamazsınız.
Aşağıdaki örnek bir sanal özelliği gösterir:
class MyBaseClass
{
// virtual auto-implemented property. Overrides can only
// provide specialized behavior if they implement get and set accessors.
public virtual string Name { get; set; }

// ordinary virtual property with backing field


private int num;
public virtual int Number
{
get { return num; }
set { num = value; }
}
}

class MyDerivedClass : MyBaseClass


{
private string name;

// Override auto-implemented property with ordinary property


// to provide specialized accessor behavior.
public override string Name
{
get
{
return name;
}
set
{
if (!string.IsNullOrEmpty(value))
{
name = value;
}
else
{
name = "Unknown";
}
}
}
}

Sanal özellikler, bildirim ve çağırma söz dizimi farklılıkları dışında sanal yöntemler gibi davranır.
Statik bir özellikte virtual değiştiricisinin kullanılması hatadır.
Bir sanal devralınmış özellik, override değiştiricisini kullanan bir özellik bildirimi eklenerek,
türetilmiş sınıfta geçersiz kılınabilir.

Örnek
Bu örnekte, Shape sınıfı iki koordinat x , y ve Area() sanal yöntemi içerir. @No__t-0, Cylinder ve
Sphere gibi farklı şekil sınıfları Shape sınıfını miras alır ve yüzey alanı her bir şekil için hesaplanır. Her
türetilmiş sınıfın kendi geçersiz kılma Area() ' dır.
Devralınan sınıfların Circle , Sphere ve Cylinder ' nin, aşağıdaki bildirimde gösterildiği gibi, temel sınıfı
başlatacak olan oluşturuculara sahip olduğuna dikkat edin.

public Cylinder(double r, double h): base(r, h) {}

Aşağıdaki program, yöntemiyle ilişkili nesneye göre Area() yönteminin uygun uygulamasını çağırarak
her bir şekil için uygun alanı hesaplar ve görüntüler.
class TestClass
{
public class Shape
{
public const double PI = Math.PI;
protected double x, y;

public Shape()
{
}

public Shape(double x, double y)


{
this.x = x;
this.y = y;
}

public virtual double Area()


{
return x * y;
}
}

public class Circle : Shape


{
public Circle(double r) : base(r, 0)
{
}

public override double Area()


{
return PI * x * x;
}
}

class Sphere : Shape


{
public Sphere(double r) : base(r, 0)
{
}

public override double Area()


{
return 4 * PI * x * x;
}
}

class Cylinder : Shape


{
public Cylinder(double r, double h) : base(r, h)
{
}

public override double Area()


{
return 2 * PI * x * x + 2 * PI * x * y;
}
}

static void Main()


{
double r = 3.0, h = 5.0;
Shape c = new Circle(r);
Shape s = new Sphere(r);
Shape l = new Cylinder(r, h);
// Display results.
Console.WriteLine("Area of Circle = {0:F2}", c.Area());
Console.WriteLine("Area of Sphere = {0:F2}", s.Area());
Console.WriteLine("Area of Cylinder = {0:F2}", l.Area());
}
}
/*
Output:
Area of Circle = 28.27
Area of Sphere = 113.10
Area of Cylinder = 150.80
*/

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
Çok biçimlilik
abstract
override
Yeni (değiştirici)
volatile (C# Başvurusu)
4.11.2019 • 4 minutes to read • Edit Online

volatile anahtar sözcüğü, bir alanın aynı anda yürütülen birden çok iş parçacığı tarafından değiştirildiğini belirtir.
Derleyici, çalışma zamanı sistemi ve hatta donanım, performans nedeniyle bellek konumlarına okuma ve yazma
işlemlerini yeniden düzenleyebilir. volatile olarak belirtilen alanlar bu iyileştirmelere tabi değildir. volatile
değiştiricisini eklemek, tüm iş parçacıklarının gerçekleştirilen diğer bir iş parçacığı tarafından gerçekleştirilen geçici
yazmaları gözlemleyecek olmasını sağlar. Yürütmenin tüm iş parçacıklarından görüldüğü şekilde, tek bir toplam
geçici yazma sıralaması garantisi yoktur.
volatile anahtar sözcüğü bu türlerin alanlarına uygulanabilir:
Başvuru türleri.
İşaretçi türleri (güvenli olmayan bir bağlamda). İşaretçinin kendisi geçici olsa da, işaret ettiği nesnenin bu
şekilde olduğunu unutmayın. Diğer bir deyişle, "geçici işaretçi işaretçisi" bildiremezsiniz.
sbyte , byte , short , ushort , int , uint , char , float ve bool gibi basit türler.
Aşağıdaki temel türlerden birine sahip enum türü: byte , sbyte , short , ushort , int veya uint .
Başvuru türleri olarak bilinen genel tür parametreleri.
IntPtr ve UIntPtr.
double ve long dahil diğer türler volatile olarak işaretlenemez, çünkü bu türlerin alanlarına okuma ve yazma
işlemleri atomik olarak garanti edilemez. Bu tür alanlara çok iş parçacıklı erişimi korumak için, Interlocked sınıf
üyelerini kullanın veya lock ifadesini kullanarak erişimi koruyun.
volatile anahtar sözcüğü yalnızca bir class veya struct alanlara uygulanabilir. Yerel değişkenler volatile
olarak bildirilemez.

Örnek
Aşağıdaki örnek, volatile olarak bir ortak alan değişkeninin nasıl bildirilemeyeceğini gösterir.

class VolatileTest
{
public volatile int sharedStorage;

public void Test(int _i)


{
sharedStorage = _i;
}
}

Aşağıdaki örnek, birincil iş parçacığından paralel olarak işleme gerçekleştirmek için bir yardımcı veya çalışan iş
parçacığının nasıl oluşturulup kullanılabileceğini gösterir. Çoklu iş parçacığı hakkında daha fazla bilgi için bkz.
yönetilen Iş parçacığı.
public class Worker
{
// This method is called when the thread is started.
public void DoWork()
{
bool work = false;
while (!_shouldStop)
{
work = !work; // simulate some work
}
Console.WriteLine("Worker thread: terminating gracefully.");
}
public void RequestStop()
{
_shouldStop = true;
}
// Keyword volatile is used as a hint to the compiler that this data
// member is accessed by multiple threads.
private volatile bool _shouldStop;
}

public class WorkerThreadExample


{
public static void Main()
{
// Create the worker thread object. This does not start the thread.
Worker workerObject = new Worker();
Thread workerThread = new Thread(workerObject.DoWork);

// Start the worker thread.


workerThread.Start();
Console.WriteLine("Main thread: starting worker thread...");

// Loop until the worker thread activates.


while (!workerThread.IsAlive)
;

// Put the main thread to sleep for 500 milliseconds to


// allow the worker thread to do some work.
Thread.Sleep(500);

// Request that the worker thread stop itself.


workerObject.RequestStop();

// Use the Thread.Join method to block the current thread


// until the object's thread terminates.
workerThread.Join();
Console.WriteLine("Main thread: worker thread has terminated.");
}
// Sample output:
// Main thread: starting worker thread...
// Worker thread: terminating gracefully.
// Main thread: worker thread has terminated.
}

_shouldStop bildirimine eklenen volatile değiştiricisi ile, her zaman aynı sonuçları elde edersiniz (Yukarıdaki
kodda gösterilen alıntıya benzer). Ancak, _shouldStop üyesinde Bu değiştirici olmadan davranış tahmin edilemez.
DoWork yöntemi üye erişimini iyileştirebilmenizi sağlayabilir ve bu da eski verilerin okunmasına yol açar. Çok iş
parçacıklı programlama doğası nedeniyle, eski okuma sayısı tahmin edilemez. Programın farklı çalıştırmaları biraz
farklı sonuçlar üretecektir.

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir kaynaktır.
Ayrıca bkz.
C#dil belirtimi: volatile anahtar sözcüğü
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
Değiştiriciler
Lock deyimleri
Interlocked
Deyim anahtar sözcükleri (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

Deyimleri program yönergeleri verilmiştir. Hariç aşağıdaki tabloda başvurulan konularda açıklandığı gibi ifadeler
sırayla yürütülür. Aşağıdaki tablo, C# deyim anahtar sözcükleri listeler. Tüm anahtar sözcüğüne sahip olmayan
ifade deyimleri hakkında daha fazla bilgi için bkz. deyimleri.

KATEGORI C# ANAHTAR SÖZCÜKLERI

Seçim deyimleri varsa, başka, geçiş, çalışması

Yineleme deyimleri yapmak, için, foreach, içinde, sırada

Atlama deyimleri Kesme, devam, varsayılan, goto, dönüş, yield

Özel durum işleme deyimleri throw, try-catch, try-finally, try-catch-finally

Checked ve unchecked işaretli, seçeneği işaretli değil

fixed deyimi düzeltildi

lock deyimi lock

Ayrıca bkz.
C# başvurusu
Deyimler
C# Anahtar Sözcükleri
if-else (C# Başvurusu)
23.10.2019 • 7 minutes to read • Edit Online

Bir if deyimi çalıştırmak için hangi deyimi, bir Boolean ifadesinin değerine göre tanımlar. Aşağıdaki örnekte,
bool değişkeni condition ayarlanır true ve ardından iade if deyimi. Çıktı The variable is set to true. .

bool condition = true;

if (condition)
{
Console.WriteLine("The variable is set to true.");
}
else
{
Console.WriteLine("The variable is set to false.");
}

Bunları yerleştirerek bu konudaki örnekler çalıştırabilirsiniz Main bir konsol uygulaması yöntemi.
Bir if C# deyimi, aşağıdaki örnekte gösterildiği gibi iki form alabilir.

// if-else statement
if (condition)
{
then-statement;
}
else
{
else-statement;
}
// Next statement in the program.

// if statement without an else


if (condition)
{
then-statement;
}
// Next statement in the program.

İçinde bir ifadesi varsa condition true olarak değerlendirilen then-statement çalıştırır. Varsa
if-else
condition false ise else-statement çalıştırır. Çünkü condition aynı anda true ve false olamaz then-statement
ve else-statement , bir if-else deyimi hiçbir zaman hem de çalıştırabilirsiniz. Sonra then-statement veya
else-statement çalıştığında, Denetim, sonra sonraki deyime aktarılır if deyimi.

İçinde bir if deyimi içermeyen bir else deyimi, condition true ise then-statement çalıştırır. Varsa
condition yanlış denetimi sonra sonraki deyime aktarılır if deyimi.
Hem then-statement ve else-statement tek bir deyim veya küme ayraçları içine alınmış birden çok deyim
içerebilir ( {} ). Tek bir deyim için Küme ayraçları isteğe bağlıdır ancak önerilir.
Deyim ya da deyimlerinde then-statement ve else-statement başka dahil olmak üzere, herhangi bir türden
olabilir if deyimi özgün içinde iç içe if deyimi. İçinde iç içe geçmiş if deyimleri, her else yan tümcesi ait
son if karşılık gelen yok else . Aşağıdaki örnekte, Result1 her iki görünür m > 10 ve n > 20 true olarak
değerlendirin. Varsa m > 10 geçerlidir ancak n > 20 false ise Result2 görünür.
// Try with m = 12 and then with m = 8.
int m = 12;
int n = 18;

if (m > 10)
if (n > 20)
{
Console.WriteLine("Result1");
}
else
{
Console.WriteLine("Result2");
}

Bunun yerine, isterseniz Result2 olduğunda görüntülenecek (m > 10) başındaki ve sonundaki iç içe'kurmak
için küme ayraçlarını kullanarak bu ilişkiyi belirleyebilir, yanlış if aşağıdaki örnekte gösterildiği gibi bir ifade.

// Try with m = 12 and then with m = 8.


if (m > 10)
{
if (n > 20)
Console.WriteLine("Result1");
}
else
{
Console.WriteLine("Result2");
}

Result2 görünür koşul (m > 10) yanlış olarak değerlendirilir.

Örnek
Aşağıdaki örnekte, bir karakter klavyeden girmeniz ve iç içe bir programın kullandığı if girdi karakteri
alfabetik bir karakter olup olmadığını belirlemek için deyimi. Girdi karakteri alfabetik bir karakter ise,
programın giriş karakterin büyük harf veya küçük harf olup olmadığını denetler. Her durum için bir ileti
görüntülenir.
Console.Write("Enter a character: ");
char c = (char)Console.Read();
if (Char.IsLetter(c))
{
if (Char.IsLower(c))
{
Console.WriteLine("The character is lowercase.");
}
else
{
Console.WriteLine("The character is uppercase.");
}
}
else
{
Console.WriteLine("The character isn't an alphabetic character.");
}

//Sample Output:

//Enter a character: 2
//The character isn't an alphabetic character.

//Enter a character: A
//The character is uppercase.

//Enter a character: h
//The character is lowercase.

Örnek
Ayrıca yuvalayabilirsiniz bir if başka bir blok içinde bir ifade aşağıdaki kodu kısmi gösterildiği gibi. Örnek
Yuvalar if iki başka blokları ve ardından bloğu içindeki deyimler. True veya false her blok içinde hangi
koşullar açıklamaları belirtin.
// Change the values of these variables to test the results.
bool Condition1 = true;
bool Condition2 = true;
bool Condition3 = true;
bool Condition4 = true;

if (Condition1)
{
// Condition1 is true.
}
else if (Condition2)
{
// Condition1 is false and Condition2 is true.
}
else if (Condition3)
{
if (Condition4)
{
// Condition1 and Condition2 are false. Condition3 and Condition4 are true.
}
else
{
// Condition1, Condition2, and Condition4 are false. Condition3 is true.
}
}
else
{
// Condition1, Condition2, and Condition3 are false.
}

Örnek
Aşağıdaki örnek, bir girdi karakteri küçük harf, bir büyük harf veya sayı olup olmadığını belirler. Üç tüm
koşullar false olursa, karakterin alfasayısal bir karakter değildir. Örneğin, her örneği için bir ileti görüntüler.
Console.Write("Enter a character: ");
char ch = (char)Console.Read();

if (Char.IsUpper(ch))
{
Console.WriteLine("The character is an uppercase letter.");
}
else if (Char.IsLower(ch))
{
Console.WriteLine("The character is a lowercase letter.");
}
else if (Char.IsDigit(ch))
{
Console.WriteLine("The character is a number.");
}
else
{
Console.WriteLine("The character is not alphanumeric.");
}

//Sample Input and Output:


//Enter a character: E
//The character is an uppercase letter.

//Enter a character: e
//The character is a lowercase letter.

//Enter a character: 4
//The character is a number.

//Enter a character: =
//The character is not alphanumeric.

Yalnızca bir deyimde başka bloğu ya da sonra blok herhangi bir geçerli ifade olabilir, koşul için geçerli bir Boole
ifade kullanabilirsiniz. Kullanabileceğiniz mantıksal işleçler gibi ! , && , || , & , | , ve ^ Bileşik koşul yapma.
Aşağıdaki kod örnekleri gösterir.
// NOT
bool result = true;
if (!result)
{
Console.WriteLine("The condition is true (result is false).");
}
else
{
Console.WriteLine("The condition is false (result is true).");
}

// Short-circuit AND
int m = 9;
int n = 7;
int p = 5;
if (m >= n && m >= p)
{
Console.WriteLine("Nothing is larger than m.");
}

// AND and NOT


if (m >= n && !(p > m))
{
Console.WriteLine("Nothing is larger than m.");
}

// Short-circuit OR
if (m > n || m > p)
{
Console.WriteLine("m isn't the smallest.");
}

// NOT and OR
m = 4;
if (!(m >= n || m >= p))
{
Console.WriteLine("Now m is the smallest.");
}
// Output:
// The condition is false (result is true).
// Nothing is larger than m.
// Nothing is larger than m.
// m isn't the smallest.
// Now m is the smallest.

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
C# başvurusu
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
?: İşleç
if-else Deyimi (C++)
switch
anahtar (C# başvuru)
29.11.2019 • 22 minutes to read • Edit Online

switch, Match ifadesiylebir model eşleşmesi temelinde aday listesinden yürütülecek tek bir anahtar
bölümü seçen bir seçim deyimidir.

using System;

public class Example


{
public static void Main()
{
int caseSwitch = 1;

switch (caseSwitch)
{
case 1:
Console.WriteLine("Case 1");
break;
case 2:
Console.WriteLine("Case 2");
break;
default:
Console.WriteLine("Default case");
break;
}
}
}
// The example displays the following output:
// Case 1

Tek bir ifade üç veya daha fazla koşula göre test edildiğinde, switch deyimi genellikle If-Else yapısına
alternatif olarak kullanılır. Örneğin, aşağıdaki switch ifade, Color türünde bir değişkenin üç değerden
birine sahip olup olmadığını belirler:
using System;

public enum Color { Red, Green, Blue }

public class Example


{
public static void Main()
{
Color c = (Color) (new Random()).Next(0, 3);
switch (c)
{
case Color.Red:
Console.WriteLine("The color is red");
break;
case Color.Green:
Console.WriteLine("The color is green");
break;
case Color.Blue:
Console.WriteLine("The color is blue");
break;
default:
Console.WriteLine("The color is unknown.");
break;
}
}
}

Bir if - else yapısını kullanan aşağıdaki örneğe eşdeğerdir.

using System;

public enum Color { Red, Green, Blue }

public class Example


{
public static void Main()
{
Color c = (Color) (new Random()).Next(0, 3);
if (c == Color.Red)
Console.WriteLine("The color is red");
else if (c == Color.Green)
Console.WriteLine("The color is green");
else if (c == Color.Blue)
Console.WriteLine("The color is blue");
else
Console.WriteLine("The color is unknown.");
}
}
// The example displays the following output:
// The color is red

Match ifadesi
Match ifadesi case etiketlerindeki desenlerle eşleşecek değeri sağlar. Sözdizimi şöyledir:

switch (expr)

C# 6 ve önceki sürümlerde, Match ifadesi aşağıdaki türlerde bir değer döndüren bir ifade olmalıdır:
bir char.
bir dize.
bir bool.
int veya long gibi bir integral değeri.
bir sabit listesi değeri.
7,0 ile C# başlayarak, Match ifadesi null olmayan herhangi bir ifade olabilir.

Anahtar bölümü
switch bir ifade bir veya daha fazla anahtar bölümü içerir. Her anahtar bölümü bir veya daha fazla
durum etiketi (bir Case veya default etiketi) ve ardından bir veya daha fazla deyimi içerir. switch
deyiminiz, herhangi bir switch bölümüne yerleştirilmiş en çok bir varsayılan etiket içerebilir. Aşağıdaki
örnek, her biri iki deyim içeren üç anahtar bölümü olan basit bir switch deyimini gösterir. İkinci anahtar
bölümü case 2: ve case 3: etiketlerini içerir.
switchbir ifade herhangi bir sayıda anahtar bölümü içerebilir ve aşağıdaki örnekte gösterildiği gibi her
bölümde bir veya daha fazla Case etiketi olabilir. Ancak, iki durum etiketi de aynı ifadeyi içeremez.

using System;

public class Example


{
public static void Main()
{
Random rnd = new Random();
int caseSwitch = rnd.Next(1,4);

switch (caseSwitch)
{
case 1:
Console.WriteLine("Case 1");
break;
case 2:
case 3:
Console.WriteLine($"Case {caseSwitch}");
break;
default:
Console.WriteLine($"An unexpected value ({caseSwitch})");
break;
}
}
}
// The example displays output like the following:
// Case 1

Switch deyimindeki yalnızca bir switch bölümü yürütülür. C#yürütmenin bir geçiş bölümünden bir
sonrakine devam etmesine izin vermez. Bu nedenle, aşağıdaki kod bir derleyici hatası oluşturuyor,
CS0163: "Denetim bir case etiketinden (<Case Label >) başka bir şekilde geçemez."

switch (caseSwitch)
{
// The following switch section causes an error.
case 1:
Console.WriteLine("Case 1...");
// Add a break or other jump statement here.
case 2:
Console.WriteLine("... and/or Case 2");
break;
}

Bu gereksinim, genellikle bir Break, gotoveya Return ifadesiyle Switch bölümünden açıkça çıkarken
karşılanır. Ancak, program denetiminin default Switch bölümüne dönememesini sağladığından
aşağıdaki kod da geçerlidir.

switch (caseSwitch)
{
case 1:
Console.WriteLine("Case 1...");
break;
case 2:
case 3:
Console.WriteLine("... and/or Case 2");
break;
case 4:
while (true)
Console.WriteLine("Endless looping. . . .");
default:
Console.WriteLine("Default value...");
break;
}

Eşleştirme ifadesiyle eşleşen bir Case etiketi ile Switch bölümündeki deyim listesinin yürütülmesi ilk
deyimle başlar ve genellikle bir break , goto case``goto label gibi bir geç deyim olarak deyim listesini
ilerler. , return veya throw ulaşılmıştır. Bu noktada denetim switch deyimin dışına veya başka bir Case
etiketine aktarılır. goto bir deyimin kullanılması, denetimin bir sabit etikete aktarılmalıdır. Bu kısıtlama
gereklidir, çünkü denetimi sabit olmayan bir etikete aktarmaya çalışmak, denetimi kodda istenmeyen bir
konuma aktarmak veya sonsuz bir döngü oluşturmak gibi istenmeyen yan etkilere sahip olabilir.

Case etiketleri
Her Case etiketi, Match ifadesiyle Karşılaştırılacak bir model belirtir (önceki örneklerde caseSwitch
değişkeni). Eşleşiyorsa denetim, ilk eşleşen Case etiketini içeren Switch bölümüne aktarılır. Hiçbir Case
etiket deseninin eşleşme ifadesiyle eşleşmesi halinde, denetim varsa default Case etiketiyle birlikte
bölümüne aktarılır. default bir durum yoksa, herhangi bir anahtar bölümünde hiçbir deyim yürütülmez
ve denetim switch deyimi dışında aktarılır.
switch deyimleri ve model eşleştirme hakkında daha fazla bilgi için, switch deyimiyle eşleşen düzende
eşleşme bölümüne bakın.
C# 6 yalnızca sabit bir stili desteklediğinden ve sabit değerlerin yinelenmesinde izin vermediğinden, Case
etiketleri birbirini dışlayan değerleri tanımlar ve yalnızca bir desenler eşleştirme ifadesiyle eşleştirebilir.
Sonuç olarak, case deyimlerinin göründüğü sıra önemli değildir.
Ancak C# 7,0 ' de, diğer desenler desteklendiğinden, büyük/küçük harf etiketlerinin birbirini dışlayan
değerler tanımlamamalıdır ve birden çok desen eşleştirme ifadesiyle eşleşemez. Yalnızca eşleşen düzeni
içeren ilk anahtar bölümündeki deyimler yürütüldüğü için case deyimlerinin göründüğü sıra artık
önemlidir. Case C# deyimi veya deyimleri önceki deyimlerin alt kümelerine eşit olan bir switch bölümü
algılarsa, "switch case zaten önceki bir durum tarafından işlenmiştir." bir derleyici hatası oluşturur.
Aşağıdaki örnek, birbirini dışlayan farklı desenler kullanan bir switch ifadesini gösterir. case 0: Switch
bölümünü switch deyimindeki ilk bölüm olmayacak şekilde taşırsanız, C# değeri sıfır olan bir tamsayı,
case int val ifadesiyle tanımlanan bir alt küme olan tüm tamsayıların bir alt kümesi olduğundan bir
derleyici hatası oluşturur. .

using System;
using System.Collections.Generic;
using System.Linq;

public class Example


public class Example
{
public static void Main()
{
var values = new List<object>();
for (int ctr = 0; ctr <= 7; ctr++) {
if (ctr == 2)
values.Add(DiceLibrary.Roll2());
else if (ctr == 4)
values.Add(DiceLibrary.Pass());
else
values.Add(DiceLibrary.Roll());
}

Console.WriteLine($"The sum of { values.Count } die is { DiceLibrary.DiceSum(values) }");


}
}

public static class DiceLibrary


{
// Random number generator to simulate dice rolls.
static Random rnd = new Random();

// Roll a single die.


public static int Roll()
{
return rnd.Next(1, 7);
}

// Roll two dice.


public static List<object> Roll2()
{
var rolls = new List<object>();
rolls.Add(Roll());
rolls.Add(Roll());
return rolls;
}

// Calculate the sum of n dice rolls.


public static int DiceSum(IEnumerable<object> values)
{
var sum = 0;
foreach (var item in values)
{
switch (item)
{
// A single zero value.
case 0:
break;
// A single value.
case int val:
sum += val;
break;
// A non-empty collection.
case IEnumerable<object> subList when subList.Any():
sum += DiceSum(subList);
break;
// An empty collection.
case IEnumerable<object> subList:
break;
// A null reference.
case null:
break;
// A value that is neither an integer nor a collection.
default:
throw new InvalidOperationException("unknown item type");
}
}
return sum;
}
}

public static object Pass()


{
if (rnd.Next(0, 2) == 0)
return null;
else
return new List<object>();
}
}

Bu sorunu düzeltebilir ve iki şekilde derleyici uyarısını ortadan kaldırabilirsiniz:


Anahtar bölümlerinin sırasını değiştirerek.
case etiketinde bir WHERE yan tümcesi kullanarak.

default durumu
default Case, Match ifadesi başka bir case etiketiyle eşleşmezse yürütülecek Switch bölümünü belirtir.
default bir durum yoksa ve eşleştirme ifadesi başka bir case etiketiyle eşleşmezse, program akışı
switch ifadesiyle geçer.

default durum, switch deyimindeki herhangi bir sırada görünebilir. Kaynak kodundaki sıralarından
bağımsız olarak, tüm case etiketleri değerlendirildikten sonra her zaman son değerlendirilir.

switch ifadesiyle desenli eşleme


Her case deyimi, eşleşme ifadesiyle eşleşiyorsa, kapsayan anahtar bölümünün yürütülmesine neden
olan bir model tanımlar. Tüm sürümleri sabit C# düzende desteklenir. Kalan desenler C# 7,0 tarihinden
itibaren desteklenmektedir.
Sabit model
Sabit model, eşleşme ifadesinin belirtilen bir sabit değere eşit olup olmadığını sınar. Sözdizimi şöyledir:

case constant:

Burada Constant , test edilecek değerdir. sabit , aşağıdaki sabit ifadelerden herhangi biri olabilir:
Bir bool sabit değeri: true ya da false .
int , long veya byte gibi herhangi bir integral sabiti.
Belirtilen bir const değişkeninin adı.
Bir numaralandırma sabiti.
Bir char sabit değeri.
Dize sabit değeri.
Sabit ifade aşağıdaki gibi değerlendirilir:
Expr ve Constant integral türse, C# eşitlik işleci ifadenin true (yani expr == constant ) döndürüp
döndürmeyeceğini belirler.
Aksi takdirde, ifadenin değeri static Object. Equals (Expr, Constant) yöntemi çağrısıyla belirlenir.
Aşağıdaki örnek, belirli bir tarihin hafta sonu, çalışma haftasının ilk günü mi, çalışma haftasının son günü
mi yoksa çalışma haftasının ortasında mi olduğunu anlamak için sabit bir düzende kullanılır. Geçerli
günün DateTime.DayOfWeek özelliğini DayOfWeek numaralandırmanın üyelerine göre değerlendirir.
using System;

class Program
{
static void Main()
{
switch (DateTime.Now.DayOfWeek)
{
case DayOfWeek.Sunday:
case DayOfWeek.Saturday:
Console.WriteLine("The weekend");
break;
case DayOfWeek.Monday:
Console.WriteLine("The first day of the work week.");
break;
case DayOfWeek.Friday:
Console.WriteLine("The last day of the work week.");
break;
default:
Console.WriteLine("The middle of the work week.");
break;
}
}
}
// The example displays output like the following:
// The middle of the work week.

Aşağıdaki örnek, bir otomatik kahve makinesine benzetim yapan bir konsol uygulamasında kullanıcı
girişini işlemek için sabit bir model kullanır.
using System;

class Example
{
static void Main()
{
Console.WriteLine("Coffee sizes: 1=small 2=medium 3=large");
Console.Write("Please enter your selection: ");
string str = Console.ReadLine();
int cost = 0;

// Because of the goto statements in cases 2 and 3, the base cost of 25


// cents is added to the additional cost for the medium and large sizes.
switch (str)
{
case "1":
case "small":
cost += 25;
break;
case "2":
case "medium":
cost += 25;
goto case "1";
case "3":
case "large":
cost += 50;
goto case "1";
default:
Console.WriteLine("Invalid selection. Please select 1, 2, or 3.");
break;
}
if (cost != 0)
{
Console.WriteLine("Please insert {0} cents.", cost);
}
Console.WriteLine("Thank you for your business.");
}
}
// The example displays output like the following:
// Coffee sizes: 1=small 2=medium 3=large
// Please enter your selection: 2
// Please insert 50 cents.
// Thank you for your business.

Tür stili
Tür stili, kısa tür değerlendirmesi ve dönüştürmeyi mümkün bir şekilde sunar. Model eşleştirmeyi
gerçekleştirmek için switch ifadesiyle birlikte kullanıldığında, bir ifadenin belirtilen bir türe
dönüştürülüp dönüştürülmeyeceğini ve olup olmadığını test eder. Sözdizimi şöyledir:

case type varname

Burada tür , Expr 'nin sonucunun dönüştürülecek türün adı ve varname , eşleşme başarılı olursa ifadenin
sonucunun dönüştürüldüğü nesnedir. İfadenin derleme zamanı türü, 7,1 ile C# başlayan genel bir tür
parametresi olabilir.
Aşağıdakilerden biri doğruysa case ifadesi true :
Expr , türüile aynı türde bir örneğidir.
Expr türündentüretilen bir türün örneğidir. Diğer bir deyişle, ifadenin sonucu türündebir örneğe
eklenebilir.
ifadenin türünde birtemel sınıf olan bir derleme zamanı türü vardır ve Expr türü veya türünden
türetilmişbir çalışma zamanı türü vardır. Bir değişkenin derleme zamanı türü , tür bildiriminde
tanımlanan değişkenin türüdür. Bir değişkenin çalışma zamanı türü , bu değişkene atanan örneğin
türüdür.
Expr , tür arabirimini uygulayan bir türün örneğidir.
Case ifadesi true ise, varname kesinlikle atanır ve yalnızca switch bölümü içinde yerel kapsama sahiptir.
null bir türle eşleşmediğini unutmayın. Bir null eşleştirmek için aşağıdaki case etiketini kullanın:

case null:

Aşağıdaki örnek, çeşitli türlerdeki koleksiyon türleri hakkında bilgi sağlamak için tür modelini kullanır.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

class Example
{
static void Main(string[] args)
{
int[] values = { 2, 4, 6, 8, 10 };
ShowCollectionInformation(values);

var names = new List<string>();


names.AddRange( new string[] { "Adam", "Abigail", "Bertrand", "Bridgette" } );
ShowCollectionInformation(names);

List<int> numbers = null;


ShowCollectionInformation(numbers);
}

private static void ShowCollectionInformation(object coll)


{
switch (coll)
{
case Array arr:
Console.WriteLine($"An array with {arr.Length} elements.");
break;
case IEnumerable<int> ieInt:
Console.WriteLine($"Average: {ieInt.Average(s => s)}");
break;
case IList list:
Console.WriteLine($"{list.Count} items");
break;
case IEnumerable ie:
string result = "";
foreach (var e in ie)
result += "${e} ";
Console.WriteLine(result);
break;
case null:
// Do nothing for a null.
break;
default:
Console.WriteLine($"A instance of type {coll.GetType().Name}");
break;
}
}
}
// The example displays the following output:
// An array with 5 elements.
// 4 items

object yerine, aşağıdaki kodda gösterildiği gibi koleksiyonun türünü tür parametresi olarak kullanarak
genel bir yöntem yapabilirsiniz:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

class Example
{
static void Main(string[] args)
{
int[] values = { 2, 4, 6, 8, 10 };
ShowCollectionInformation(values);

var names = new List<string>();


names.AddRange( new string[] { "Adam", "Abigail", "Bertrand", "Bridgette" } );
ShowCollectionInformation(names);

List<int> numbers = null;


ShowCollectionInformation(numbers);
}

private static void ShowCollectionInformation<T>(T coll)


{
switch (coll)
{
case Array arr:
Console.WriteLine($"An array with {arr.Length} elements.");
break;
case IEnumerable<int> ieInt:
Console.WriteLine($"Average: {ieInt.Average(s => s)}");
break;
case IList list:
Console.WriteLine($"{list.Count} items");
break;
case IEnumerable ie:
string result = "";
foreach (var e in ie)
result += "${e} ";
Console.WriteLine(result);
break;
case object o:
Console.WriteLine($"A instance of type {o.GetType().Name}");
break;
default:
Console.WriteLine("Null passed to this method.");
break;
}
}
}
// The example displays the following output:
// An array with 5 elements.
// 4 items
// Null passed to this method.

Genel sürüm, ilk örnekten iki şekilde farklıdır. İlk olarak null örneğini kullanamazsınız. Derleyici
herhangi bir rastgele tür T object dışında herhangi bir türe dönüştüremediğinden herhangi bir sabit
durumu kullanamazsınız. default durumu artık null olmayan bir object sınar. Diğer bir deyişle,
default durum testleri yalnızca null için geçerlidir.

Model eşleştirmesi olmadan bu kod aşağıdaki gibi yazılabilir. Tür deseninin kullanımı, bir dönüştürmenin
sonucunun null olup olmadığını test etme veya yinelenen yayınlar gerçekleştirme gereksinimini
ortadan kaldırarak daha kompakt, okunabilir kod üretir.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

class Example
{
static void Main(string[] args)
{
int[] values = { 2, 4, 6, 8, 10 };
ShowCollectionInformation(values);

var names = new List<string>();


names.AddRange( new string[] { "Adam", "Abigail", "Bertrand", "Bridgette" } );
ShowCollectionInformation(names);

List<int> numbers = null;


ShowCollectionInformation(numbers);
}

private static void ShowCollectionInformation(object coll)


{
if (coll is Array) {
Array arr = (Array) coll;
Console.WriteLine($"An array with {arr.Length} elements.");
}
else if (coll is IEnumerable<int>) {
IEnumerable<int> ieInt = (IEnumerable<int>) coll;
Console.WriteLine($"Average: {ieInt.Average(s => s)}");
}
else if (coll is IList) {
IList list = (IList) coll;
Console.WriteLine($"{list.Count} items");
}
else if (coll is IEnumerable) {
IEnumerable ie = (IEnumerable) coll;
string result = "";
foreach (var e in ie)
result += "${e} ";
Console.WriteLine(result);
}
else if (coll == null) {
// Do nothing.
}
else {
Console.WriteLine($"An instance of type {coll.GetType().Name}");
}
}
}
// The example displays the following output:
// An array with 5 elements.
// 4 items

case deyimi ve when yan tümcesini


7,0 ' C# den itibaren, Case deyimlerinin birbirini dışlanması gerektiğinden, Case ifadesinin true olarak
değerlendirilmesi için karşılanması gereken ek bir koşul belirtmek üzere bir when yan tümcesi
ekleyebilirsiniz. when yan tümcesi, Boolean değer döndüren herhangi bir ifade olabilir.
Aşağıdaki örnek, bir temel Shape sınıfını, Shape türetilen bir Rectangle sınıfını ve Rectangle türetilen bir
Square sınıfını tanımlar. ShowShapeInfo , Square bir nesne olarak örneği oluşturulmasa bile, eşit
uzunlukta ve genişliklerin Square olarak atanmış bir Rectangle nesnesine davrandığından emin olmak
için when yan tümcesini kullanır. Yöntemi, null bir nesne veya alanı sıfır olan bir şekil hakkında bilgi
görüntülemeyi denemez.

using System;

public abstract class Shape


{
public abstract double Area { get; }
public abstract double Circumference { get; }
}

public class Rectangle : Shape


{
public Rectangle(double length, double width)
{
Length = length;
Width = width;
}

public double Length { get; set; }


public double Width { get; set; }

public override double Area


{
get { return Math.Round(Length * Width,2); }
}

public override double Circumference


{
get { return (Length + Width) * 2; }
}
}

public class Square : Rectangle


{
public Square(double side) : base(side, side)
{
Side = side;
}

public double Side { get; set; }


}

public class Circle : Shape


{
public Circle(double radius)
{
Radius = radius;
}

public double Radius { get; set; }

public override double Circumference


{
get { return 2 * Math.PI * Radius; }
}

public override double Area


{
get { return Math.PI * Math.Pow(Radius, 2); }
}
}

public class Example


{
public static void Main()
{
Shape sh = null;
Shape[] shapes = { new Square(10), new Rectangle(5, 7),
Shape[] shapes = { new Square(10), new Rectangle(5, 7),
sh, new Square(0), new Rectangle(8, 8),
new Circle(3) };
foreach (var shape in shapes)
ShowShapeInfo(shape);
}

private static void ShowShapeInfo(Shape sh)


{
switch (sh)
{
// Note that this code never evaluates to true.
case Shape shape when shape == null:
Console.WriteLine($"An uninitialized shape (shape == null)");
break;
case null:
Console.WriteLine($"An uninitialized shape");
break;
case Shape shape when sh.Area == 0:
Console.WriteLine($"The shape: {sh.GetType().Name} with no dimensions");
break;
case Square sq when sh.Area > 0:
Console.WriteLine("Information about square:");
Console.WriteLine($" Length of a side: {sq.Side}");
Console.WriteLine($" Area: {sq.Area}");
break;
case Rectangle r when r.Length == r.Width && r.Area > 0:
Console.WriteLine("Information about square rectangle:");
Console.WriteLine($" Length of a side: {r.Length}");
Console.WriteLine($" Area: {r.Area}");
break;
case Rectangle r when sh.Area > 0:
Console.WriteLine("Information about rectangle:");
Console.WriteLine($" Dimensions: {r.Length} x {r.Width}");
Console.WriteLine($" Area: {r.Area}");
break;
case Shape shape when sh != null:
Console.WriteLine($"A {sh.GetType().Name} shape");
break;
default:
Console.WriteLine($"The {nameof(sh)} variable does not represent a Shape.");
break;
}
}
}
// The example displays the following output:
// Information about square:
// Length of a side: 10
// Area: 100
// Information about rectangle:
// Dimensions: 5 x 7
// Area: 35
// An uninitialized shape
// The shape: Square with no dimensions
// Information about square rectangle:
// Length of a side: 8
// Area: 64
// A Circle shape

Örnekteki bir Shape nesnesinin null yürütülüp yürütülmediğini test girişiminde bulunan when yan
tümcesinin olduğunu unutmayın. null için test edilecek doğru tür deseninin case null: .

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminde Switch ifadesine bakın. Dil belirtimi, C# sözdizimi ve kullanımı
için kesin bir kaynaktır.
Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
if-else
Desen Eşleştirme
do (C# Başvurusu)
29.11.2019 • 2 minutes to read • Edit Online

do deyimi, belirtilen bir Boole ifadesi true değerlendirirken bir deyimi veya bir deyim bloğunu yürütür. Bu
ifade döngünün her yürütülmesinden sonra değerlendirildiğinden, bir do-while döngüsü bir veya daha fazla
kez yürütülür. Bu, sıfır veya daha fazla kez yürütülen while döngüsünden farklıdır.
do bildiri bloğunun içindeki herhangi bir noktada Break ifadesini kullanarak döngünün dışına kesebilirsiniz.
Continue deyimini kullanarak while ifadesinin değerlendirmesine doğrudan ilerleyerek. İfade true olarak
değerlendirilirse, yürütme döngüdeki ilk deyimde devam eder. Aksi halde, yürütme döngüden sonraki ilk
ifadede devam eder.
Ayrıca, goto, Returnveya throw deyimleriyle bir do-while döngüsünden çıkabilirsiniz.

Örnek
Aşağıdaki örnek do deyimin kullanımını gösterir. Örnek kodu çalıştırmak için Çalıştır ' ı seçin. Bundan sonra
kodu değiştirip yeniden çalıştırabilirsiniz.

int n = 0;
do
{
Console.WriteLine(n);
n++;
} while (n < 5);

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin Do deyimin bölümüne bakın.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
while ekstresi
(C# başvuru) için
29.11.2019 • 4 minutes to read • Edit Online

for deyimi, belirtilen bir Boole ifadesi true değerlendirirken bir deyimi veya bir deyim bloğunu yürütür.
for bildiri bloğunun içindeki herhangi bir noktada, Break ifadesini kullanarak döngünün dışına bölebilir
veya Continue ifadesini kullanarak döngünün bir sonraki yinelemesine adım aktarabilirsiniz. Ayrıca, goto,
Returnveya throw deyimleriyle bir for döngüsünden çıkabilirsiniz.

for deyimin yapısı


for bildiri Başlatıcı, koşulve Yineleyici bölümlerini tanımlar:

for (initializer; condition; iterator)


body

Üç bölüm de isteğe bağlıdır. Döngünün gövdesi bir deyim ya da deyimler bloğu.


Aşağıdaki örnekte, tanımlı tüm bölümler ile for deyimleri gösterilmektedir:

for (int i = 0; i < 5; i++)


{
Console.WriteLine(i);
}

Başlatıcı bölümü
Başlatıcı bölümündeki deyimler, döngüyü girmeden önce yalnızca bir kez yürütülür. Başlatıcı bölümü
aşağıdakilerden biri olabilir:
Döngü dışından erişilemeyen bir yerel döngü değişkeninin bildirimi ve başlatılması.
Aşağıdaki listeden, virgülle ayrılmış olarak sıfır veya daha fazla deyim ifadesi:
atama ekstresi
bir yöntemin çağrılması
++i veya i++ gibi önek veya sonek artışı ifadesi
--i veya i-- gibi ön ek veya sonek azaltma ifadesi
New işlecini kullanarak bir nesne oluşturma
await ifadesi
Yukarıdaki örnekteki Başlatıcı bölümü, i yerel döngü değişkenini bildirir ve başlatır:

int i = 0

Koşul bölümü
Koşul bölümü varsa, bir Boolean ifadesi olmalıdır. Bu ifade, her döngü yinelemesinden önce değerlendirilir.
Koşul bölümü yoksa veya boole ifadesi true olarak değerlendirilirse, sonraki döngü yinelemesi yürütülür;
Aksi takdirde, döngüden çıkıldı.
Yukarıdaki örnekteki koşul bölümü, döngünün yerel döngü değişkeninin değerine göre sonlandırdığını
belirler:

i < 5

Yineleyici bölümü
Yineleyici bölümü, döngü gövdesinin her yinelemesinden sonra ne olacağını tanımlar. Yineleyici bölümü,
virgülle ayrılmış olarak aşağıdaki deyim ifadelerinden sıfır veya daha fazlasını içerir:
atama ekstresi
bir yöntemin çağrılması
++i veya i++ gibi önek veya sonek artışı ifadesi
--i veya i-- gibi ön ek veya sonek azaltma ifadesi
New işlecini kullanarak bir nesne oluşturma
await ifadesi
Yukarıdaki örnekteki Yineleyici bölümü, yerel döngü değişkenini artırır:

i++

Örnekler
Aşağıdaki örnek, for deyimin bölümlerinin birkaç daha az ortak kullanımını göstermektedir: Başlatıcı
bölümünde bir dış döngü değişkenine değer atama, hem Başlatıcı hem de Yineleyici içinde bir yöntemi
çağırma bölümler ve Yineleyici bölümünde iki değişkenin değerlerini değiştirme. Örnek kodu çalıştırmak
için Çalıştır ' ı seçin. Bundan sonra kodu değiştirip yeniden çalıştırabilirsiniz.

int i;
int j = 10;
for (i = 0, Console.WriteLine($"Start: i={i}, j={j}"); i < j; i++, j--, Console.WriteLine($"Step: i=
{i}, j={j}"))
{
// Body of the loop.
}

Aşağıdaki örnek sonsuz for döngüsünü tanımlar:

for ( ; ; )
{
// Body of the loop.
}

C# dili belirtimi
Daha fazla bilgi için bkz. C# dil belirtiminin for deyimleri bölümü.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
foreach, in
foreach, in (C# başvuru)
4.11.2019 • 4 minutes to read • Edit Online

foreach deyimi, System.Collections.IEnumerable veya System.Collections.Generic.IEnumerable<T>


arabirimini uygulayan tür örneğindeki her öğe için bir deyimi veya bir deyim bloğunu yürütür. foreach
deyimleri bu türlerle sınırlı değildir ve aşağıdaki koşullara uyan herhangi bir türün örneğine
uygulanabilir:
, dönüş türü Class, struct veya Interface türünde olan public parametresiz GetEnumerator yöntemine
sahiptir
GetEnumerator yönteminin dönüş türü, ortak Current özelliğine ve dönüş türü Booleanolan public
parametresiz MoveNext metoduna sahiptir.
7,3 ile C# başlayarak, numaralandırıcının Current özelliği bir Başvuru dönüş değeri döndürürse ( T
koleksiyon öğesinin türü olduğu ref T ), yineleme değişkenini ref veya ref readonly değiştiricisiyle
bildirebilirsiniz.
foreach bildiri bloğunun içindeki herhangi bir noktada, Break ifadesini kullanarak döngünün dışına
bölebilir veya Continue ifadesini kullanarak döngünün bir sonraki yinelemesine adım aktarabilirsiniz.
Ayrıca, goto, Returnveya throw deyimleriyle bir foreach döngüsünden çıkabilirsiniz.
foreach deyimin null uygulanmışsa bir NullReferenceException oluşturulur. foreach deyimin kaynak
koleksiyonu boşsa, foreach döngüsünün gövdesi yürütülmez ve atlanır.

Örnekler
NOTE
Bu makalede, C# örnekleri çalıştırmak Try.NET satır içi kod Çalıştırıcısı ve oyun alanı. Seçin çalıştırma bir
etkileşimli penceresinde bir örnek çalıştırmak için düğme. Kod yürüttükten sonra değiştirmek ve seçerek
değiştirilmiş kodu çalıştırmak çalıştırma yeniden. Değiştirilmiş ya da çalıştırmalarını etkileşimli pencerede kod ya
da derleme başarısız olursa, tüm C# Derleyici hata iletilerini etkileşimli pencere görüntüler.

Aşağıdaki örnek, IEnumerable<T> arabirimini uygulayan List<T> türünün bir örneği ile foreach
deyimin kullanımını gösterir:

var fibNumbers = new List<int> { 0, 1, 1, 2, 3, 5, 8, 13 };


int count = 0;
foreach (int element in fibNumbers)
{
count++;
Console.WriteLine($"Element #{count}: {element}");
}
Console.WriteLine($"Number of elements: {count}");

Sonraki örnek, hiçbir arabirim uygulamayan System.Span<T> türünün bir örneği ile foreach ifadesini
kullanır:
public class IterateSpanExample
{
public static void Main()
{
Span<int> numbers = new int[] { 3, 14, 15, 92, 6 };
foreach (int number in numbers)
{
Console.Write($"{number} ");
}
Console.WriteLine();
}
}

Aşağıdaki örnek, bir stackalloc dizisindeki her bir öğenin değerini ayarlamak için bir ref yineleme
değişkeni kullanır. ref readonly sürümü, tüm değerleri yazdırmak için koleksiyonu yineler. readonly
bildirimi örtük bir yerel değişken bildirimi kullanır. Örtük değişken bildirimleri ref veya ref readonly
bildirimleriyle birlikte kullanılabilir, böylece açıkça değişken bildirimleri bulunabilir.

public class ForeachRefExample


{
public static void Main()
{
Span<int> storage = stackalloc int[10];
int num = 0;
foreach (ref int item in storage)
{
item = num++;
}

foreach (ref readonly var item in storage)


{
Console.Write($"{item} ");
}
// Output:
// 0 1 2 3 4 5 6 7 8 9
}
}

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin foreach ifadesi bölümüne bakın.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
Dizilerle foreach kullanma
for deyimleri
while (C# Başvurusu)
29.11.2019 • 2 minutes to read • Edit Online

while deyimi, belirtilen bir Boole ifadesi true değerlendirirken bir deyimi veya bir deyim bloğunu yürütür. Bu
ifade döngünün her yürütmeden önce değerlendirildiğinden while döngüsü sıfır veya daha fazla kez
yürütülür. Bu, bir veya daha fazla kez yürütülen Do döngüsünden farklıdır.
while bildiri bloğunun içindeki herhangi bir noktada Break ifadesini kullanarak döngünün dışına kesebilirsiniz.
Continue deyimini kullanarak while ifadesinin değerlendirmesine doğrudan ilerleyerek. İfade true olarak
değerlendirilirse, yürütme döngüdeki ilk deyimde devam eder. Aksi halde, yürütme döngüden sonraki ilk
ifadede devam eder.
Ayrıca, goto, Returnveya throw deyimleriyle bir while döngüsünden çıkabilirsiniz.

Örnek
Aşağıdaki örnek while deyimin kullanımını gösterir. Örnek kodu çalıştırmak için Çalıştır ' ı seçin. Bundan
sonra kodu değiştirip yeniden çalıştırabilirsiniz.

int n = 0;
while (n < 5)
{
Console.WriteLine(n);
n++;
}

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin while ifadesinin bölümüne bakın.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
do ekstresi
Break (C# başvuru)
23.10.2019 • 3 minutes to read • Edit Online

@No__t-0 ifadesi, göründüğü en yakın kapsayan döngüyü veya Switch ifadesini sonlandırır. Denetim, varsa,
sonlandırılmış deyimden sonraki ifadeye geçirilir.

Örnek
Bu örnekte, koşullu ifade 1 ile 100 arasında bir sayı olması beklenen bir sayaç içerir; Ancak break ifadesinde,
döngü 4 saydıktan sonra sonlandırılır.

class BreakTest
{
static void Main()
{
for (int i = 1; i <= 100; i++)
{
if (i == 5)
{
break;
}
Console.WriteLine(i);
}

// Keep the console open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/*
Output:
1
2
3
4
*/

Örnek
Bu örnek, Switch ifadesinde break ' ın kullanımını gösterir.
class Switch
{
static void Main()
{
Console.Write("Enter your selection (1, 2, or 3): ");
string s = Console.ReadLine();
int n = Int32.Parse(s);

switch (n)
{
case 1:
Console.WriteLine("Current value is 1");
break;
case 2:
Console.WriteLine("Current value is 2");
break;
case 3:
Console.WriteLine("Current value is 3");
break;
default:
Console.WriteLine("Sorry, invalid selection.");
break;
}

// Keep the console open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/*
Sample Input: 1

Sample Output:
Enter your selection (1, 2, or 3): 1
Current value is 1
*/

@No__t-0 girdiyseniz, çıkış şöyle olur:

Enter your selection (1, 2, or 3): 4


Sorry, invalid selection.

Örnek
Bu örnekte, break , iç içe geçmiş bir döngüyü bölmek için kullanılır ve denetimin dıştaki döngüye dönmesini
sağlar. Denetim, iç içe Döngülerde yalnızca bir düzey yukarı döndürülür.
class BreakInNestedLoops
{
static void Main(string[] args)
{

int[] numbers = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
char[] letters = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' };

// Outer loop.
for (int i = 0; i < numbers.Length; i++)
{
Console.WriteLine($"num = {numbers[i]}");

// Inner loop.
for (int j = 0; j < letters.Length; j++)
{
if (j == i)
{
// Return control to outer loop.
break;
}
Console.Write($" {letters[j]} ");
}
Console.WriteLine();
}

// Keep the console open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}

/*
* Output:
num = 0

num = 1
a
num = 2
a b
num = 3
a b c
num = 4
a b c d
num = 5
a b c d e
num = 6
a b c d e f
num = 7
a b c d e f g
num = 8
a b c d e f g h
num = 9
a b c d e f g h i
*/

Örnek
Bu örnekte, break deyimleri yalnızca döngünün her yinelemesi sırasında geçerli dalı bölmek için kullanılır.
Döngünün kendisi, iç içe geçmiş anahtar ifadesine ait olan break örneklerinden etkilenmez.
class BreakFromSwitchInsideLoop
{
static void Main(string[] args)
{
// loop 1 to 3
for (int i = 1; i <= 3; i++)
{
switch(i)
{
case 1:
Console.WriteLine("Current value is 1");
break;
case 2:
Console.WriteLine("Current value is 2");
break;
case 3:
Console.WriteLine("Current value is 3");
break;
default:
Console.WriteLine("This shouldn't happen.");
break;
}
}

// Keep the console open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}

/*
* Output:
Current value is 1
Current value is 2
Current value is 3
*/

C#dil belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
C#Başvurunun
C#Programlama Kılavuzu
C#Lerimi
değiştirebilirsiniz
continue (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

İfadesi, denetimi içinde göründüğü while, do, for veya ForEach deyimlerinin bir sonraki yinelemesine geçirir.
continue

Örnek
Bu örnekte, bir sayaç 1 ile 10 arasında bir sayı olarak başlatılır. continue Deyimini ifadesiyle (i < 9) birlikte
kullanarak, for gövdenin sonu arasındaki continue deyimler atlanır.

class ContinueTest
{
static void Main()
{
for (int i = 1; i <= 10; i++)
{
if (i < 9)
{
continue;
}
Console.WriteLine(i);
}

// Keep the console open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/*
Output:
9
10
*/

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
break Deyimi
goto (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

goto Deyimi programın denetimini doğrudan etiketli bir deyime aktarır.


Yaygın goto belirli bir anahtar durumu etiket ya da varsayılan etiket, denetimin aktarmaktır bir switch
deyimi.
goto Deyimi, ayrıca iç içe döngüleri dışında almak kullanışlıdır.

Örnek
Aşağıdaki örneği kullanarak göstermektedir goto içinde bir geçiş deyimi.

class SwitchTest
{
static void Main()
{
Console.WriteLine("Coffee sizes: 1=Small 2=Medium 3=Large");
Console.Write("Please enter your selection: ");
string s = Console.ReadLine();
int n = int.Parse(s);
int cost = 0;
switch (n)
{
case 1:
cost += 25;
break;
case 2:
cost += 25;
goto case 1;
case 3:
cost += 50;
goto case 1;
default:
Console.WriteLine("Invalid selection.");
break;
}
if (cost != 0)
{
Console.WriteLine($"Please insert {cost} cents.");
}
Console.WriteLine("Thank you for your business.");

// Keep the console open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/*
Sample Input: 2

Sample Output:
Coffee sizes: 1=Small 2=Medium 3=Large
Please enter your selection: 2
Please insert 50 cents.
Thank you for your business.
*/
Örnek
Aşağıdaki örneği kullanarak göstermektedir goto iç içe döngüleri ayırmak için.

public class GotoTest1


{
static void Main()
{
int x = 200, y = 4;
int count = 0;
string[,] array = new string[x, y];

// Initialize the array.


for (int i = 0; i < x; i++)

for (int j = 0; j < y; j++)


array[i, j] = (++count).ToString();

// Read input.
Console.Write("Enter the number to search for: ");

// Input a string.
string myNumber = Console.ReadLine();

// Search.
for (int i = 0; i < x; i++)
{
for (int j = 0; j < y; j++)
{
if (array[i, j].Equals(myNumber))
{
goto Found;
}
}
}

Console.WriteLine($"The number {myNumber} was not found.");


goto Finish;

Found:
Console.WriteLine($"The number {myNumber} is found.");

Finish:
Console.WriteLine("End of search.");

// Keep the console open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/*
Sample Input: 44

Sample Output
Enter the number to search for: 44
The number 44 is found.
End of search.
*/

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.
Ayrıca bkz.
C# başvurusu
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
goto Deyimi (C++)
return (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

return Deyimi yöntemin hangi görüntülenir ve çağıran Metoda döndürür denetim yürütülmesini
sonlandırır. Ayrıca, isteğe bağlı bir değer de döndürebilir. Yöntem ise bir void türü return ifade
atlanabilir.
Return deyimi içinde ise bir try bloğu finally bloğu, varsa, yürütülecek önce denetimini çağıran
Metoda döndürür.

Örnek
Aşağıdaki örnekte, yöntem CalculateArea() yerel değişkeni döndürür area olarak bir double değeri.

class ReturnTest
{
static double CalculateArea(int r)
{
double area = r * r * Math.PI;
return area;
}

static void Main()


{
int radius = 5;
double result = CalculateArea(radius);
Console.WriteLine("The area is {0:0.00}", result);

// Keep the console open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
// Output: The area is 78.54

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
C# başvurusu
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
return Deyimi
throw (C# Başvurusu)
31.10.2019 • 4 minutes to read • Edit Online

Programın yürütülmesi sırasında bir özel durumun oluşumunu bildirir.

Açıklamalar
throw sözdizimi şöyledir:

throw [e];

Burada e System.Exceptiontüretilen bir sınıfın örneğidir. Aşağıdaki örnek, GetNumber adlı bir metoda
geçirilen bağımsız değişken iç dizinin geçerli bir dizinine karşılık gelmiyorsa, bir IndexOutOfRangeException
oluşturmak için throw ifadesini kullanır.

using System;

public class NumberGenerator


{
int[] numbers = { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };

public int GetNumber(int index)


{
if (index < 0 || index >= numbers.Length) {
throw new IndexOutOfRangeException();
}
return numbers[index];
}
}

Yöntem çağıranları, sonra oluşturulan özel durumu işlemek için bir try-catch veya try-catch-finally
bloğu kullanır. Aşağıdaki örnek, GetNumber metodu tarafından oluşturulan özel durumu işler.

using System;

public class Example


{
public static void Main()
{
var gen = new NumberGenerator();
int index = 10;
try {
int value = gen.GetNumber(index);
Console.WriteLine($"Retrieved {value}");
}
catch (IndexOutOfRangeException e)
{
Console.WriteLine($"{e.GetType().Name}: {index} is outside the bounds of the array");
}
}
}
// The example displays the following output:
// IndexOutOfRangeException: 10 is outside the bounds of the array
Özel durum yeniden oluşturuluyor
throw , bir catch bloğunda işlenen bir özel durumu yeniden oluşturmak için bir catch bloğunda de
kullanılabilir. Bu durumda, throw bir özel durum işleneni almaz. Bir yöntem çağıran bir bağımsız değişkende
diğer bir kitaplık yöntemine geçtiğinde ve kitaplık yöntemi çağırana geçirilmesi gereken bir özel durum
oluşturduğunda, en çok yararlı olur. Örneğin, aşağıdaki örnek, başlatılmamış bir dizenin ilk karakterini
almaya çalışırken oluşturulan bir NullReferenceException yeniden oluşturur.

using System;

public class Sentence


{
public Sentence(string s)
{
Value = s;
}

public string Value { get; set; }

public char GetFirstCharacter()


{
try {
return Value[0];
}
catch (NullReferenceException e) {
throw;
}
}
}

public class Example


{
public static void Main()
{
var s = new Sentence(null);
Console.WriteLine($"The first character is {s.GetFirstCharacter()}");
}
}
// The example displays the following output:
// Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an
object.
// at Sentence.GetFirstCharacter()
// at Example.Main()

IMPORTANT
Çağırana geçirdiğiniz yeni bir özel durum oluşturmak için bir catch bloğunda throw e sözdizimini de
kullanabilirsiniz. Bu durumda, StackTrace özelliğinden erişilebilen özgün özel durumun yığın izlemesi korunmaz.

throw ifadesi
7,0 ile C# başlayarak, throw bir deyim ve deyim olarak kullanılabilir. Bu, daha önce desteklenmeyen
bağlamlarda bir özel durumun oluşturulmasına olanak sağlar. Bu güncelleştirmeler şunlardır:
koşullu işleç. Aşağıdaki örnek, bir yöntem boş bir dize dizisi geçirtiyse bir ArgumentException
oluşturmak için throw ifadesini kullanır. 7,0 C# ' den önce, bu mantığın bir if / else ifadesinde
görünmesi gerekir.
private static void DisplayFirstNumber(string[] args)
{
string arg = args.Length >= 1 ? args[0] :
throw new ArgumentException("You must supply an argument");
if (Int64.TryParse(arg, out var number))
Console.WriteLine($"You entered {number:F0}");
else
Console.WriteLine($"{arg} is not a number.");

null birleşim işleci. Aşağıdaki örnekte, bir Name özelliğine atanan dize null bir özel durum
oluşturmak için null birleşim işleci ile bir throw ifadesi kullanılır.

public string Name


{
get => name;
set => name = value ??
throw new ArgumentNullException(paramName: nameof(value), message: "Name cannot be null");
}

ifade-Bodied lambda veya yöntem. Aşağıdaki örnek, bir DateTime değerine dönüştürme
desteklenmediğinden bir InvalidCastException oluşturan ifade-Bodied yöntemini gösterir.

DateTime ToDateTime(IFormatProvider provider) =>


throw new InvalidCastException("Conversion to a DateTime is not supported.");

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
try-catch
C# Anahtar Sözcükleri
Nasıl yapılır: Açıkça Özel Durumlar Oluşturma
try-catch (C# Başvurusu)
23.10.2019 • 13 minutes to read • Edit Online

Try-catch deyimleri, farklı özel durumlar try için işleyiciler belirten bir veya daha catch fazla yan tümce
tarafından izlenen bir bloğundan oluşur.
Bir özel durum oluştuğunda, ortak dil çalışma zamanı (CLR ) bu özel durumu işleyen catch ifadeye bakar.
Şu anda yürütülmekte olan yöntem böyle bir catch blok içermiyorsa, clr geçerli yöntemi çağıran yönteme
bakar ve bu şekilde çağrı yığınını alır. Hiçbir catch blok bulunamazsa, clr kullanıcıya işlenmeyen bir özel
durum iletisi görüntüler ve programın yürütülmesini engeller.
try Blok, özel duruma neden olabilecek korunan kodu içerir. Bir özel durum oluşturuluncaya veya
başarıyla tamamlanana kadar blok yürütülür. Örneğin, bir null nesneyi atama girişimi şu
NullReferenceException özel durumu oluşturur:

object o2 = null;
try
{
int i2 = (int)o2; // Error
}

catch Yan tümcesi herhangi bir tür özel durum yakalamak için bağımsız değişken olmadan
kullanılabilmesine rağmen, bu kullanım önerilmez. Genel olarak, yalnızca kurtarmayı bildiğiniz özel
durumları yakamalısınız. Bu nedenle, her zaman ' dan System.Exception türetilmiş bir nesne bağımsız
değişkeni belirtmeniz gerekir:

catch (InvalidCastException e)
{
}

Aynı try-catch deyimi içinde birden çok özel catch yan tümce kullanmak mümkündür. Bu durumda, yan
tümceler sırasıyla catch catch incelenmediği için yan tümcelerinin sırası önemlidir. Daha az özel
durumları daha az spesifik olanlardan önce yakalayın. Daha sonraki bir bloba ulaşılmaması için catch
bloklarını sıralarsanız derleyici bir hata oluşturur.
Bağımsız catch değişkenlerin kullanılması, işlemek istediğiniz özel durumları filtrelemek için bir yoldur.
Ayrıca, işleme karar vermek için özel durumu daha ayrıntılı bir şekilde inceleyen bir özel durum filtresi de
kullanabilirsiniz. Özel durum filtresi false döndürürse, işleyici araması devam eder.

catch (ArgumentException e) when (e.ParamName == "…")


{
}

Özel durum filtreleri yakalamak ve yeniden oluşturmak tercih edilir (aşağıda açıklanmıştır) çünkü filtreler
yığından ayrılmaz. Daha sonraki bir işleyici yığının dökümünü alıyorsa, özel durumun ilk olarak
oluşturulduğu son yerde değil, ilk olarak nereden geldiğini görebilirsiniz. Özel durum filtre ifadelerinin
yaygın kullanımı günlüğe kaydedilir. Her zaman bir günlüğe çıkış yapan yanlış değeri döndüren bir filtre
oluşturabilirsiniz, bunları işlemek ve yeniden oluşturmak zorunda kalmadan, özel durumları bu şekilde
günlüğe kaydedebilirsiniz.
Throw deyimleri, catch catch ifadesiyle yakalanan özel durumu yeniden oluşturmak için bir blokta
kullanılabilir. Aşağıdaki örnek, bir IOException özel durumdan kaynak bilgilerini ayıklar ve ardından ana
yöntemin özel durumunu oluşturur.

catch (FileNotFoundException e)
{
// FileNotFoundExceptions are handled here.
}
catch (IOException e)
{
// Extract some information from this exception, and then
// throw it to the parent method.
if (e.Source != null)
Console.WriteLine("IOException source: {0}", e.Source);
throw;
}

Bir özel durumu yakalayabilir ve farklı bir özel durum oluşturabilirsiniz. Bunu yaptığınızda, aşağıdaki
örnekte gösterildiği gibi, iç özel durum olarak yakalandığı özel durumu belirtin.

catch (InvalidCastException e)
{
// Perform some action here, and then throw a new exception.
throw new YourCustomException("Put your error message here.", e);
}

Ayrıca, aşağıdaki örnekte gösterildiği gibi, belirli bir koşul true olduğunda bir özel durumu yeniden
oluşturabilirsiniz.

catch (InvalidCastException e)
{
if (e.Data == null)
{
throw;
}
else
{
// Take some action.
}
}

NOTE
Benzer bir sonucu genellikle temizleyici bir şekilde (Bu belgede daha önce açıklandığı gibi, yığın değiştirilmeyen) almak
için bir özel durum filtresi kullanmak da mümkündür. Aşağıdaki örnekte, bir önceki örnek olarak çağıranlar için benzer
bir davranış vardır. İşlevi, InvalidCastException e.Data olduğundaçağırana geri dönerek atar. null

catch (InvalidCastException e) when (e.Data != null)


{
// Take some action.
}

Bir try bloğun içinden yalnızca içinde belirtilen değişkenleri başlatın. Aksi takdirde, bloğun yürütülmesi
tamamlanmadan önce bir özel durum ortaya çıkabilir. Örneğin, aşağıdaki kod örneğinde değişken n try
blok içinde başlatılır. Bu değişkeni try Write(n) ifadesinde bloğunun dışında kullanma girişimi bir
derleyici hatası oluşturur.
static void Main()
{
int n;
try
{
// Do not initialize this variable here.
n = 123;
}
catch
{
}
// Error: Use of unassigned local variable 'n'.
Console.Write(n);
}

Catch hakkında daha fazla bilgi için bkz. try-catch-finally.

Zaman uyumsuz yöntemlerde özel durumlar


Zaman uyumsuz bir yöntem, zaman uyumsuz bir değiştirici tarafından işaretlenir ve genellikle bir veya
daha fazla await ifadesi ya da deyimi içerir. Await ifadesi bir veya Task<TResult>' a Task await işlecini
uygular.
Denetim zaman uyumsuz yöntemde await bir ulaştığında, beklenen görev tamamlanana kadar
yöntemindeki ilerleme askıya alınır. Görev tamamlandığında, yürütme yöntemi içinde çalışmaya çalışabilir.
Daha fazla bilgi için bkz. Async ve await ile zaman uyumsuz programlama ve zaman uyumsuz
programlarda denetim akışı.
Uygulanan tamamlanan görev await , görevi döndüren yöntemdeki işlenmeyen bir özel durum nedeniyle
hatalı bir durumda olabilir. Görevin bekleniyor bir özel durum oluşturur. Aynı zamanda, döndüren zaman
uyumsuz işlem iptal edilirse, bir görev iptal edilmiş durumda da bitebilirler. İptal edilen bir görevin
bekleniyor bir OperationCanceledException oluşturur. Zaman uyumsuz bir işlemi iptal etme hakkında daha
fazla bilgi için bkz. zaman uyumsuz uygulamanızda Ince ayar yapma.
Özel durumu yakalamak için, görevi bir try blokta bekleve özel durumu ilişkili catch blokta yakalayacak.
Örneğin, zaman uyumsuz yöntem örneği bölümüne bakın.
Beklenen zaman uyumsuz yöntemde birden çok özel durum oluştuğundan, görev hatalı durumda olabilir.
Örneğin, görev bir çağrısının Task.WhenAllsonucu olabilir. Böyle bir görevi bekleyettiğinizde, özel
durumların yalnızca biri yakalanacaktır ve hangi özel durumun yakalanıp yakalanmayacak olduğunu
tahmin edemeyecektir. Bir örnek için, Task. WhenAll örnek bölümüne bakın.

Örnek
Aşağıdaki örnekte, try blok bir özel duruma neden olabilecek ProcessString metoda bir çağrı içerir.
catch Yan tümcesi yalnızca ekranda bir ileti görüntüleyen özel durum işleyicisini içerir. İfade içinden
MyMethod çağrıldığında, sistem, catch ifadeyi arar ve iletiyi Exception caught görüntüler. throw
class TryFinallyTest
{
static void ProcessString(string s)
{
if (s == null)
{
throw new ArgumentNullException();
}
}

static void Main()


{
string s = null; // For demonstration purposes.

try
{
ProcessString(s);
}
catch (Exception e)
{
Console.WriteLine("{0} Exception caught.", e);
}
}
}
/*
Output:
System.ArgumentNullException: Value cannot be null.
at TryFinallyTest.Main() Exception caught.
* */

İki catch bloğu örneği


Aşağıdaki örnekte, iki catch bloğu kullanılır ve ilk olarak gelen en özel durum yakalanmalıdır.
En az özel durumu yakalamak için, içindeki ProcessString throw ifadesini aşağıdaki deyimle
değiştirebilirsiniz:. throw new Exception()
Örneğe en az özel catch bloğunu yerleştirirseniz, aşağıdaki hata iletisi görüntülenir:
A previous catch clause already catches all exceptions of this or a super type ('System.Exception') .
class ThrowTest3
{
static void ProcessString(string s)
{
if (s == null)
{
throw new ArgumentNullException();
}
}

static void Main()


{
try
{
string s = null;
ProcessString(s);
}
// Most specific:
catch (ArgumentNullException e)
{
Console.WriteLine("{0} First exception caught.", e);
}
// Least specific:
catch (Exception e)
{
Console.WriteLine("{0} Second exception caught.", e);
}
}
}
/*
Output:
System.ArgumentNullException: Value cannot be null.
at Test.ThrowTest3.ProcessString(String s) ... First exception caught.
*/

Async yöntemi örneği


Aşağıdaki örnek, zaman uyumsuz metotlar için özel durum işlemeyi gösterir. Zaman uyumsuz bir görevin
aldığı bir özel durumu yakalamak için, await ifadeyi bir try blok içine yerleştirin ve özel durumu bir
catch blokta yakalayın.

Özel durum işlemeyi göstermek için örnekteki satırınaçıklamasınıkaldırın. throw new Exception Görevin
IsFaulted özelliği olarak True ayarlanır, görevin Exception.InnerException özelliği özel duruma ayarlanır
ve özel durum catch bloğunda yakalanır.
Zaman uyumsuz bir işlemi iptal ettiğinizde ne olacağını göstermek için çizgininaçıklamasınıkaldırın.
throw new OperationCanceledException Görevin IsCanceled özelliği olarak true ayarlanır ve catch özel
durum bloğunda yakalanır. Bu örnek için geçerli olmayan bazı koşullar IsFaulted altında, görevin özelliği
olarak true ayarlanır ve IsCanceled olarak false ayarlanır.
public async Task DoSomethingAsync()
{
Task<string> theTask = DelayAsync();

try
{
string result = await theTask;
Debug.WriteLine("Result: " + result);
}
catch (Exception ex)
{
Debug.WriteLine("Exception Message: " + ex.Message);
}
Debug.WriteLine("Task IsCanceled: " + theTask.IsCanceled);
Debug.WriteLine("Task IsFaulted: " + theTask.IsFaulted);
if (theTask.Exception != null)
{
Debug.WriteLine("Task Exception Message: "
+ theTask.Exception.Message);
Debug.WriteLine("Task Inner Exception Message: "
+ theTask.Exception.InnerException.Message);
}
}

private async Task<string> DelayAsync()


{
await Task.Delay(100);

// Uncomment each of the following lines to


// demonstrate exception handling.

//throw new OperationCanceledException("canceled");


//throw new Exception("Something happened.");
return "Done";
}

// Output when no exception is thrown in the awaited method:


// Result: Done
// Task IsCanceled: False
// Task IsFaulted: False

// Output when an Exception is thrown in the awaited method:


// Exception Message: Something happened.
// Task IsCanceled: False
// Task IsFaulted: True
// Task Exception Message: One or more errors occurred.
// Task Inner Exception Message: Something happened.

// Output when a OperationCanceledException or TaskCanceledException


// is thrown in the awaited method:
// Exception Message: canceled
// Task IsCanceled: True
// Task IsFaulted: False

Task. WhenAll örneği


Aşağıdaki örnekte, birden çok görevin birden çok özel durum ile sonuçlanbildiği özel durum işleme
gösterilmektedir. Blok try ,Task.WhenAllçağrısı tarafından döndürülen görevi bekler. Bu görev, WhenAll
'un uygulandığı üç görev tamamlandığında tamamlanmıştır.
Üç görevin her biri özel duruma neden olur. Blok, Exception.InnerExceptions
tarafındanTask.WhenAlldöndürülen görevin özelliğinde bulunan özel durumlar boyunca yinelenir. catch
public async Task DoMultipleAsync()
{
Task theTask1 = ExcAsync(info: "First Task");
Task theTask2 = ExcAsync(info: "Second Task");
Task theTask3 = ExcAsync(info: "Third Task");

Task allTasks = Task.WhenAll(theTask1, theTask2, theTask3);

try
{
await allTasks;
}
catch (Exception ex)
{
Debug.WriteLine("Exception: " + ex.Message);
Debug.WriteLine("Task IsFaulted: " + allTasks.IsFaulted);
foreach (var inEx in allTasks.Exception.InnerExceptions)
{
Debug.WriteLine("Task Inner Exception: " + inEx.Message);
}
}
}

private async Task ExcAsync(string info)


{
await Task.Delay(100);

throw new Exception("Error-" + info);


}

// Output:
// Exception: Error-First Task
// Task IsFaulted: True
// Task Inner Exception: Error-First Task
// Task Inner Exception: Error-Second Task
// Task Inner Exception: Error-Third Task

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin TRY deyimin bölümüne bakın.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
try, throw ve catch Deyimleri (C++)
throw
try-finally
Nasıl yapılır: Özel durumları açık olarak oluştur
try-finally (C# Başvurusu)
23.10.2019 • 4 minutes to read • Edit Online

Bir finally blok kullanarak, bir TRY bloğunda ayrılan tüm kaynakları temizleyebilir ve bir try özel durum
bloğunda meydana gelirse bile kodu çalıştırabilirsiniz. Genellikle, denetim bir finally try deyiminden
ayrıldığında blok deyimleri çalışır. Denetimin aktarımı normal yürütme,, break , veya continue goto return
bildiriminin yürütülmesi ya da deyimdenbirözeldurumunyayılmasındankaynaklanıyorolabilir. try
İşlenmiş bir özel durum içinde, ilişkili finally bloğun çalıştırılması garanti edilir. Ancak, özel durum
işlenmemiş ise, finally bloğun yürütülmesi özel durum geriye doğru tetikleme işleminin tetiklendiği duruma
bağlıdır. Bu da, bilgisayarınızın nasıl ayarlanmayacağına bağlıdır.
Genellikle, işlenmeyen bir özel durum uygulamayı sona erdirdiğinde, finally bloğun çalıştırılıp
çalıştırılmayacağı önemli değildir. Ancak, bu durumda bile çalıştırılması gereken bir finally blokta deyimler
varsa, bir çözüm finally ifadeye bir catch blok try - eklemektir. Alternatif olarak, çağrı yığınının try üst
kısmında yer alan bir try - finally deyimin bloğunda ortaya atılmış olabilecek özel durumu
yakalayabilirsiniz. Diğer bir deyişle, bir yöntemi, try finally ifadeyi içeren - yöntemi veya bu yöntemi
çağıran yöntemi ya da çağrı yığınında herhangi bir yöntemi çağıran yöntemini yakalayabilirsiniz. Özel durum
yakalanmadığında, finally bloğun yürütülmesi işletim sisteminin özel durum geriye doğru izleme işlemi
tetiklemeyi seçip seçmediğine bağlıdır.

Örnek
Aşağıdaki örnekte, geçersiz bir dönüştürme açıklaması System.InvalidCastException özel duruma neden olur.
Özel durum işlenmemiş olur.
public class ThrowTestA
{
static void Main()
{
int i = 123;
string s = "Some string";
object obj = s;

try
{
// Invalid conversion; obj contains a string, not a numeric type.
i = (int)obj;

// The following statement is not run.


Console.WriteLine("WriteLine at the end of the try block.");
}
finally
{
// To run the program in Visual Studio, type CTRL+F5. Then
// click Cancel in the error dialog.
Console.WriteLine("\nExecution of the finally block after an unhandled\n" +
"error depends on how the exception unwind operation is triggered.");
Console.WriteLine("i = {0}", i);
}
}
// Output:
// Unhandled Exception: System.InvalidCastException: Specified cast is not valid.
//
// Execution of the finally block after an unhandled
// error depends on how the exception unwind operation is triggered.
// i = 123
}

Aşağıdaki örnekte, TryCast yöntem içindeki bir özel durum, çağrı yığınının ardından bir yöntemde yakalanır.
public class ThrowTestB
{
static void Main()
{
try
{
// TryCast produces an unhandled exception.
TryCast();
}
catch (Exception ex)
{
// Catch the exception that is unhandled in TryCast.
Console.WriteLine
("Catching the {0} exception triggers the finally block.",
ex.GetType());

// Restore the original unhandled exception. You might not


// know what exception to expect, or how to handle it, so pass
// it on.
throw;
}
}

public static void TryCast()


{
int i = 123;
string s = "Some string";
object obj = s;

try
{
// Invalid conversion; obj contains a string, not a numeric type.
i = (int)obj;

// The following statement is not run.


Console.WriteLine("WriteLine at the end of the try block.");
}
finally
{
// Report that the finally block is run, and show that the value of
// i has not been changed.
Console.WriteLine("\nIn the finally block in TryCast, i = {0}.\n", i);
}
}
// Output:
// In the finally block in TryCast, i = 123.

// Catching the System.InvalidCastException exception triggers the finally block.

// Unhandled Exception: System.InvalidCastException: Specified cast is not valid.


}

Hakkında finally daha fazla bilgi için bkz. try-catch-finally.


C#Ayrıca, uygun bir sözdiziminde nesneler için IDisposable benzer işlevler sağlayan using ifadesinide içerir.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin TRY deyimin bölümüne bakın.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
try, throw ve catch Deyimleri (C++)
throw
try-catch
Nasıl yapılır: Özel durumları açık olarak oluştur
try-catch-finally (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

catch Ve finally catch birlikte ortak kullanımı, bir blokta kaynak almak ve kullanmak, bir bloktaki
try
olağanüstü koşullara uğramak ve bloktaki kaynakları serbest bırakmektir. finally
Özel durumları yeniden oluşturma hakkında daha fazla bilgi ve örnek için bkz. try-catch ve özel durum atma.
finally Blok hakkında daha fazla bilgi için bkz. try-finally.

Örnek
public class EHClass
{
void ReadFile(int index)
{
// To run this code, substitute a valid path from your local machine
string path = @"c:\users\public\test.txt";
System.IO.StreamReader file = new System.IO.StreamReader(path);
char[] buffer = new char[10];
try
{
file.ReadBlock(buffer, index, buffer.Length);
}
catch (System.IO.IOException e)
{
Console.WriteLine("Error reading from {0}. Message = {1}", path, e.Message);
}

finally
{
if (file != null)
{
file.Close();
}
}
// Do something with buffer...
}

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin TRY deyimin bölümüne bakın.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
try, throw ve catch Deyimleri (C++)
throw
Nasıl yapılır: Özel durumları açık olarak oluştur
using Deyimi
Checked ve Unchecked (C# Başvurusu)
24.10.2019 • 2 minutes to read • Edit Online

C#deyimler işaretli veya işaretlenmemiş bağlamda çalıştırılabilir. Denetlenen bir bağlamda aritmetik taşma bir
özel durum oluşturur. İşaretlenmemiş bir bağlamda aritmetik taşma yok sayılır ve hedef türüne uymayan yüksek
sıralı bitleri atarak sonuç kesilir.
denetlenen Denetlenen bağlamı belirtin.
işaretlenmemiş İşaretlenmeyen bağlamı belirtin.
Aşağıdaki işlemler taşma denetimini etkiler:
Tamsayı türlerinde aşağıdaki önceden tanımlanmış işleçleri kullanan ifadeler:
++ , -- , birli - , + , - , * , /

İntegral türleri arasında veya float ya da double bir integral türüne açık sayısal dönüştürmeler.
Ne checked ne de unchecked belirtilmemişse, sabit olmayan ifadeler (çalışma zamanında değerlendirilen
ifadeler) için varsayılan bağlam, -Checked derleyici seçeneğinin değeri tarafından tanımlanır. Varsayılan olarak,
bu seçeneğin değeri unset ve aritmetik işlemler işaretlenmemiş bir bağlamda yürütülür.
Sabit ifadeler (derleme sırasında tamamen değerlendirilebilecek ifadeler) için, varsayılan bağlam her zaman
denetlenir. Sabit bir ifade işaretsiz bir bağlam içine açıkça yerleştirilmediyse, ifadenin derleme zamanı
değerlendirmesi sırasında oluşan taşmalar derleme zamanı hatalarına neden olur.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
Deyim Anahtar Sözcükleri
checked (C# Başvurusu)
23.10.2019 • 3 minutes to read • Edit Online

Anahtar checked sözcüğü, tam sayı türü aritmetik işlemler ve dönüştürmeler için taşma denetimini açık bir
şekilde etkinleştirmek üzere kullanılır.
Varsayılan olarak, ifade hedef türü aralığının dışında bir değer üretirse yalnızca sabit değerler içeren bir ifade bir
derleyici hatasına neden olur. İfade bir veya daha fazla sabit olmayan değer içeriyorsa, derleyici taşmayı
algılamaz. Aşağıdaki örnekte öğesine i2 atanan ifadenin değerlendirilmesi, bir derleyici hatasına neden olmaz.

// The following example causes compiler error CS0220 because 2147483647


// is the maximum value for integers.
//int i1 = 2147483647 + 10;

// The following example, which includes variable ten, does not cause
// a compiler error.
int ten = 10;
int i2 = 2147483647 + ten;

// By default, the overflow in the previous statement also does


// not cause a run-time exception. The following line displays
// -2,147,483,639 as the sum of 2,147,483,647 and 10.
Console.WriteLine(i2);

Varsayılan olarak, bu sabit olmayan ifadeler çalışma zamanında taşma için denetlenmez ve taşma özel durumları
oluşturmaz. Önceki örnekte iki pozitif tamsayının toplamı olarak-2.147.483.639 görüntülenir.
Taşma denetimi derleyici seçenekleri, ortam yapılandırması veya checked anahtar sözcüğünün kullanımı ile
etkinleştirilebilir. Aşağıdaki örneklerde, çalışma zamanında önceki Sum tarafından checked üretilen taşmayı
checked algılamak için bir ifadenin veya bloğun nasıl kullanılacağı gösterilmektedir. Her iki örnek de bir taşma
özel durumu yükseltir.

// If the previous sum is attempted in a checked environment, an


// OverflowException error is raised.

// Checked expression.
Console.WriteLine(checked(2147483647 + ten));

// Checked block.
checked
{
int i3 = 2147483647 + ten;
Console.WriteLine(i3);
}

İşaretlenmemiş anahtar sözcük, taşma denetimini engellemek için kullanılabilir.

Örnek
Bu örnek, çalışma zamanında taşma checked denetimini etkinleştirmek için nasıl kullanılacağını gösterir.
class OverFlowTest
{
// Set maxIntValue to the maximum value for integers.
static int maxIntValue = 2147483647;

// Using a checked expression.


static int CheckedMethod()
{
int z = 0;
try
{
// The following line raises an exception because it is checked.
z = checked(maxIntValue + 10);
}
catch (System.OverflowException e)
{
// The following line displays information about the error.
Console.WriteLine("CHECKED and CAUGHT: " + e.ToString());
}
// The value of z is still 0.
return z;
}

// Using an unchecked expression.


static int UncheckedMethod()
{
int z = 0;
try
{
// The following calculation is unchecked and will not
// raise an exception.
z = maxIntValue + 10;
}
catch (System.OverflowException e)
{
// The following line will not be executed.
Console.WriteLine("UNCHECKED and CAUGHT: " + e.ToString());
}
// Because of the undetected overflow, the sum of 2147483647 + 10 is
// returned as -2147483639.
return z;
}

static void Main()


{
Console.WriteLine("\nCHECKED output value is: {0}",
CheckedMethod());
Console.WriteLine("UNCHECKED output value is: {0}",
UncheckedMethod());
}
/*
Output:
CHECKED and CAUGHT: System.OverflowException: Arithmetic operation resulted
in an overflow.
at ConsoleApplication1.OverFlowTest.CheckedMethod()

CHECKED output value is: 0


UNCHECKED output value is: -2147483639
*/
}

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.
Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
İşaretli ve İşaretsiz
unchecked
unchecked (C# Başvurusu)
23.10.2019 • 3 minutes to read • Edit Online

Anahtar unchecked sözcüğü, tamsayı türü aritmetik işlemler ve dönüştürmeler için taşma denetlemeyi gizlemek
için kullanılır.
İşaretlenmemiş bir bağlamda, bir ifade hedef türü aralığının dışında bir değer üretirse, taşma işaretlenir.
Örneğin, aşağıdaki örnekteki hesaplama bir unchecked blok veya ifadede gerçekleştirildiğinden, sonucun bir
tamsayı için çok büyük olması ve int1 -2.147.483.639 değeri atanır.

unchecked
{
int1 = 2147483647 + 10;
}
int1 = unchecked(ConstantMax + 10);

unchecked Ortam kaldırılırsa, bir derleme hatası oluşur. İfadenin tüm terimleri sabitler olduğundan, derleme
sırasında taşma tespit edilebilir.
Sabit olmayan terimleri içeren ifadeler, derleme zamanında ve çalışma zamanında varsayılan olarak işaretli
değildir. Denetlenen bir ortamı etkinleştirme hakkında bilgi için bkz. denetlenir .
Taşma için denetim zaman alacağından, hiçbir tehlike olmaması durumunda Denetlenmemiş kod kullanımı
performansı iyileştirebilir. Ancak, taşma olasılığa karşı, denetlenen bir ortam kullanılmalıdır.

Örnek
Bu örnek, unchecked anahtar sözcüğünün nasıl kullanılacağını gösterir.
class UncheckedDemo
{
static void Main(string[] args)
{
// int.MaxValue is 2,147,483,647.
const int ConstantMax = int.MaxValue;
int int1;
int int2;
int variableMax = 2147483647;

// The following statements are checked by default at compile time. They do not
// compile.
//int1 = 2147483647 + 10;
//int1 = ConstantMax + 10;

// To enable the assignments to int1 to compile and run, place them inside
// an unchecked block or expression. The following statements compile and
// run.
unchecked
{
int1 = 2147483647 + 10;
}
int1 = unchecked(ConstantMax + 10);

// The sum of 2,147,483,647 and 10 is displayed as -2,147,483,639.


Console.WriteLine(int1);

// The following statement is unchecked by default at compile time and run


// time because the expression contains the variable variableMax. It causes
// overflow but the overflow is not detected. The statement compiles and runs.
int2 = variableMax + 10;

// Again, the sum of 2,147,483,647 and 10 is displayed as -2,147,483,639.


Console.WriteLine(int2);

// To catch the overflow in the assignment to int2 at run time, put the
// declaration in a checked block or expression. The following
// statements compile but raise an overflow exception at run time.
checked
{
//int2 = variableMax + 10;
}
//int2 = checked(variableMax + 10);

// Unchecked sections frequently are used to break out of a checked


// environment in order to improve performance in a portion of code
// that is not expected to raise overflow exceptions.
checked
{
// Code that might cause overflow should be executed in a checked
// environment.
unchecked
{
// This section is appropriate for code that you are confident
// will not result in overflow, and for which performance is
// a priority.
}
// Additional checked code here.
}
}
}

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
İşaretli ve İşaretsiz
checked
fixed Deyimi (C# Başvurusu)
23.10.2019 • 5 minutes to read • Edit Online

fixed İfade, çöp toplayıcısının taşınabilir bir değişkenin yerini değiştirmesini engeller. Deyime yalnızca
güvenli olmayan bir bağlamda izin verilir. emniyetsiz fixed Sabit boyutlu arabellekleroluşturmak için fixed
anahtar sözcüğünü de kullanabilirsiniz.
fixed İfade, yönetilen bir değişkene bir işaretçi ayarlar ve deyimin yürütülmesi sırasında bu değişkene
"PIN" koyar. Taşınabilir olarak yönetilen değişkenlere yönelik işaretçiler yalnızca bir fixed bağlamda
yararlıdır. fixed Bağlam olmadan çöp toplama, değişkenleri tahmin edilmemiş şekilde yeniden
konumlandırmaya yönelik olabilir. C# Derleyici yalnızca bir fixed ifadede yönetilen değişkene bir işaretçi
atamanızı sağlar.

class Point
{
public int x;
public int y;
}

unsafe private static void ModifyFixedStorage()


{
// Variable pt is a managed variable, subject to garbage collection.
Point pt = new Point();

// Using fixed allows the address of pt members to be taken,


// and "pins" pt so that it is not relocated.

fixed (int* p = &pt.x)


{
*p = 1;
}
}

Bir diziyi, dizeyi, sabit boyutlu arabelleği veya bir değişkenin adresini kullanarak bir işaretçiyi başlatabilirsiniz.
Aşağıdaki örnek, değişken adreslerinin, dizilerin ve dizelerin kullanımını göstermektedir:

Point point = new Point();


double[] arr = { 0, 1.5, 2.3, 3.4, 4.0, 5.9 };
string str = "Hello World";

// The following two assignments are equivalent. Each assigns the address
// of the first element in array arr to pointer p.

// You can initialize a pointer by using an array.


fixed (double* p = arr) { /*...*/ }

// You can initialize a pointer by using the address of a variable.


fixed (double* p = &arr[0]) { /*...*/ }

// The following assignment initializes p by using a string.


fixed (char* p = str) { /*...*/ }

// The following assignment is not valid, because str[0] is a char,


// which is a value, not a variable.
//fixed (char* p = &str[0]) { /*...*/ }
7,3 ile C# başlayarak, fixed ifade diziler, dizeler, sabit boyutlu arabellekler veya yönetilmeyen değişkenlerin
ötesinde ek türler üzerinde çalışır. Adlı GetPinnableReference bir yöntemi uygulayan herhangi bir tür
sabitlenebilir. , GetPinnableReference Yönetilmeyen türdebir ref değişken döndürmelidir. .NET Core 2,0
System.Span<T> ' System.ReadOnlySpan<T> de sunulan .net türleri bu düzenin kullanımını ve sabitlenebilir.
Bu, aşağıdaki örnekte gösterilmiştir:

unsafe private static void FixedSpanExample()


{
int[] PascalsTriangle = {
1,
1, 1,
1, 2, 1,
1, 3, 3, 1,
1, 4, 6, 4, 1,
1, 5, 10, 10, 5, 1
};

Span<int> RowFive = new Span<int>(PascalsTriangle, 10, 5);

fixed (int* ptrToRow = RowFive)


{
// Sum the numbers 1,4,6,4,1
var sum = 0;
for (int i = 0; i < RowFive.Length; i++)
{
sum += *(ptrToRow + i);
}
Console.WriteLine(sum);
}
}

Bu modele katılması gereken türler oluşturuyorsanız, bu düzenin uygulanması örneği için bkz
Span<T>.GetPinnableReference() .
Aynı türde olan birden çok işaretçi tek bir bildirimde başlatılabilir:

fixed (byte* ps = srcarray, pd = dstarray) {...}

Farklı türlerin işaretçilerini başlatmak için aşağıdaki örnekte gösterildiği gibi fixed deyimlerini iç içe
geçirebilirsiniz.

fixed (int* p1 = &point.x)


{
fixed (double* p2 = &arr[5])
{
// Do something with p1 and p2.
}
}

Deyimdeki kod yürütüldükten sonra, sabitlenmiş değişkenler sabitlenir ve çöp toplamaya tabidir. Bu nedenle,
bu değişkenleri fixed deyimin dışında işaret etmez. fixed Bildiriminde belirtilen değişkenler, bu ifadeye
göre kapsamlandırılır ve daha kolay hale getirir:

fixed (byte* ps = srcarray, pd = dstarray)


{
...
}
// ps and pd are no longer in scope here.
fixed Deyimlerde başlatılan işaretçiler salt okunur değişkenlerdir. İşaretçi değerini değiştirmek istiyorsanız,
ikinci bir işaretçi değişkeni bildirmeniz ve bunu değiştirmeniz gerekir. fixed İfadede belirtilen değişken
değiştirilemez:

fixed (byte* ps = srcarray, pd = dstarray)


{
byte* pSourceCopy = ps;
pSourceCopy++; // point to the next element.
ps++; // invalid: cannot modify ps, as it is declared in the fixed statement.
}

Yığın üzerinde bellek ayırabilirsiniz, burada çöp toplamaya tabi değildir ve bu nedenle sabitlenmiş olması
gerekmez. Bunu yapmak için stackalloc işlecinikullanın.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin fixed deyimin bölümüne bakın.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
unsafe
İşaretçi türleri
Sabit Boyutlu Arabellekler
Lock deyimleri (C# başvuru)
23.10.2019 • 3 minutes to read • Edit Online

lock İfade, belirli bir nesne için karşılıklı dışlama kilidi alır, bir ekstre bloğunu yürütür ve sonra kilidi serbest
bırakır. Kilit tutulurken, kilidi tutan iş parçacığı kilidi yeniden alabilir ve serbest bırakabilir. Diğer herhangi bir iş
parçacığının kilidi almak engellenir ve kilit serbest bırakılana kadar bekler.
lock İfade şu biçimdedir

lock (x)
{
// Your code...
}

, başvuru türünün bir ifadesidir. x Tam olarak eşdeğerdir

object __lockObj = x;
bool __lockWasTaken = false;
try
{
System.Threading.Monitor.Enter(__lockObj, ref __lockWasTaken);
// Your code...
}
finally
{
if (__lockWasTaken) System.Threading.Monitor.Exit(__lockObj);
}

Kod bir TRY kullandığından... finally bloğu, bir lock deyimin gövdesinde özel durum oluşturulursa bile kilit
serbest bırakılır.
Bir lock deyimin gövdesinde await işlecini kullanamazsınız.

Açıklamalar
İş parçacığı erişimini paylaşılan bir kaynağa eşitlediğinizde, ayrılmış bir nesne örneği üzerinde (örneğin,
private readonly object balanceLock = new object(); ) veya kodun ilişkisiz parçaları tarafından kilit nesnesi
olarak kullanılması olası bir örnek üzerinde kilit. Farklı paylaşılan kaynaklar için aynı kilit nesnesi örneğini
kullanmaktan kaçının, çünkü kilitlenme veya kilitleme çekişmesine yol açabilir. Özellikle, Lock nesneleri olarak
aşağıdakileri kullanmaktan kaçının:
this , çünkü çağıranlar bir kilit olarak kullanılıyor olabilir.
Typeörnekler, typeof işleci veya Reflection tarafından elde edilebilir.
dize sabit değerleri de dahil olmak üzere dize örnekleri birbirinebağlı olabilir.

Örnek
Aşağıdaki örnek, adanmış Account balanceLock bir örnek üzerinde kilitleyerek özel balance alanına erişimi
eşitleyen bir sınıfı tanımlar. Kilitleme için aynı örneği kullanmak, balance alanın aynı anda Debit veya Credit
yöntemlerini çağırmaya çalışan iki iş parçacığı tarafından aynı anda güncelleştirilememesini sağlar.

using System;
using System.Threading.Tasks;
using System.Threading.Tasks;

public class Account


{
private readonly object balanceLock = new object();
private decimal balance;

public Account(decimal initialBalance)


{
balance = initialBalance;
}

public decimal Debit(decimal amount)


{
lock (balanceLock)
{
if (balance >= amount)
{
Console.WriteLine($"Balance before debit :{balance, 5}");
Console.WriteLine($"Amount to remove :{amount, 5}");
balance = balance - amount;
Console.WriteLine($"Balance after debit :{balance, 5}");
return amount;
}
else
{
return 0;
}
}
}

public void Credit(decimal amount)


{
lock (balanceLock)
{
Console.WriteLine($"Balance before credit:{balance, 5}");
Console.WriteLine($"Amount to add :{amount, 5}");
balance = balance + amount;
Console.WriteLine($"Balance after credit :{balance, 5}");
}
}
}

class AccountTest
{
static void Main()
{
var account = new Account(1000);
var tasks = new Task[100];
for (int i = 0; i < tasks.Length; i++)
{
tasks[i] = Task.Run(() => RandomlyUpdate(account));
}
Task.WaitAll(tasks);
}

static void RandomlyUpdate(Account account)


{
var rnd = new Random();
for (int i = 0; i < 10; i++)
{
var amount = rnd.Next(1, 100);
bool doCredit = rnd.NextDouble() < 0.5;
if (doCredit)
{
account.Credit(amount);
}
else
{
account.Debit(amount);
}
}
}
}

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin kilit bildirimi bölümüne bakın.

Ayrıca bkz.
System.Threading.Monitor
System.Threading.SpinLock
System.Threading.Interlocked
C#başvurunun
C# anahtar sözcükleri
Eşitleme temelleri 'ne genel bakış
Yöntem Parametreleri (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

İçinde, ref veya Outolmadan bir yöntem için belirtilen parametreler, çağrılan yönteme değere göre geçirilir. Bu
değer yönteminde değiştirilebilir, ancak denetim çağıran yordama geri geçtiğinde değiştirilen değer korunmaz. Bir
yöntem parametresi anahtar sözcüğü kullanarak bu davranışı değiştirebilirsiniz.
Bu bölümde, yöntem parametrelerini bildirirken kullanabileceğiniz anahtar sözcükler açıklanmaktadır:
params , bu parametrenin değişken sayıda bağımsız değişken götüreolabileceğini belirtir.
' de bu parametrenin başvuruya göre geçtiğini ancak çağrılan yöntemin yalnızca okuduğunuzu belirtir.
ref bu parametrenin başvuruya göre geçtiğini ve çağrılan yöntem tarafından okunabilir veya yazılabilir
olabileceğini belirtir.
Out bu parametrenin başvuruya göre geçtiğini ve çağrılan yöntem tarafından yazıldığını belirtir.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
params (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

Kullanarak params belirtebileceğiniz anahtar sözcüğü, bir yöntem parametresi , değişken sayıda bağımsız
değişken alır.
Parametre bildiriminde belirtilen türde bağımsız değişkenleri dizisini belirtilen türdeki bağımsız değişkenlerin
virgülle ayrılmış bir liste gönderebilirsiniz. Ayrıca, herhangi bir bağımsız değişken gönderebilirsiniz. Hiçbir
bağımsız değişken uzunluğu gönderirseniz params sıfır listesidir.
Ek parametre sonra izin verilen params anahtar sözcüğü bir yöntem bildiriminde ve tek params anahtar sözcüğü
bir metodun bildiriminde izin verilir.
Bildirilen türü params parametresi, aşağıdaki örnekte gösterildiği gibi bir tek boyutlu bir dizi olmalıdır. Aksi halde
bir derleyici hatası CS0225 gerçekleşir.

Örnek
Aşağıdaki örnek, bağımsız değişkenleri göndermenin çeşitli yollarını gösterir bir params parametresi.
public class MyClass
{
public static void UseParams(params int[] list)
{
for (int i = 0; i < list.Length; i++)
{
Console.Write(list[i] + " ");
}
Console.WriteLine();
}

public static void UseParams2(params object[] list)


{
for (int i = 0; i < list.Length; i++)
{
Console.Write(list[i] + " ");
}
Console.WriteLine();
}

static void Main()


{
// You can send a comma-separated list of arguments of the
// specified type.
UseParams(1, 2, 3, 4);
UseParams2(1, 'a', "test");

// A params parameter accepts zero or more arguments.


// The following calling statement displays only a blank line.
UseParams2();

// An array argument can be passed, as long as the array


// type matches the parameter type of the method being called.
int[] myIntArray = { 5, 6, 7, 8, 9 };
UseParams(myIntArray);

object[] myObjArray = { 2, 'b', "test", "again" };


UseParams2(myObjArray);

// The following call causes a compiler error because the object


// array cannot be converted into an integer array.
//UseParams(myObjArray);

// The following call does not cause an error, but the entire
// integer array becomes the first element of the params array.
UseParams2(myIntArray);
}
}
/*
Output:
1 2 3 4
1 a test

5 6 7 8 9
2 b test again
System.Int32[]
*/

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir kaynaktır.

Ayrıca bkz.
C# başvurusu
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
Yöntem Parametreleri
parametre değiştiricisi (C# Başvurusu)
23.10.2019 • 8 minutes to read • Edit Online

in Anahtar sözcüğü, başvuruya göre geçirilecek bağımsız değişkenleri neden olur. Bir değişken olmalıdır
bağımsız değişkeni için bir diğer ad biçimsel parametre kolaylaştırır. Diğer bir deyişle, herhangi bir işlem
parametresinde bağımsız değişken üzerinde yapılır. Nasıl olduğunu ref veya kullanıma anahtar sözcükler,
tek farkı, in tarafından çağrılan yöntem bağımsız değişkenleri değiştirilemez. Oysa ref bağımsız
değişkenleri değiştirilebilir, out bağımsız değişkenleri çağrılan yöntem tarafından değiştirilmelidir ve
arama bağlamda observable söz konusu değişiklikler şunlardır.

int readonlyArgument = 44;


InArgExample(readonlyArgument);
Console.WriteLine(readonlyArgument); // value is still 44

void InArgExample(in int number)


{
// Uncomment the following line to see error CS8331
//number = 19;
}

Yukarıdaki örnekte gösteren in değiştiricisi gereksiz genellikle çağıran sitede. Ayrıca, yöntem
bildiriminde yalnızca gereklidir.

NOTE
in Anahtar sözcüğü de kullanılabilir bir genel tür parametresi tür parametresi değişken karşıtı, kapsamında
olduğunu belirtmek için bir foreach deyimi veya bir parçası olarak bir join bir LINQ sorgu yan tümcesi.
Kullanımı hakkında daha fazla bilgi için in anahtar sözcüğü şu bağlamlarda bkz içinde, bu kullanan tüm bağlantılar
sağlar.

Değişkenleri olarak geçirildi in bağımsız değişken bir yöntem çağrısında iletilmeden önce başlatılması
gerekir. Ancak, çağrılan yöntem olmayan bir değer atamak veya bağımsız değişkenini değiştirin.
in Parametre değiştiricisi kullanılabilir C# 7.2 ve üzeri. Derleyici Hatası önceki sürümlerini oluşturmak
CS8107 ("özelliği 'salt okunur başvurular' kullanılabilir değil C# 7.0. Lütfen dil 7.2 veya üzeri bir sürümü
kullanın.") Derleyici dil sürüm yapılandırmak için bkz seçin C# dil sürümü.
in , ref , Ve out anahtar sözcükleri aşırı yükleme çözünürlüğü amacıyla yöntem imzasının parçası
dikkate alınmaz. Tek fark, bir yöntem aldığını ise, bu nedenle, yöntemler aşırı yüklenemez bir ref veya
in bağımsız değişkeni ve diğer alır bir out bağımsız değişken. Örneğin, aşağıdaki kod derlemeyecektir:

class CS0663_Example
{
// Compiler error CS0663: "Cannot define overloaded
// methods that differ only on in, ref and out".
public void SampleMethod(in int i) { }
public void SampleMethod(ref int i) { }
}

Aşırı yükleme varlığını temel alarak in izin verilir:


class InOverloads
{
public void SampleMethod(in int i) { }
public void SampleMethod(int i) { }
}

Aşırı yükleme çözünürlüğü kuralları


Değer yöntemleriyle aşırı yükleme çözünürlüğü kurallarını anlamak in hacktivism anlama tarafından
bağımsız değişkenleri in bağımsız değişkenler. Yöntemlerini kullanarak tanımlama in parametreleri
olan bir olası performans iyileştirme. Bazı struct tür bağımsız değişkenleri boyutu büyük ve yöntemler
sıkı döngüler veya kritik kod yollarını çağrıldığında, bu yapıları kopyalama maliyeti önemlidir. Yöntemi in
çağrılan yöntem bağımsız durumunu değiştirmez çünkü bağımsız değişkenleri başvuruya göre güvenle
geçirilebilir olduğunu belirtmek için parametreleri. Bu bağımsız değişkenleri başvuruya göre geçirme
(büyük olasılıkla) pahalı kopyalama önler.
Belirtme in çağrıda bağımsız değişkenler için site genellikle isteğe bağlıdır. Bağımsız değişkenler değere
göre geçirme ve başvuru kullanarak geçirme arasındaki semantik farklılığı yok in değiştiricisi. in
Değiştiricisi çağrı sitesinde olduğundan isteğe bağlı bağımsız değişkenin değeri değiştirilebilir belirtmek
gerekmez. Açıkça eklemeniz in değiştirici bağımsız değişken emin olmak için çağrı sitesinde başvuruya
göre değil değere göre geçirilir. Kullanarak açıkça in aşağıdaki iki etkisi olur:
İlk olarak belirterek in çağrısı site eşleşen ile tanımlanan bir yöntem seçmek için derleyicinin zorlar in
parametresi. Aksi takdirde iki yöntem yalnızca içinde varken, farklı olduğunda in , değere göre aşırı daha
iyi bir eşleşmedir.
İkinci olarak, belirtme in başvuruya göre bağımsız değişken geçmek için amacınız bildirir. İle kullanılan
bağımsız değişkenine in doğrudan başvurulabilen bir konumu temsil etmelidir. Aynı genel kurallar için
out ve ref bağımsız değişkenleri: Sabitler, sıradan özellikleri veya değerler üreten diğer ifadeler
kullanamazsınız. Aksi takdirde, atlama in çağrısı salt okunur başvuru yöntemi olarak geçirmek için geçici
bir değişken oluşturmak için sağlayacak site derleyici bildirir. Derleyici ile birkaç kısıtlamaları, geçici bir
değişken oluşturur in bağımsız değişkenleri:
Derleme zamanı sabiti olarak geçici bir değişkene izin verir in parametreleri.
Özellikleri veya diğer ifadeler için geçici değişken sağlayan in parametreleri.
Geçici bir değişken bağımsız değişkenleri sağlayan bir bağımsız değişken türü arasında örtük dönüşüm
için parametre türü olduğu.
Tüm önceki örneklerde, derleyici sabiti, özelliği veya başka bir ifadenin değerini depolayan geçici bir
değişken oluşturur.
Aşağıdaki kod bu kuralları gösterir:
static void Method(in int argument)
{
// implementation removed
}

Method(5); // OK, temporary variable created.


Method(5L); // CS1503: no implicit conversion from long to int
short s = 0;
Method(s); // OK, temporary int created with the value 0
Method(in s); // CS1503: cannot convert from in short to in int
int i = 42;
Method(i); // passed by readonly reference
Method(in i); // passed by readonly reference, explicitly using `in`

Şimdi, değer değişkenleriyle kullanarak başka bir yöntem yoktu varsayalım. Sonuçları, aşağıdaki kodda
gösterildiği gibi değiştirin:

static void Method(int argument)


{
// implementation removed
}

static void Method(in int argument)


{
// implementation removed
}

Method(5); // Calls overload passed by value


Method(5L); // CS1503: no implicit conversion from long to int
short s = 0;
Method(s); // Calls overload passed by value.
Method(in s); // CS1503: cannot convert from in short to in int
int i = 42;
Method(i); // Calls overload passed by value
Method(in i); // passed by readonly reference, explicitly using `in`

Yalnızca yöntem çağrısında bağımsız değişkenini başvuruya göre geçirildiği son sunucudur.

NOTE
Önceki kod int kolaylık olması için bağımsız değişken türü olarak. Çünkü int başvurusundan daha büyük olan
en modern makineler'de, tek bir geçirme için hiçbir avantajı yoktur int salt okunur başvuru olarak.

Sınırlamalar in parametreleri
Kullanamazsınız in , ref , ve out yöntemleri aşağıdaki türde için anahtar sözcükler:
Kullanarak tanımladığınız zaman uyumsuz yöntemlerde zaman uyumsuz değiştiricisi.
Yineleyici yöntemleri dahil bir yield return veya yield break deyimi.

C# Dil Belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
C# başvurusu
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
Yöntem Parametreleri
Güvenli verimli kod yazma
ref (C# Başvurusu)
23.10.2019 • 15 minutes to read • Edit Online

Anahtar ref sözcüğü, başvuruya göre geçirilen bir değeri gösterir. Dört farklı bağlamda kullanılır:
Bir yöntem imzasında ve bir yöntem çağrısında, bir bağımsız değişkeni başvuruya göre bir
yönteme geçirmek için. Daha fazla bilgi için bkz. bir bağımsız değişkeni başvuruya göre geçirme.
Bir yöntem imzasında, çağıran öğesine başvuruya göre bir değer döndürün. Daha fazla bilgi için
bkz. Başvuru dönüş değerleri.
Bir üye gövdesinde, bir başvuru dönüş değerinin, çağıranın değiştirme amaçladığı bir başvuru
olarak yerel olarak depolandığını belirtmek için, yerel bir değişken başvuruya göre başka bir
değere erişir. Daha fazla bilgi için bkz. ref Yereller.
Bir veya ' i struct ref struct bildirmek için bir bildirimde. readonly ref struct Daha fazla bilgi
için bkz. ref struct Types.

Bir bağımsız değişkeni başvuruya göre geçirme


Bir yöntemin parametre listesinde kullanıldığında, ref anahtar sözcüğü bir bağımsız değişkenin
değere göre değil başvuruya göre geçtiğini gösterir. ref Anahtar sözcüğü, bir değişken olması
gereken bağımsız değişken için biçimsel parametreye bir diğer ad getirir. Diğer bir deyişle,
parametresindeki tüm işlemler bağımsız değişkende yapılır. Örneğin, çağıran bir yerel değişken
ifadesi veya bir dizi öğesi erişim ifadesi geçirirse ve çağrılan yöntem Ref parametresinin başvurduğu
nesnenin yerini alırsa, bu durumda çağıranın yerel değişkeni veya Array öğesi artık yeni nesnesine
başvurur Yöntemi döndürür.

NOTE
Başvuru türü kavramıyla başvuruya göre geçirme kavramını karıştırmayın. İki kavram aynı değildir. Bir yöntem
parametresi, bir değer türü ref veya bir başvuru türü olmasına bakılmaksızın değiştirilebilir. Başvuru ile
geçirildiğinde bir değer türünün kutulenmesi yoktur.

Bir ref parametre kullanmak için, aşağıdaki örnekte gösterildiği gibi yöntem tanımı ve çağırma
yöntemi ref anahtar sözcüğünü açıkça kullanmalıdır.

void Method(ref int refArgument)


{
refArgument = refArgument + 44;
}

int number = 1;
Method(ref number);
Console.WriteLine(number);
// Output: 45

Bir ref veya in parametresine geçirilen bir bağımsız değişken geçirilmeden önce başlatılmalıdır. Bu,
bağımsız değişkenlerin geçirilmeden önce açıkça başlatılmış olması gereken Out parametrelerinden
farklıdır.
Bir sınıfın üyelerinin yalnızca, ref in , veya out ile farklı imzaları olamaz. Bir türün ref iki üyesi
arasındaki tek fark, bir parametre içeriyorsa ve diğeri out veya in parametresi varsa bir derleyici
hatası oluşur. Aşağıdaki kod, örneğin derlenmiyor.

class CS0663_Example
{
// Compiler error CS0663: "Cannot define overloaded
// methods that differ only on ref and out".
public void SampleMethod(out int i) { }
public void SampleMethod(ref int i) { }
}

Ancak, bir yöntem bir ref , in veya out parametresi olduğunda ve diğeri bir değer parametresine
sahip olduğunda, aşağıdaki örnekte gösterildiği gibi yöntemler aşırı yüklenebilir.

class RefOverloadExample
{
public void SampleMethod(int i) { }
public void SampleMethod(ref int i) { }
}

İmza eşleştirmesi gerektiren diğer durumlarda,,, ve,, ve ' ı in gizleme ref veya geçersiz out kılma,,,
ve birbirini eşleştirmeyin.
Özellikler değişken değildir. Bunlar yöntemlerdir ve ref parametrelere geçirilemez.
Aşağıdaki tür yöntemler için ref , in ve out anahtar sözcüklerini kullanamazsınız:
Zaman uyumsuz değiştirici kullanarak tanımladığınız zaman uyumsuz yöntemler.
Bir yield return veya yield break bildiri içeren Yineleyici yöntemleri.

Bir bağımsız değişkeni başvuruya göre geçirme: Örnek


Önceki örneklerde değer türleri başvuruya göre geçer. Başvuru türlerini başvuruya göre geçirmek
ref için anahtar sözcüğünü de kullanabilirsiniz. Başvuru türü başvuruya göre geçirilme yöntemi,
çağrılan yöntemin, başvuru parametresinin çağırıcının başvurduğu nesneyi değiştirmesini sağlar.
Nesnenin depolama konumu, başvuru parametresi değeri olarak yöntemine geçirilir. Parametresinin
depolama konumundaki değeri değiştirirseniz (yeni bir nesneyi işaret etmek için), çağıranın
başvurduğu depolama konumunu da değiştirirsiniz. Aşağıdaki örnek, bir başvuru türünün örneğini
bir ref parametre olarak geçirir.
class Product
{
public Product(string name, int newID)
{
ItemName = name;
ItemID = newID;
}

public string ItemName { get; set; }


public int ItemID { get; set; }
}

private static void ChangeByReference(ref Product itemRef)


{
// Change the address that is stored in the itemRef parameter.
itemRef = new Product("Stapler", 99999);

// You can change the value of one of the properties of


// itemRef. The change happens to item in Main as well.
itemRef.ItemID = 12345;
}

private static void ModifyProductsByReference()


{
// Declare an instance of Product and display its initial values.
Product item = new Product("Fasteners", 54321);
System.Console.WriteLine("Original values in Main. Name: {0}, ID: {1}\n",
item.ItemName, item.ItemID);

// Pass the product instance to ChangeByReference.


ChangeByReference(ref item);
System.Console.WriteLine("Back in Main. Name: {0}, ID: {1}\n",
item.ItemName, item.ItemID);
}

// This method displays the following output:


// Original values in Main. Name: Fasteners, ID: 54321
// Back in Main. Name: Stapler, ID: 12345

Başvuru türlerini değere ve başvuruya göre geçirme hakkında daha fazla bilgi için bkz. başvuru türü
parametrelerini geçirme.

Başvuru dönüş değerleri


Başvuru dönüş değerleri (veya ref dönüşler), bir yöntemin çağırana başvuruya göre döndürdüğü
değerlerdir. Diğer bir deyişle, çağıran bir yöntem tarafından döndürülen değeri değiştirebilir ve bu
değişiklik yöntemi içeren nesnenin durumunda yansıtılır.
Bir başvuru dönüş değeri ref anahtar sözcüğü kullanılarak tanımlanır:
Metot imzasında. Örneğin, aşağıdaki yöntem imzası, GetCurrentPrice yöntemin başvuruya göre
bir Decimal değer döndürdüğünü gösterir.

public ref decimal GetCurrentPrice()

Belirteç ve yöntemin içindeki bir return ifadede döndürülen değişken. return Örneğin:

return ref DecimalArray[0];


Çağıranın nesnenin durumunu değiştirmesi için, başvuru dönüş değeri açıkça bir ref yerelolarak
tanımlanmış bir değişkene depolanmalıdır.
Çağrılan yöntem, değeri başvuruya göre döndürmek ref readonly için dönüş değerini de bildirebilir
ve çağıran kodun döndürülen değeri değiştiremeyeceğini zorunlu kılabilir. Çağırma yöntemi, değeri
yerel bir ref salt okunur değişkeninde depolayarak döndürülen değerli değeri kopyalamayı önleyebilir.
Bir örnek için, bkz. bir başvuru dönüşleri ve ref Yereller örneği.

Başvuru yerelleri
Kullanılarak return ref döndürülen değerlere başvurmak için bir başvuru yerel değişkeni kullanılır.
Bir ref yerel değişkeni, ref olmayan bir dönüş değeri olarak başlatılamaz. Diğer bir deyişle,
başlatmanın sağ tarafı bir başvuru olmalıdır. Ref Local değerindeki tüm değişiklikler, metodu, yöntemi
başvuruya göre döndürülen nesnenin durumuna yansıtılır.
Değişken bildiriminden önce ref anahtar sözcüğünü kullanarak bir ref yerel tanımlayın ve değeri
başvuruya göre döndüren yönteme çağrıdan hemen önce.
Örneğin, aşağıdaki ifade adlı GetEstimatedValue bir yöntem tarafından döndürülen bir başvuru yerel
değeri tanımlar:

ref decimal estValue = ref Building.GetEstimatedValue();

Başvuruya göre bir değere aynı şekilde erişebilirsiniz. Bazı durumlarda, başvuruya göre değere
erişmek, potansiyel olarak pahalı bir kopyalama işlemini önleyerek performansı artırır. Örneğin,
aşağıdaki ifade bir değere başvurmak için kullanılan bir başvuru yerel değerini nasıl tanımlayacağınızı
gösterir.

ref VeryLargeStruct reflocal = ref veryLargeStruct;

Her iki örnekte ref anahtar sözcüğünün her iki yerde de kullanılması gerektiğini veya derleyicinin
hata CS8172 hata yaratmadığını, "bir değere sahip bir başvuru değişkeni başlatamıyor."
7,3 ile C# başlayarak, foreach deyimin yineleme değişkeni ref yerel veya ref ReadOnly yerel
değişken olabilir. Daha fazla bilgi için foreach ifadesi makalesine bakın.

Ref ReadOnly Yereller


Ref salt okunur yerel değeri, imzası ve kullanımları ref readonly return ref olan yöntem veya
özellik tarafından döndürülen değerleri ifade etmek için kullanılır. Değişken, ref yerel bir değişkenin
özelliklerini bir readonly değişkenle birleştirir: Bu, atandığı depolamanın diğer adıdır ve
değiştirilemez. ref readonly

Bir ref, ve ref Yereller örneği döndürür


Aşağıdaki Book örnek, String Title ve ikialanıolanbirsınıfıtanımlar. Author Ayrıca, BookCollection
Book özel nesne dizisi içeren bir sınıfı tanımlar. Bağımsız kitap nesneleri, GetBookByTitle yöntemi
çağırarak başvuruya göre döndürülür.
public class Book
{
public string Author;
public string Title;
}

public class BookCollection


{
private Book[] books = { new Book { Title = "Call of the Wild, The", Author = "Jack London"
},
new Book { Title = "Tale of Two Cities, A", Author = "Charles Dickens" }
};
private Book nobook = null;

public ref Book GetBookByTitle(string title)


{
for (int ctr = 0; ctr < books.Length; ctr++)
{
if (title == books[ctr].Title)
return ref books[ctr];
}
return ref nobook;
}

public void ListBooks()


{
foreach (var book in books)
{
Console.WriteLine($"{book.Title}, by {book.Author}");
}
Console.WriteLine();
}
}

Çağıran, GetBookByTitle yöntem tarafından döndürülen değeri bir ref yerel olarak depoladığında,
çağıranın dönüş değeri için yaptığı değişiklikler, aşağıdaki örnekte gösterildiği gibi BookCollection
nesnesine yansıtılır.

var bc = new BookCollection();


bc.ListBooks();

ref var book = ref bc.GetBookByTitle("Call of the Wild, The");


if (book != null)
book = new Book { Title = "Republic, The", Author = "Plato" };
bc.ListBooks();
// The example displays the following output:
// Call of the Wild, The, by Jack London
// Tale of Two Cities, A, by Charles Dickens
//
// Republic, The, by Plato
// Tale of Two Cities, A, by Charles Dickens

Ref struct türleri


ref Bir struct bildirime değiştiricisini eklemek, bu türdeki örneklerin yığın olarak ayrılmış olması
gerektiğini tanımlar. Diğer bir deyişle, bu türlerin örnekleri başka bir sınıfın üyesi olarak yığın üzerinde
hiçbir şekilde oluşturulamaz. Bu özellik Span<T> için birincil mosyon ve ilgili yapılar.
Bir ref struct türü yığın olarak ayrılmış bir değişken olarak tutmanın hedefi, derleyicinin tüm
ref struct türler için uyguladığı çeşitli kurallar sunar.
Bir ref struct kutusu ekleyemezsiniz. Türü ref struct object , veya dynamic herhangi bir
arabirim türü değişkenine bir tür atayamazsınız.
ref struct türler arabirimleri uygulayamaz.
Bir ref struct sınıfın alan üyesi olarak veya normal bir yapının bildirimini yapamazsınız. Bu, bir
derleyici tarafından oluşturulan bir yedekleme alanı oluşturan otomatik uygulanan bir özellik
bildirimi içerir.
Zaman uyumsuz metotlarda ref struct türler olan yerel değişkenler bildiremezsiniz. Bunları,
Task Task<TResult> veya benzeritürlerdöndürenzamanuyumluyöntemlerlebildirebilirsiniz. Task
Yineleyiciler içinde ref struct yerel değişkenler bildiremezsiniz.
Lambda ifadelerinde veya ref struct yerel işlevlerde değişkenleri yakalayamazsınız.

Bu kısıtlamalar, yanlışlıkla bir ref struct ' i yönetilen yığına yükseltebilen bir şekilde kullanmamasını
sağlar.
Bir yapıyı olarak readonly ref tanımlamak için değiştiriciler birleştirebilirsiniz. , readonly ref struct
ref struct Ve bildirimlerinin readonly struct avantajlarını ve kısıtlamalarını birleştirir.

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin
bir kaynaktır.

Ayrıca bkz.
Güvenli verimli kod yazma
Ref dönüşler ve ref yerel ayarlar
Koşullu başvuru ifadesi
ref atama işleci
Parametreleri Geçirme
Yöntem Parametreleri
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
out parametresi değiştiricisi (C# Başvurusu)
23.10.2019 • 6 minutes to read • Edit Online

Anahtar out sözcüğü, bağımsız değişkenlerin başvuruya göre geçirilmesine neden olur. Bir değişken
olması gereken, biçimsel parametreye bağımsız değişken için bir diğer ad oluşturur. Diğer bir deyişle,
parametresindeki tüm işlemler bağımsız değişkende yapılır. Ref anahtar sözcüğüne benzer, ancak bu
ref , değişkeninin geçirilmeden önce başlatılması gerekir. Aynı zamanda ın anahtar sözcüğüne benzer,
ancak in çağrılan yöntemin bağımsız değişken değerini değiştirmesine izin vermez. Bir out
parametre kullanmak için, hem yöntem tanımı hem de çağıran yöntemi, out anahtar sözcüğünü
açıkça kullanmalıdır. Örneğin:

int initializeInMethod;
OutArgExample(out initializeInMethod);
Console.WriteLine(initializeInMethod); // value is now 44

void OutArgExample(out int number)


{
number = 44;
}

NOTE
out Anahtar sözcüğü, tür parametresinin covaryant olduğunu belirtmek için genel bir tür parametresiyle de
kullanılabilir. out Anahtar sözcüğünün bu bağlamda kullanımı hakkında daha fazla bilgi için bkz. Out (genel
değiştirici).

Bağımsız değişken olarak out geçirilen değişkenlerin, yöntem çağrısında geçirilmeden önce
başlatılması gerekmez. Ancak, yöntemi döndürmadan önce bir değer atamak için çağrılan yöntem
gereklidir.
in , ref Ve anahtar out kelimeleri, aşırı yükleme çözümlemesi amacıyla yöntem imzasının bir parçası
olarak kabul edilmez. Bu nedenle, tek fark bir yöntemin bir ref veya in bağımsız değişken alırsa ve
diğeri bir out bağımsız değişken alırsa Yöntemler aşırı yüklenemez. Aşağıdaki kod, örneğin
derlenmeyecektir:

class CS0663_Example
{
// Compiler error CS0663: "Cannot define overloaded
// methods that differ only on ref and out".
public void SampleMethod(out int i) { }
public void SampleMethod(ref int i) { }
}

Ancak, bir yöntem bir ref , in veya out bağımsız değişkeni alırsa ve diğeri bu değiştiricilerin
hiçbirini içeriyorsa, bunun gibi aşırı yükleme geçerlidir:
class OutOverloadExample
{
public void SampleMethod(int i) { }
public void SampleMethod(out int i) => i = 5;
}

Derleyici, çağrı sitesindeki parametre değiştiricilerini Yöntem çağrısında kullanılan parametre


değiştiricilerine eşleyerek en iyi aşırı yüklemeyi seçer.
Özellikler değişken değildir ve bu nedenle parametre olarak out geçirilemez.
Aşağıdaki tür yöntemler için in , ref ve out anahtar sözcüklerini kullanamazsınız:
Zaman uyumsuz değiştirici kullanarak tanımladığınız zaman uyumsuz yöntemler.
Bir yield return veya yield break bildiri içeren Yineleyici yöntemleri.

Parametreleri out bildirme


out Bağımsız değişkenlerle bir yöntemi bildirmek, birden çok değer döndürmek için klasik bir geçici
çözümdür. 7,0 ' C# den başlayarak, benzer senaryolar için başlıkları göz önünde bulundurun. Aşağıdaki
örnek, tek out bir yöntem çağrısıyla üç değişken döndürmek için kullanır. Üçüncü bağımsız
değişkenin null 'a atandığını unutmayın. Bu, yöntemlerin değerleri isteğe bağlı olarak döndürmesini
sağlar.

void Method(out int answer, out string message, out string stillNull)
{
answer = 44;
message = "I've been returned";
stillNull = null;
}

int argNumber;
string argMessage, argDefault;
Method(out argNumber, out argMessage, out argDefault);
Console.WriteLine(argNumber);
Console.WriteLine(argMessage);
Console.WriteLine(argDefault == null);

// The example displays the following output:


// 44
// I've been returned
// True

out Bağımsız değişkenle bir yöntemi çağırma


C# 6 ve önceki sürümlerde, out bağımsız değişken olarak geçirmeden önce bir değişkeni ayrı bir
ifadede bildirmeniz gerekir. Aşağıdaki örnek, bir dizeyi bir sayıya number dönüştürmeyi deneyen Int32.
TryParse yöntemine geçirilmeden önce adlı bir değişken bildirir.
string numberAsString = "1640";

int number;
if (Int32.TryParse(numberAsString, out number))
Console.WriteLine($"Converted '{numberAsString}' to {number}");
else
Console.WriteLine($"Unable to convert '{numberAsString}'");
// The example displays the following output:
// Converted '1640' to 1640

C# 7,0 ' den başlayarak out değişkeni ayrı bir değişken bildiriminde değil, yöntem çağrısının bağımsız
değişken listesinde bildirebilirsiniz. Bu daha kompakt, okunabilir kod üretir ve ayrıca yöntem
çağrısından önce değişkene yanlışlıkla bir değer atamaktan de engel olur. Aşağıdaki örnek, number
Int32. TryParse yöntemine yapılan çağrıda değişkeni tanımladığından, önceki örneğe benzer.

string numberAsString = "1640";

if (Int32.TryParse(numberAsString, out int number))


Console.WriteLine($"Converted '{numberAsString}' to {number}");
else
Console.WriteLine($"Unable to convert '{numberAsString}'");
// The example displays the following output:
// Converted '1640' to 1640

Önceki örnekte, number değişken kesin olarak bir int olarak yazılır. Ayrıca, aşağıdaki örnekte olduğu
gibi örtük olarak yazılmış bir yerel değişken de bildirebilirsiniz.

string numberAsString = "1640";

if (Int32.TryParse(numberAsString, out var number))


Console.WriteLine($"Converted '{numberAsString}' to {number}");
else
Console.WriteLine($"Unable to convert '{numberAsString}'");
// The example displays the following output:
// Converted '1640' to 1640

C# Dil Belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
Yöntem Parametreleri
namespace (C# Başvurusu)
4.11.2019 • 2 minutes to read • Edit Online

namespaceanahtar sözcüğü, ilgili nesneler kümesini içeren bir kapsamı bildirmek için kullanılır. Kod öğelerini
düzenlemek ve genel benzersiz türler oluşturmak için bir ad alanı kullanabilirsiniz.

namespace SampleNamespace
{
class SampleClass { }

interface ISampleInterface { }

struct SampleStruct { }

enum SampleEnum { a, b }

delegate void SampleDelegate(int i);

namespace Nested
{
class SampleClass2 { }
}
}

Açıklamalar
Bir ad alanı içinde, aşağıdaki türlerden sıfır veya daha fazlasını bildirebilirsiniz:
başka bir ad alanı
class
interface
struct
enum
delegate
Bir C# kaynak dosyasında açıkça bir ad alanı bildirip bildirmeyeceğinizi belirtir, derleyici varsayılan bir ad alanı
ekler. Her zaman genel ad alanı olarak adlandırılan bu adlandırılmamış ad alanı her dosyada mevcuttur. Genel ad
alanındaki herhangi bir tanımlayıcı, adlandırılmış bir ad alanında kullanılmak üzere kullanılabilir.
Ad alanları örtük olarak ortak erişime sahiptir ve bu değiştirilebilir değildir. Bir ad alanındaki öğelere
atayabileceğiniz erişim değiştiricilerine ilişkin bir tartışma için bkz. erişim değiştiricileri.
İki veya daha fazla bildiriminde bir ad alanı tanımlamak mümkündür. Örneğin, aşağıdaki örnek, MyCompany ad
alanının parçası olarak iki sınıfı tanımlar:
namespace MyCompany.Proj1
{
class MyClass
{
}
}

namespace MyCompany.Proj1
{
class MyClass1
{
}
}

Örnek
Aşağıdaki örnek, iç içe bir ad alanında statik bir yöntemin nasıl çağrılacağını gösterir.

namespace SomeNameSpace
{
public class MyClass
{
static void Main()
{
Nested.NestedNameSpaceClass.SayHello();
}
}

// a nested namespace
namespace Nested
{
public class NestedNameSpaceClass
{
public static void SayHello()
{
Console.WriteLine("Hello");
}
}
}
}
// Output: Hello

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin ad alanları bölümüne bakın.

Ayrıca bkz.
C#başvurunun
C# anahtar sözcükleri
using
statik kullanma
Ad alanı diğer adı niteleyicisi ::
Ad alanları
using (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

using Anahtar sözcüğü sahip üç ana kullanır:


Using deyimi hangi nesne elden sonunda bir kapsam tanımlar.
Using yönergesi bir ad alanı için bir diğer ad oluşturur veya diğer ad alanlarında tanımlı türleri içeri aktarır.
Using static yönergesi tek bir sınıf üyelerinin içeri aktarır.

Ayrıca bkz.
C# başvurusu
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
Ad Alanları
extern
using yönergesi (C# başvuru)
4.11.2019 • 4 minutes to read • Edit Online

using yönergesinin üç kullanımı vardır:


Bir ad alanında türlerin kullanılmasına izin vermek için, bu ad alanında bir tür kullanımını
nitelendirmeniz gerekmez:

using System.Text;

Tür adıyla erişimi nitelemek zorunda kalmadan statik üyelere ve bir tür iç içe türlerine erişmenize izin
vermek için.

using static System.Math;

Daha fazla bilgi için bkz. using static yönergesi.


Bir ad alanı veya tür için bir diğer ad oluşturmak için. Bu, Using alias yönergesiolarak adlandırılır.

using Project = PC.MyCompany.Project;

using anahtar sözcüğü Ayrıca, dosyalar ve yazı tipleri gibi IDisposable nesnelerin doğru şekilde işlenmesini
sağlamaya yardımcı olan using deyimlerinioluşturmak için kullanılır. Daha fazla bilgi için bkz. using deyimleri .

Statik tür kullanma


Tür adıyla erişimi nitelemek zorunda kalmadan, bir türün statik üyelerine erişebilirsiniz:

using static System.Console;


using static System.Math;
class Program
{
static void Main()
{
WriteLine(Sqrt(3*3 + 4*4));
}
}

Açıklamalar
using yönergesinin kapsamı, göründüğü dosyayla sınırlıdır.
using yönergesi görünebilir:
Bir kaynak kodu dosyasının başlangıcında, herhangi bir ad alanı veya tür tanımlarından önce.
Herhangi bir ad alanında, bu ad alanında bildirilmeyen herhangi bir ad alanı veya türden önce.
Aksi halde, derleyici hatası CS1529 oluşturulur.
Bir tanımlayıcıyı bir ad alanına veya türe göre bulmayı kolaylaştırmak için using bir diğer ad yönergesi
oluşturun. Herhangi bir using yönergesinde, bundan önce gelen using yönergelerinden bağımsız olarak
tam nitelenmiş ad alanı veya tür kullanılmalıdır. using yönergesinin bildiriminde using diğer ad
kullanılamaz. Örneğin, aşağıdakiler bir derleyici hatası oluşturur:

using s = System.Text;
using s.RegularExpressions;

Ad alanını belirtmek zorunda kalmadan bir ad alanındaki türleri kullanmak için bir using yönergesi
oluşturun. using yönergesi, belirttiğiniz ad alanı içinde iç içe geçmiş herhangi bir ad alanı için erişim
sağlamaz.
Ad alanları iki kategoride gelir: Kullanıcı tanımlı ve sistem tanımlı. Kullanıcı tanımlı ad alanları kodunuzda
tanımlı ad uzaylardır. Sistem tanımlı ad alanlarının listesi için bkz. .NET API Browser.

Örnek 1
Aşağıdaki örnek, bir ad alanı için using diğer adının nasıl tanımlanacağını ve kullanılacağını gösterir:

namespace PC
{
// Define an alias for the nested namespace.
using Project = PC.MyCompany.Project;
class A
{
void M()
{
// Use the alias
var mc = new Project.MyClass();
}
}
namespace MyCompany
{
namespace Project
{
public class MyClass { }
}
}
}

Using takma ad yönergesinin sağ tarafta açık genel bir türü olamaz. Örneğin, bir List<T> için bir using diğer
adı oluşturamazsınız, ancak bir List<int> için bir tane oluşturabilirsiniz.

Örnek 2
Aşağıdaki örnek, bir sınıf için using yönergesinin ve using diğer adının nasıl tanımlanacağını
göstermektedir:
using System;

// Using alias directive for a class.


using AliasToMyClass = NameSpace1.MyClass;

// Using alias directive for a generic class.


using UsingAlias = NameSpace2.MyClass<int>;

namespace NameSpace1
{
public class MyClass
{
public override string ToString()
{
return "You are in NameSpace1.MyClass.";
}
}

namespace NameSpace2
{
class MyClass<T>
{
public override string ToString()
{
return "You are in NameSpace2.MyClass.";
}
}
}

namespace NameSpace3
{
class MainClass
{
static void Main()
{
var instance1 = new AliasToMyClass();
Console.WriteLine(instance1);

var instance2 = new UsingAlias();


Console.WriteLine(instance2);

}
}
}
// Output:
// You are in NameSpace1.MyClass.
// You are in NameSpace2.MyClass.

C# dili belirtimi
Daha fazla bilgi için bkz. C# dil belirtiminde yönergeleri kullanma . Dil belirtimi, C# sözdizimi ve kullanımı
için kesin bir kaynaktır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
Ad Alanlarını Kullanma
C# Anahtar Sözcükleri
Ad alanları
using Deyimi
static yönergesini kullanma (C# başvuru)
31.10.2019 • 5 minutes to read • Edit Online

using static yönergesi statik üyeleri ve iç içe geçmiş türleri bir tür adı belirtmeden erişebileceğiniz bir türü
belirler. Sözdizimi şöyledir:

using static <fully-qualified-type-name>;

tam nitelikli tür adı, statik üyeleri ve iç içe türlerine bir tür adı belirtilmeden başvurulabilen türün adıdır. Tam
nitelikli tür adı (tür adıyla birlikte tam ad alanı adı) sağlamazsanız, C# derleyici hatası oluşturur CS0246: "tür veya
ad alanı adı ' Type/Namespace ' bulunamadı (bir using yönergeniz veya bir bütünleştirilmiş kod eksik olabilir
başvuru?) ".
using static yönergesi, örnek üyelerine de sahip olsa bile statik üyelere (veya iç içe türler) sahip her tür için
geçerlidir. Ancak, örnek üyeleri yalnızca tür örneği aracılığıyla çağrılabilir.
using static yönergesi 6 ' da C# sunulmuştur.

Açıklamalar
Genellikle, bir statik üye çağırdığınızda, tür adını üye adıyla birlikte sağlarsınız. Türün üyelerini çağırmak için aynı
tür adının tekrar tekrar girilmesi, ayrıntılı ve belirsiz kod oluşmasına neden olabilir. Örneğin, bir Circle sınıfının
aşağıdaki tanımı Math sınıfının bir dizi üyesine başvurur.

using System;

public class Circle


{
public Circle(double radius)
{
Radius = radius;
}

public double Radius { get; set; }

public double Diameter


{
get { return 2 * Radius; }
}

public double Circumference


{
get { return 2 * Radius * Math.PI; }
}

public double Area


{
get { return Math.PI * Math.Pow(Radius, 2); }
}
}

Bir üyeye her başvurulilişinde Math sınıfına açıkça başvuru ihtiyacını ortadan kaldırarak using static yönergesi
çok Temizleyici kod üretir:
using System;
using static System.Math;

public class Circle


{
public Circle(double radius)
{
Radius = radius;
}

public double Radius { get; set; }

public double Diameter


{
get { return 2 * Radius; }
}

public double Circumference


{
get { return 2 * Radius * PI; }
}

public double Area


{
get { return PI * Pow(Radius, 2); }
}
}

using static , yalnızca erişilebilir statik üyeleri ve belirtilen türde tanımlanan iç içe geçmiş türleri içeri aktarır.
Devralınan Üyeler içeri aktarılmaz. Visual Basic modüller dahil olmak üzere, bir using static yönergesi ile herhangi
bir adlandırılmış türden içeri aktarabilirsiniz. F# Üst düzey işlevler, adı geçerli C# bir tanımlayıcı olan adlandırılmış
türün statik üyeleri olarak meta verilerde görünürse, F# işlevler içeri aktarılabilir.
using static , belirtilen türde tanımlanan uzantı yöntemlerinin genişletme yöntemi araması için kullanılabilir
olmasını sağlar. Ancak, uzantı yöntemlerinin adları kodda nitelenmemiş başvuru için kapsama aktarılmaz.
Aynı ada sahip Yöntemler aynı derleme birimi veya ad alanı içinde farklı using static yönergeleri tarafından bir
yöntem grubu oluşturur. Bu yöntem grupları içindeki aşırı yükleme çözümlemesi normal C# kuralları izler.

Örnek
Aşağıdaki örnek, Console, Mathve String sınıflarının statik üyelerini tür adlarını belirtmek zorunda kalmadan
kullanılabilir hale getirmek için using static yönergesini kullanır.
using System;
using static System.Console;
using static System.Math;
using static System.String;

class Program
{
static void Main()
{
Write("Enter a circle's radius: ");
var input = ReadLine();
if (!IsNullOrEmpty(input) && double.TryParse(input, out var radius)) {
var c = new Circle(radius);

string s = "\nInformation about the circle:\n";


s = s + Format(" Radius: {0:N2}\n", c.Radius);
s = s + Format(" Diameter: {0:N2}\n", c.Diameter);
s = s + Format(" Circumference: {0:N2}\n", c.Circumference);
s = s + Format(" Area: {0:N2}\n", c.Area);
WriteLine(s);
}
else {
WriteLine("Invalid input...");
}
}
}

public class Circle


{
public Circle(double radius)
{
Radius = radius;
}

public double Radius { get; set; }

public double Diameter


{
get { return 2 * Radius; }
}

public double Circumference


{
get { return 2 * Radius * PI; }
}

public double Area


{
get { return PI * Pow(Radius, 2); }
}
}
// The example displays the following output:
// Enter a circle's radius: 12.45
//
// Information about the circle:
// Radius: 12.45
// Diameter: 24.90
// Circumference: 78.23
// Area: 486.95

Örnekte, using static yönergesi Double türüne de uygulanmış olabilir. Bu, bir tür adı belirtmeden
TryParse(String, Double) yöntemini çağırmak mümkün hale gelir. Ancak, bu, hangi sayısal tür TryParse
yönteminin çağrıldığını belirleyen using static deyimlerini denetlemek için gerekli hale geldiği için, daha az
okunabilir bir kod oluşturur.
Ayrıca bkz.
using yönergesi
C#Başvurunun
C# Anahtar Sözcükleri
Ad Alanlarını Kullanma
Ad alanları
using deyimleri (C# başvuru)
4.11.2019 • 4 minutes to read • Edit Online

IDisposable nesnelerinin doğru kullanımını sağlayan uygun bir sözdizimi sağlar.

Örnek
Aşağıdaki örnek, using deyimin nasıl kullanılacağını göstermektedir.

using (var font1 = new Font("Arial", 10.0f))


{
byte charset = font1.GdiCharSet;
}

8,0 ile C# başlayarak, küme ayraçları gerektirmeyen using bildiri için aşağıdaki alternatif sözdizimini
kullanabilirsiniz:

using var font1 = new Font("Arial", 10.0f);


byte charset = font1.GdiCharSet;

Açıklamalar
File ve Font, yönetilmeyen kaynaklara erişen yönetilen türlerin örnekleridir (Bu durumda dosya tutamaçları
ve cihaz bağlamları). Birçok farklı türde yönetilmeyen kaynak ve bunları kapsülleyen sınıf kitaplığı türleri
vardır. Bu tür türler IDisposable arabirimini gerçekleştirmelidir.
Bir IDisposable nesnesinin kullanım ömrü tek bir yöntemle sınırlıysa, bunu using bildiriminde bildirmeniz
ve oluşturmanız gerekir. using ifade, nesne üzerinde Dispose yöntemini doğru şekilde çağırır ve (daha önce
gösterildiği gibi kullandığınızda), Dispose çağrıldığında nesnenin kendisinin kapsam dışına geçmesine da
neden olur. using bloğunda, nesnesi salt okunurdur ve değiştirilemez ya da yeniden atanamaz.
using bildiri, using bloğunda bir özel durum gerçekleşse bile Dispose çağırılmasını sağlar. Nesneyi try
bloğunun içine yerleştirerek ve sonra Dispose bir finally bloğunda çağırarak aynı sonucu elde edebilirsiniz;
Aslında using deyimin derleyici tarafından çevrilme yöntemi budur. Kod örneği, derleme zamanında
aşağıdaki koda genişletilir (nesne için sınırlı kapsam oluşturmak için ek küme ayraçları aklınızda):

{
var font1 = new Font("Arial", 10.0f);
try
{
byte charset = font1.GdiCharSet;
}
finally
{
if (font1 != null)
((IDisposable)font1).Dispose();
}
}

Yeni using deyimin sözdizimi, çok benzer bir koda çevrilir. try bloğu, değişkenin bildirildiği yerde açılır.
finally bloğu, genellikle bir yöntemin sonunda kapsayan bloğun yakın bir tarafında eklenir.
try - finally ifadesiyle ilgili daha fazla bilgi için, try-finally konusuna bakın.
Aşağıdaki örnekte gösterildiği gibi, bir türün birden çok örneği using bildiriminde bildirilebilecek:

using (Font font3 = new Font("Arial", 10.0f),


font4 = new Font("Arial", 10.0f))
{
// Use font3 and font4.
}

Aynı türde birden çok bildirimi, C# 8 ' in yanı sıra sunulan yeni sözdizimini kullanarak birleştirebilirsiniz. Bu,
aşağıdaki örnekte gösterilmiştir:

using Font font3 = new Font("Arial", 10.0f),


font4 = new Font("Arial", 10.0f);
// Use font3 and font4.

Kaynak nesnesini örnekleyebilirsiniz ve sonra değişkeni using ifadesine geçirebilirsiniz, ancak bu en iyi
yöntem değildir. Bu durumda, denetim using bloğundan ayrıldıktan sonra nesne kapsamda kalır, büyük
olasılıkla yönetilmeyen kaynaklarına erişemez. Diğer bir deyişle, artık tam olarak başlatılamaz. Nesneyi
using bloğunun dışında kullanmaya çalışırsanız, bir özel durumun bir istisna olmasına neden olur. Bu
nedenle, using deyimindeki nesnenin örneğini oluşturmak ve kapsamını using bloğu ile sınırlandırmak
genellikle daha iyidir.

var font2 = new Font("Arial", 10.0f);


using (font2) // not recommended
{
// use font2
}
// font2 is still in scope
// but the method call throws an exception
float f = font2.GetHeight();

IDisposable nesnelerini elden atma hakkında daha fazla bilgi için, bkz. IDisposable uygulayan nesneleri
kullanma.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminde using ifadesine bakın. Dil belirtimi, C# sözdizimi ve kullanımı için
kesin bir kaynaktır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
using Yönergesi
Atık Toplama
IDisposable uygulayan nesneleri kullanma
IDisposable arabirimi
8,0 içinde C# using deyimleri
extern alias (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

Aynı tam tür adlarına sahip derlemelerin iki sürümüne başvurmanız gerekebilir. Örneğin, bir derlemenin iki veya
daha fazla sürümünü aynı uygulamada kullanmanız gerekebilir. Bir dış derleme diğer adı kullanarak, her
derlemeden ad alanları, diğer ad tarafından adlandırılan ve aynı dosyada kullanılmasına olanak sağlayan kök
düzeyi ad alanları içinde sarmalanabilir.

NOTE
Extern anahtar sözcüğü, yönetilmeyen kodda yazılmış bir yöntemi bildiren bir yöntem değiştiricisi olarak da kullanılır.

Aynı tam tür adlarıyla iki derlemeye başvurmak için, bir diğer ad aşağıdaki gibi bir komut isteminde
belirtilmelidir:
/r:GridV1=grid.dll

/r:GridV2=grid20.dll

Bu, GridV1 ve GridV2 dış diğer adlarını oluşturur. Bu diğer adları bir program içinden kullanmak için, extern
anahtar sözcüğünü kullanarak bunlara başvurun. Örneğin:
extern alias GridV1;

extern alias GridV2;

Her extern diğer ad bildirimi, genel ad alanını paraleller (ancak içinde olmayan) ek bir kök düzeyi ad alanı sunar.
Bu nedenle, her bir derlemeden türler, uygun ad alanı-diğer adı altında belirtildiği gibi tam nitelikli adı kullanılarak
belirsizlik olmadan başvuruda bulunulabilir.
Önceki örnekte, GridV1::Grid kılavuz denetimi grid.dll ve grid20.dll GridV2::Grid kılavuz denetimi olacaktır.

C# Dil Belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir kaynaktır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
:: İşleci
-Reference (C# derleyici seçenekleri)
is (C# Başvurusu)
23.10.2019 • 10 minutes to read • Edit Online

İşleci, bir ifadenin sonucunun verilen türle uyumlu olup olmadığını denetler veya (7,0 ile C# başlayarak) bir
ifadeyi bir düzene göre sınar. is Tür testi is işleci hakkında daha fazla bilgi için, tür-test ve atama işleçleri
makalesinin işleç bölümüne bakın.

İle eşleşen desenler is


7,0 ile C# başlayarak, is ve Switch deyimleri, model eşleştirmeyi destekler. is Anahtar sözcüğü aşağıdaki
desenleri destekler:
Bir ifadenin belirtilen türe dönüştürülüp dönüştürülebileceğini test eden tür stili, bu, bir ifadenin bu
türden bir değişkene dönüştürülmesini sağlar.
Bir ifadenin belirtilen sabit değer olarak değerlendirilip değerlendirilmediğini test eden sabit bir model.
var olan model, her zaman başarılı olan ve bir ifadenin değerini yeni bir yerel değişkene bağlayan bir
eşleşme.
Tür stili
Model eşleştirmeyi gerçekleştirmek için tür modelini kullanırken, is bir ifadenin belirtilen bir türe
dönüştürülüp dönüştürülebileceğini ve bu türden bir değişkene bir değişken verip etmediğini test eder. Bu, is
kısa tür değerlendirmesi ve dönüştürmeyi sağlayan deyimin basit bir uzantısıdır. is Tür deseninin genel formu:

expr is type varname

Burada Expr , bir türün bir örneğini değerlendiren bir ifadedir, tür , Expr 'nin sonucunun dönüştürülecek türün
adı, varname ise ifadenin sonucunun dönüştürüldüğü nesne, is test . true
İfade, Expr null değilse ve aşağıdakilerden herhangi biri doğru ise geçerlidir: is true

Expr , türüile aynı türde bir örneğidir.


Expr türündentüretilen bir türün örneğidir. Diğer bir deyişle, ifadenin sonucu türündebir örneğe
eklenebilir.
ifadenin türünde bir temel sınıf olan bir derleme zamanı türü vardır ve Expr türü veya türünden türetilmiş
bir çalışma zamanı türü vardır. Bir değişkenin derleme zamanı türü , bildiriminde tanımlanan değişkenin
türüdür. Bir değişkenin çalışma zamanı türü , bu değişkene atanan örneğin türüdür.
Expr , tür arabirimini uygulayan bir türün örneğidir.
7,1 ile C# başlayarak, Expr genel bir tür parametresi ve kısıtlamaları tarafından tanımlanan bir derleme zamanı
türüne sahip olabilir.
Expr ise true ve is bir if ifadesiyle birlikte kullanılırsa, varname yalnızca deyimin içinde atanır. if
Varname kapsamı, is ifadeden if deyimi kapsayan bloğun sonuna kadar olur. Başka bir konumda varname
kullanılması atanmamış bir değişkenin kullanımı için derleme zamanı hatası oluşturur.
Aşağıdaki örnek, bir is IComparable.CompareTo(Object) türün yönteminin uygulanmasını sağlamak için tür
modelini kullanır.
using System;

public class Employee : IComparable


{
public String Name { get; set; }
public int Id { get; set; }

public int CompareTo(Object o)


{
if (o is Employee e)
{
return Name.CompareTo(e.Name);
}
throw new ArgumentException("o is not an Employee object.");
}
}

Model eşleştirmesi olmadan bu kod aşağıdaki gibi yazılabilir. Tür deseninin kullanımı, dönüştürmenin
sonucunun bir null olup olmadığını test etme gereksinimini ortadan kaldırarak daha kompakt, okunabilir kod
üretir.

using System;

public class Employee : IComparable


{
public String Name { get; set; }
public int Id { get; set; }

public int CompareTo(Object o)


{
var e = o as Employee;
if (e == null)
{
throw new ArgumentException("o is not an Employee object.");
}
return Name.CompareTo(e.Name);
}
}

is Tür deseninin de bir değer türünün türü belirlenirken daha kompakt kod üretir. Aşağıdaki örnek, uygun bir
is özelliğin değerini görüntülemeden önce bir nesnenin bir Person mi Dog yoksa bir örnek mi olduğunu
anlamak için tür modelini kullanır.
using System;

public class Example


{
public static void Main()
{
Object o = new Person("Jane");
ShowValue(o);

o = new Dog("Alaskan Malamute");


ShowValue(o);
}

public static void ShowValue(object o)


{
if (o is Person p) {
Console.WriteLine(p.Name);
}
else if (o is Dog d) {
Console.WriteLine(d.Breed);
}
}
}

public struct Person


{
public string Name { get; set; }

public Person(string name) : this()


{
Name = name;
}
}

public struct Dog


{
public string Breed { get; set; }

public Dog(string breedName) : this()


{
Breed = breedName;
}
}
// The example displays the following output:
// Jane
// Alaskan Malamute

Desenler eşleşmesi olmayan eşdeğer kod, açık bir dönüştürme içeren ayrı bir atama gerektirir.
using System;

public class Example


{
public static void Main()
{
Object o = new Person("Jane");
ShowValue(o);

o = new Dog("Alaskan Malamute");


ShowValue(o);
}

public static void ShowValue(object o)


{
if (o is Person) {
Person p = (Person) o;
Console.WriteLine(p.Name);
}
else if (o is Dog) {
Dog d = (Dog) o;
Console.WriteLine(d.Breed);
}
}
}

public struct Person


{
public string Name { get; set; }

public Person(string name) : this()


{
Name = name;
}
}

public struct Dog


{
public string Breed { get; set; }

public Dog(string breedName) : this()


{
Breed = breedName;
}
}
// The example displays the following output:
// Jane
// Alaskan Malamute

Sabit model
Sabit örüntüyle eşleşen desenler gerçekleştirirken, is bir ifadenin belirtilen bir sabit değere eşit olup
olmadığını sınar. C# 6 ve önceki sürümlerde, sabit model Switch ifadesiyle desteklenir. 7,0 ' C# den başlayarak,
bu, is bildiri tarafından da desteklenir. Sözdizimi şöyledir:

expr is constant

Burada Expr , değerlendirilecek ifadedir ve sabitin test edilecek değerdir. sabit , aşağıdaki sabit ifadelerden
herhangi biri olabilir:
Değişmez değer.
Belirtilen const değişkenin adı.
Bir numaralandırma sabiti.
Sabit ifade aşağıdaki gibi değerlendirilir:
Eğer Expr ve Constant integral türse, C# eşitlik işleci ifadenin döndürülüp döndürülmeyeceğini true
(yani, expr == constant ne olduğunu) belirler.
Aksi takdirde, ifadenin değeri static Object. Equals (Expr, Constant) yöntemi çağrısıyla belirlenir.
Aşağıdaki örnek, bir nesnenin bir Dice örnek olup olmadığını test etmek için tür ve sabit desenleri ve bir zar
rulosu değerinin 6 olup olmadığını anlamak için birleştirir.

using System;

public class Dice


{
Random rnd = new Random();
public Dice()
{

}
public int Roll()
{
return rnd.Next(1, 7);
}
}

class Program
{
static void Main(string[] args)
{
var d1 = new Dice();
ShowValue(d1);
}

private static void ShowValue(object o)


{
const int HIGH_ROLL = 6;

if (o is Dice d && d.Roll() is HIGH_ROLL)


Console.WriteLine($"The value is {HIGH_ROLL}!");
else
Console.WriteLine($"The dice roll is not a {HIGH_ROLL}!");
}
}
// The example displays output like the following:
// The value is 6!

İçin nulldenetim, sabit model kullanılarak gerçekleştirilebilir. Anahtar sözcüğü, is ifadesiyle desteklenir.
null Sözdizimi şöyledir:

expr is null

Aşağıdaki örnek, null denetimlerin karşılaştırmasını gösterir:


using System;

class Program
{
static void Main(string[] args)
{
object o = null;

if (o is null)
{
Console.WriteLine("o does not have a value");
}
else
{
Console.WriteLine($"o is {o}");
}

int? x = 10;

if (x is null)
{
Console.WriteLine("x does not have a value");
}
else
{
Console.WriteLine($"x is {x.Value}");
}

// 'null' check comparison


Console.WriteLine($"'is' constant pattern 'null' check result : { o is null }");
Console.WriteLine($"object.ReferenceEquals 'null' check result : { object.ReferenceEquals(o, null)
}");
Console.WriteLine($"Equality operator (==) 'null' check result : { o == null }");
}

// The example displays the following output:


// o does not have a value
// x is 10
// 'is' constant pattern 'null' check result : True
// object.ReferenceEquals 'null' check result : True
// Equality operator (==) 'null' check result : True
}

var deseninin
Bu var , herhangi bir tür veya değer için bir catch-all ' dır. Expr 'nin değeri her zaman bir yerel değişkene, aynı
türde Expr'nin derleme zamanı türüyle atanır. is İfadenin sonucu her zaman true olur. Sözdizimi şöyledir:

expr is var varname

Aşağıdaki örnek, adlı obj bir değişkene bir ifade atamak için var modelini kullanır. Daha sonra değerini ve
türünü obj görüntüler.
using System;

class Program
{
static void Main()
{
object[] items = { new Book("The Tempest"), new Person("John") };
foreach (var item in items) {
if (item is var obj)
Console.WriteLine($"Type: {obj.GetType().Name}, Value: {obj}");
}
}
}

class Book
{
public Book(string title)
{
Title = title;
}

public string Title { get; set; }

public override string ToString()


{
return Title;
}
}

class Person
{
public Person(string name)
{
Name = name;
}

public string Name


{ get; set; }

public override string ToString()


{
return Name;
}
}
// The example displays the following output:
// Type: Book, Value: The Tempest
// Type: Person, Value: John

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin ve aşağıdaki C# dil tekliflerinin işleç bölümüne bakın:
Desen eşleştirme
Genel türler ile desen eşleştirme

Ayrıca bkz.
C#başvurunun
C# anahtar sözcükleri
Tür testi ve atama işleçleri
New kısıtlaması (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

new Kısıtlaması belirtir bir genel sınıf bildiriminde tür bağımsız değişkeni genel bir parametresiz oluşturucusu
olmalıdır. Kullanılacak new kısıtlaması, türü olamaz abstract.
Uygulama new öğesini aşağıdaki örnekte gösterildiği gibi genel bir sınıf türünün yeni örneğini oluşturduğunda,
bir tür parametresi kısıtlaması:

class ItemFactory<T> where T : new()


{
public T GetNewItem()
{
return new T();
}
}

Kullanırken new() kısıtlama diğer kısıtlamalarla en son belirtilmelidir:

public class ItemFactory2<T>


where T : IComparable, new()
{ }

Daha fazla bilgi için tür parametrelerindeki kısıtlamalar.


De kullanabilirsiniz new anahtar bir türün bir örneğini oluşturma veya farklı bir üye bildirim değiştirici.

C# dili belirtimi
Daha fazla bilgi için tür parametresi kısıtlamaları bölümünü C# dil belirtimi.

Ayrıca bkz.
C# başvurusu
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
Genel Türler
where (genel tür kısıtlaması) (C# Başvurusu)
25.11.2019 • 6 minutes to read • Edit Online

Genel tanımda where yan tümcesi, genel bir tür, metot, temsilci veya yerel işlev içindeki tür parametreleri için
bağımsız değişken olarak kullanılan türlerde kısıtlamalar belirtir. Kısıtlamalar, arabirimler, temel sınıflar veya bir
genel türün bir başvuru, değer veya yönetilmeyen tür olmasını gerektirebilir. Bunlar, tür bağımsız değişkeninin
sahip olması gereken özellikleri bildirir.
Örneğin, T tür parametresi IComparable<T> arabirimini uyguladığı için, MyGenericClass genel bir sınıf
bildirebilirsiniz:

public class AGenericClass<T> where T : IComparable<T> { }

NOTE
Bir sorgu ifadesindeki WHERE yan tümcesi hakkında daha fazla bilgi için bkz. WHERE yan tümcesi.

where yan tümcesi bir temel sınıf kısıtlaması de içerebilir. Temel sınıf kısıtlaması, bu genel türün tür bağımsız
değişkeni olarak kullanılacak bir türün, bu genel tür için bir tür bağımsız değişkeni olarak kullanılacak bir temel
sınıf (veya temel sınıf) olarak belirtilen sınıfa sahip olduğunu belirtir. Temel sınıf kısıtlaması kullanılırsa, bu tür
parametresindeki diğer kısıtlamaların önüne gelmelidir. Bir temel sınıf kısıtlaması olarak bazı türlere izin verilmez:
Object, Arrayve ValueType. C# 7,3 ' den önceki Enum, Delegateve MulticastDelegate de temel sınıf kısıtlamaları
olarak izin verilmedi. Aşağıdaki örnek, artık temel sınıf olarak belirtime türleri göstermektedir:

public class UsingEnum<T> where T : System.Enum { }

public class UsingDelegate<T> where T : System.Delegate { }

public class Multicaster<T> where T : System.MulticastDelegate { }

where yan tümcesi, türün bir class veya struct olduğunu belirtebilir. struct kısıtlaması, System.ValueType
temel sınıf kısıtlaması belirtme gereksinimini ortadan kaldırır. System.ValueType türü, temel sınıf kısıtlaması olarak
kullanılamaz. Aşağıdaki örnek hem class hem de struct kısıtlamalarını göstermektedir:

class MyClass<T, U>


where T : class
where U : struct
{ }

where yan tümcesi notnull kısıtlaması içerebilir. notnull kısıtlaması, tür parametresini null yapılamayan türler
ile sınırlandırır. Bu tür bir değer türü veya null yapılamayan bir başvuru türü olabilir. notnull kısıtlaması, bir
nullable enable bağlamındaderlenen C# kod için 8,0 ' den başlayarak kullanılabilir. Diğer kısıtlamaların aksine,
bir tür bağımsız değişkeni notnull kısıtlamasını ihlal ederse, derleyici hata yerine bir uyarı oluşturur. Uyarılar
yalnızca bir nullable enable bağlamında oluşturulur.
IMPORTANT
notnull kısıtlamasını içeren genel bildirimler null olabilir bir zorunluluvou bağlamında kullanılabilir, ancak derleyici
kısıtlamayı zorlamaz.

#nullable enable
class NotNullContainer<T>
where T : notnull
{

}
#nullable restore

where yan tümcesi Ayrıca bir unmanaged kısıtlaması içerebilir. unmanaged kısıtlaması, tür parametresini
yönetilmeyen türlerolarak bilinen türlerle sınırlandırır. unmanaged kısıtlaması, ' de C#alt düzey birlikte çalışma
kodu yazmayı kolaylaştırır. Bu kısıtlama, tüm yönetilmeyen türler arasında yeniden kullanılabilir yordamlar sunar.
unmanaged kısıtlaması class veya struct kısıtlaması ile birleştirilemez. unmanaged kısıtlaması, türün bir struct
olması için zorlar:

class UnManagedWrapper<T>
where T : unmanaged
{ }

where yan tümcesi Ayrıca, new() bir Oluşturucu kısıtlaması içerebilir. Bu kısıtlama, new işlecini kullanarak bir tür
parametresinin örneğini oluşturmayı mümkün kılar. New () kısıtlaması , derleyicinin sağlanan herhangi bir tür
bağımsız değişkeninin erişilebilir parametresiz bir oluşturucuya sahip olması gerektiğini bilmesini sağlar. Örneğin:

public class MyGenericClass<T> where T : IComparable<T>, new()


{
// The following line is not possible without new() constraint:
T item = new T();
}

new() kısıtlaması where yan tümcesinde son görünür. new() kısıtlaması struct veya unmanaged kısıtlamalarıyla
birleştirilemez. Bu kısıtlamaların karşılankarşılayan tüm türlerin erişilebilir bir parametresiz oluşturucusu olması ve
new() kısıtlamasının gereksiz hale getirilmesi gerekir.

Birden çok tür parametresiyle, her tür parametresi için bir where yan tümcesi kullanın, örneğin:

public interface IMyInterface { }

namespace CodeExample
{
class Dictionary<TKey, TVal>
where TKey : IComparable<TKey>
where TVal : IMyInterface
{
public void Add(TKey key, TVal val) { }
}
}

Ayrıca, aşağıdaki örnekte gösterildiği gibi genel yöntemlerin tür parametrelerine kısıtlamalar ekleyebilirsiniz:

public void MyMethod<T>(T t) where T : IMyInterface { }


Temsilcilerle ilgili tür parametresi kısıtlamalarını betimleyen sözdiziminin, metodların türüyle aynı olduğunu
unutmayın:

delegate T MyDelegate<T>() where T : new();

Genel Temsilciler hakkında daha fazla bilgi için bkz. Genel Temsilciler.
Kısıtlamaların sözdizimi ve kullanımı hakkında ayrıntılı bilgi için bkz. tür parametrelerindeki kısıtlamalar.

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir kaynaktır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
Genel Türlere Giriş
new Kısıtlaması
Tür Parametrelerindeki Kısıtlamalar
base (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

base Anahtar sözcüğü türetilmiş bir sınıf içinden temel sınıfın üyelerine erişmek için kullanılır:
Temel sınıfta, başka bir yöntem tarafından geçersiz kılınan bir yöntemi çağırın.
Türetilmiş sınıfın örneklerini oluştururken hangi temel sınıf oluşturucunun çağrılması gerektiğini
belirtin.
Temel sınıf erişimine yalnızca bir oluşturucuda, örnek yönteminde veya örnek özellik erişimcisinde izin verilir.
base Anahtar sözcüğünün statik bir yöntem içinden kullanılması hatadır.
Erişilen temel sınıf, sınıf bildiriminde belirtilen temel sınıftır. Örneğin, öğesini belirtirseniz
class ClassB : ClassA , ClassA 'nın temel sınıfından bağımsız olarak SınıfB ' den erişim altına alınır.

Örnek
Bu örnekte, hem taban sınıfının Person hem de türetilmiş Employee sınıfın adında Getinfo bir yöntemi vardır.
base Anahtar sözcüğünü kullanarak, türetilmiş sınıfın içindeki Getinfo yöntemi temel sınıfta çağırmak
mümkündür.
public class Person
{
protected string ssn = "444-55-6666";
protected string name = "John L. Malgraine";

public virtual void GetInfo()


{
Console.WriteLine("Name: {0}", name);
Console.WriteLine("SSN: {0}", ssn);
}
}
class Employee : Person
{
public string id = "ABC567EFG";
public override void GetInfo()
{
// Calling the base class GetInfo method:
base.GetInfo();
Console.WriteLine("Employee ID: {0}", id);
}
}

class TestClass
{
static void Main()
{
Employee E = new Employee();
E.GetInfo();
}
}
/*
Output
Name: John L. Malgraine
SSN: 444-55-6666
Employee ID: ABC567EFG
*/

Daha fazla örnek için bkz. New, Virtualve override.

Örnek
Bu örnek, türetilmiş bir sınıfın örneklerini oluştururken çağrılan temel sınıf oluşturucunun nasıl ekleneceğini
gösterir.
public class BaseClass
{
int num;

public BaseClass()
{
Console.WriteLine("in BaseClass()");
}

public BaseClass(int i)
{
num = i;
Console.WriteLine("in BaseClass(int i)");
}

public int GetNum()


{
return num;
}
}

public class DerivedClass : BaseClass


{
// This constructor will call BaseClass.BaseClass()
public DerivedClass() : base()
{
}

// This constructor will call BaseClass.BaseClass(int i)


public DerivedClass(int i) : base(i)
{
}

static void Main()


{
DerivedClass md = new DerivedClass();
DerivedClass md1 = new DerivedClass(1);
}
}
/*
Output:
in BaseClass()
in BaseClass(int i)
*/

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
this
this (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

this Anahtar sözcüğü, sınıfın geçerli örneğine başvurur ve bir genişletme yönteminin ilk parametresi için bir
değiştirici olarak da kullanılır.

NOTE
Bu makalede, sınıf örneklerinin kullanımı this ele alınmaktadır. Uzantı yöntemlerinde kullanımı hakkında daha fazla bilgi
için bkz. Uzantı yöntemleri.

Aşağıdakiler yaygın kullanımları this aşağıda verilmiştir:


Benzer adlarla gizlenen üyeleri nitelemek için, örneğin:

public class Employee


{
private string alias;
private string name;

public Employee(string name, string alias)


{
// Use this to qualify the members of the class
// instead of the constructor parameters.
this.name = name;
this.alias = alias;
}
}

Bir nesneyi diğer yöntemlere parametre olarak geçirmek için, örneğin:

CalcTax(this);

Dizin oluşturucular bildirmek için örneğin:

public int this[int param]


{
get { return array[param]; }
set { array[param] = value; }
}

Statik üye işlevleri, sınıf düzeyinde olduklarından ve bir nesnenin parçası olarak değil, bir this işaretçisine
sahip değildir. Statik bir yöntemde başvurmak this için bir hatadır.

Örnek
Bu this örnekte, Employee sınıf üyelerini name nitelemek ve alias benzer adlarla gizlenen için kullanılır.
Ayrıca, başka bir sınıfa ait olan yöntemine CalcTax bir nesne geçirmek için de kullanılır.
class Employee
{
private string name;
private string alias;
private decimal salary = 3000.00m;

// Constructor:
public Employee(string name, string alias)
{
// Use this to qualify the fields, name and alias:
this.name = name;
this.alias = alias;
}

// Printing method:
public void printEmployee()
{
Console.WriteLine("Name: {0}\nAlias: {1}", name, alias);
// Passing the object to the CalcTax method by using this:
Console.WriteLine("Taxes: {0:C}", Tax.CalcTax(this));
}

public decimal Salary


{
get { return salary; }
}
}

class Tax
{
public static decimal CalcTax(Employee E)
{
return 0.08m * E.Salary;
}
}

class MainClass
{
static void Main()
{
// Create objects:
Employee E1 = new Employee("Mingda Pan", "mpan");

// Display results:
E1.printEmployee();
}
}
/*
Output:
Name: Mingda Pan
Alias: mpan
Taxes: $240.00
*/

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
base
Yöntemler
null (C# Başvurusu)
8.11.2019 • 2 minutes to read • Edit Online

null anahtar sözcüğü, herhangi bir nesneye başvurmayan bir null başvurusunu temsil eden bir sabit
değerdir. null , başvuru türü değişkenlerinin varsayılan değeridir. Null değer türleri hariçsıradan değer
türleri null olamaz.
Aşağıdaki örnek, null anahtar sözcüğünün bazı davranışlarını göstermektedir:
class Program
{
class MyClass
{
public void MyMethod() { }
}

static void Main(string[] args)


{
// Set a breakpoint here to see that mc = null.
// However, the compiler considers it "unassigned."
// and generates a compiler error if you try to
// use the variable.
MyClass mc;

// Now the variable can be used, but...


mc = null;

// ... a method call on a null object raises


// a run-time NullReferenceException.
// Uncomment the following line to see for yourself.
// mc.MyMethod();

// Now mc has a value.


mc = new MyClass();

// You can call its method.


mc.MyMethod();

// Set mc to null again. The object it referenced


// is no longer accessible and can now be garbage-collected.
mc = null;

// A null string is not the same as an empty string.


string s = null;
string t = String.Empty; // Logically the same as ""

// Equals applied to any null object returns false.


bool b = (t.Equals(s));
Console.WriteLine(b);

// Equality operator also returns false when one


// operand is null.
Console.WriteLine("Empty string {0} null string", s == t ? "equals": "does not equal");

// Returns true.
Console.WriteLine("null == null is {0}", null == null);

// A value type cannot be null


// int i = null; // Compiler error!

// Use a nullable value type instead:


int? i = null;

// Keep the console window open in debug mode.


System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();

}
}

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
C#başvurunun
C# anahtar sözcükleri
Varsayılan değerler tablosu
Nothing (Visual Basic)
bool (C# başvuru)
29.11.2019 • 2 minutes to read • Edit Online

bool Type anahtar sözcüğü, true veya false olabilen bir Boolean değeri temsil eden .NET
System.Boolean yapı türü için bir diğer addır.
bool türünün değerleriyle mantıksal işlemler gerçekleştirmek için, Boolean mantıksal işleçler kullanın.
bool türü karşılaştırma ve eşitlik işleçlerinin sonuç türüdür. bool ifade, IF, Do, whileve for deyimlerinde
ve koşullu işleç ?: bir denetim koşullu ifadesi olabilir.
bool türünün varsayılan değeri false .

Sabit değerler
bool değişkenini başlatmak veya bir bool değeri geçirmek için true ve false değişmez değerleri
kullanabilirsiniz:

bool check = true;


Console.WriteLine(check ? "Checked" : "Not checked"); // output: Checked

Console.WriteLine(false ? "Checked" : "Not checked"); // output: Not checked

Dönüşümler
C# bool türünü içeren yalnızca iki dönüştürme sağlar. Bunlar, karşılık gelen null yapılabilir bool? türüne
örtülü bir dönüşümtür ve bool? türünden açık bir dönüştürme. Ancak, .NET bool türüne dönüştürmek
için kullanabileceğiniz ek yöntemler sağlar. Daha fazla bilgi için, System.Boolean API başvurusu sayfasının
Boole değerlerine dönüştürme bölümüne bakın.

Üç değerli Boole mantığı


Üç değerli mantığı desteketmeniz gerekiyorsa (örneğin, üç değerli bir Boolean türünü destekleyen
veritabanlarıyla çalışırken) null yapılabilir bool? türünü kullanın. bool? işlenenleri için, önceden
tanımlanmış & ve | işleçleri üç değerli mantığı destekler. Daha fazla bilgi için, Boole mantıksal işleçler
makalesinin Nullable Boolean mantıksal işleçler bölümüne bakın.
Null yapılabilir değer türleri hakkında daha fazla bilgi için bkz. Nullable değer türleri.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin bool türü bölümüne bakın.

Ayrıca bkz.
C#başvurunun
Yerleşik türler tablosu
true ve false işleçleri
default (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

default Anahtar sözcüğü iki şekilde kullanılabilir:


Deyimdeki varsayılan etiketi belirtmek için. switch
Varsayılan işleç veya değişmez değer olarak bir türün varsayılan değerini üretir.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
Bağlamsal Anahtar Sözcükler (C# Başvurusu)
4.11.2019 • 2 minutes to read • Edit Online

Bağlam anahtar sözcüğü, kodda belirli bir anlamı sağlamak için kullanılır, ancak içinde C#ayrılmış bir sözcük
değildir. Bu bölümde aşağıdaki bağlamsal anahtar sözcükler sunulmuştur:

SÖZCÜKLE AÇIKLAMA

add İstemci kodu olaya abone olduğunda çağrılan özel bir olay
erişimcisi tanımlar.

async Değiştirilen yöntem, lambda ifadesi veya adsız yöntemin


zaman uyumsuz olduğunu gösterir.

await Beklenen bir görev tamamlanana kadar zaman uyumsuz bir


yöntemi askıya alır.

dynamic Derleme zamanı tür denetimini atlamak için gerçekleştiği


işlemleri sağlayan bir başvuru türü tanımlar.

get Bir özellik veya Dizin Oluşturucu için bir erişimci yöntemi
tanımlar.

global Genel ad alanının diğer adı, aksi durumda adlandırılmamış.

kısmi Aynı derleme birimi boyunca kısmi sınıfları, yapıları ve


arabirimleri tanımlar.

remove İstemci kodu olaydan aboneliği kaldırılırken çağrılan özel bir


olay erişimcisi tanımlar.

set Bir özellik veya Dizin Oluşturucu için bir erişimci yöntemi
tanımlar.

value Erişimcileri ayarlamak ve olay işleyicilerini eklemek veya


kaldırmak için kullanılır.

var Yöntem kapsamında belirtilen bir değişken türünün derleyici


tarafından belirlenmesi için izin sağlar.

oluşturulurken Bir catch bloğu veya switch deyimin case etiketi için bir
filtre koşulu belirtir.

olmadığı Genel bildirime kısıtlamalar ekler. (Ayrıca bkz .).

yield Bir yineleyici bloğunda, Numaralandırıcı nesnesine bir değer


döndürmek veya yinelemenin sonuna işaret etmek için
kullanılır.

3,0 içinde C# tanıtılan tüm sorgu anahtar sözcükleri de bağlamsal. Daha fazla bilgi için bkz. sorgu anahtar
sözcükleri (LINQ ).
Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
add (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

Bağlamsal add anahtar sözcüğü, istemci kodu olayınız için abone olduğunda çağrılan özel bir olay erişimcisini
tanımlamak için kullanılır . Özel add bir erişimci sağlarsanız Ayrıca bir kaldırma erişimcisi sağlamanız gerekir.

Örnek
Aşağıdaki örnek, özel add ve kaldırma erişimcileri olan bir olay gösterir. Tam örnek için bkz . nasıl yapılır:
Arabirim olaylarınıuygulayın.

class Events : IDrawingObject


{
event EventHandler PreDrawEvent;

event EventHandler IDrawingObject.OnDraw


{
add => PreDrawEvent += value;
remove => PreDrawEvent -= value;
}
}

Genellikle kendi özel olay erişimcilerini sağlamanız gerekmez. Bir olay bildirdiğinizde derleyici tarafından
otomatik olarak oluşturulan erişimciler çoğu senaryo için yeterlidir.

Ayrıca bkz.
Olaylar
get (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

Anahtar sözcüğü, özellik değeri veya Indexer öğesi döndüren bir özellikte veya dizin oluşturucuda bir
erişimci yöntemi tanımlar. get Daha fazla bilgi için bkz. Özellikler, Otomatik uygulanan özellikler ve Dizin
oluşturucular.
Aşağıdaki örnek adlı get set birözellik Seconds için hem hem de erişimcisini tanımlar. Özellik değerini
geri yüklemek için adlı _seconds bir özel alan kullanır.

class TimePeriod
{
private double _seconds;

public double Seconds


{
get { return _seconds; }
set { _seconds = value; }
}
}

Genellikle, get erişimci, önceki örnekte olduğu gibi bir değer döndüren tek bir deyimden oluşur. 7,0 ' C#
den başlayarak, get erişimciyi bir ifade olarak uygulayabilirsiniz. Aşağıdaki örnek, get set hem hem de
erişimcisini ifade-Bodied Üyeler olarak uygular.

class TimePeriod
{
private double _seconds;

public double Seconds


{
get => _seconds;
set => _seconds = value;
}
}

Bir özelliğin get ve set erişimcilerinin özel bir destek alanındaki bir değeri ayarlamaktan veya almadan
başka bir işlem gerçekleştirdiği basit durumlarda, C# derleyicinin otomatik olarak uygulanmış olan
desteğiyle faydalanabilirsiniz özelliklerinin. Aşağıdaki örnek Hours otomatik uygulanan bir özellik olarak
uygulanır.

class TimePeriod2
{
public double Hours { get; set; }
}

C# Dil Belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.
Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
Özellikler
Kısmi tür (C# başvuru)
4.11.2019 • 2 minutes to read • Edit Online

Kısmi tür tanımları bir sınıf, yapı veya arabirimin tanımının birden fazla dosyaya bölünmesine izin verir.
File1.csiçinde:

namespace PC
{
partial class A
{
int num = 0;
void MethodA() { }
partial void MethodC();
}
}

File2.cs 'de bildirimi:

namespace PC
{
partial class A
{
void MethodB() { }
partial void MethodC() { }
}
}

Açıklamalar
Bir sınıf, yapı veya arabirim türünün birkaç dosya üzerinde bölünmesi, büyük projelerle çalışırken veya Windows
Form Tasarımcısıtarafından sağlandığı gibi otomatik olarak oluşturulan kodla yararlı olabilir. Kısmi bir tür, kısmi
bir Yöntemiçerebilir. Daha fazla bilgi için bkz. kısmi sınıflar ve Yöntemler.

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir kaynaktır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
Değiştiriciler
Genel Türlere Giriş
Kısmi yöntem (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

Kısmi bir yöntem, imzasını kısmi türün bir parçasında, uygulamasını ise başka bir parçasında tanımlatır. Kısmi
yöntemler sınıf tasarımcılarının, geliştiricilerin uygulamaya veya uygulamamaya karar verebildikleri olay
işleyicilerine benzer yöntem kancaları sağlamasına olanak sağlar. Geliştirici bir uygulama sağlamazsa, derleyici
derleme zamanında imzayı kaldırır. Aşağıdaki koşullar kısmi yöntemler için geçerlidir:
Kısmi türün her iki tarafındaki imzaların eşleşmesi gerekir.
Yöntem boş döndürmelidir.
Hiçbir erişim değiştiricisine izin verilmez. Kısmi yöntemler dolaylı olarak özeldir.
Aşağıdaki örnek, kısmi bir sınıfın iki parçasında tanımlanan kısmi bir yöntemi gösterir:

namespace PM
{
partial class A
{
partial void OnSomethingHappened(string s);
}

// This part can be in a separate file.


partial class A
{
// Comment out this method and the program
// will still compile.
partial void OnSomethingHappened(String s)
{
Console.WriteLine("Something happened: {0}", s);
}
}
}

Daha fazla bilgi için kısmi sınıflar ve yöntemler.

Ayrıca bkz.
C# başvurusu
Kısmi türü
remove (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

remove Bağlamsal anahtar sözcüğü gelen istemci kodu aboneliği kaldırma çağrılan bir özel olay erişimci
tanımlamak için kullanılır, olay. Özel bir sağlarsanız remove erişimci gerekir da sağlamanız bir ekleme erişimcisi.

Örnek
Aşağıdaki örnek, bir özel olayla gösterir ekleme ve remove erişimcileri. Tam bir örnek için bkz nasıl yapılır:
Arabirim olaylarını uygulama.

class Events : IDrawingObject


{
event EventHandler PreDrawEvent;

event EventHandler IDrawingObject.OnDraw


{
add => PreDrawEvent += value;
remove => PreDrawEvent -= value;
}
}

Genellikle kendi özel olay erişimcilerini sağlamanız gerekmez. Olay bildirdiğinizde, derleyici tarafından otomatik
olarak oluşturulan erişimcileri, çoğu senaryo için yeterlidir.

Ayrıca bkz.
Olaylar
set (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

set Tanımlayan anahtar sözcüğü bir erişimci yönteminde bir özellik veya dizin özelliği veya dizin oluşturucu
öğenin bir değer atar. Daha fazla bilgi ve örnekler için bkz. özellikleri, Implemented Properties, ve dizin
oluşturucular.
Aşağıdaki örnek, her ikisi de tanımlar bir get ve set adlı bir özellik erişimcisi Seconds . Adlı bir özel alan
kullanan _seconds özellik değeri yedeklenir.

class TimePeriod
{
private double _seconds;

public double Seconds


{
get { return _seconds; }
set { _seconds = value; }
}
}

Genellikle, set erişimci, önceki örnekte olduğu gibi bir değer atar tek bir deyimde oluşur. C# 7.0 ile
başlayarak, uygulayabileceğiniz set bir ifade gövdeli üyesi erişimcisi. Aşağıdaki örnek her ikisini birden
uygular get ve set ifade gövdeli üyeler olarak erişimcileri.

class TimePeriod
{
private double _seconds;

public double Seconds


{
get => _seconds;
set => _seconds = value;
}
}

Basit durumlarda için bir özelliğin get ve set erişimcileri ayarlama veya özel destek alanı bir değer
alınırken daha başka bir işlem gerçekleştirme, otomatik uygulanan özellikler için C# Derleyici desteği
yararlanabilir. Aşağıdaki örnek uygulayan Hours otomatik uygulanan bir özellik olarak.

class TimePeriod2
{
public double Hours { get; set; }
}

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.
Ayrıca bkz.
C# başvurusu
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
Özellikler
zaman (C# Başvurusu)
23.10.2019 • 4 minutes to read • Edit Online

Kullanabileceğiniz when iki bağlamlarda bir filtre koşulu belirtmek için bağlamsal anahtar sözcük:
İçinde catch deyiminin bir try/catch veya try/catch/finally blok.
İçinde case etiketi bir geçiş deyimi.

when içinde bir catch deyimi


C# 6 ile başlayarak when kullanılabilir bir catch deyimini yürütmek belirli bir özel durum işleyicisi için doğru bir
koşulu belirtin. Kendi sözdizimi aşağıdaki gibidir:

catch (ExceptionType [e]) when (expr)

Burada expr bir Boole değerini döndüren bir ifadedir. Döndürürse true , özel durum işleyicisi; ise yürütülür false ,
yok.
Aşağıdaki örnekte when işleyicileri için koşullu olarak yürütülecek anahtar sözcüğü bir HttpRequestException bağlı
özel durum iletisi metni görüntülenir.

using System;
using System.Net.Http;
using System.Threading.Tasks;

class Program
{
static void Main()
{
Console.WriteLine(MakeRequest().Result);
}

public static async Task<string> MakeRequest()


{
var client = new HttpClient();
var streamTask = client.GetStringAsync("https://localHost:10000");
try
{
var responseText = await streamTask;
return responseText;
}
catch (HttpRequestException e) when (e.Message.Contains("301"))
{
return "Site Moved";
}
catch (HttpRequestException e) when (e.Message.Contains("404"))
{
return "Page Not Found";
}
catch (HttpRequestException e)
{
return e.Message;
}
}
}
when içinde bir switch deyimi
C# 7.0 ile başlayan case etiketleri artık olması birbirini özel ve sırayı case etiketler görünür bir switch deyimi,
hangi anahtar bloğu belirleyebilir yürütür. when Anahtar sözcüğü, yalnızca filtre koşulu da true ise true olması,
ilişkili case etiketi neden olan bir filtre koşulu belirtmek için kullanılabilir. Kendi sözdizimi aşağıdaki gibidir:

case (expr) when (when-condition):

Burada expr bir sabit desen veya eşleşme ifadesi için karşılaştırma türü desendir ve olduğunda koşul herhangi bir
Boolean ifadesi.
Aşağıdaki örnekte when sınamak için anahtar sözcüğü Shape çeşitli için test etmek için sıfır de bir alan olan
nesneleri Shape sıfırdan büyük bir alan olan nesne.

using System;

public abstract class Shape


{
public abstract double Area { get; }
public abstract double Circumference { get; }
}

public class Rectangle : Shape


{
public Rectangle(double length, double width)
{
Length = length;
Width = width;
}

public double Length { get; set; }


public double Width { get; set; }

public override double Area


{
get { return Math.Round(Length * Width,2); }
}

public override double Circumference


{
get { return (Length + Width) * 2; }
}
}

public class Square : Rectangle


{
public Square(double side) : base(side, side)
{
Side = side;
}

public double Side { get; set; }


}

public class Example


{
public static void Main()
{
Shape sh = null;
Shape[] shapes = { new Square(10), new Rectangle(5, 7),
new Rectangle(10, 10), sh, new Square(0) };
foreach (var shape in shapes)
ShowShapeInfo(shape);
}
}

private static void ShowShapeInfo(Object obj)


{
switch (obj)
{
case Shape shape when shape.Area == 0:
Console.WriteLine($"The shape: {shape.GetType().Name} with no dimensions");
break;
case Square sq when sq.Area > 0:
Console.WriteLine("Information about the square:");
Console.WriteLine($" Length of a side: {sq.Side}");
Console.WriteLine($" Area: {sq.Area}");
break;
case Rectangle r when r.Area > 0:
Console.WriteLine("Information about the rectangle:");
Console.WriteLine($" Dimensions: {r.Length} x {r.Width}");
Console.WriteLine($" Area: {r.Area}");
break;
case Shape shape:
Console.WriteLine($"A {shape.GetType().Name} shape");
break;
case null:
Console.WriteLine($"The {nameof(obj)} variable is uninitialized.");
break;
default:
Console.WriteLine($"The {nameof(obj)} variable does not represent a Shape.");
break;
}
}
}
// The example displays the following output:
// Information about the square:
// Length of a side: 10
// Area: 100
// Information about the rectangle:
// Dimensions: 5 x 7
// Area: 35
// Information about the rectangle:
// Dimensions: 10 x 10
// Area: 100
// The obj variable is uninitialized.
// The shape: Square with no dimensions

Ayrıca bkz.
switch deyimi
try/catch deyimi
try/catch/finally deyimi
value (C# Başvurusu)
24.10.2019 • 2 minutes to read • Edit Online

Bağlamsal anahtar sözcük value , özellik ve dizin oluşturucu bildirimlerinde set erişimcisinde kullanılır.
Yöntemin giriş parametresine benzerdir. Sözcük value , istemci kodunun özelliğe veya dizin oluşturucusuna
atamaya çalışan değere başvurur. Aşağıdaki örnekte MyDerivedClass , name yedekleme alanına yeni bir dize
atamak için value parametresini kullanan Name adlı bir özelliğe sahiptir. İstemci kodunun bakış noktasından,
işlem basit atama olarak yazılır.

class MyBaseClass
{
// virtual auto-implemented property. Overrides can only
// provide specialized behavior if they implement get and set accessors.
public virtual string Name { get; set; }

// ordinary virtual property with backing field


private int num;
public virtual int Number
{
get { return num; }
set { num = value; }
}
}

class MyDerivedClass : MyBaseClass


{
private string name;

// Override auto-implemented property with ordinary property


// to provide specialized accessor behavior.
public override string Name
{
get
{
return name;
}
set
{
if (!string.IsNullOrEmpty(value))
{
name = value;
}
else
{
name = "Unknown";
}
}
}
}

Daha fazla bilgi için bkz. Özellikler ve Indexeres makaleleri.

C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir kaynaktır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Anahtar Sözcükleri
yield (C# Başvurusu)
23.10.2019 • 6 minutes to read • Edit Online

Bir ifadede yield bağlamsal anahtar sözcüğünü kullandığınızda, görünen yöntemin, işlecin veya get
erişimcinin bir yineleyici olduğunu belirtirsiniz. Bir yield Yineleyici tanımlamak için kullanmak, özel bir
koleksiyon için IEnumerable ve IEnumerator modelini uyguladığınızda açık bir ek sınıfa yönelik
gereksinimi kaldırır (bir numaralandırma için durumu IEnumerator<T> tutan sınıf, bir örnek için bkz.)
türüyle.
Aşağıdaki örnekte, yield ifadesinin iki formu gösterilmektedir.

yield return <expression>;


yield break;

Açıklamalar
Her öğeyi birer yield return birer döndürmek için bir ifade kullanırsınız.
Bir yineleyici yönteminden döndürülen sıra, foreach IFADESI veya LINQ sorgusu kullanılarak tüketilebilir.
foreach Döngünün her yinelemesi yineleyici yöntemini çağırır. Yineleyici yönteminde yield return bir
ifadeye ulaşıldığında, expression döndürülür ve koddaki geçerli konum korunur. Yürütme, yineleyici
işlevinin bir sonraki çağrılmasında bu konumdan başlar.
Yinelemeyi sonlandırmak için bir yield break ifade kullanabilirsiniz.
Yineleyiciler hakkında daha fazla bilgi için bkz. yineleyiciler.

Yineleyici yöntemleri ve get erişimcileri


Bir yineleyicinin bildirimi aşağıdaki gerekliliklerle uyuşmalıdır:
IEnumerableDönüş türü IEnumerable<T> ,,veyaIEnumerator<T>olmalıdır. IEnumerator
Bildirimin parametreleri olamaz ref veya Out .
Veya yield döndürenbirIEnumerable Yineleyici türü . object IEnumerator Yineleyici veya
IEnumerable<T> IEnumerator<T>döndürürse, deyimde deyim yield return türünden genel tür
parametresine örtük bir dönüştürme olmalıdır.
yield return İçine or yield break ifadesini ekleyemezsiniz:
Lambda ifadeleri ve Anonim yöntemler.
Güvenli olmayan bloklar içeren yöntemler. Daha fazla bilgi için bkz. güvenli değil.

Özel durum işleme


Bir yield return ifade, try-catch bloğunda bulunamaz. Bir yield return ifade, try-finally ifadesinin try
bloğunda bulunabilir.
Bir yield break ifade bir try bloğunda veya catch bloğunda bulunabilir, ancak finally bloğunda yer alabilir.
Gövde (yineleyici yönteminin dışında) bir özel durum oluşturursa, yineleyici yönteminde bir finally blok
yürütülür. foreach

Teknik uygulama
Aşağıdaki kod bir yineleyici yönteminden IEnumerable<string> bir döndürür ve sonra öğeleri boyunca
yinelenir.

IEnumerable<string> elements = MyIteratorMethod();


foreach (string element in elements)
{
...
}

Çağrısı MyIteratorMethod , yönteminin gövdesini yürütmez. Bunun yerine, çağrı IEnumerable<string>


elements değişkenine bir döndürür.
foreach Döngüsünün bir yinelemesinde MoveNext , yöntemi için elements çağrılır. Bu çağrı, sonraki
MyIteratorMethod yield return ifadeye ulaşılana kadar gövdesini yürütür. yield return Deyimi
tarafından döndürülen ifade, yalnızca Current döngü gövdesi tarafından tüketim için element değişkenin
değerini değil, öğesinin elements özelliğini de bir IEnumerable<string> olarak belirler.
foreach Döngünün sonraki tekrarında, yineleyici gövdesinin yürütülmesi kaldığınız yerden devam eder,
bir yield return ifadeye ulaştığında yeniden durdurulur. Yineleyici yönteminin sonuna veya bir
yield break ifadeye ulaşıldığında döngütamamlanır. foreach

Örnek
Aşağıdaki örnekte, for döngüsünün içinde yield return olan bir ifade vardır. Yöntemi içindeki ifade
gövdesinin her yinelemesi Power , Yineleyici işlevine bir çağrı oluşturur. foreach Main Yineleyici işlevine
yapılan her çağrı, yield return for döngüsünün bir sonraki yinelemesi sırasında ortaya çıkan deyimin
bir sonraki yürütmeye ilerler.
Yineleyici yönteminin IEnumerabledönüş türü, yineleyici arabirim türü olan. Yineleyici yöntem
çağrıldığında, bir sayının kuvvetlerini içeren sayılabilir bir nesne döndürür.
public class PowersOf2
{
static void Main()
{
// Display powers of 2 up to the exponent of 8:
foreach (int i in Power(2, 8))
{
Console.Write("{0} ", i);
}
}

public static System.Collections.Generic.IEnumerable<int> Power(int number, int exponent)


{
int result = 1;

for (int i = 0; i < exponent; i++)


{
result = result * number;
yield return result;
}
}

// Output: 2 4 8 16 32 64 128 256


}

Örnek
Aşağıdaki örnek, yineleyici olan get bir erişimciyi gösterir. Örnekte, her yield return bir ifade Kullanıcı
tanımlı bir sınıfın bir örneğini döndürür.

public static class GalaxyClass


{
public static void ShowGalaxies()
{
var theGalaxies = new Galaxies();
foreach (Galaxy theGalaxy in theGalaxies.NextGalaxy)
{
Debug.WriteLine(theGalaxy.Name + " " + theGalaxy.MegaLightYears.ToString());
}
}

public class Galaxies


{

public System.Collections.Generic.IEnumerable<Galaxy> NextGalaxy


{
get
{
yield return new Galaxy { Name = "Tadpole", MegaLightYears = 400 };
yield return new Galaxy { Name = "Pinwheel", MegaLightYears = 25 };
yield return new Galaxy { Name = "Milky Way", MegaLightYears = 0 };
yield return new Galaxy { Name = "Andromeda", MegaLightYears = 3 };
}
}

public class Galaxy


{
public String Name { get; set; }
public int MegaLightYears { get; set; }
}
}
C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir
kaynaktır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
foreach, in
Yineleyiciler
Sorgu anahtar sözcükleriC# (başvuru)
4.11.2019 • 2 minutes to read • Edit Online

Bu bölüm sorgu ifadelerinde kullanılan bağlamsal anahtar sözcüklerini içerir.

Bu bölümde
YAN TÜMCE AÇIKLAMA

Kaynak Bir veri kaynağını ve bir Aralık değişkenini (yineleme


değişkenine benzer) belirtir.

olmadığı Mantıksal ve ve veya işleçlerle ( && veya || ) ayrılmış bir


veya daha fazla Boole ifadesine göre kaynak öğelerine filtre
uygular.

seçin Sorgu yürütüldüğünde döndürülen dizideki öğelerin sahip


olacağı türü ve şekli belirtir.

grubu Sorgu sonuçlarını belirtilen bir anahtar değerine göre


gruplandırır.

into JOIN, Group veya Select yan tümcesinin sonuçlarına başvuru


olarak sunacak bir tanımlayıcı sağlar.

OrderBy Sorgu sonuçlarını, öğe türünün varsayılan karşılaştırmasına


göre artan veya azalan düzende sıralar.

ayrılma İki veri kaynağını belirtilen iki eşleşen ölçüt arasında bir eşitlik
karşılaştırması temelinde birleştirir.

atalım Bir sorgu ifadesinde alt ifade sonuçlarının depolanması için bir
Aralık değişkeni tanıtır.

in JOIN yan tümcesinde bağlamsal anahtar sözcüğü.

on JOIN yan tümcesinde bağlamsal anahtar sözcüğü.

equals JOIN yan tümcesinde bağlamsal anahtar sözcüğü.

by Bir Group yan tümcesindeki bağlamsal anahtar sözcüğü.

ascending Bir OrderBy yan tümcesindeki bağlamsal anahtar sözcüğü.

descending Bir OrderBy yan tümcesindeki bağlamsal anahtar sözcüğü.

Ayrıca bkz.
C# Anahtar Sözcükleri
LINQ (dil ile tümleşik sorgu)
C# üzerinde LINQ
C#'de LINQ Kullanmaya Başlama
from tümcesi (C# Başvurusu)
23.10.2019 • 8 minutes to read • Edit Online

Sorgu ifadesi ile başlamalıdır bir from yan tümcesi. Ayrıca, bir sorgu ifadesi de şununla alt sorgularda
içerebilir bir from yan tümcesi. from Yan tümcesi şunları belirtir:
Veri kaynağı üzerinde sorgu veya alt sorgu çalıştırılır.
Yerel bir aralık değişkeni , kaynak dizideki her öğe temsil eder.
Veri kaynağı ve aralık değişkeni kesin türlü yapılır. Başvurulan veri kaynağı from yan tümcesi, bir tür
olmalıdır IEnumerable, IEnumerable<T>, veya türetilmiş bir tür gibi IQueryable<T>.
Aşağıdaki örnekte, numbers veri kaynağıdır ve num aralık değişkeni. Her iki değişken olsa bile kesin olarak
belirlenmiştir, Not var anahtar sözcüğü kullanılır.

class LowNums
{
static void Main()
{
// A simple data source.
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

// Create the query.


// lowNums is an IEnumerable<int>
var lowNums = from num in numbers
where num < 5
select num;

// Execute the query.


foreach (int i in lowNums)
{
Console.Write(i + " ");
}
}
}
// Output: 4 1 3 2 0

Aralık değişkeni
Veri kaynağı uygular, derleyici Aralık değişkeninin türünü çıkarsar IEnumerable<T>. Örneğin, kaynak türü
varsa IEnumerable<Customer> , aralık değişkeni olması sorguluyorsanız Customer . Açıkça türüdür ne zaman
belirtmelisiniz. yalnızca bir kez kaynağı olan genel olmayan IEnumerable gibi yazın ArrayList. Daha fazla bilgi
için nasıl yapılır: LINQ ile ArrayList sorgulama.
Önceki örnekte num türünde olmasını çıkarılan int . Aralık değişkeninin türü kesin olarak belirtilmiş
olduğundan üzerinde yöntemleri çağırmak ya da diğer işlemleri kullanın. Örneğin, yazmak yerine select num
, şunu yazabilirsiniz select num.ToString() dize yerine tamsayı bir dizisini döndürmek sorgu ifadesi neden
olacak. Veya şunu yazabilirsiniz select num + 10 14 dizisini döndürmek için ifadeyi neden 11, 13, 12, 10.
Daha fazla bilgi için select yan tümcesi.
Bir yineleme değişkeni aralık değişkeni benzer bir foreach çok önemli bir fark dışında deyimi: bir aralık
değişkenine asla gerçekten kaynaktan gelen verileri depolar. Yalnızca bir sorgu çalıştırıldığında ne olacağını
açıklamak sorgu sağlar söz dizimsel kolaylık bir özelliktir. Daha fazla bilgi için (C#) LINQ sorgularına giriş.
Bileşik yan tümcelerinden
Bazı durumlarda, kaynak dizideki her öğe kendisi ya da bir dizi veya bir dizisini içerir. Örneğin, veri
kaynağınızın olabilir bir IEnumerable<Student> burada dizideki her Öğrenci nesne içeren test puanlarını listesi.
Her iç listesine erişmek için Student öğesi bileşik kullanabilirsiniz from yan tümceleri. Kullanarak içe gibi
tekniktir foreach deyimleri. Ekleyebileceğiniz burada veya orderby ya da yan tümceleri from sonuçları
filtrelemek için yan tümcesi. Aşağıdaki örnek, bir dizi gösterir Student her biri içeren bir iç nesneler List
tamsayılar temsil eden test puanlarını. İç listesine erişmek için bileşik kullanın from yan tümcesi. İkisi
arasındaki yan tümce ekleyebilirsiniz from yan tümceleri gerekirse.
class CompoundFrom
{
// The element type of the data source.
public class Student
{
public string LastName { get; set; }
public List<int> Scores {get; set;}
}

static void Main()


{

// Use a collection initializer to create the data source. Note that


// each element in the list contains an inner sequence of scores.
List<Student> students = new List<Student>
{
new Student {LastName="Omelchenko", Scores= new List<int> {97, 72, 81, 60}},
new Student {LastName="O'Donnell", Scores= new List<int> {75, 84, 91, 39}},
new Student {LastName="Mortensen", Scores= new List<int> {88, 94, 65, 85}},
new Student {LastName="Garcia", Scores= new List<int> {97, 89, 85, 82}},
new Student {LastName="Beebe", Scores= new List<int> {35, 72, 91, 70}}
};

// Use a compound from to access the inner sequence within each element.
// Note the similarity to a nested foreach statement.
var scoreQuery = from student in students
from score in student.Scores
where score > 90
select new { Last = student.LastName, score };

// Execute the queries.


Console.WriteLine("scoreQuery:");
// Rest the mouse pointer on scoreQuery in the following line to
// see its type. The type is IEnumerable<'a>, where 'a is an
// anonymous type defined as new {string Last, int score}. That is,
// each instance of this anonymous type has two members, a string
// (Last) and an int (score).
foreach (var student in scoreQuery)
{
Console.WriteLine("{0} Score: {1}", student.Last, student.score);
}

// Keep the console window open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/*
scoreQuery:
Omelchenko Score: 97
O'Donnell Score: 91
Mortensen Score: 94
Garcia Score: 97
Beebe Score: 91
*/

Birleştirmeler gerçekleştirme için birden çok yan tümceleri'den


kullanma
Bileşik from yan tümcesi, tek bir veri kaynağındaki iç koleksiyonlara erişmek için kullanılır. Ancak, bir sorgu
birden çok de içerebilir from yan tümceleri bağımsız veri kaynaklarından ek sorgular oluşturun. Belirli
türlerini kullanarak mümkün olmayan birleştirme işlemleri gerçekleştirmek Bu teknik sayesinde JOIN yan
tümcesi.
Aşağıdaki örnekte gösterildiği nasıl iki from yan tümceleri, iki veri kaynaklarının tam çapraz birleştirme
oluşturmak için kullanılabilir.
class CompoundFrom2
{
static void Main()
{
char[] upperCase = { 'A', 'B', 'C' };
char[] lowerCase = { 'x', 'y', 'z' };

// The type of joinQuery1 is IEnumerable<'a>, where 'a


// indicates an anonymous type. This anonymous type has two
// members, upper and lower, both of type char.
var joinQuery1 =
from upper in upperCase
from lower in lowerCase
select new { upper, lower };

// The type of joinQuery2 is IEnumerable<'a>, where 'a


// indicates an anonymous type. This anonymous type has two
// members, upper and lower, both of type char.
var joinQuery2 =
from lower in lowerCase
where lower != 'x'
from upper in upperCase
select new { lower, upper };

// Execute the queries.


Console.WriteLine("Cross join:");
// Rest the mouse pointer on joinQuery1 to verify its type.
foreach (var pair in joinQuery1)
{
Console.WriteLine("{0} is matched to {1}", pair.upper, pair.lower);
}

Console.WriteLine("Filtered non-equijoin:");
// Rest the mouse pointer over joinQuery2 to verify its type.
foreach (var pair in joinQuery2)
{
Console.WriteLine("{0} is matched to {1}", pair.lower, pair.upper);
}

// Keep the console window open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* Output:
Cross join:
A is matched to x
A is matched to y
A is matched to z
B is matched to x
B is matched to y
B is matched to z
C is matched to x
C is matched to y
C is matched to z
Filtered non-equijoin:
y is matched to A
y is matched to B
y is matched to C
z is matched to A
z is matched to B
z is matched to C
*/

Birden çok kullanan birleştirme işlemleri hakkında daha fazla bilgi için from yan tümcesi bkz sol dış
birleştirmeler gerçekleştirme.

Ayrıca bkz.
Query Keywords (LINQ )
Dil ile Tümleşik Sorgu (LINQ )
where tümcesi (C# Başvurusu)
4.11.2019 • 4 minutes to read • Edit Online

where yan tümcesi, sorgu ifadesinde veri kaynağından hangi öğelerin döndürüleceğini belirtmek için bir
sorgu ifadesinde kullanılır. Her kaynak öğesine (Aralık değişkeni tarafından başvurulan) bir Boolean koşulu
(koşul) uygular ve belirtilen koşulun doğru olduğu öğeleri döndürür. Tek bir sorgu ifadesinde birden çok
where yan tümce bulunabilir ve tek bir yan tümce birden çok koşul alt ifadesi içerebilir.

Örnek
Aşağıdaki örnekte where yan tümcesi, beş ' den az olanlar hariç tüm sayıları filtreler. where yan tümcesini
kaldırırsanız, veri kaynağındaki tüm sayılar döndürülür. num < 5 ifadesi her bir öğeye uygulanan belirtedir.

class WhereSample
{
static void Main()
{
// Simple data source. Arrays support IEnumerable<T>.
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

// Simple query with one predicate in where clause.


var queryLowNums =
from num in numbers
where num < 5
select num;

// Execute the query.


foreach (var s in queryLowNums)
{
Console.Write(s.ToString() + " ");
}
}
}
//Output: 4 1 3 2 0

Örnek
Tek bir where yan tümcesi içinde, && ve | işleçlerini kullanarak gereken sayıda koşul belirtebilirsiniz.
Aşağıdaki örnekte sorgu, yalnızca beş ' dan küçük olan sayıları seçmek için iki koşul belirtir.
class WhereSample2
{
static void Main()
{
// Data source.
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

// Create the query with two predicates in where clause.


var queryLowNums2 =
from num in numbers
where num < 5 && num % 2 == 0
select num;

// Execute the query


foreach (var s in queryLowNums2)
{
Console.Write(s.ToString() + " ");
}
Console.WriteLine();

// Create the query with two where clause.


var queryLowNums3 =
from num in numbers
where num < 5
where num % 2 == 0
select num;

// Execute the query


foreach (var s in queryLowNums3)
{
Console.Write(s.ToString() + " ");
}

}
}
// Output:
// 4 2 0
// 4 2 0

Örnek
where yan tümcesi, Boole değerleri döndüren bir veya daha fazla yöntem içerebilir. Aşağıdaki örnekte,
where yan tümcesi, Aralık değişkeninin geçerli değerinin çift mi yoksa tek mi olduğunu anlamak için bir
yöntem kullanır.
class WhereSample3
{
static void Main()
{
// Data source
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

// Create the query with a method call in the where clause.


// Note: This won't work in LINQ to SQL unless you have a
// stored procedure that is mapped to a method by this name.
var queryEvenNums =
from num in numbers
where IsEven(num)
select num;

// Execute the query.


foreach (var s in queryEvenNums)
{
Console.Write(s.ToString() + " ");
}
}

// Method may be instance method or static method.


static bool IsEven(int i)
{
return i % 2 == 0;
}
}
//Output: 4 8 6 2 0

Açıklamalar
where yan tümcesi bir filtreleme mekanizmasıdır. Bir sorgu ifadesinde neredeyse her yerde
konumlandırılmış olabilir, ancak ilk veya son yan tümce olamaz. Bir where yan tümcesi,
gruplandırıldıklarında veya sonra kaynak öğeleri filtrelemeniz gerekip gerekmediğini bağlı olarak, bir Grup
yan tümcesinden önce veya sonra görünebilir.
Belirtilen koşul veri kaynağındaki öğeler için geçerli değilse, bir derleme zamanı hatası ortaya kalır. Bu,
LINQtarafından sunulan güçlü tür denetlemenin bir avantajıdır.
Derleme zamanında where anahtar sözcüğü Where standart sorgu Işleci yöntemine yapılan çağrıya
dönüştürülür.

Ayrıca bkz.
Sorgu anahtar sözcükleri (LINQ )
from yan tümcesi
select yan tümcesi
Verileri Filtreleme
C# üzerinde LINQ
C#'de LINQ Kullanmaya Başlama
select tümcesi (C# Başvurusu)
4.11.2019 • 7 minutes to read • Edit Online

Sorgu ifadesinde select yan tümcesi, sorgu yürütüldüğünde üretilecek değerlerin türünü belirtir. Sonuç,
tüm önceki yan tümcelerinin ve select yan tümcesinin içindeki herhangi bir ifadenin değerlendirmesine
dayanır. Sorgu ifadesinin bir select yan tümcesiyle veya bir Grup yan tümcesiyle sonlandırılması gerekir.
Aşağıdaki örnekte, bir sorgu ifadesinde basit bir select yan tümcesi gösterilmektedir.

class SelectSample1
{
static void Main()
{
//Create the data source
List<int> Scores = new List<int>() { 97, 92, 81, 60 };

// Create the query.


IEnumerable<int> queryHighScores =
from score in Scores
where score > 80
select score;

// Execute the query.


foreach (int i in queryHighScores)
{
Console.Write(i + " ");
}
}
}
//Output: 97 92 81

select yan tümcesi tarafından üretilen sıranın türü, queryHighScores sorgu değişkeninin türünü belirler. En
basit durumda, select yan tümcesi yalnızca Aralık değişkenini belirtir. Bu, döndürülen sıranın veri
kaynağıyla aynı türdeki öğeleri içermesini sağlar. Daha fazla bilgi için bkz. LINQ sorgu Işlemlerinde tür
ilişkileri. Ancak select yan tümcesi, kaynak verilerini yeni türlere dönüştürmek (veya yansıtma) için güçlü
bir mekanizma sağlar. Daha fazla bilgi için bkz. LINQ (C#) ile veri dönüştürmeleri.

Örnek
Aşağıdaki örnek, bir select yan tümcesinin götüreolabileceği tüm farklı formları gösterir. Her sorguda
select yan tümcesi ve sorgu değişkeninin türü ( studentQuery1 , studentQuery2 , vb.) arasındaki ilişkiyi
aklınızda yazın.

class SelectSample2
{
// Define some classes
public class Student
{
public string First { get; set; }
public string Last { get; set; }
public int ID { get; set; }
public List<int> Scores;
public ContactInfo GetContactInfo(SelectSample2 app, int id)
{
ContactInfo cInfo =
(from ci in app.contactList
where ci.ID == id
where ci.ID == id
select ci)
.FirstOrDefault();

return cInfo;
}

public override string ToString()


{
return First + " " + Last + ":" + ID;
}
}

public class ContactInfo


{
public int ID { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public override string ToString() { return Email + "," + Phone; }
}

public class ScoreInfo


{
public double Average { get; set; }
public int ID { get; set; }
}

// The primary data source


List<Student> students = new List<Student>()
{
new Student {First="Svetlana", Last="Omelchenko", ID=111, Scores= new List<int>() {97, 92,
81, 60}},
new Student {First="Claire", Last="O'Donnell", ID=112, Scores= new List<int>() {75, 84, 91,
39}},
new Student {First="Sven", Last="Mortensen", ID=113, Scores= new List<int>() {88, 94, 65,
91}},
new Student {First="Cesar", Last="Garcia", ID=114, Scores= new List<int>() {97, 89, 85,
82}},
};

// Separate data source for contact info.


List<ContactInfo> contactList = new List<ContactInfo>()
{
new ContactInfo {ID=111, Email="SvetlanO@Contoso.com", Phone="206-555-0108"},
new ContactInfo {ID=112, Email="ClaireO@Contoso.com", Phone="206-555-0298"},
new ContactInfo {ID=113, Email="SvenMort@Contoso.com", Phone="206-555-1130"},
new ContactInfo {ID=114, Email="CesarGar@Contoso.com", Phone="206-555-0521"}
};

static void Main(string[] args)


{
SelectSample2 app = new SelectSample2();

// Produce a filtered sequence of unmodified Students.


IEnumerable<Student> studentQuery1 =
from student in app.students
where student.ID > 111
select student;

Console.WriteLine("Query1: select range_variable");


foreach (Student s in studentQuery1)
{
Console.WriteLine(s.ToString());
}

// Produce a filtered sequence of elements that contain


// only one property of each Student.
IEnumerable<String> studentQuery2 =
from student in app.students
from student in app.students
where student.ID > 111
select student.Last;

Console.WriteLine("\r\n studentQuery2: select range_variable.Property");


foreach (string s in studentQuery2)
{
Console.WriteLine(s);
}

// Produce a filtered sequence of objects created by


// a method call on each Student.
IEnumerable<ContactInfo> studentQuery3 =
from student in app.students
where student.ID > 111
select student.GetContactInfo(app, student.ID);

Console.WriteLine("\r\n studentQuery3: select range_variable.Method");


foreach (ContactInfo ci in studentQuery3)
{
Console.WriteLine(ci.ToString());
}

// Produce a filtered sequence of ints from


// the internal array inside each Student.
IEnumerable<int> studentQuery4 =
from student in app.students
where student.ID > 111
select student.Scores[0];

Console.WriteLine("\r\n studentQuery4: select range_variable[index]");


foreach (int i in studentQuery4)
{
Console.WriteLine("First score = {0}", i);
}

// Produce a filtered sequence of doubles


// that are the result of an expression.
IEnumerable<double> studentQuery5 =
from student in app.students
where student.ID > 111
select student.Scores[0] * 1.1;

Console.WriteLine("\r\n studentQuery5: select expression");


foreach (double d in studentQuery5)
{
Console.WriteLine("Adjusted first score = {0}", d);
}

// Produce a filtered sequence of doubles that are


// the result of a method call.
IEnumerable<double> studentQuery6 =
from student in app.students
where student.ID > 111
select student.Scores.Average();

Console.WriteLine("\r\n studentQuery6: select expression2");


foreach (double d in studentQuery6)
{
Console.WriteLine("Average = {0}", d);
}

// Produce a filtered sequence of anonymous types


// that contain only two properties from each Student.
var studentQuery7 =
from student in app.students
where student.ID > 111
select new { student.First, student.Last };
Console.WriteLine("\r\n studentQuery7: select new anonymous type");
foreach (var item in studentQuery7)
{
Console.WriteLine("{0}, {1}", item.Last, item.First);
}

// Produce a filtered sequence of named objects that contain


// a method return value and a property from each Student.
// Use named types if you need to pass the query variable
// across a method boundary.
IEnumerable<ScoreInfo> studentQuery8 =
from student in app.students
where student.ID > 111
select new ScoreInfo
{
Average = student.Scores.Average(),
ID = student.ID
};

Console.WriteLine("\r\n studentQuery8: select new named type");


foreach (ScoreInfo si in studentQuery8)
{
Console.WriteLine("ID = {0}, Average = {1}", si.ID, si.Average);
}

// Produce a filtered sequence of students who appear on a contact list


// and whose average is greater than 85.
IEnumerable<ContactInfo> studentQuery9 =
from student in app.students
where student.Scores.Average() > 85
join ci in app.contactList on student.ID equals ci.ID
select ci;

Console.WriteLine("\r\n studentQuery9: select result of join clause");


foreach (ContactInfo ci in studentQuery9)
{
Console.WriteLine("ID = {0}, Email = {1}", ci.ID, ci.Email);
}

// Keep the console window open in debug mode


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* Output
Query1: select range_variable
Claire O'Donnell:112
Sven Mortensen:113
Cesar Garcia:114

studentQuery2: select range_variable.Property


O'Donnell
Mortensen
Garcia

studentQuery3: select range_variable.Method


ClaireO@Contoso.com,206-555-0298
SvenMort@Contoso.com,206-555-1130
CesarGar@Contoso.com,206-555-0521

studentQuery4: select range_variable[index]


First score = 75
First score = 88
First score = 97

studentQuery5: select expression


Adjusted first score = 82.5
Adjusted first score = 96.8
Adjusted first score = 106.7
Adjusted first score = 106.7

studentQuery6: select expression2


Average = 72.25
Average = 84.5
Average = 88.25

studentQuery7: select new anonymous type


O'Donnell, Claire
Mortensen, Sven
Garcia, Cesar

studentQuery8: select new named type


ID = 112, Average = 72.25
ID = 113, Average = 84.5
ID = 114, Average = 88.25

studentQuery9: select result of join clause


ID = 114, Email = CesarGar@Contoso.com
*/

Önceki örnekte studentQuery8 gösterildiği gibi, bazen döndürülen dizideki öğelerin yalnızca kaynak öğelerin
özelliklerinin bir alt kümesini içermesini isteyebilirsiniz. Döndürülen sırayı mümkün olduğunca küçük
tutarak, bellek gereksinimlerini azaltabilir ve sorgunun yürütme hızını artırabilirsiniz. Bunu, select yan
tümcesinde anonim bir tür oluşturarak ve kaynak öğeden uygun özelliklerle başlatmak için bir nesne
Başlatıcısı kullanarak yapabilirsiniz. Bunun nasıl yapılacağı hakkında bir örnek için bkz. nesne ve koleksiyon
başlatıcıları.

Açıklamalar
Derleme zamanında, select yan tümcesi Select standart sorgu işlecine bir yöntem çağrısına çevrilir.

Ayrıca bkz.
C#Başvurunun
Sorgu anahtar sözcükleri (LINQ )
from yan tümcesi
partial (Yöntem) (C# başvuru)
Anonim Tipler
C# üzerinde LINQ
C#'de LINQ Kullanmaya Başlama
group tümcesi (C# Başvurusu)
27.11.2019 • 11 minutes to read • Edit Online

group yan tümcesi, grup için anahtar değeriyle eşleşen sıfır veya daha fazla öğe içeren bir
IGrouping<TKey,TElement> nesneleri dizisi döndürür. Örneğin, her bir dizedeki ilk harfe göre bir dizi dizeyi
gruplandırabilirsiniz. Bu durumda, ilk harf anahtardır ve bir tür chariçerir ve her
IGrouping<TKey,TElement> nesnesinin Key özelliğinde saklanır. Derleyici, anahtarın türünü haller.
Aşağıdaki örnekte gösterildiği gibi, bir sorgu ifadesini group yan tümcesiyle sona erdirmek isteyebilirsiniz:

// Query variable is an IEnumerable<IGrouping<char, Student>>


var studentQuery1 =
from student in students
group student by student.Last[0];

Her grupta ek sorgu işlemleri gerçekleştirmek istiyorsanız, ' ın bağlamsal anahtar sözcüğünü kullanarak
geçici bir tanımlayıcı belirtebilirsiniz. into kullandığınızda, sorguyla devam etmeniz ve sonunda aşağıdaki
alıntıda gösterildiği gibi bir select deyimi veya başka bir group yan tümcesiyle sona erdirmek gerekir:

// Group students by the first letter of their last name


// Query variable is an IEnumerable<IGrouping<char, Student>>
var studentQuery2 =
from student in students
group student by student.Last[0] into g
orderby g.Key
select g;

Bu makalenin örnek bölümünde into ve olmadan group kullanımı için daha kapsamlı örnekler verilmiştir.

Bir grup sorgusunun sonuçlarını numaralandırma


Bir group sorgusu tarafından oluşturulan IGrouping<TKey,TElement> nesneleri temelde bir liste listesi
olduğundan, her bir gruptaki öğelere erişmek için iç içe geçmiş bir foreach döngüsü kullanmanız gerekir.
Dış döngü grup anahtarlarının üzerinde yinelenir ve iç döngü gruptaki her öğe için yinelenir. Bir grupta
anahtar olabilir ancak öğe yok. Aşağıda, önceki kod örneklerinde sorguyu yürüten foreach döngüsü
verilmiştir:

// Iterate group items with a nested foreach. This IGrouping encapsulates


// a sequence of Student objects, and a Key of type char.
// For convenience, var can also be used in the foreach statement.
foreach (IGrouping<char, Student> studentGroup in studentQuery2)
{
Console.WriteLine(studentGroup.Key);
// Explicit type for student could also be used here.
foreach (var student in studentGroup)
{
Console.WriteLine(" {0}, {1}", student.Last, student.First);
}
}

Anahtar türleri
Grup anahtarları dize, yerleşik bir sayısal tür veya Kullanıcı tanımlı adlandırılmış tür veya anonim tür gibi
herhangi bir tür olabilir.
Dizeye göre gruplandırma
Önceki kod örnekleri bir char kullandı. Bunun yerine bir dize anahtarı kolayca belirtilmelidir, örneğin, son
soyadı adı:

// Same as previous example except we use the entire last name as a key.
// Query variable is an IEnumerable<IGrouping<string, Student>>
var studentQuery3 =
from student in students
group student by student.Last;

Bool ile gruplandırma


Aşağıdaki örnek, sonuçları iki gruba bölmek için bir anahtar için bool değer kullanımını gösterir. Değerin
group yan tümcesindeki bir alt ifade tarafından üretildiğini unutmayın.

class GroupSample1
{
// The element type of the data source.
public class Student
{
public string First { get; set; }
public string Last { get; set; }
public int ID { get; set; }
public List<int> Scores;
}

public static List<Student> GetStudents()


{
// Use a collection initializer to create the data source. Note that each element
// in the list contains an inner sequence of scores.
List<Student> students = new List<Student>
{
new Student {First="Svetlana", Last="Omelchenko", ID=111, Scores= new List<int> {97, 72, 81,
60}},
new Student {First="Claire", Last="O'Donnell", ID=112, Scores= new List<int> {75, 84, 91,
39}},
new Student {First="Sven", Last="Mortensen", ID=113, Scores= new List<int> {99, 89, 91,
95}},
new Student {First="Cesar", Last="Garcia", ID=114, Scores= new List<int> {72, 81, 65, 84}},
new Student {First="Debra", Last="Garcia", ID=115, Scores= new List<int> {97, 89, 85, 82}}
};

return students;

static void Main()


{
// Obtain the data source.
List<Student> students = GetStudents();

// Group by true or false.


// Query variable is an IEnumerable<IGrouping<bool, Student>>
var booleanGroupQuery =
from student in students
group student by student.Scores.Average() >= 80; //pass or fail!

// Execute the query and access items in each group


foreach (var studentGroup in booleanGroupQuery)
{
Console.WriteLine(studentGroup.Key == true ? "High averages" : "Low averages");
foreach (var student in studentGroup)
foreach (var student in studentGroup)
{
Console.WriteLine(" {0}, {1}:{2}", student.Last, student.First,
student.Scores.Average());
}
}

// Keep the console window open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* Output:
Low averages
Omelchenko, Svetlana:77.5
O'Donnell, Claire:72.25
Garcia, Cesar:75.5
High averages
Mortensen, Sven:93.5
Garcia, Debra:88.25
*/

Sayısal aralığa göre gruplandırma


Sonraki örnek, bir yüzdebirlik aralığını temsil eden sayısal grup anahtarları oluşturmak için bir ifade
kullanır. Yöntem çağrı sonucunu depolamak için uygun bir konum olarak izin ver öğesinin kullanımını
unutmayın. bu sayede yöntemi group yan tümcesinde iki kez çağırmak zorunda kalmazsınız. Sorgu
ifadelerinde yöntemleri güvenle kullanma hakkında daha fazla bilgi için bkz. nasıl yapılır: sorgu Ifadelerinde
özel durumları işleme.

class GroupSample2
{
// The element type of the data source.
public class Student
{
public string First { get; set; }
public string Last { get; set; }
public int ID { get; set; }
public List<int> Scores;
}

public static List<Student> GetStudents()


{
// Use a collection initializer to create the data source. Note that each element
// in the list contains an inner sequence of scores.
List<Student> students = new List<Student>
{
new Student {First="Svetlana", Last="Omelchenko", ID=111, Scores= new List<int> {97, 72, 81,
60}},
new Student {First="Claire", Last="O'Donnell", ID=112, Scores= new List<int> {75, 84, 91,
39}},
new Student {First="Sven", Last="Mortensen", ID=113, Scores= new List<int> {99, 89, 91,
95}},
new Student {First="Cesar", Last="Garcia", ID=114, Scores= new List<int> {72, 81, 65, 84}},
new Student {First="Debra", Last="Garcia", ID=115, Scores= new List<int> {97, 89, 85, 82}}
};

return students;

// This method groups students into percentile ranges based on their


// grade average. The Average method returns a double, so to produce a whole
// number it is necessary to cast to int before dividing by 10.
static void Main()
{
// Obtain the data source.
// Obtain the data source.
List<Student> students = GetStudents();

// Write the query.


var studentQuery =
from student in students
let avg = (int)student.Scores.Average()
group student by (avg / 10) into g
orderby g.Key
select g;

// Execute the query.


foreach (var studentGroup in studentQuery)
{
int temp = studentGroup.Key * 10;
Console.WriteLine("Students with an average between {0} and {1}", temp, temp + 10);
foreach (var student in studentGroup)
{
Console.WriteLine(" {0}, {1}:{2}", student.Last, student.First,
student.Scores.Average());
}
}

// Keep the console window open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* Output:
Students with an average between 70 and 80
Omelchenko, Svetlana:77.5
O'Donnell, Claire:72.25
Garcia, Cesar:75.5
Students with an average between 80 and 90
Garcia, Debra:88.25
Students with an average between 90 and 100
Mortensen, Sven:93.5
*/

Bileşik anahtarlara göre gruplandırma


Öğeleri birden fazla anahtara göre gruplandırmak istediğinizde bileşik anahtar kullanın. Anahtar öğesini
tutmak için anonim bir tür veya adlandırılmış bir tür kullanarak bileşik anahtar oluşturursunuz. Aşağıdaki
örnekte, bir sınıf Person surname ve city adlı üyelerle bildirildiği varsayılır. group yan tümcesi, aynı
soyadı ve aynı şehirde bulunan her kişi kümesi için ayrı bir grubun oluşturulmasına neden olur.

group person by new {name = person.surname, city = person.city};

Sorgu değişkenini başka bir yönteme geçirmeniz gerekiyorsa adlandırılmış bir tür kullanın. Anahtarlar için
otomatik uygulanan özellikler kullanarak özel bir sınıf oluşturun ve ardından Equals ve GetHashCode
yöntemlerini geçersiz kılın. Ayrıca, bu yöntemleri kesin bir şekilde geçersiz kılmak zorunda değilsiniz bir
yapı da kullanabilirsiniz. Daha fazla bilgi için bkz. Otomatik uygulanan özelliklerle hafif bir sınıf uygulama
ve nasıl yapılır: bir dizin ağacındaki yinelenen dosyaları sorgulama. İkinci makalede, adlandırılmış tür ile
bileşik anahtarın nasıl kullanılacağını gösteren bir kod örneği bulunur.

Örnek
Aşağıdaki örnek, gruplara ek sorgu mantığı uygulanırken kaynak verileri gruplara sıralamak için standart
düzeni gösterir. Bu, devamlılık olmadan gruplandırma olarak adlandırılır. Dizeler dizisindeki öğeler, ilk
harfine göre gruplandırılır. Sorgunun sonucu, char türünde ortak bir Key özelliği ve gruplandırmadaki
her öğeyi içeren bir IEnumerable<T> koleksiyonu içeren IGrouping<TKey,TElement> türüdür.
group yan tümcesinin sonucu bir dizi dizidir. Bu nedenle, döndürülen her grup içindeki ayrı öğelere
erişmek için, aşağıdaki örnekte gösterildiği gibi, döngü içinde, bir iç içe foreach döngüsünü kullanın.

class GroupExample1
{
static void Main()
{
// Create a data source.
string[] words = { "blueberry", "chimpanzee", "abacus", "banana", "apple", "cheese" };

// Create the query.


var wordGroups =
from w in words
group w by w[0];

// Execute the query.


foreach (var wordGroup in wordGroups)
{
Console.WriteLine("Words that start with the letter '{0}':", wordGroup.Key);
foreach (var word in wordGroup)
{
Console.WriteLine(word);
}
}

// Keep the console window open in debug mode


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* Output:
Words that start with the letter 'b':
blueberry
banana
Words that start with the letter 'c':
chimpanzee
cheese
Words that start with the letter 'a':
abacus
apple
*/

Örnek
Bu örnek, into ile devam eden bir devamlılığın kullanıldığı gruplar üzerinde ek mantığın nasıl
gerçekleştirileceğini gösterir. Daha fazla bilgi için bkz .. Aşağıdaki örnek, her bir grubu yalnızca anahtar
değerini bir sesli harf olarak seçmek üzere sorgular.
class GroupClauseExample2
{
static void Main()
{
// Create the data source.
string[] words2 = { "blueberry", "chimpanzee", "abacus", "banana", "apple", "cheese",
"elephant", "umbrella", "anteater" };

// Create the query.


var wordGroups2 =
from w in words2
group w by w[0] into grps
where (grps.Key == 'a' || grps.Key == 'e' || grps.Key == 'i'
|| grps.Key == 'o' || grps.Key == 'u')
select grps;

// Execute the query.


foreach (var wordGroup in wordGroups2)
{
Console.WriteLine("Groups that start with a vowel: {0}", wordGroup.Key);
foreach (var word in wordGroup)
{
Console.WriteLine(" {0}", word);
}
}

// Keep the console window open in debug mode


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* Output:
Groups that start with a vowel: a
abacus
apple
anteater
Groups that start with a vowel: e
elephant
Groups that start with a vowel: u
umbrella
*/

Açıklamalar
Derleme zamanında, group yan tümceleri GroupBy yöntemine yapılan çağrılara çevrilir.

Ayrıca bkz.
IGrouping<TKey,TElement>
GroupBy
ThenBy
ThenByDescending
Sorgu Anahtar Sözcükleri
Dil ile Tümleşik Sorgu (LINQ )
İç içe geçmiş grup oluşturma
Sorgu sonuçlarını gruplandırma
Gruplandırma işleminde alt sorgu gerçekleştirme
into (C# Başvurusu)
4.11.2019 • 2 minutes to read • Edit Online

into bağlamsal anahtar sözcüğü, bir Grup, JOIN veya Select yan tümcesinin sonuçlarını yeni bir tanımlayıcıya
depolamak üzere geçici bir tanımlayıcı oluşturmak için kullanılabilir. Bu tanımlayıcı, ek sorgu komutları için bir
Oluşturucu olabilir. Bir group veya select yan tümcesinde kullanıldığında, yeni tanımlayıcının kullanımı bazen
devamlılıkolarak adlandırılır.

Örnek
Aşağıdaki örnek, fruitGroup bir IGrouping türü olan geçici bir tanımlayıcıyı etkinleştirmek için into anahtar
sözcüğünün kullanımını gösterir. Tanımlayıcıyı kullanarak, her grupta Count yöntemi çağırabilir ve yalnızca iki
veya daha fazla sözcük içeren grupları seçebilirsiniz.

class IntoSample1
{
static void Main()
{

// Create a data source.


string[] words = { "apples", "blueberries", "oranges", "bananas", "apricots"};

// Create the query.


var wordGroups1 =
from w in words
group w by w[0] into fruitGroup
where fruitGroup.Count() >= 2
select new { FirstLetter = fruitGroup.Key, Words = fruitGroup.Count() };

// Execute the query. Note that we only iterate over the groups,
// not the items in each group
foreach (var item in wordGroups1)
{
Console.WriteLine(" {0} has {1} elements.", item.FirstLetter, item.Words);
}

// Keep the console window open in debug mode


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* Output:
a has 2 elements.
b has 2 elements.
*/

group yan tümcesinde into kullanımı yalnızca her grupta ek sorgu işlemleri gerçekleştirmek istediğinizde
gereklidir. Daha fazla bilgi için bkz. Group yan tümcesi.
Bir join yan tümcesinde into kullanımı örneği için bkz. JOIN yan tümcesi.

Ayrıca bkz.
Sorgu anahtar sözcükleri (LINQ )
C# üzerinde LINQ
group yan tümcesi
orderby tümcesi (C# Başvurusu)
4.11.2019 • 3 minutes to read • Edit Online

Sorgu ifadesinde orderby yan tümcesi, döndürülen sıranın veya alt dizinin (Grup) artan veya azalan sırada
sıralanmasını sağlar. Bir veya daha fazla ikincil sıralama işlemi gerçekleştirmek için birden çok anahtar
belirtilebilir. Sıralama, öğe türü için varsayılan karşılaştırıcı tarafından gerçekleştirilir. Varsayılan sıralama
düzeni artan. Ayrıca, özel bir karşılaştırıcı da belirtebilirsiniz. Ancak, yalnızca Yöntem tabanlı sözdizimi
kullanılarak kullanılabilir. Daha fazla bilgi için bkz. verileri sıralama.

Örnek
Aşağıdaki örnekte, ilk sorgu kelimeleri bir ' dan başlayarak alfabetik sırada sıralar ve ikinci sorgu aynı
sözcükleri azalan düzende sıralar. ( ascending anahtar sözcüğü varsayılan sıralama değeridir ve atlanabilir.)
class OrderbySample1
{
static void Main()
{
// Create a delicious data source.
string[] fruits = { "cherry", "apple", "blueberry" };

// Query for ascending sort.


IEnumerable<string> sortAscendingQuery =
from fruit in fruits
orderby fruit //"ascending" is default
select fruit;

// Query for descending sort.


IEnumerable<string> sortDescendingQuery =
from w in fruits
orderby w descending
select w;

// Execute the query.


Console.WriteLine("Ascending:");
foreach (string s in sortAscendingQuery)
{
Console.WriteLine(s);
}

// Execute the query.


Console.WriteLine(Environment.NewLine + "Descending:");
foreach (string s in sortDescendingQuery)
{
Console.WriteLine(s);
}

// Keep the console window open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* Output:
Ascending:
apple
blueberry
cherry

Descending:
cherry
blueberry
apple
*/

Örnek
Aşağıdaki örnek, öğrencilerin soyadı üzerinde birincil bir sıralama ve ardından ilk adlarında ikinci bir
sıralama gerçekleştirir.

class OrderbySample2
{
// The element type of the data source.
public class Student
{
public string First { get; set; }
public string Last { get; set; }
public int ID { get; set; }
}
public static List<Student> GetStudents()
{
// Use a collection initializer to create the data source. Note that each element
// in the list contains an inner sequence of scores.
List<Student> students = new List<Student>
{
new Student {First="Svetlana", Last="Omelchenko", ID=111},
new Student {First="Claire", Last="O'Donnell", ID=112},
new Student {First="Sven", Last="Mortensen", ID=113},
new Student {First="Cesar", Last="Garcia", ID=114},
new Student {First="Debra", Last="Garcia", ID=115}
};

return students;

}
static void Main(string[] args)
{
// Create the data source.
List<Student> students = GetStudents();

// Create the query.


IEnumerable<Student> sortedStudents =
from student in students
orderby student.Last ascending, student.First ascending
select student;

// Execute the query.


Console.WriteLine("sortedStudents:");
foreach (Student student in sortedStudents)
Console.WriteLine(student.Last + " " + student.First);

// Now create groups and sort the groups. The query first sorts the names
// of all students so that they will be in alphabetical order after they are
// grouped. The second orderby sorts the group keys in alpha order.
var sortedGroups =
from student in students
orderby student.Last, student.First
group student by student.Last[0] into newGroup
orderby newGroup.Key
select newGroup;

// Execute the query.


Console.WriteLine(Environment.NewLine + "sortedGroups:");
foreach (var studentGroup in sortedGroups)
{
Console.WriteLine(studentGroup.Key);
foreach (var student in studentGroup)
{
Console.WriteLine(" {0}, {1}", student.Last, student.First);
}
}

// Keep the console window open in debug mode


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* Output:
sortedStudents:
Garcia Cesar
Garcia Debra
Mortensen Sven
O'Donnell Claire
Omelchenko Svetlana

sortedGroups:
G
Garcia, Cesar
Garcia, Cesar
Garcia, Debra
M
Mortensen, Sven
O
O'Donnell, Claire
Omelchenko, Svetlana
*/

Açıklamalar
Derleme zamanında, orderby yan tümcesi OrderBy yöntemine yapılan çağrıya çevrilir. orderby yan
tümcesindeki birden çok anahtar ThenBy yöntemi çağrılarına çeviri yapar.

Ayrıca bkz.
C#Başvurunun
Sorgu anahtar sözcükleri (LINQ )
Dil ile Tümleşik Sorgu (LINQ )
group yan tümcesi
C#'de LINQ Kullanmaya Başlama
join tümcesi (C# Başvurusu)
23.10.2019 • 13 minutes to read • Edit Online

join Yan tümcesi, nesne modelinde hiçbir doğrudan ilişkisi olan farklı kaynak dizilerinden öğelerini
ilişkilendirmek için kullanışlıdır. Her kaynak öğeleri eşitlik için karşılaştırılması gereken bazı değeri
paylaşmak tek gereksinim olmasıdır. Örneğin, bir yiyecek dağıtımcısı, belirli bir ürünü tedarikçileri listesini
ve alıcıların listesi sahip olabilir. A join yan tümcesi, örneğin, üreticiler listesini oluşturmak için
kullanılabilir ve tüm aynı olan alıcılar bu ürünün belirtilen bölge.
A join yan tümcesi, iki kaynak dizileri girdi alır. Her bir dizideki öğelerin olması veya diğer dizisindeki
karşılık gelen bir özellik için karşılaştırılabilir bir özelliği içerir. join Yan tümcesi, özel kullanarak eşitlik
için belirtilen anahtarları karşılaştırır equals anahtar sözcüğü. Tarafından gerçekleştirilen tüm
birleştirmeler join yan tümcesi olan equijoins. Çıkışı şeklini bir join yan tümcesi yapmakta olduğunuz
birleştirme belirli türüne göre değişir. En yaygın üç birleşim türleri şunlardır:
İç birleştirme
Grup birleştirme
Sol dış birleştirme

İç birleştirme
Aşağıdaki örnek, basit bir iç equijoin gösterir. Bu sorgu düz dizisi üretir "ürün adı / kategorisi" çiftleri. Aynı
kategori dize birden çok öğe görünür. Bir öğeyi, categories eşleşen yok products , bu kategoriye
sonuçlarında görünmez.

var innerJoinQuery =
from category in categories
join prod in products on category.ID equals prod.CategoryID
select new { ProductName = prod.Name, Category = category.Name }; //produces flat sequence

Daha fazla bilgi için iç birleştirmeler gerçekleştirme.

Grup birleştirme
A join yan tümcesiyle birlikte bir into ifadesi, bir grup birleştirme çağrılır.

var innerGroupJoinQuery =
from category in categories
join prod in products on category.ID equals prod.CategoryID into prodGroup
select new { CategoryName = category.Name, Products = prodGroup };

Grup birleştirme sağ tarafındaki kaynak dizideki eşleşen öğelerin bir veya daha fazla sol kaynak dizisinin
öğelerini ilişkilendirir bir hiyerarşik bir sonuç dizisi üretir. Grup birleştirme eşdeğeri ilişkisel koşullarını
vardır. Bu temelde bir nesne dizisidir.
Öğenin sol kaynakta, eşleştirilecek öğe için doğru kaynak sırasından bulunursa join yan tümcesi, o öğe
için boş bir dizi üretir. Sonuç dizisi gruplar halinde düzenlenir. Bu nedenle, group JOIN hala temelde iç-
equijoin olmasıdır.
Grup birleştirme sonuçlarını seçmeniz yeterlidir, öğelere erişebilirsiniz, ancak bunlar üzerinde eşleşen
anahtar tanımlayamaz. Bu nedenle, önceki örnekte gösterildiği gibi anahtar adı olan yeni bir türe group
JOIN sonuçlarını seçin genel olarak daha yararlı olur.
Ayrıca, bir grup birleştirme sonucu başka bir alt sorgu oluşturucu olarak kullanabilirsiniz:

var innerGroupJoinQuery2 =
from category in categories
join prod in products on category.ID equals prod.CategoryID into prodGroup
from prod2 in prodGroup
where prod2.UnitPrice > 2.50M
select prod2;

Daha fazla bilgi için gruplandırılmış birleştirmeler gerçekleştirme.

Sol dış birleştirme


Eşleşen bir öğe doğru sırada olsa bile bir sol dış birleştirme, soldaki kaynak dizisindeki tüm öğeleri,
döndürülür. Bir sol dış birleştirme gerçekleştirmek için LINQ, kullanın DefaultIfEmpty sol taraftaki öğesi
herhangi bir eşleşme varsa üretmek için bir varsayılan sağ taraftaki öğesi belirtmek için bir grup
birleştirme birlikte yöntemi. Kullanabileceğiniz null olarak herhangi bir referans için varsayılan değer
türü veya bir kullanıcı tanımlı tür belirtebilirsiniz. Aşağıdaki örnekte, bir kullanıcı tarafından tanımlanan
varsayılan türü gösterilmiştir:

var leftOuterJoinQuery =
from category in categories
join prod in products on category.ID equals prod.CategoryID into prodGroup
from item in prodGroup.DefaultIfEmpty(new Product { Name = String.Empty, CategoryID = 0 })
select new { CatName = category.Name, ProdName = item.Name };

Daha fazla bilgi için sol dış birleştirmeler gerçekleştirme.

Eşittir işleci
A join yan tümcesi equijoin gerçekleştirir. Diğer bir deyişle, iki anahtar eşitlik yalnızca temel eşleşmeleri
ile kullanabilirsiniz. Karşılaştırma "büyük" veya "eşit değildir" gibi diğer türleri desteklenmez. Tüm
birleştirmeler equijoins, olduğunu netleştirmek için join yan tümcesi kullanan equals anahtar sözcüğü
yerine == işleci. equals Anahtar sözcüğü yalnızca kullanılabilir bir join yan tümcesi ve farklıdır ==
önemli bir şekilde işleci. İle equals sol ok tuşu dış kaynak dizisini tüketir ve sağ ok tuşu iç kaynak kullanır.
Yalnızca sol tarafındaki kapsamda dış kaynağıdır equals ve iç kaynak yalnızca işlecin sağ tarafındaki
kapsamda sırasıdır.

Olmayan equijoins
Çapraz birleştirme ve diğer özel birleştirme işlemleri olmayan-equijoins, birden çok kullanarak
gerçekleştirebileceğiniz from yeni dizileri bağımsız olarak bir sorguya tanıtmak amacıyla yan tümceler.
Daha fazla bilgi için özel birleştirme işlemleri gerçekleştirme.

Nesnesi koleksiyonlar ilişkisel tabloları ve birleşimler


İçinde bir LINQ sorgu ifadesinde, birleştirme işlemleri, nesne koleksiyonları üzerinde gerçekleştirilir.
Nesne koleksiyonları "iki ilişkisel tabloları tam olarak aynı şekilde katılamaz". İçinde LINQ, açık join yan
tümceleri, yalnızca iki kaynak dizileri tarafından herhangi bir ilişki bağlanmayan gereklidir. İle çalışırken
LINQ - SQL, yabancı anahtar tabloları nesne modelinde birincil tablo özellikleri olarak temsil edilir.
Örneğin, Northwind veritabanında yabancı anahtar ilişkisi Siparişler tablosu ile müşteri tablosu vardır.
Tablolar için nesne modeli eşlediğinizde, müşteri sınıfı bu müşteriyle ilgili Siparişler topluluğu içeren bir
sipariş özelliğine sahiptir. Aslında, birleştirme zaten sizin için yapılmıştır.
Bağlamında ilgili tablolar üzerinden sorgulama hakkında daha fazla bilgi için LINQ - SQL, bkz: nasıl
yapılır: Veritabanı ilişkileri eşleme.

Bileşik anahtarlar
Bir bileşik anahtarı kullanılarak birden çok değer eşitliği test edebilirsiniz. Daha fazla bilgi için bileşik
anahtarlar kullanarak birleştirme. Bileşik anahtarlar da kullanılabilir bir group yan tümcesi.

Örnek
Aşağıdaki örnek, aynı eşleşen anahtarlar kullanılarak bir iç birleştirme, bir grup katma ve aynı veri
kaynaklarında bir sol dış birleştirme sonuçlarının karşılaştırır. Bazı ek bir kod sonuçları konsol açıklamak
için bu örnekleri eklenir.

class JoinDemonstration
{
#region Data

class Product
{
public string Name { get; set; }
public int CategoryID { get; set; }
}

class Category
{
public string Name { get; set; }
public int ID { get; set; }
}

// Specify the first data source.


List<Category> categories = new List<Category>()
{
new Category {Name="Beverages", ID=001},
new Category {Name="Condiments", ID=002},
new Category {Name="Vegetables", ID=003},
new Category {Name="Grains", ID=004},
new Category {Name="Fruit", ID=005}
};

// Specify the second data source.


List<Product> products = new List<Product>()
{
new Product {Name="Cola", CategoryID=001},
new Product {Name="Tea", CategoryID=001},
new Product {Name="Mustard", CategoryID=002},
new Product {Name="Pickles", CategoryID=002},
new Product {Name="Carrots", CategoryID=003},
new Product {Name="Bok Choy", CategoryID=003},
new Product {Name="Peaches", CategoryID=005},
new Product {Name="Melons", CategoryID=005},
};
#endregion

static void Main(string[] args)


{
JoinDemonstration app = new JoinDemonstration();

app.InnerJoin();
app.GroupJoin();
app.GroupInnerJoin();
app.GroupInnerJoin();
app.GroupJoin3();
app.LeftOuterJoin();
app.LeftOuterJoin2();

// Keep the console window open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}

void InnerJoin()
{
// Create the query that selects
// a property from each element.
var innerJoinQuery =
from category in categories
join prod in products on category.ID equals prod.CategoryID
select new { Category = category.ID, Product = prod.Name };

Console.WriteLine("InnerJoin:");
// Execute the query. Access results
// with a simple foreach statement.
foreach (var item in innerJoinQuery)
{
Console.WriteLine("{0,-10}{1}", item.Product, item.Category);
}
Console.WriteLine("InnerJoin: {0} items in 1 group.", innerJoinQuery.Count());
Console.WriteLine(System.Environment.NewLine);

void GroupJoin()
{
// This is a demonstration query to show the output
// of a "raw" group join. A more typical group join
// is shown in the GroupInnerJoin method.
var groupJoinQuery =
from category in categories
join prod in products on category.ID equals prod.CategoryID into prodGroup
select prodGroup;

// Store the count of total items (for demonstration only).


int totalItems = 0;

Console.WriteLine("Simple GroupJoin:");

// A nested foreach statement is required to access group items.


foreach (var prodGrouping in groupJoinQuery)
{
Console.WriteLine("Group:");
foreach (var item in prodGrouping)
{
totalItems++;
Console.WriteLine(" {0,-10}{1}", item.Name, item.CategoryID);
}
}
Console.WriteLine("Unshaped GroupJoin: {0} items in {1} unnamed groups", totalItems,
groupJoinQuery.Count());
Console.WriteLine(System.Environment.NewLine);
}

void GroupInnerJoin()
{
var groupJoinQuery2 =
from category in categories
orderby category.ID
join prod in products on category.ID equals prod.CategoryID into prodGroup
select new
{
Category = category.Name,
Products = from prod2 in prodGroup
orderby prod2.Name
select prod2
};

//Console.WriteLine("GroupInnerJoin:");
int totalItems = 0;

Console.WriteLine("GroupInnerJoin:");
foreach (var productGroup in groupJoinQuery2)
{
Console.WriteLine(productGroup.Category);
foreach (var prodItem in productGroup.Products)
{
totalItems++;
Console.WriteLine(" {0,-10} {1}", prodItem.Name, prodItem.CategoryID);
}
}
Console.WriteLine("GroupInnerJoin: {0} items in {1} named groups", totalItems,
groupJoinQuery2.Count());
Console.WriteLine(System.Environment.NewLine);
}

void GroupJoin3()
{

var groupJoinQuery3 =
from category in categories
join product in products on category.ID equals product.CategoryID into prodGroup
from prod in prodGroup
orderby prod.CategoryID
select new { Category = prod.CategoryID, ProductName = prod.Name };

//Console.WriteLine("GroupInnerJoin:");
int totalItems = 0;

Console.WriteLine("GroupJoin3:");
foreach (var item in groupJoinQuery3)
{
totalItems++;
Console.WriteLine(" {0}:{1}", item.ProductName, item.Category);
}

Console.WriteLine("GroupJoin3: {0} items in 1 group", totalItems);


Console.WriteLine(System.Environment.NewLine);
}

void LeftOuterJoin()
{
// Create the query.
var leftOuterQuery =
from category in categories
join prod in products on category.ID equals prod.CategoryID into prodGroup
select prodGroup.DefaultIfEmpty(new Product() { Name = "Nothing!", CategoryID =
category.ID });

// Store the count of total items (for demonstration only).


int totalItems = 0;

Console.WriteLine("Left Outer Join:");

// A nested foreach statement is required to access group items


foreach (var prodGrouping in leftOuterQuery)
{
Console.WriteLine("Group:");
foreach (var item in prodGrouping)
{
totalItems++;
totalItems++;
Console.WriteLine(" {0,-10}{1}", item.Name, item.CategoryID);
}
}
Console.WriteLine("LeftOuterJoin: {0} items in {1} groups", totalItems,
leftOuterQuery.Count());
Console.WriteLine(System.Environment.NewLine);
}

void LeftOuterJoin2()
{
// Create the query.
var leftOuterQuery2 =
from category in categories
join prod in products on category.ID equals prod.CategoryID into prodGroup
from item in prodGroup.DefaultIfEmpty()
select new { Name = item == null ? "Nothing!" : item.Name, CategoryID = category.ID };

Console.WriteLine("LeftOuterJoin2: {0} items in 1 group", leftOuterQuery2.Count());


// Store the count of total items
int totalItems = 0;

Console.WriteLine("Left Outer Join 2:");

// Groups have been flattened.


foreach (var item in leftOuterQuery2)
{
totalItems++;
Console.WriteLine("{0,-10}{1}", item.Name, item.CategoryID);
}
Console.WriteLine("LeftOuterJoin2: {0} items in 1 group", totalItems);
}
}
/*Output:

InnerJoin:
Cola 1
Tea 1
Mustard 2
Pickles 2
Carrots 3
Bok Choy 3
Peaches 5
Melons 5
InnerJoin: 8 items in 1 group.

Unshaped GroupJoin:
Group:
Cola 1
Tea 1
Group:
Mustard 2
Pickles 2
Group:
Carrots 3
Bok Choy 3
Group:
Group:
Peaches 5
Melons 5
Unshaped GroupJoin: 8 items in 5 unnamed groups

GroupInnerJoin:
Beverages
Cola 1
Tea 1
Condiments
Mustard 2
Mustard 2
Pickles 2
Vegetables
Bok Choy 3
Carrots 3
Grains
Fruit
Melons 5
Peaches 5
GroupInnerJoin: 8 items in 5 named groups

GroupJoin3:
Cola:1
Tea:1
Mustard:2
Pickles:2
Carrots:3
Bok Choy:3
Peaches:5
Melons:5
GroupJoin3: 8 items in 1 group

Left Outer Join:


Group:
Cola 1
Tea 1
Group:
Mustard 2
Pickles 2
Group:
Carrots 3
Bok Choy 3
Group:
Nothing! 4
Group:
Peaches 5
Melons 5
LeftOuterJoin: 9 items in 5 groups

LeftOuterJoin2: 9 items in 1 group


Left Outer Join 2:
Cola 1
Tea 1
Mustard 2
Pickles 2
Carrots 3
Bok Choy 3
Nothing! 4
Peaches 5
Melons 5
LeftOuterJoin2: 9 items in 1 group
Press any key to exit.
*/

Açıklamalar
A join tarafından izlenmiyor yan tümcesi into erişimcisine bir Join yöntem çağrısı. A join takip yan
tümcesi into çevrildiğinde bir GroupJoin yöntem çağrısı.

Ayrıca bkz.
Query Keywords (LINQ )
Dil ile Tümleşik Sorgu (LINQ )
Birleştirme İşlemleri
group yan tümcesi
Sol dış birleştirmeler gerçekleştirme
İç birleşimler gerçekleştirme
Gruplanmış birleşimler gerçekleştirme
Join yan tümcesinin sonuçlarını sıralama
Bileşik anahtarlar kullanarak birleştirme
Visual Studio için uyumlu veritabanı sistemleri
let tümcesi (C# Başvurusu)
4.11.2019 • 2 minutes to read • Edit Online

Bir sorgu ifadesinde, alt ifadenin sonucunu izleyen yan tümcelerde kullanmak üzere depolamak bazen yararlı
olur. Bunu, yeni bir Aralık değişkeni oluşturan ve bunu sağladığınız ifadenin sonucuyla Başlatan let anahtar
sözcüğüyle yapabilirsiniz. Bir değerle başlatıldıktan sonra, Aralık değişkeni başka bir değeri depolamak için
kullanılamaz. Ancak, Aralık değişkeni sorgulanabilir bir tür içeriyorsa, bu, sorgulanabilir.

Örnek
Aşağıdaki örnekte let iki şekilde kullanılır:
1. Kendisi için sorgulanabilen bir sıralanabilir tür oluşturmak için.
2. Sorgunun ToLower Aralık değişkeninde yalnızca bir kez çağırmasını sağlamak için word . let
kullanmadan, where yan tümcesindeki her koşulda ToLower çağırmanız gerekir.
class LetSample1
{
static void Main()
{
string[] strings =
{
"A penny saved is a penny earned.",
"The early bird catches the worm.",
"The pen is mightier than the sword."
};

// Split the sentence into an array of words


// and select those whose first letter is a vowel.
var earlyBirdQuery =
from sentence in strings
let words = sentence.Split(' ')
from word in words
let w = word.ToLower()
where w[0] == 'a' || w[0] == 'e'
|| w[0] == 'i' || w[0] == 'o'
|| w[0] == 'u'
select word;

// Execute the query.


foreach (var v in earlyBirdQuery)
{
Console.WriteLine("\"{0}\" starts with a vowel", v);
}

// Keep the console window open in debug mode.


Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* Output:
"A" starts with a vowel
"is" starts with a vowel
"a" starts with a vowel
"earned." starts with a vowel
"early" starts with a vowel
"is" starts with a vowel
*/

Ayrıca bkz.
C#Başvurunun
Sorgu anahtar sözcükleri (LINQ )
Dil ile Tümleşik Sorgu (LINQ )
C#'de LINQ Kullanmaya Başlama
Sorgu ifadelerinde özel durumları işleme
ascending (C# Başvurusu)
4.11.2019 • 2 minutes to read • Edit Online

ascending bağlamsal anahtar sözcüğü, sıralama sırasının en küçükten en büyüğe doğru olduğunu belirtmek için
sorgu ifadelerinde OrderBy yan tümcesinde kullanılır. ascending varsayılan sıralama düzeni olduğundan, bunu
belirtmeniz gerekmez.

Örnek
Aşağıdaki örnek, bir OrderBy yan tümcesindeki ascending kullanımını gösterir.

IEnumerable<string> sortAscendingQuery =
from vegetable in vegetables
orderby vegetable ascending
select vegetable;

Ayrıca bkz.
C#Başvurunun
C# üzerinde LINQ
descending
descending (C# Başvurusu)
4.11.2019 • 2 minutes to read • Edit Online

descending bağlamsal anahtar sözcüğü, sıralama sırasının en küçükten en küçüğe doğru olduğunu belirtmek için
sorgu ifadelerinde OrderBy yan tümcesinde kullanılır.

Örnek
Aşağıdaki örnek, bir OrderBy yan tümcesindeki descending kullanımını gösterir.

IEnumerable<string> sortDescendingQuery =
from vegetable in vegetables
orderby vegetable descending
select vegetable;

Ayrıca bkz.
C#Başvurunun
C# üzerinde LINQ
ascending
on (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

on Bağlamsal anahtar sözcüğü kullanılır JOIN yan tümcesi birleşim koşulu belirtmek için bir sorgu ifadesinin.

Örnek
Aşağıdaki örnek kullanımını gösterir on içinde bir join yan tümcesi.

var innerJoinQuery =
from category in categories
join prod in products on category.ID equals prod.CategoryID
select new { ProductName = prod.Name, Category = category.Name };

Ayrıca bkz.
C# başvurusu
Dil ile Tümleşik Sorgu (LINQ )
equals (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

equals Bağlamsal anahtar sözcük kullanılan bir join iki sıranın öğelerini karşılaştırmak için bir sorgu ifadesinde
yan tümcesi. Daha fazla bilgi için JOIN yan tümcesi.

Örnek
Aşağıdaki örnek kullanımını gösterir equals anahtar sözcüğü bir join yan tümcesi.

var innerJoinQuery =
from category in categories
join prod in products on category.ID equals prod.CategoryID
select new { ProductName = prod.Name, Category = category.Name };

Ayrıca bkz.
Dil ile Tümleşik Sorgu (LINQ )
by (C# Başvurusu)
4.11.2019 • 2 minutes to read • Edit Online

by bağlamsal anahtar sözcüğü, döndürülen öğelerin nasıl gruplanacağını belirtmek için bir sorgu ifadesindeki
group yan tümcesinde kullanılır. Daha fazla bilgi için bkz. Group yan tümcesi.

Örnek
Aşağıdaki örnek, öğrencilerin her öğrencinin son adının ilk harfine göre gruplanacağını belirtmek için bir group
yan tümcesinde by bağlamsal anahtar sözcüğünün kullanımını gösterir.

var query = from student in students


group student by student.LastName[0];

Ayrıca bkz.
C# üzerinde LINQ
in (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

in Anahtar sözcüğü, dört bağlamlarında kullanılır:


genel tür parametreleri genel arabirimler ve temsilciler.
Olarak bir parametre değiştiricisi, olanak sağlayan, bağımsız değişken bir yönteme başvuru yerine değere göre
geçirin.
foreach deyimleri.
yan tümceleri gelen LINQ Sorgu ifadeleri.
JOIN yan tümceleri LINQ Sorgu ifadeleri.

Ayrıca bkz.
C# Anahtar Sözcükleri
C# başvurusu
C#İşleçler (C# başvuru)
29.11.2019 • 5 minutes to read • Edit Online

C#Yerleşik türler tarafından desteklenen bir dizi işleç sağlar. Örneğin, Aritmetik işleçler sayısal Işlenenler
ve Boole mantıksal işleçleri bool işlenenleri olan mantıksal işlemleri gerçekleştirir. Bazı işleçler
aşırıyüklenebilir. İşleç aşırı yüklemesi ile, Kullanıcı tanımlı bir türün işlenenleri için işleç davranışını
belirtebilirsiniz.
Bir ifadede, işleç önceliği ve ilişkilendirilebilirliği, işlemlerin gerçekleştirileceği sırayı belirlemektir. İşleç
önceliği ve ilişkilendirilebilirliği tarafından uygulanan değerlendirmenin sırasını değiştirmek için ayraçları
kullanabilirsiniz.

İşleç önceliği
Birden çok işleç içeren bir ifadede, daha yüksek önceliğe sahip işleçler, daha düşük önceliğe sahip
işleçlerden önce değerlendirilir. Aşağıdaki örnekte, daha yüksek önceliğe sahip olduğu için çarpma ilk
olarak gerçekleştirilir:

var a = 2 + 2 * 2;
Console.WriteLine(a); // output: 6

İşleç önceliğine göre uygulanan değerlendirmenin sırasını değiştirmek için ayraçları kullanın:

var a = (2 + 2) * 2;
Console.WriteLine(a); // output: 8

Aşağıdaki tabloda en düşük önceliğe C# göre başlayan işleçler listelenmektedir. Her satır içindeki işleçler
aynı önceliğe sahiptir.

İŞLEÇLER KATEGORI VEYA AD

x. y, x?. y, x? [ y], f (x), a[i], x + +, x--, New, typeof, Birincil


Checked, denetimsiz, Default, NameOf, Delegate, sizeof,
stackalloc, x-> y

+ x, -x, !x, ~ x, + + x, --x, ^ x, (t) x, await, & x, * x, true ve Li


false

x.. Iz Aralık

x * y, x/y, x% y Çarpma

x + y, x – y Msal

x << y, x > > y Karakter

x < y, x > y, x <= y, x > = y, , as İlişkisel ve tür-test

x = = y, x! = y Eşitlik
İŞLEÇLER KATEGORI VEYA AD

x & y Boolean MANTıKSAL ve veya BIT düzeyinde mantıksal ve

x ^ y Boole MANTıKSAL XOR veya BIT düzeyinde mantıksal


XOR

x | y Boolean MANTıKSAL veya veya BIT düzeyinde mantıksal


or

x&&y Koşullu VE

x||y Koşullu VEYA

x?? Iz Null birleşim işleci

,? t: f Koşullu işleç

x = y, x + = y, x-= y, x * = y, x /= y, x% = y, x & = y, x |= Atama ve lambda bildirimi


y, x ^ =y, x < < = y, x > > = y, x?? = y, =>

Operatör ilişkilendirilebilirliği
İşleçler aynı önceliğe sahip olduğunda, işleçlerin ilişkilendirilebilirliği, işlemlerin gerçekleştirilme sırasını
belirler:
Sola ilişkilendirilebilir işleçler, soldan sağa doğru sırayla değerlendirilir. Atama işleçleri ve null birleşim
işleçlerihariç, tüm ikili işleçler sola ilişkilendirilebilir. Örneğin, a + b - c (a + b) - c olarak
değerlendirilir.
Sağdan ilişkilendirilebilir işleçler, sağdan sola sırayla değerlendirilir. Atama işleçleri, null birleşim
işleçleri ve koşullu işleç ?: , doğru ilişkilendirilebilir. Örneğin, x = y = z x = (y = z) olarak
değerlendirilir.
İşleç ilişkilendirilebilirliği tarafından uygulanan değerlendirmenin sırasını değiştirmek için ayraçları
kullanın:

int a = 13 / 5 / 2;
int b = 13 / (5 / 2);
Console.WriteLine($"a = {a}, b = {b}"); // output: a = 1, b = 6

İşlenen değerlendirmesi
Operatör önceliği ve ilişkilendirilebilirliği ile ilgisiz, bir ifadede işlenen işlenenleri soldan sağa
değerlendirilir. Aşağıdaki örneklerde, işleçleri ve işlenenleri değerlendirilen sıra gösterilmektedir:

İFADE DEĞERLENDIRME SIRASI

a + b a, b, +

a + b * c a, b, c, *, +

a / b + c * d a, b,/, c, d, *, +
İFADE DEĞERLENDIRME SIRASI

a / (b + c) * d a, b, c, +,/, d, *

Genellikle, tüm işleç işlenenleri değerlendirilir. Ancak, bazı işleçler işlenenleri koşullu olarak değerlendirir.
Diğer bir deyişle, bu tür bir işlecin en sol işleneninin değeri, (veya hangi) diğer işlenenleri
değerlendirileceğini tanımlar. Bu işleçler, Koşullu mantıksal ve ( && ) ve ya da ( || ) işleçleridir, null birleşim
işleçleri ?? ve ??= , null koşullu işleçler ?. ve ?[] ve koşullu işleç ?: . Daha fazla bilgi için her işlecin
açıklamasına bakın.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin işleçler bölümüne bakın.

Ayrıca bkz.
C#başvurunun
İfadeler
Aritmetik işleçler (C# başvuru)
30.10.2019 • 14 minutes to read • Edit Online

Aşağıdaki işleçler, sayısal türlerde işlenenler ile aritmetik işlemler gerçekleştirir:


Birli ++ (artış), -- (azaltma), + (artı)ve - (eksi) işleçleri
İkili * (çarpma), / (bölme), % (kalan), + (toplama)ve - (çıkarma) işleçleri

Bu işleçler tüm integral ve kayan nokta sayısal türleri tarafından desteklenir.

Artış işleci + +
Birli artış işleci ++ işlenenini 1 artırır. İşlenen bir değişken, özellik erişimi veya Dizin Oluşturucu erişimi
olmalıdır.
Artırma işleci iki biçimde desteklenir: sonek artırma işleci, x++ ve önek artışı işleci, ++x .
Sonek artırma işleci
Aşağıdaki örnekte gösterildiği gibi, x++ sonucu işlemden önce x değeridir:

int i = 3;
Console.WriteLine(i); // output: 3
Console.WriteLine(i++); // output: 3
Console.WriteLine(i); // output: 4

Ön ek artırma işleci
Aşağıdaki örnekte gösterildiği gibi, ++x sonucu işlemden sonra x değeridir:

double a = 1.5;
Console.WriteLine(a); // output: 1.5
Console.WriteLine(++a); // output: 2.5
Console.WriteLine(a); // output: 2.5

Azaltma işleci--
Birli azaltma işleci -- işlenenini 1 azaltır. İşlenen bir değişken, özellik erişimi veya Dizin Oluşturucu erişimi
olmalıdır.
Azaltma işleci iki formda desteklenir: sonek azaltma işleci, x-- ve ön ek azaltma işleci, --x .
Sonek azaltma işleci
Aşağıdaki örnekte gösterildiği gibi, x-- sonucu işlemden önce x değeridir:

int i = 3;
Console.WriteLine(i); // output: 3
Console.WriteLine(i--); // output: 3
Console.WriteLine(i); // output: 2

Önek azaltma işleci


Aşağıdaki örnekte gösterildiği gibi, --x sonucu işlemden sonra x değeridir:
double a = 1.5;
Console.WriteLine(a); // output: 1.5
Console.WriteLine(--a); // output: 0.5
Console.WriteLine(a); // output: 0.5

Birli artı ve eksi işleçleri


Birli + işleci, işleneninin değerini döndürür. Birli - işleci, işleneninin sayısal olumsuzunu hesaplar.

Console.WriteLine(+4); // output: 4

Console.WriteLine(-4); // output: -4
Console.WriteLine(-(-4)); // output: 4

uint a = 5;
var b = -a;
Console.WriteLine(b); // output: -5
Console.WriteLine(b.GetType()); // output: System.Int64

Console.WriteLine(-double.NaN); // output: NaN

Ulong türü birli - işlecini desteklemez.

Çarpma işleci *
Çarpma işleci * işlenenlerinin çarpımını hesaplar:

Console.WriteLine(5 * 2); // output: 10


Console.WriteLine(0.5 * 2.5); // output: 1.25
Console.WriteLine(0.1m * 23.4m); // output: 2.34

Birli * işleci, işaretçi yöneltme işleçtir.

Bölme işleci/
Bölme işleci / sol tarafından sağ işleneniyle böler.
Tamsayı bölme
Tamsayı türlerinin işlenenleri için, / işlecinin sonucu bir tamsayı türüdür ve iki işlenenlerin sıfıra yuvarlayarak
Bu bölüm eşittir:

Console.WriteLine(13 / 5); // output: 2


Console.WriteLine(-13 / 5); // output: -2
Console.WriteLine(13 / -5); // output: -2
Console.WriteLine(-13 / -5); // output: 2

İki işlenenin bir kayan noktalı sayı olarak bölümünü almak için float , double veya decimal türünü kullanın:

Console.WriteLine(13 / 5.0); // output: 2.6

int a = 13;
int b = 5;
Console.WriteLine((double)a / b); // output: 2.6

Kayan nokta bölme


float , double ve decimal türlerinde, / işlecinin sonucu iki işlenenin bir bölümü olur:

Console.WriteLine(16.8f / 4.1f); // output: 4.097561


Console.WriteLine(16.8d / 4.1d); // output: 4.09756097560976
Console.WriteLine(16.8m / 4.1m); // output: 4.0975609756097560975609756098

İşlenenlerden biri decimal , başka bir işlenen float veya double olamaz, çünkü hiçbir float veya double
örtük olarak decimal dönüştürülebilir. float veya double işlenenini decimal türüne açıkça dönüştürmeniz
gerekir. Sayısal türler arasındaki dönüşümler hakkında daha fazla bilgi için bkz. yerleşik sayısal dönüşümler.

Kalan işleç yüzdesi


Geri kalan işleç % sol taraftaki işleneni sağ tarafıyla ayırarak kalanı hesaplar.
Tamsayı geri kalanı
Tamsayı türlerinin işlenenleri için a % b sonucu, a - (a / b) * b tarafından oluşturulan değerdir. Sıfır olmayan
geri kalanın işareti, aşağıdaki örnekte gösterildiği gibi, sol taraftaki işleneniyle aynıdır:

Console.WriteLine(5 % 4); // output: 1


Console.WriteLine(5 % -4); // output: 1
Console.WriteLine(-5 % 4); // output: -1
Console.WriteLine(-5 % -4); // output: -1

Hem tamsayı bölme hem de kalan sonuçları hesaplamak için Math.DivRem yöntemini kullanın.
Kayan nokta kalanı
float ve double işlenenleri için x % y sonucu sınırlı x ve y için z değer
Sıfır olmayan z işareti, x işaretiyle aynıdır.
z mutlak değeri, n |x| / |y| ve |x| sıfırdan küçük veya buna eşit olan en büyük olası tamsayıdır ve
|y| x ve y değerlerinin mutlak değerleri olduğundan, |x| - n * |y| tarafından oluşturulan değerdir. anı.

NOTE
Bu geri kalanı hesaplama yöntemi, tamsayı işlenenleri için kullanılan, ancak IEEE 754 belirtiminden farklı olacak şekilde
benzerdir. IEEE 754 belirtimine uyan geri kalan işleme ihtiyacınız varsa Math.IEEERemainder yöntemini kullanın.

% işlecinin sonlu olmayan işlenenlerle davranışı hakkında daha fazla bilgi için, C# dil belirtiminin geri kalan
işleci bölümüne bakın.
decimal işlenenleri için, % kalan işleç System.Decimal türünün kalan işlecine eşdeğerdir.
Aşağıdaki örnek, kayan nokta işlenenleri geri kalan işlecinin davranışını gösterir:

Console.WriteLine(-5.2f % 2.0f); // output: -1.2


Console.WriteLine(5.9 % 3.1); // output: 2.8
Console.WriteLine(5.9m % 3.1m); // output: 2.8

Toplama işleci +
Toplama işleci + işlenenlerinin toplamını hesaplar:
Console.WriteLine(5 + 4); // output: 9
Console.WriteLine(5 + 4.3); // output: 9.3
Console.WriteLine(5.1m + 4.2m); // output: 9.3

Dize birleştirme ve temsilci birleşimi için + işlecini de kullanabilirsiniz. Daha fazla bilgi için + ve +=
İşletmenleri makalesine bakın.

Çıkarma işleci-
Çıkarma işleci - sağ işlenenini sol tarafından çıkartır:

Console.WriteLine(47 - 3); // output: 44


Console.WriteLine(5 - 4.3); // output: 0.7
Console.WriteLine(7.5m - 2.3m); // output: 5.2

Temsilci kaldırma için - işlecini de kullanabilirsiniz. Daha fazla bilgi için - ve -= İşletmenleri makalesine
bakın.

Bileşik atama
Bir ikili işleci için op , formun bileşik atama ifadesi

x op= y

eşdeğerdir

x = x op y

x yalnızca bir kez değerlendirilir.


Aşağıdaki örnek, aritmetik bir atama kullanımını Aritmetik işleçlerle gösterir:

int a = 5;
a += 9;
Console.WriteLine(a); // output: 14

a -= 4;
Console.WriteLine(a); // output: 10

a *= 2;
Console.WriteLine(a); // output: 20

a /= 4;
Console.WriteLine(a); // output: 5

a %= 3;
Console.WriteLine(a); // output: 2

Sayısal yükseltmelernedeniyle op işleminin sonucu x T türüne örtülü olarak dönüştürülebilir olmayabilir.


Böyle bir durumda, op önceden tanımlanmış bir işleçse ve işlemin sonucu x T türüne açıkça
dönüştürülesiyse, formun bileşik atama ifadesi x op= y eşdeğerdir x = (T)(x op y) x hariç, yalnızca bir kez
değerlendirilir. Aşağıdaki örnekte bu davranış gösterilmektedir:
byte a = 200;
byte b = 100;

var c = a + b;
Console.WriteLine(c.GetType()); // output: System.Int32
Console.WriteLine(c); // output: 300

a += b;
Console.WriteLine(a); // output: 44

Ayrıca, sırasıyla bir olayaabone olmak ve aboneliği kaldırmak için += ve -= işleçlerini da kullanırsınız. Daha
fazla bilgi için bkz. nasıl yapılır: olaylara abone olma ve aboneliği kaldırma.

İşleç önceliği ve ilişkilendirilebilirlik


Aşağıdaki liste, en yüksek öncelikten en düşüğe başlayarak aritmetik işleçleri sıralar:
Sonek artırma x++ ve azaltma x-- işleçleri
Önek artırma ++x ve azaltma --x ve birli + ve - işleçleri
Çarpma * , / ve % işleçleri
Adli + ve - işleçleri

İkili aritmetik işleçler sola ilişkilendirilebilir. Diğer bir deyişle, aynı öncelik düzeyine sahip işleçler soldan sağa
değerlendirilir.
İşleç önceliği ve ilişkilendirilebilirliği tarafından uygulanan değerlendirmenin sırasını değiştirmek için parantez,
() kullanın.

Console.WriteLine(2 + 2 * 2); // output: 6


Console.WriteLine((2 + 2) * 2); // output: 8

Console.WriteLine(9 / 5 / 2); // output: 0


Console.WriteLine(9 / (5 / 2)); // output: 4

Öncelik düzeyine göre sıralanan C# işleçlerin tüm listesi için, C# işleçler makalesinin operatör önceliği
bölümüne bakın.

Aritmetik taşma ve sıfıra bölme


Bir aritmetik işlemin sonucu, ilgili sayısal türün olası sonlu değerler aralığının dışında olduğunda, bir aritmetik
işlecin davranışı işlenenlerinin türüne bağlıdır.
Tamsayı aritmetik taşması
Sayı sıfıra bölme her zaman bir DivideByZeroException oluşturur.
Tamsayı aritmetik taşması olması durumunda, denetlenen veya işaretlenmemişbir taşma Denetim bağlamı
ortaya çıkan davranışı denetler:
Denetlenen bir bağlamda, sabit bir ifadede taşma gerçekleşirse, derleme zamanı hatası oluşur. Aksi takdirde,
işlem çalışma zamanında gerçekleştirildiğinde bir OverflowException oluşturulur.
İşaretlenmemiş bir bağlamda, sonuç, hedef türüne sığmayan yüksek sıralı bitleri atarak kesilir.
Checked ve unchecked deyimlerinin yanı sıra, bir ifadenin değerlendirildiği taşma denetimi bağlamını
denetlemek için checked ve unchecked işleçlerini kullanabilirsiniz:
int a = int.MaxValue;
int b = 3;

Console.WriteLine(unchecked(a + b)); // output: -2147483646


try
{
int d = checked(a + b);
}
catch(OverflowException)
{
Console.WriteLine($"Overflow occurred when adding {a} to {b}.");
}

Varsayılan olarak, aritmetik işlemler işaretlenmemiş bir bağlamda oluşur.


Kayan nokta aritmetik taşması
float ve double türleriyle aritmetik işlemler hiçbir şekilde özel durum oluşturmaz. Bu türlere sahip aritmetik
işlemlerin sonucu, sonsuz ve bir sayı olmayan özel değerlerden biri olabilir:

double a = 1.0 / 0.0;


Console.WriteLine(a); // output: Infinity
Console.WriteLine(double.IsInfinity(a)); // output: True

Console.WriteLine(double.MaxValue + double.MaxValue); // output: Infinity

double b = 0.0 / 0.0;


Console.WriteLine(b); // output: NaN
Console.WriteLine(double.IsNaN(b)); // output: True

decimal türünün işlenenleri için aritmetik taşma her zaman bir OverflowException oluşturur ve sıfıra bölme her
zaman bir DivideByZeroExceptionoluşturur.

Yuvarlama hataları
Gerçek sayıların ve kayan nokta aritmetiğinin kayan nokta gösteriminin genel sınırlamaları nedeniyle, kayan
nokta türleriyle hesaplamalar halinde yuvarlama hataları oluşabilir. Diğer bir deyişle, bir ifadenin üretilen
sonucu beklenen matematik sonucundan farklı olur. Aşağıdaki örnekte bu gibi birkaç durum gösterilmektedir:

Console.WriteLine(.41f % .2f); // output: 0.00999999

double a = 0.1;
double b = 3 * a;
Console.WriteLine(b == 0.3); // output: False
Console.WriteLine(b - 0.3); // output: 5.55111512312578E-17

decimal c = 1 / 3.0m;
decimal d = 3 * c;
Console.WriteLine(d == 1.0m); // output: False
Console.WriteLine(d); // output: 0.9999999999999999999999999999

Daha fazla bilgi için bkz. System. Double, System. Singleveya System. Decimal başvuru sayfalarındaki
açıklamalar.

Operatör overloadability
Kullanıcı tanımlı bir tür birli ( ++ , -- , + ve - ) ve ikili ( * , / , % , + ve - ) aritmetik operatörlerini aşırı
yükleyebilir. İkili işleç aşırı yüklendiğinde, karşılık gelen bileşik atama işleci de örtük olarak aşırı yüklenmiştir.
Kullanıcı tanımlı bir tür, bileşik atama işlecini açıkça aşırı yükleyemez.
C# dili belirtimi
Daha fazla bilgi için, C# dil belirtimininaşağıdaki bölümlerine bakın:
Sonek artırma ve azaltma işleçleri
Ön ek artırma ve azaltma işleçleri
Birli Plus işleci
Birli eksi işleci
Çarpma işleci
Bölme işleci
Kalan işleç
Toplama işleci
Çıkarma işleci
Bileşik atama
Checked ve unchecked işleçleri
Sayısal yükseltmeler

Ayrıca bkz.
C#başvurunun
C# işleçleri
System.Math
System.MathF
.NET Sayısal Değerleri
Boole mantıksal işleçleri (C# başvuru)
29.11.2019 • 12 minutes to read • Edit Online

Aşağıdaki işleçler bool işlenenleri olan mantıksal işlemler gerçekleştirir:


Birli ! (mantıksal değilleme) işleci.
İkili & (MANTıKSAL ve), | (mantıksal or)ve ^ (mantıksal dışlamalı veya) işleçler. Bu operatörler her iki
işleneni de değerlendirir.
İkili && (koşullu MANTıKSAL and) ve || (Koşullu mantıksal or) işleçleri. Bu işleçler yalnızca gerekli
olması durumunda sağ işleneni değerlendirir.
İntegral sayısal türlerinişlenenleri için, & , | ve ^ işleçleri bit düzeyinde mantıksal işlemler gerçekleştirir.
Daha fazla bilgi için bkz. bit düzeyinde and SHIFT işleçleri.

Mantıksal Değilleme İşleci!


Birli önek ! işleci, işleneninin mantıksal olumsuzunu hesaplar. Diğer bir deyişle, işlenen false
değerlendirilirse true üretir ve işlenen true olarak değerlendirilirse false :

bool passed = false;


Console.WriteLine(!passed); // output: True
Console.WriteLine(!true); // output: False

8,0 ile C# başlayarak birli sonek ! işleci null-forverme işleçtir.

Mantıksal AND işleci &


& işleci, işlenenlerinin mantıksal ve işlecini hesaplar. x & y sonucu, hem x hem de y true olarak
değerlendirilir true . Aksi takdirde, sonuç false .
& işleci, sol taraftaki işlenen false olarak değerlendirilse bile her iki işleneni de değerlendirir, böylece işlem
sonucu sağ işlenen değerden bağımsız olarak false .
Aşağıdaki örnekte, & işlecinin sağ işleneni, sol işlenenin değerinden bağımsız olarak gerçekleştirilen bir
yöntem çağrıdır:

bool SecondOperand()
{
Console.WriteLine("Second operand is evaluated.");
return true;
}

bool a = false & SecondOperand();


Console.WriteLine(a);
// Output:
// Second operand is evaluated.
// False

bool b = true & SecondOperand();


Console.WriteLine(b);
// Output:
// Second operand is evaluated.
// True
Koşullu MANTıKSAL and işleci && Ayrıca, işlenenlerinin mantıksal ve işlecini hesaplar, ancak sol işlenen
false olarak değerlendirilirse sağ işleneni değerlendirmez.

İntegral sayısal türlerinişlenenleri için & işleci, işlenenlerinin BIT düzeyinde mantıksal ve işlecini hesaplar. Birli
& işleci, Adres işleçtir.

Mantıksal dışlamalı OR işleci ^


^ işleci, işlenenlerinin mantıksal XOR olarak da bilinen mantıksal dışlamalı veya bir şekilde hesaplar. x ^ y
sonucu, x true olarak değerlendirilir ve y false olarak değerlendirilir ve x false olarak değerlendirilir
true . Aksi takdirde, sonuç false . Diğer bir deyişle, bool işlenenleri için ^ işleci, eşitsizlik işleci != aynı
sonucu hesaplar.

Console.WriteLine(true ^ true); // output: False


Console.WriteLine(true ^ false); // output: True
Console.WriteLine(false ^ true); // output: True
Console.WriteLine(false ^ false); // output: False

İntegral sayısal türlerinişlenenleri için, ^ işleci, işlenenlerinin bit düzeyinde MANTıKSAL dışlamalı veya
bunların işlenenleri hesaplar.

Mantıksal OR işleci |
| işleci, işlenenlerinin mantıksal veya işlecini hesaplar. x | y sonucu, x veya y true olarak
değerlendirilirse true . Aksi takdirde, sonuç false .
| işleci, sol taraftaki işlenen true olarak değerlendirilse bile her iki işleneni de değerlendirir, böylece işlem
sonucu sağ işlenen değerden bağımsız olarak true .
Aşağıdaki örnekte, | işlecinin sağ işleneni, sol işlenenin değerinden bağımsız olarak gerçekleştirilen bir
yöntem çağrıdır:

bool SecondOperand()
{
Console.WriteLine("Second operand is evaluated.");
return true;
}

bool a = true | SecondOperand();


Console.WriteLine(a);
// Output:
// Second operand is evaluated.
// True

bool b = false | SecondOperand();


Console.WriteLine(b);
// Output:
// Second operand is evaluated.
// True

Koşullu MANTıKSAL or işleci || Ayrıca, işlenenlerinin mantıksal veya işlecini hesaplar, ancak sol işlenen
true olarak değerlendirilirse sağ işleneni değerlendirmez.

İntegral sayısal türlerinişlenenleri için | işleci, işlenenlerinin BIT düzeyinde mantıksal veya işlecini hesaplar.

Koşullu mantıksal AND işleci &&


"Kısa devre dışı" mantıksal AND işleci olarak da bilinen Koşullu mantıksal ve işleç && , işlenenlerinin mantıksal
ve işlecini hesaplar. x && y sonucu, hem x hem de y true olarak değerlendirilir true . Aksi takdirde, sonuç
false . x false değerlendirilirse y değerlendirilmez.

Aşağıdaki örnekte, && işlecinin sağ işleneni, sol taraftaki işlenen false olarak değerlendirilirse
gerçekleştirilmeyen bir yöntem çağrıdır:

bool SecondOperand()
{
Console.WriteLine("Second operand is evaluated.");
return true;
}

bool a = false && SecondOperand();


Console.WriteLine(a);
// Output:
// False

bool b = true && SecondOperand();


Console.WriteLine(b);
// Output:
// Second operand is evaluated.
// True

MANTıKSAL and işleci & Ayrıca IŞLENENLERININ mantıksal ve ' lerini hesaplar, ancak her iki işleneni de
değerlendirir.

Koşullu mantıksal OR işleci | |


"Kısa devre dışı" mantıksal OR işleci olarak da bilinen Koşullu mantıksal OR işleci || , işlenenlerinin mantıksal
veya işlecini hesaplar. x || y sonucu, x veya y true olarak değerlendirilirse true . Aksi takdirde, sonuç
false . x true değerlendirilirse y değerlendirilmez.

Aşağıdaki örnekte, || işlecinin sağ işleneni, sol taraftaki işlenen true olarak değerlendirilirse
gerçekleştirilmeyen bir yöntem çağrıdır:

bool SecondOperand()
{
Console.WriteLine("Second operand is evaluated.");
return true;
}

bool a = true || SecondOperand();


Console.WriteLine(a);
// Output:
// True

bool b = false || SecondOperand();


Console.WriteLine(b);
// Output:
// Second operand is evaluated.
// True

Ayrıca, MANTıKSAL or işleci | işlenenlerini de hesaplar, ancak her iki işleneni de değerlendirir.

Null yapılabilir Boolean mantıksal işleçler


bool? işlenenleri için, & ve | işleçleri üç değerli mantığı destekler. Bu işleçlerin semantiği aşağıdaki tablo
tarafından tanımlanır:
X {1>Y<1} X&Y X|Y

true true true true

true {1>false<1} {1>false<1} true

true {1>null<1} {1>null<1} true

{1>false<1} true {1>false<1} true

{1>false<1} {1>false<1} {1>false<1} {1>false<1}

{1>false<1} {1>null<1} {1>false<1} {1>null<1}

{1>null<1} true {1>null<1} true

{1>null<1} {1>false<1} {1>false<1} {1>null<1}

{1>null<1} {1>null<1} {1>null<1} {1>null<1}

Bu işleçlerin davranışı, null yapılabilir değer türleriyle tipik işleç davranışından farklıdır. Genellikle, bir değer
türünün işlenenleri için tanımlanan bir işleç, karşılık gelen Nullable değer türünün işlenenleri ile de
kullanılabilir. Bu tür bir operatör, işlenenleri null değerlendirilirse null üretir. Ancak, & ve | işleçleri,
işlenenlerden biri null olarak değerlendirilse bile null olmayan üretebilir. Null yapılabilir değer türleriyle
operatör davranışı hakkında daha fazla bilgi için, Nullable değer türleri makalesinin yükseltilmemiş işleçleri
bölümüne bakın.
Aşağıdaki örnekte gösterildiği gibi, ! ve ^ işleçlerini bool? işlenenleriyle de kullanabilirsiniz:

bool? test = null;


Display(!test); // output: null
Display(test ^ false); // output: null
Display(test ^ null); // output: null
Display(true ^ null); // output: null

void Display(bool? b) => Console.WriteLine(b is null ? "null" : b.Value.ToString());

Koşullu mantıksal işleçler && ve || bool? işlenenleri desteklemez.

Bileşik atama
Bir ikili işleç op için, formun bileşik atama ifadesi

x op= y

eşdeğerdir

x = x op y

x hariç, yalnızca bir kez değerlendirilir.


& , | ve ^ işleçleri, aşağıdaki örnekte gösterildiği gibi bileşik atamayı destekler:
bool test = true;
test &= false;
Console.WriteLine(test); // output: False

test |= true;
Console.WriteLine(test); // output: True

test ^= false;
Console.WriteLine(test); // output: True

Koşullu mantıksal işleçler && ve || bileşik atamayı desteklemez.

İşleç önceliği
Aşağıdaki liste, en yüksek öncelikten başlayarak mantıksal işleçleri en düşüğe göre sıralar:
Mantıksal Değilleme İşleci !
Mantıksal AND işleci &
Mantıksal dışlamalı OR işleci ^
Mantıksal OR işleci |
Koşullu mantıksal AND işleci &&
Koşullu mantıksal OR işleci ||

İşleç önceliğine göre uygulanan değerlendirmenin sırasını değiştirmek için parantez, () kullanın:

Console.WriteLine(true | true & false); // output: True


Console.WriteLine((true | true) & false); // output: False

bool Operand(string name, bool value)


{
Console.WriteLine($"Operand {name} is evaluated.");
return value;
}

var byDefaultPrecedence = Operand("A", true) || Operand("B", true) && Operand("C", false);


Console.WriteLine(byDefaultPrecedence);
// Output:
// Operand A is evaluated.
// True

var changedOrder = (Operand("A", true) || Operand("B", true)) && Operand("C", false);


Console.WriteLine(changedOrder);
// Output:
// Operand A is evaluated.
// Operand C is evaluated.
// False

Öncelik düzeyine göre sıralanan C# işleçlerin tüm listesi için, C# işleçler makalesinin operatör önceliği
bölümüne bakın.

Operatör overloadability
Kullanıcı tanımlı bir tür ! , & , | ve ^ işleçlerini aşırı yükleyebilir. İkili işleç aşırı yüklendiğinde, karşılık gelen
bileşik atama işleci de örtük olarak aşırı yüklenmiştir. Kullanıcı tanımlı bir tür, bileşik atama işlecini açıkça aşırı
yükleyemez.
Kullanıcı tanımlı bir tür koşullu mantıksal işleçleri && ve || aşırı yükleyemez. Ancak, Kullanıcı tanımlı bir tür
true ve false işleçlerini ve & ya da | işlecini belirli bir şekilde aşırı yükleiyorsa, sırasıyla && veya || işlemi
bu türün işlenenleri için değerlendirilebilir. Daha fazla bilgi için, C# dil belirtiminin Kullanıcı tanımlı Koşullu
mantıksal işleçler bölümüne bakın.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtimininaşağıdaki bölümlerine bakın:
Mantıksal Değilleme İşleci
Mantıksal işleçler
Koşullu mantıksal işleçler
Bileşik atama

Ayrıca bkz.
C#başvurunun
C# işleçleri
Bit düzeyinde ve kaydırma işleçleri
Bit düzeyinde ve kaydırma işleçleriC# (başvuru)
27.11.2019 • 12 minutes to read • Edit Online

Aşağıdaki işleçler integral sayısal türlerin veya char türünün işlenenleri ile bit düzeyinde veya SHIFT işlemleri
gerçekleştirir:
Birli ~ (bit düzeyinde tamamlama) işleci
İkili << (sol SHIFT ) ve >> ( Sağ Shift) kaydırma işleçleri
İkili & ( MANTıKSAL ve), | (mantıksal or )ve ^ (mantıksal dışlamalı veya) işleçler

Bu işleçler int , uint , long ve ulong türleri için tanımlanmıştır. Her iki işlenen de diğer integral türlerindiğinde
( sbyte , byte , short , ushort veya char ), değerleri bir işlemin sonuç türü olan int türüne dönüştürülür.
İşlenenler farklı integral türlerindiğinde, değerleri, en yakın integral türüne dönüştürülür. Daha fazla bilgi için, C#
dil belirtiminin sayısal yükseltmeler bölümüne bakın.
& , | ve ^ işleçleri Ayrıca bool türünün işlenenleri için de tanımlanmıştır. Daha fazla bilgi için bkz. Boolean
mantıksal işleçler.
Bit düzeyinde ve kaydırma işlemleri hiçbir şekilde taşmaya neden olmaz ve denetlenen ve işaretlenmeyen
bağlamlarda aynı sonuçları üretir.

Bit düzeyinde tamamlama işleci ~


~ işleci, her biti ters çevirerek işleneni bir bit düzeyinde tamamlayıcı üretir:

uint a = 0b_0000_1111_0000_1111_0000_1111_0000_1100;
uint b = ~a;
Console.WriteLine(Convert.ToString(b, toBase: 2));
// Output:
// 11110000111100001111000011110011

Sonlandırıcıları bildirmek için ~ sembolünü de kullanabilirsiniz. Daha fazla bilgi için bkz. sonlandırıcılar.

Sola kaydırma işleci <<


<< işleci sol taraftaki işlenenini sağ işleneni tarafından tanımlanan bit sayısına göre sola kaydırır.
Aşağıdaki örnekte gösterildiği gibi, sol SHIFT işlemi, sonuç türü aralığının dışındaki yüksek sıralı bitleri atar ve
düşük sıralı boş bit konumlarını sıfıra ayarlar:

uint x = 0b_1100_1001_0000_0000_0000_0000_0001_0001;
Console.WriteLine($"Before: {Convert.ToString(x, toBase: 2)}");

uint y = x << 4;
Console.WriteLine($"After: {Convert.ToString(y, toBase: 2)}");
// Output:
// Before: 11001001000000000000000000010001
// After: 10010000000000000000000100010000

SHIFT işleçleri yalnızca int , uint , long ve ulong türleri için tanımlandığından, bir işlemin sonucu her zaman
en az 32 bit içerir. Sol işlenen başka bir integral türü ( sbyte , byte , short , ushort veya char ) ise, aşağıdaki
örnekte gösterildiği gibi, değeri int türüne dönüştürülür:
byte a = 0b_1111_0001;

var b = a << 8;
Console.WriteLine(b.GetType());
Console.WriteLine($"Shifted byte: {Convert.ToString(b, toBase: 2)}");
// Output:
// System.Int32
// Shifted byte: 1111000100000000

<< işlecinin sağ işleneninin kaydırma sayısını tanımladığı hakkında daha fazla bilgi için SHIFT Operators
bölümünün kaydırma sayısına bakın.

Sağa kaydırma işleci > >


>> işleci, sol işlenenin sağ işleneni tarafından tanımlanan bit sayısına göre sağa kayar.
Aşağıdaki örnekte gösterildiği gibi, doğru kaydırma işlemi düşük sıralı bitleri atar:

uint x = 0b_1001;
Console.WriteLine($"Before: {Convert.ToString(x, toBase: 2), 4}");

uint y = x >> 2;
Console.WriteLine($"After: {Convert.ToString(y, toBase: 2), 4}");
// Output:
// Before: 1001
// After: 10

Yüksek sıralı boş bit konumları, sol taraftaki işlenenin türüne göre aşağıdaki gibi ayarlanır:
Sol işlenen int veya long türünde ise, sağ SHIFT işleci bir Aritmetik kaydırma gerçekleştirir: sol
işlenenin en önemli bit (işaret biti) değeri, yüksek sıralı boş bit konumlarına yayılır. Diğer bir deyişle, sol
işlenen negatif olmayan ve negatifse bir tane olarak ayarlandıysa, yüksek sıralı boş bit konumları sıfır
olarak ayarlanır.

int a = int.MinValue;
Console.WriteLine($"Before: {Convert.ToString(a, toBase: 2)}");

int b = a >> 3;
Console.WriteLine($"After: {Convert.ToString(b, toBase: 2)}");
// Output:
// Before: 10000000000000000000000000000000
// After: 11110000000000000000000000000000

Sol işlenen uint veya ulong türünde ise, sağ SHIFT işleci bir mantıksal kaydırma gerçekleştirir: yüksek
sıralı boş bit konumları her zaman sıfır olarak ayarlanır.

uint c = 0b_1000_0000_0000_0000_0000_0000_0000_0000;
Console.WriteLine($"Before: {Convert.ToString(c, toBase: 2), 32}");

uint d = c >> 3;
Console.WriteLine($"After: {Convert.ToString(d, toBase: 2), 32}");
// Output:
// Before: 10000000000000000000000000000000
// After: 10000000000000000000000000000

>> işlecinin sağ işleneninin kaydırma sayısını tanımladığı hakkında daha fazla bilgi için SHIFT Operators
bölümünün kaydırma sayısına bakın.
Mantıksal AND işleci &
& işleci, işlenenlerinin bit düzeyinde mantıksal ve işlecini hesaplar:

uint a = 0b_1111_1000;
uint b = 0b_1001_1101;
uint c = a & b;
Console.WriteLine(Convert.ToString(c, toBase: 2));
// Output:
// 10011000

bool işlenenleri için & işleci, işlenenlerinin MANTıKSAL ve işlecini hesaplar. Birli & işleci, Adres işleçtir.

Mantıksal dışlamalı OR işleci ^


^ işleci, işlenenlerinin bit düzeyinde mantıksal XOR değeri olarak da bilinen bit düzeyinde mantıksal dışlamalı
veya bir şekilde hesaplar:

uint a = 0b_1111_1000;
uint b = 0b_0001_1100;
uint c = a ^ b;
Console.WriteLine(Convert.ToString(c, toBase: 2));
// Output:
// 11100100

bool işlenenleri için ^ işleci, işlenenlerinin mantıksal dışlamalı veya bir listesini hesaplar.

Mantıksal OR işleci |
| işleci, işlenenlerinin bit düzeyinde mantıksal veya işlecini hesaplar:

uint a = 0b_1010_0000;
uint b = 0b_1001_0001;
uint c = a | b;
Console.WriteLine(Convert.ToString(c, toBase: 2));
// Output:
// 10110001

bool işlenenleri için | işleci, işlenenlerinin MANTıKSAL veya işlecini hesaplar.

Bileşik atama
Bir ikili işleç op için, formun bileşik atama ifadesi

x op= y

eşdeğerdir

x = x op y

x hariç, yalnızca bir kez değerlendirilir.


Aşağıdaki örnek, bileşik atamanın bit düzeyinde ve kaydırma işleçleriyle kullanımını gösterir:
uint a = 0b_1111_1000;
a &= 0b_1001_1101;
Display(a); // output: 10011000

a |= 0b_0011_0001;
Display(a); // output: 10111001

a ^= 0b_1000_0000;
Display(a); // output: 111001

a <<= 2;
Display(a); // output: 11100100

a >>= 4;
Display(a); // output: 1110

void Display(uint x) => Console.WriteLine($"{Convert.ToString(x, toBase: 2), 8}");

Sayısal yükseltmelernedeniyle op işleminin sonucu x``T türüne örtülü olarak dönüştürülebilir olmayabilir.
Böyle bir durumda, op önceden tanımlanmış bir işleçse ve işlemin sonucu x``T türüne açıkça dönüştürülesiyse,
x = (T)(x op y) yalnızca bir kez değerlendirilmemesi dışında, form x op= y bir bileşik atama ifadesi x değerine
eşdeğerdir. Aşağıdaki örnekte bu davranış gösterilmektedir:

byte x = 0b_1111_0001;

int b = x << 8;
Console.WriteLine($"{Convert.ToString(b, toBase: 2)}"); // output: 1111000100000000

x <<= 8;
Console.WriteLine(x); // output: 0

İşleç önceliği
Aşağıdaki liste, en yüksek öncelikten en düşüğe başlayarak bit düzeyinde ve kaydırma işleçlerini sıralar:
Bit düzeyinde tamamlama işleci ~
SHIFT işleçleri << ve >>
Mantıksal AND işleci &
Mantıksal dışlamalı OR işleci ^
Mantıksal OR işleci |
İşleç önceliğine göre uygulanan değerlendirmenin sırasını değiştirmek için parantez, () kullanın:

uint a = 0b_1101;
uint b = 0b_1001;
uint c = 0b_1010;

uint d1 = a | b & c;
Display(d1); // output: 1101

uint d2 = (a | b) & c;
Display(d2); // output: 1000

void Display(uint x) => Console.WriteLine($"{Convert.ToString(x, toBase: 2), 4}");

Öncelik düzeyine göre sıralanan C# işleçlerin tüm listesi için, C# işleçler makalesinin operatör önceliği bölümüne
bakın.
Kaydırma işleçlerinin kaydırma sayısı
<< ve >> kaydırma işleçleri için sağ işlenen türü, int için önceden tanımlanmış bir örtülü sayısal dönüştürmeye
sahip int veya bir tür olmalıdır.
x << count ve x >> count ifadelerinde, gerçek kaydırma sayısı x türüne aşağıdaki gibi bağlıdır:
x türü int veya uint ise, kaydırma sayısı sağ işlenenin düşük sıralı beş biti tarafından tanımlanır. Diğer
bir deyişle, kaydırma sayısı count & 0x1F (veya count & 0b_1_1111 ) olarak hesaplanır.
x türü long veya ulong ise, kaydırma sayısı sağ işlenenin alt-sırası altı bitsiyle tanımlanır. Diğer bir
deyişle, kaydırma sayısı count & 0x3F (veya count & 0b_11_1111 ) olarak hesaplanır.

Aşağıdaki örnekte bu davranış gösterilmektedir:

int count1 = 0b_0000_0001;


int count2 = 0b_1110_0001;

int a = 0b_0001;
Console.WriteLine($"{a} << {count1} is {a << count1}; {a} << {count2} is {a << count2}");
// Output:
// 1 << 1 is 2; 1 << 225 is 2

int b = 0b_0100;
Console.WriteLine($"{b} >> {count1} is {b >> count1}; {b} >> {count2} is {b >> count2}");
// Output:
// 4 >> 1 is 2; 4 >> 225 is 2

Sabit listesi mantıksal işleçleri


~ , & , | ve ^ işleçleri her bir numaralandırma türü tarafından da desteklenir. Aynı numaralandırma türünün
işlenenleri için, temel alınan integral türünün karşılık gelen değerlerinde bir mantıksal işlem gerçekleştirilir.
Örneğin, herhangi bir x ve y bir numaralandırma türü T temel alınan bir tür U için, x & y ifadesi
(T)((U)x & (U)y) ifadesiyle aynı sonucu üretir.

Genellikle, Flags özniteliğiyle tanımlanan bir numaralandırma türü ile bit düzeyinde mantıksal işleçler
kullanırsınız. Daha fazla bilgi için Listeleme türleri makalesinin numaralandırma türleri bit bayrakları bölümüne
bakın.

Operatör overloadability
Kullanıcı tanımlı bir tür ~ , << , >> , & , | ve ^ işleçlerini aşırı yükleyebilir. İkili işleç aşırı yüklendiğinde, karşılık
gelen bileşik atama işleci de örtük olarak aşırı yüklenmiştir. Kullanıcı tanımlı bir tür, bileşik atama işlecini açıkça
aşırı yükleyemez.
Kullanıcı tanımlı bir tür T << veya >> işlecini aşırı yükletir, sol taraftaki işlenenin türü T olmalı ve sağ işlenen
türü int olmalıdır.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtimininaşağıdaki bölümlerine bakın:
Bit düzeyinde tamamlama işleci
Kaydırma işleçleri
Mantıksal işleçler
Bileşik atama
Sayısal yükseltmeler

Ayrıca bkz.
C#başvurunun
C# işleçleri
Boole mantıksal işleçler
Eşitlik işleçleri (C# başvuru)
30.10.2019 • 5 minutes to read • Edit Online

== (eşitlik) ve != (eşitsizlik) işleçleri işlenenlerinin eşit olup olmadığını denetler.

Eşitlik işleci = =
== eşitlik işleci, işlenenleri eşitse true döndürür false Aksi takdirde.
Değer türleri eşitlik
Yerleşik değer türlerinin işlenenleri, değerleri eşitse eşittir:

int a = 1 + 2 + 3;
int b = 6;
Console.WriteLine(a == b); // output: True

char c1 = 'a';
char c2 = 'A';
Console.WriteLine(c1 == c2); // output: False
Console.WriteLine(c1 == char.ToLower(c2)); // output: True

NOTE
== , < , > , <= ve >= işleçleri için, işlenenlerin herhangi biri bir sayı değilse (Double.NaN veya Single.NaN), işlemin
sonucu false olur. Diğer bir deyişle, NaN değeri, NaN dahil diğer double (veya float ) bir değere eşit, bundan
küçüktür veya eşit değildir. Daha fazla bilgi ve örnek için Double.NaN veya Single.NaN başvuru makalesine bakın.

Temeldeki integral türünün karşılık gelen değerleri eşitse aynı sabit listesi türünün iki işleneni eşittir.
Kullanıcı tanımlı Yapı türleri varsayılan olarak == işlecini desteklemez. == işlecini desteklemek için Kullanıcı
tanımlı bir yapının onu tekrar yüklemesi gerekir.
7,3 ile C# başlayarak, == ve != işleçleri C# dizilertarafından desteklenir. Daha fazla bilgi için C# demet türleri
makalesinin eşitlik ve diziler bölümüne bakın.
Başvuru türleri eşitliği
Varsayılan olarak, iki başvuru türü işlenen aynı nesneye başvurduklarında eşittir:
public class ReferenceTypesEquality
{
public class MyClass
{
private int id;

public MyClass(int id) => this.id = id;


}

public static void Main()


{
var a = new MyClass(1);
var b = new MyClass(1);
var c = a;
Console.WriteLine(a == b); // output: False
Console.WriteLine(a == c); // output: True
}
}

Örnekte gösterildiği gibi, Kullanıcı tanımlı başvuru türleri varsayılan olarak == işlecini destekler. Ancak, bir
başvuru türü == işlecini aşırı yükleyebilir. Bir başvuru türü == işlecini aşırı yükle, bu türden iki başvurunun
aynı nesneye başvurmasını denetlemek için Object.ReferenceEquals yöntemini kullanın.
Dize eşitlik
İki dize işleneni, her ikisi de null olduğunda veya her iki dize örneği de aynı uzunluktadır ve her bir karakter
konumunda aynı karakterlere sahip olduğunda eşittir:

string s1 = "hello!";
string s2 = "HeLLo!";
Console.WriteLine(s1 == s2.ToLower()); // output: True

string s3 = "Hello!";
Console.WriteLine(s1 == s3); // output: False

Bu, büyük/küçük harfe duyarlı bir sıra karşılaştırmasına sahiptir. Dize karşılaştırması hakkında daha fazla bilgi
için bkz. dizeleri C#karşılaştırma .
Temsilci eşitlik
Aynı çalışma zamanı türünün iki temsilci işleneni, her ikisi de null olduğunda veya çağrı listeleri aynı
uzunluktadır ve her konumda eşit girişlere sahip olduğunda eşittir:

Action a = () => Console.WriteLine("a");

Action b = a + a;
Action c = a + a;
Console.WriteLine(object.ReferenceEquals(b, c)); // output: False
Console.WriteLine(b == c); // output: True

Daha fazla bilgi için, C# dil belirtiminin, eşitlik işleçlerini devretmek bölümüne bakın.
Anlamsal olarak özdeş lambda ifadeleri değerlendirmesinden üretilen temsilciler, aşağıdaki örnekte gösterildiği
gibi eşit değildir:
Action a = () => Console.WriteLine("a");
Action b = () => Console.WriteLine("a");

Console.WriteLine(a == b); // output: False


Console.WriteLine(a + b == a + b); // output: True
Console.WriteLine(b + a == a + b); // output: False

Eşitsizlik işleci! =
Eşitsizlik işleci != , işlenenleri eşit değilse true döndürür false Aksi takdirde. Yerleşik türlerinişlenenleri için
x != y ifadesi, !(x == y) ifadesiyle aynı sonucu üretir. Tür eşitliği hakkında daha fazla bilgi için eşitlik işleci
bölümüne bakın.
Aşağıdaki örnek != işlecinin kullanımını gösterir:

int a = 1 + 1 + 2 + 3;
int b = 6;
Console.WriteLine(a != b); // output: True

string s1 = "Hello";
string s2 = "Hello";
Console.WriteLine(s1 != s2); // output: False

object o1 = 1;
object o2 = 1;
Console.WriteLine(o1 != o2); // output: True

Operatör overloadability
Kullanıcı tanımlı bir tür, == ve != işleçlerini aşırı yükleyebilir. Bir tür iki işleçten birini aşırı yüklediğinden, başka
bir tane de aşırı yüklemesi gerekir.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin ilişkisel ve tür-test işleçleri bölümüne bakın.

Ayrıca bkz.
C#başvurunun
C# işleçleri
System.IEquatable<T>
Object.Equals
Object.ReferenceEquals
Eşitlik karşılaştırmaları
Karşılaştırma işleçleri
Karşılaştırma işleçleri (C# başvuru)
30.10.2019 • 3 minutes to read • Edit Online

İlişkisel olarak da bilinen < (küçüktür), > (büyüktür), <= (küçüktür veya eşittir) ve >= (büyüktür veya eşittir)
karşılaştırması. Bu işleçler tüm integral ve kayan nokta sayısal türleri tarafından desteklenir.

NOTE
== , < , > , <= ve >= işleçleri için, işlenenlerin herhangi biri bir sayı değilse (Double.NaN veya Single.NaN), işlemin
sonucu false olur. Diğer bir deyişle, NaN değeri, NaN dahil diğer double (veya float ) bir değere eşit, bundan
küçüktür veya eşit değildir. Daha fazla bilgi ve örnek için Double.NaN veya Single.NaN başvuru makalesine bakın.

Numaralandırma türleri de karşılaştırma işleçlerini destekler. Aynı sabit listesi türünün işlenenleri için,
temeldeki integral türünün karşılık gelen değerleri karşılaştırılır.
== ve != işleçleri işlenenlerinin eşit olup olmadığını denetler.

Küçüktür işleci <


< işleci, sol işlenenin sağ işleneninden daha küçükse true döndürür false Aksi takdirde:

Console.WriteLine(7.0 < 5.1); // output: False


Console.WriteLine(5.1 < 5.1); // output: False
Console.WriteLine(0.0 < 5.1); // output: True

Console.WriteLine(double.NaN < 5.1); // output: False


Console.WriteLine(double.NaN >= 5.1); // output: False

Büyüktür işleci >


> işleci, sol işleneni sağ işleneninden büyükse true döndürür false Aksi takdirde:

Console.WriteLine(7.0 > 5.1); // output: True


Console.WriteLine(5.1 > 5.1); // output: False
Console.WriteLine(0.0 > 5.1); // output: False

Console.WriteLine(double.NaN > 5.1); // output: False


Console.WriteLine(double.NaN <= 5.1); // output: False

Küçüktür veya eşittir işleci <=


<= işleci, sol işlenenin sağ işleneninden küçük veya ona eşit olması durumunda true döndürür false Aksi
takdirde:

Console.WriteLine(7.0 <= 5.1); // output: False


Console.WriteLine(5.1 <= 5.1); // output: True
Console.WriteLine(0.0 <= 5.1); // output: True

Console.WriteLine(double.NaN > 5.1); // output: False


Console.WriteLine(double.NaN <= 5.1); // output: False
Büyüktür veya eşittir işleci > =
>= işleci, sol işlenenin sağ işleneninden büyük veya ona eşit olması durumunda true döndürür false Aksi
takdirde:

Console.WriteLine(7.0 >= 5.1); // output: True


Console.WriteLine(5.1 >= 5.1); // output: True
Console.WriteLine(0.0 >= 5.1); // output: False

Console.WriteLine(double.NaN < 5.1); // output: False


Console.WriteLine(double.NaN >= 5.1); // output: False

Operatör overloadability
Kullanıcı tanımlı bir tür < , > , <= ve >= işleçlerini aşırı yükleyebilir.
Bir tür < veya > işleçlerinden birini aşırı yüklerinde, hem < hem de > aşırı yüklemesi gerekir. Bir tür <=
veya >= işleçlerinden birini aşırı yüklerinde, hem <= hem de >= aşırı yüklemesi gerekir.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin ilişkisel ve tür-test işleçleri bölümüne bakın.

Ayrıca bkz.
C#başvurunun
C# işleçleri
System.IComparable<T>
Eşitlik işleçleri
Üye erişim işleçleri (C# başvuru)
30.10.2019 • 10 minutes to read • Edit Online

Bir tür üyesine eriştiğinizde aşağıdaki işleçleri kullanabilirsiniz:


. (üye erişimi): bir ad alanının veya türün üyesine erişmek için
[] (dizi öğesi veya Dizin Oluşturucu erişimi): bir dizi öğesine veya bir tür dizin oluşturucusuna erişmek için
?. ve ?[] (null-koşullu işleçler ): yalnızca bir işlenen null değilse bir üye veya öğe erişim işlemi
gerçekleştirmek için
() (çağırma): erişilen bir yöntemi çağırmak veya bir temsilciyi çağırmak için
^ (uçtan dizin): öğe konumunun bir sıranın sonundan olduğunu göstermek için
.. ( Aralık): dizi öğeleri aralığını almak için kullanabileceğiniz bir dizin aralığı belirtmek için

Üye erişim işleci.


Aşağıdaki örneklerde gösterildiği gibi, bir ad alanı veya tür üyesine erişmek için . belirtecini kullanın:
Bir using yönergesinin aşağıdaki örneğinde gösterildiği gibi, bir ad alanı içinde iç içe geçmiş bir ad alanına
erişmek için . kullanın:

using System.Collections.Generic;

Aşağıdaki kodun gösterdiği gibi, bir ad alanı içindeki bir türe erişmek üzere nitelenmiş bir ad oluşturmak için
. kullanın:

System.Collections.Generic.IEnumerable<int> numbers = new int[] { 1, 2, 3 };

Nitelenmiş adların kullanımını isteğe bağlı yapmak için bir using yönergesi kullanın.
Aşağıdaki kodda gösterildiği gibi, tür üyelerine, statik ve statik olmayan erişim için . kullanın:

var constants = new List<double>();


constants.Add(Math.PI);
constants.Add(Math.E);
Console.WriteLine($"{constants.Count} values to show:");
Console.WriteLine(string.Join(", ", constants));
// Output:
// 2 values to show:
// 3.14159265358979, 2.71828182845905

Uzantı yöntemineerişmek için . de kullanabilirsiniz.

Indexer işleci []
Köşeli ayraçlar [] , genellikle Array, Indexer veya pointer öğesi erişimi için kullanılır.
Dizi erişimi
Aşağıdaki örnek, dizi öğelerine nasıl erişileceğini göstermektedir:
int[] fib = new int[10];
fib[0] = fib[1] = 1;
for (int i = 2; i < fib.Length; i++)
{
fib[i] = fib[i - 1] + fib[i - 2];
}
Console.WriteLine(fib[fib.Length - 1]); // output: 55

double[,] matrix = new double[2,2];


matrix[0,0] = 1.0;
matrix[0,1] = 2.0;
matrix[1,0] = matrix[1,1] = 3.0;
var determinant = matrix[0,0] * matrix[1,1] - matrix[1,0] * matrix[0,1];
Console.WriteLine(determinant); // output: -3

Bir dizi dizini, bir dizi karşılık gelen boyutun sınırları dışındaysa bir IndexOutOfRangeException oluşturulur.
Yukarıdaki örnekte gösterildiği gibi, bir dizi türü bildirdiğinizde veya bir dizi örneği örneklediğinizde köşeli
parantezleri de kullanabilirsiniz.
Diziler hakkında daha fazla bilgi için bkz. diziler.
Dizin Oluşturucu erişimi
Aşağıdaki örnek, Dizin Oluşturucu erişimini göstermek için .NET Dictionary<TKey,TValue> türünü kullanır:

var dict = new Dictionary<string, double>();


dict["one"] = 1;
dict["pi"] = Math.PI;
Console.WriteLine(dict["one"] + dict["pi"]); // output: 4.14159265358979

Dizin oluşturucular, Kullanıcı tanımlı bir türün örneklerinin, dizi dizini oluşturma gibi benzer şekilde dizinlemesini
sağlar. Tamsayı olması gereken dizi dizinlerinin aksine, Dizin Oluşturucu parametreleri herhangi bir türde olacak
şekilde bildirilmelidir.
Dizin oluşturucular hakkında daha fazla bilgi için bkz. Dizin oluşturucular.
[] Diğer kullanımları
İşaretçi öğesi erişimi hakkında daha fazla bilgi için, işaretçi ilgili işleçler makalesinin işaretçi öğesi erişim işleci []
bölümüne bakın.
Ayrıca, öznitelikleribelirtmek için köşeli parantezleri de kullanabilirsiniz:

[System.Diagnostics.Conditional("DEBUG")]
void TraceMethod() {}

Null koşullu işleçler?. '? []


C# 6 ve sonrasında kullanılabilir, null koşullu bir operatör, yalnızca bu işlenen null olmayan bir değer olarak
değerlendiriliyorsa, bir üye erişimi, ?. veya öğe erişimi, ?[] işlemi uygular. İşlenen null değerlendirilirse, işleci
uygulamanın sonucu null . Null koşullu üye erişim işleci ?. ELVIS işleci olarak da bilinir.
Null koşullu işleçler kısa devre dışı. Diğer bir deyişle, bir koşullu üye veya öğe erişim işlemleri zincirindeki bir işlem
null döndürürse, zincirin geri kalanı yürütülmez. Aşağıdaki örnekte, A null değerlendirilirse B
değerlendirilmez ve A veya B null olarak değerlendirilirse C değerlendirilmez:
A?.B?.Do(C);
A?.B?[C];

Aşağıdaki örnek, ?. ve ?[] işleçlerinin kullanımını gösterir:

double SumNumbers(List<double[]> setsOfNumbers, int indexOfSetToSum)


{
return setsOfNumbers?[indexOfSetToSum]?.Sum() ?? double.NaN;
}

var sum1 = SumNumbers(null, 0);


Console.WriteLine(sum1); // output: NaN

var numberSets = new List<double[]>


{
new[] { 1.0, 2.0, 3.0 },
null
};

var sum2 = SumNumbers(numberSets, 0);


Console.WriteLine(sum2); // output: 6

var sum3 = SumNumbers(numberSets, 1);


Console.WriteLine(sum3); // output: NaN

Yukarıdaki örnek ayrıca null birleşim işlecini ?? , null koşullu bir işlemin sonucu null sonucunu değerlendirmek
üzere alternatif bir ifade belirtmek için kullanır.
İş parçacığı açısından güvenli temsilci çağırma
Bir temsilcinin null olup olmadığını denetlemek ve iş parçacığı güvenli bir şekilde (örneğin, bir olayyükselttiğinizde)
aşağıdaki kodun gösterdiği gibi, bir temsilciyi çağırmak için ?. işlecini kullanın:

PropertyChanged?.Invoke(…)

Bu kod, C# 5 veya daha önceki sürümlerde kullanacağınız aşağıdaki koda eşdeğerdir:

var handler = this.PropertyChanged;


if (handler != null)
{
handler(…);
}

Çağırma işleci ()
Bir yöntemi çağırmak veya bir temsilciyiçağırmak için parantez, () kullanın.
Aşağıdaki örnek, bağımsız değişkenler içeren veya olmayan bir yöntemin nasıl çağrılacağını gösterir ve bir
temsilciyi çağırır:
Action<int> display = s => Console.WriteLine(s);

var numbers = new List<int>();


numbers.Add(10);
numbers.Add(17);
display(numbers.Count); // output: 2

numbers.Clear();
display(numbers.Count); // output: 0

Ayrıca, new işleçle bir Oluşturucu çağırdığınızda parantezleri de kullanabilirsiniz.


() Diğer kullanımları
Ayrıca, bir ifadede işlemlerin değerlendirileceği sırayı ayarlamak için parantez de kullanabilirsiniz. Daha fazla bilgi
için bkz C# . işleçler.
Açık tür dönüştürmeleri gerçekleştiren atama ifadeleri, parantez de kullanır.

Bitiş işlecinden Dizin ^


C# 8,0 ve sonraki sürümlerde kullanılabilen ^ işleci, öğe konumunun sıranın sonundan itibaren olduğunu gösterir.
length bir dizi Uzunluk için, ^n bir sıranın başından itibaren length - n olan öğeye işaret eder. Örneğin ^1 ,
sıranın son öğesine işaret eder ve ^length bir dizinin ilk öğesine işaret eder.

int[] xs = new[] { 0, 10, 20, 30, 40 };


int last = xs[^1];
Console.WriteLine(last); // output: 40

var lines = new List<string> { "one", "two", "three", "four" };


string prelast = lines[^2];
Console.WriteLine(prelast); // output: three

string word = "Twenty";


Index toFirst = ^word.Length;
char first = word[toFirst];
Console.WriteLine(first); // output: T

Yukarıdaki örnekte gösterildiği gibi ifade ^e System.Index türüdür. İfade ^e , e sonucu int örtülü olarak
dönüştürülebilir olmalıdır.
Ayrıca, dizin aralığı oluşturmak için ^ işlecini Aralık işleciyle de kullanabilirsiniz. Daha fazla bilgi için bkz. Dizinler
ve aralıklar.

Aralık işleci..
C# 8,0 ve sonraki sürümlerde kullanılabilen .. işleci, işlenen bir dizin aralığının başlangıcını ve sonunu belirtir. Sol
işlenen bir aralığın kapsamlı bir başlangıcı olur. Sağ işlenen bir aralığın dışlamalı bir sonu. Her iki işlenen de,
aşağıdaki örnekte gösterildiği gibi, bir sıranın başından veya sonundan bir dizin olabilir:
int[] numbers = new[] { 0, 10, 20, 30, 40, 50 };
int start = 1;
int amountToTake = 3;
int[] subset = numbers[start..(start + amountToTake)];
Display(subset); // output: 10 20 30

int margin = 1;
int[] inner = numbers[margin..^margin];
Display(inner); // output: 10 20 30 40

string line = "one two three";


int amountToTakeFromEnd = 5;
Range endIndices = ^amountToTakeFromEnd..^0;
string end = line[endIndices];
Console.WriteLine(end); // output: three

void Display<T>(IEnumerable<T> xs) => Console.WriteLine(string.Join(" ", xs));

Yukarıdaki örnekte gösterildiği gibi ifade a..b System.Range türüdür. İfade a..b , a ve b sonuçları int veya
Indexörtülü olarak dönüştürülebilir olmalıdır.
Açık uçlu bir Aralık almak için .. işlecinin herhangi bir işlenenini atlayabilirsiniz:
a.. a..^0 eşdeğerdir
..b 0..b eşdeğerdir
.. 0..^0 eşdeğerdir

int[] numbers = new[] { 0, 10, 20, 30, 40, 50 };


int amountToDrop = numbers.Length / 2;

int[] rightHalf = numbers[amountToDrop..];


Display(rightHalf); // output: 30 40 50

int[] leftHalf = numbers[..^amountToDrop];


Display(leftHalf); // output: 0 10 20

int[] all = numbers[..];


Display(all); // output: 0 10 20 30 40 50

void Display<T>(IEnumerable<T> xs) => Console.WriteLine(string.Join(" ", xs));

Daha fazla bilgi için bkz. Dizinler ve aralıklar.

Operatör overloadability
. , () , ^ ve .. işleçleri aşırı yüklenemez. [] işleci de aşırı yüklenebilir olmayan bir operatör olarak
değerlendirilir. Kullanıcı tanımlı türlerle Dizin oluşturmayı desteklemek için Dizin oluşturucular kullanın.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtimininaşağıdaki bölümlerine bakın:
Üye erişimi
Öğe erişimi
Null-koşullu işleç
Çağırma ifadeleri
Dizinler ve aralıklar hakkında daha fazla bilgi için bkz. özellik teklifi Note.
Ayrıca bkz.
C#başvurunun
C# işleçleri
?? (null birleşim işleci)
:: işleci
Tür-test ve atama işleçleri (C# başvuru)
25.11.2019 • 9 minutes to read • Edit Online

Tür denetimi veya tür dönüştürme gerçekleştirmek için aşağıdaki işleçleri kullanabilirsiniz:
işleç: bir ifadenin çalışma zamanı türünün belirli bir tür ile uyumlu olup olmadığını denetlemek için
as işleci: çalışma zamanı türü bu türle uyumluysa bir ifadeyi açıkça belirli bir türe dönüştürmek için
cast işleci (): açık bir dönüştürme gerçekleştirmek için
typeof işleci: bir türün System.Type örneğini almak için

işleç
is işleci, bir ifade sonucunun çalışma zamanı türünün belirli bir tür ile uyumlu olup olmadığını denetler. C# 7,0 '
den başlayarak, is işleci bir düzene karşı bir ifade sonucunu da sınar.
Tür-test is işleci olan ifade aşağıdaki biçimdedir

E is T

Burada E bir değer döndüren bir ifadedir ve T bir türün veya bir tür parametresinin adıdır. E anonim bir
yöntem veya lambda ifadesi olamaz.
E is T ifadesi, E sonucu null değilse ve bir başvuru dönüştürmesi, paketleme dönüştürmesi ya da bir kutudan
çıkarma dönüştürmesi tarafından T türüne dönüştürülebiliyorsanız true döndürür. Aksi takdirde, false
döndürür. is işleci Kullanıcı tanımlı dönüştürmeleri dikkate almaz.
Aşağıdaki örnek, bir ifade sonucunun çalışma zamanı türü verilen bir türden türetilse, yani türler arasında bir
başvuru dönüştürmesi varsa is işlecinin true döndürdüğünü gösterir:

public class Base { }

public class Derived : Base { }

public static class IsOperatorExample


{
public static void Main()
{
object b = new Base();
Console.WriteLine(b is Base); // output: True
Console.WriteLine(b is Derived); // output: False

object d = new Derived();


Console.WriteLine(d is Base); // output: True
Console.WriteLine(d is Derived); // output: True
}
}

Sonraki örnek, is işlecinin hesap paketleme ve kutudan çıkarma dönüştürmelerine sahip olduğunu ancak sayısal
dönüştürmeleridüşünmediğini gösterir:
int i = 27;
Console.WriteLine(i is System.IFormattable); // output: True

object iBoxed = i;
Console.WriteLine(iBoxed is int); // output: True
Console.WriteLine(iBoxed is long); // output: False

Dönüşümler hakkında C# daha fazla bilgi için bkz. C# dil belirtiminin dönüşümler bölümü.
Model eşleştirme ile test türü
C# 7,0 ' den başlayarak, is işleci bir düzene karşı bir ifade sonucunu da sınar. Özellikle, aşağıdaki biçimde tür
düzenlerini destekler:

E is T v

E , bir değer döndüren bir ifadedir, T bir tür ya da bir tür parametresidir ve v T türünde yeni bir yerel
değişkendir. E sonucu null değilse ve bir başvuru, paketleme veya kutudan çıkarma dönüştürmesi tarafından T
dönüştürülebiliyorsanız, E is T v ifadesi true döndürür ve E sonucunun dönüştürülmüş değeri değişken v
atanır.
Aşağıdaki örnek, is işlecinin tür düzeniyle kullanımını gösterir:

int i = 23;
object iBoxed = i;
int? jNullable = 7;
if (iBoxed is int a && jNullable is int b)
{
Console.WriteLine(a + b); // output 30
}

Tür deseni ve diğer desteklenen desenler hakkında daha fazla bilgi için, bkz. deseniyle eşleme.

as işleci
as işleci, bir ifadenin sonucunu açıkça belirli bir başvuruya veya null yapılabilir değer türüne dönüştürür.
Dönüştürme mümkün değilse, as işleci null döndürür. Atama işlecinin ()aksine, as işleci hiçbir şekilde özel
durum oluşturmaz.
Formun ifadesi

E as T

E , bir değer döndüren ve T bir tür veya tür parametresinin adı olan bir ifadedir, aynı sonucu şöyle üretir

E is T ? (T)(E) : (T)null

E hariç, yalnızca bir kez değerlendirilir.


as işleci yalnızca başvuru, null yapılabilir, kutulama ve kutudan çıkarma dönüştürmelerini dikkate alır. Kullanıcı
tanımlı bir dönüştürme gerçekleştirmek için as işlecini kullanamazsınız. Bunu yapmak için, cast işlecini ()kullanın.
Aşağıdaki örnek as işlecinin kullanımını gösterir:
IEnumerable<int> numbers = new[] { 10, 20, 30 };
IList<int> indexable = numbers as IList<int>;
if (indexable != null)
{
Console.WriteLine(indexable[0] + indexable[indexable.Count - 1]); // output: 40
}

NOTE
Yukarıdaki örnekte gösterildiği gibi, dönüştürmenin başarılı olup olmadığını denetlemek için as ifadesinin sonucunu null
karşılaştırmanız gerekir. 7,0 ' C# den başlayarak, dönüştürmenin başarılı olup olmadığını test etmek için, her iki işleci de
kullanabilirsiniz ve başarılı olursa, sonucunu yeni bir değişkene atayın.

Cast işleci ()
Form (T)E bir atama ifadesi, T yazmak için ifade E sonucunun açık bir şekilde dönüştürülmesini gerçekleştirir.
E türünden T türüne açık bir dönüştürme yoksa, derleme zamanı hatası oluşur. Çalışma zamanında, açık bir
dönüştürme başarılı olmayabilir ve bir atama ifadesi bir özel durum oluşturabilir.
Aşağıdaki örnek, açık sayısal ve başvuru dönüştürmelerini göstermektedir:

double x = 1234.7;
int a = (int)x;
Console.WriteLine(a); // output: 1234

IEnumerable<int> numbers = new int[] { 10, 20, 30 };


IList<int> list = (IList<int>)numbers;
Console.WriteLine(list.Count); // output: 3
Console.WriteLine(list[1]); // output: 20

Desteklenen açık dönüştürmeler hakkında daha fazla bilgi için, C# dil belirtiminin Açık dönüşümler bölümüne
bakın. Özel bir açık veya örtük tür dönüştürme tanımlama hakkında daha fazla bilgi için bkz. Kullanıcı tanımlı
dönüştürme işleçleri.
() Diğer kullanımları
Ayrıca, bir yöntemi çağırmak veya bir temsilciyi çağırmakiçin parantezleri de kullanabilirsiniz.
Diğer parantez kullanımı, bir ifadede işlemlerin değerlendirileceği sırayı ayarlamadır. Daha fazla bilgi için bkz C# .
işleçler.

typeof işleci
typeof işleci bir tür için System.Type örneğini alır. Aşağıdaki örnekte gösterildiği gibi typeof işlecinin bağımsız
değişkeni bir tür veya tür parametresinin adı olmalıdır:

void PrintType<T>() => Console.WriteLine(typeof(T));

Console.WriteLine(typeof(List<string>));
PrintType<int>();
PrintType<System.Int32>();
PrintType<Dictionary<int, char>>();
// Output:
// System.Collections.Generic.List`1[System.String]
// System.Int32
// System.Int32
// System.Collections.Generic.Dictionary`2[System.Int32,System.Char]
typeof işlecini ilişkisiz genel türlerle de kullanabilirsiniz. İlişkisiz genel türün adı, tür parametrelerinin sayısından
küçük olan uygun sayıda virgül içermelidir. Aşağıdaki örnek, typeof işlecinin ilişkisiz genel bir tür kullanımını
gösterir:

Console.WriteLine(typeof(Dictionary<,>));
// Output:
// System.Collections.Generic.Dictionary`2[TKey,TValue]

İfade typeof işlecinin bağımsız değişkeni olamaz. Bir ifade sonucunun çalışma zamanı türü System.Type örneğini
almak için Object.GetType metodunu kullanın.
typeof işleci ile test yazın
İfade sonucunun çalışma zamanı türünün verilen bir türle tam olarak eşleşip eşleşmediğini denetlemek için
typeof işlecini kullanın. Aşağıdaki örnek, typeof işleci ve işleç işleciile gerçekleştirilen tür denetimi arasındaki
farkı gösterir:

public class Animal { }

public class Giraffe : Animal { }

public static class TypeOfExample


{
public static void Main()
{
object b = new Giraffe();
Console.WriteLine(b is Animal); // output: True
Console.WriteLine(b.GetType() == typeof(Animal)); // output: False

Console.WriteLine(b is Giraffe); // output: True


Console.WriteLine(b.GetType() == typeof(Giraffe)); // output: True
}
}

Operatör overloadability
is , as ve typeof işleçleri aşırı yüklenemez.
Kullanıcı tanımlı bir tür () işlecini aşırı yükleyemez, ancak bir atama ifadesi tarafından gerçekleştirilebilecek özel
tür dönüştürmeleri tanımlayabilir. Daha fazla bilgi için bkz. Kullanıcı tanımlı dönüştürme işleçleri.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtimininaşağıdaki bölümlerine bakın:
SIS işleci
As işleci
Atama ifadeleri
Typeof işleci

Ayrıca bkz.
C#başvurunun
C# işleçleri
Desenler ve as işleçlerini kullanarak güvenli bir şekilde atama
.NET 'teki genel türler
Kullanıcı tanımlı dönüştürme işleçleri (C# başvuru)
30.10.2019 • 2 minutes to read • Edit Online

Kullanıcı tanımlı bir tür, ya da başka bir türe özel örtük veya açık bir dönüştürme tanımlayabilir.
Örtük dönüştürmeler özel sözdiziminin çağrılmasını gerektirmez ve örneğin atamalar ve Yöntemler
çağırmaları gibi çeşitli durumlarda gerçekleşebilir. Önceden C# tanımlanmış örtük dönüştürmeler her zaman
başarılı olur ve hiçbir zaman özel durum oluşturmaz. Kullanıcı tanımlı örtük dönüştürmeler de bu şekilde
davranmalıdır. Özel bir dönüştürme özel durum oluşturabilir veya bilgi kaybedebilir, onu açık bir dönüştürme
olarak tanımlayın.
Kullanıcı tanımlı dönüştürmeler , ve gibi işleçler tarafından değerlendirilmez. Kullanıcı tanımlı bir açık
dönüştürme çağırmak için cast işlecini () kullanın.
Sırasıyla örtük veya açık bir dönüştürme tanımlamak için operator ve implicit veya explicit anahtar
sözcüklerini kullanın. Bir dönüştürmeyi tanımlayan tür bir kaynak türü ya da bu dönüştürmenin hedef türü
olmalıdır. Kullanıcı tanımlı iki tür arasında dönüştürme iki türden birinde tanımlanabilir.
Aşağıdaki örnek, örtük ve açık bir dönüştürmenin nasıl tanımlanacağını göstermektedir:

using System;

public readonly struct Digit


{
private readonly byte digit;

public Digit(byte digit)


{
if (digit > 9)
{
throw new ArgumentOutOfRangeException(nameof(digit), "Digit cannot be greater than nine.");
}
this.digit = digit;
}

public static implicit operator byte(Digit d) => d.digit;


public static explicit operator Digit(byte b) => new Digit(b);

public override string ToString() => $"{digit}";


}

public static class UserDefinedConversions


{
public static void Main()
{
var d = new Digit(7);

byte number = d;
Console.WriteLine(number); // output: 7

Digit digit = (Digit)number;


Console.WriteLine(digit); // output: 7
}
}

Ayrıca, önceden tanımlanmış C# bir işleci aşırı yüklemek için operator anahtar sözcüğünü de kullanabilirsiniz.
Daha fazla bilgi için bkz. operatör aşırı yüklemesi.
C# dili belirtimi
Daha fazla bilgi için, C# dil belirtimininaşağıdaki bölümlerine bakın:
Dönüştürme işleçleri
Kullanıcı tanımlı dönüştürmeler
Örtük dönüştürmeler
Açık dönüşümler

Ayrıca bkz.
C#başvurunun
C# işleçleri
İşleç aşırı yüklemesi
Tür testi ve atama işleçleri
Atama ve tür dönüştürme
Üzerinde Kullanıcı tanımlı açık dönüşümlerC#
İşaretçiden ilgili işleçler (C# başvuru)
30.10.2019 • 11 minutes to read • Edit Online

İşaretçilerle çalışmak için aşağıdaki işleçleri kullanabilirsiniz:


Birli (Adres-of) işleci: bir değişkenin adresini almak için
&
Birli * (işaretçi yöneltme) işleci: bir işaretçiye göre işaret eden değişkeni elde etmek için
-> (üye erişimi) ve [] (öğe erişimi) işleçleri
Aritmetik işleçler + , - , ++ ve --
Karşılaştırma işleçleri == , != , < , > , <= ve >=
İşaretçi türleri hakkında bilgi için bkz. işaretçi türleri.

NOTE
İşaretçilerle herhangi bir işlem güvenli olmayan bir bağlam gerektirir. Güvenli olmayan bloklar içeren kodun -unsafe
derleyici seçeneğiyle derlenmesi gerekir.

Address-of işleci &


Birli & işleci, işleneninin adresini döndürür:

unsafe
{
int number = 27;
int* pointerToNumber = &number;

Console.WriteLine($"Value of the variable: {number}");


Console.WriteLine($"Address of the variable: {(long)pointerToNumber:X}");
}
// Output is similar to:
// Value of the variable: 27
// Address of the variable: 6C1457DBD4

& işlecinin işleneni sabit bir değişken olmalıdır. Sabit değişkenler, Atık toplayıcısınınişleminden etkilenmeyen
depolama konumlarında bulunan değişkenlerdir. Yukarıdaki örnekte, number yerel değişkeni yığında
bulunduğundan sabit bir değişkendir. Çöp toplayıcısından etkilenebilecek (örneğin, yeniden konumlandırılan)
depolama konumlarında bulunan değişkenler Taşınabilir değişkenler olarak adlandırılır. Nesne alanları ve dizi
öğeleri taşınabilir değişkenlerin örnekleridir. Taşınabilir bir değişkenin adresini, bir fixed ifadesiyle"düzelmiyor"
veya "sabitle" yaparsanız alabilirsiniz. Alınan adres yalnızca bir fixed deyimin bloğu içinde geçerlidir. Aşağıdaki
örnek, bir fixed deyimin ve & işlecinin nasıl kullanılacağını gösterir:

unsafe
{
byte[] bytes = { 1, 2, 3 };
fixed (byte* pointerToFirst = &bytes[0])
{
// The address stored in pointerToFirst
// is valid only inside this fixed statement block.
}
}
Bir sabit veya bir değerin adresini alamazsınız.
Sabit ve taşınabilir değişkenler hakkında daha fazla bilgi için, C# dil belirtiminin sabit ve taşınabilir değişkenler
bölümüne bakın.
İkili & işleci, Boolean işlenenlerinin MANTıKSAL ve mantıksal değerini ya da tam sayı işlenenlerini hesaplar.

İşaretçi yöneltme işleci *


Birli işaretçi yöneltme işleci * işleneninin gösterdiği değişkeni alır. Başvuru operatörü olarak da bilinir. *
işlecinin işleneni bir işaretçi türünde olmalıdır.

unsafe
{
char letter = 'A';
char* pointerToLetter = &letter;
Console.WriteLine($"Value of the `letter` variable: {letter}");
Console.WriteLine($"Address of the `letter` variable: {(long)pointerToLetter:X}");

*pointerToLetter = 'Z';
Console.WriteLine($"Value of the `letter` variable after update: {letter}");
}
// Output is similar to:
// Value of the `letter` variable: A
// Address of the `letter` variable: DCB977DDF4
// Value of the `letter` variable after update: Z

void* türündeki bir ifadeye * işlecini uygulayamazsınız.


İkili * işleci, sayısal işlenenlerinin çarpımını hesaplar.

İşaretçi üyesi erişim işleci->


-> işleci, işaretçi yöneltme ve üye erişiminibirleştirir. Diğer bir deyişle, x T* türünde bir işaretçisiyse ve y T
türü bir ifade olan erişilebilir bir üyedir.

x->y

eşdeğerdir

(*x).y

Aşağıdaki örnek -> işlecinin kullanımını gösterir:


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

public class PointerMemberAccessExample


{
public static unsafe void Main()
{
Coords coords;
Coords* p = &coords;
p->X = 3;
p->Y = 4;
Console.WriteLine(p->ToString()); // output: (3, 4)
}
}

void* türündeki bir ifadeye -> işlecini uygulayamazsınız.

İşaretçi öğesi erişim işleci []


İşaretçi türünün bir ifadesi p için, form p[n] bir işaretçi öğesi erişimi *(p + n) olarak değerlendirilir, burada n
örtük olarak int , uint , long bir türde olmalıdır veya ulong . İşaretçilerle + işlecinin davranışı hakkında daha
fazla bilgi için, bir tam sayı değerini bir işaretçi bölümüne ekleme veya çıkarma bölümüne bakın.
Aşağıdaki örnek, bir işaretçi ve [] işleci ile dizi öğelerine nasıl erişileceğini gösterir:

unsafe
{
char* pointerToChars = stackalloc char[123];

for (int i = 65; i < 123; i++)


{
pointerToChars[i] = (char)i;
}

Console.Write("Uppercase letters: ");


for (int i = 65; i < 91; i++)
{
Console.Write(pointerToChars[i]);
}
}
// Output:
// Uppercase letters: ABCDEFGHIJKLMNOPQRSTUVWXYZ

Örnek, yığında bir bellek bloğu ayırmak için stackalloc işlecini kullanır.

NOTE
İşaretçi öğesi erişim işleci, sınır dışı hataları denetlemez.

void* türünde bir ifadeyle işaretçi öğesi erişimi için [] kullanamazsınız.


Dizi öğesi veya Dizin Oluşturucu erişimiiçin [] işlecini de kullanabilirsiniz.

İşaretçi aritmetik işleçleri


İşaretçilerle aşağıdaki aritmetik işlemleri gerçekleştirebilirsiniz:
Bir işaretçiye veya işaretçiden tamsayı değer ekleme veya çıkarma
İki işaretçileri çıkar
Bir işaretçiyi artırma veya azaltma
void* türündeki işaretçilerle bu işlemleri gerçekleştiremezsiniz.
Sayısal türlerle desteklenen aritmetik işlemler hakkında daha fazla bilgi için bkz. Aritmetik işleçler.
Bir işaretçiye veya bir işaretçiye tamsayı değer ekleme veya çıkarma
T* türü bir işaretçi p ve int , uint , long , veya ulong , toplama ve çıkarma için örtük olarak dönüştürülebilir
bir türün n ifadesi aşağıdaki gibi tanımlanır:
Hem p + n hem de n + p ifadeleri, p tarafından verilen adrese n * sizeof(T) eklemenin sonucu T*
türünde bir işaretçi üretir.
p - n ifade, p tarafından verilen adresten n * sizeof(T) çıkarılmasına neden olan T* türünde bir işaretçi
üretir.
sizeof işleci , bir türün boyutunu bayt cinsinden alır.
Aşağıdaki örnek bir işaretçiyle + işlecinin kullanımını gösterir:

unsafe
{
const int Count = 3;
int[] numbers = new int[Count] { 10, 20, 30 };
fixed (int* pointerToFirst = &numbers[0])
{
int* pointerToLast = pointerToFirst + (Count - 1);

Console.WriteLine($"Value {*pointerToFirst} at address {(long)pointerToFirst}");


Console.WriteLine($"Value {*pointerToLast} at address {(long)pointerToLast}");
}
}
// Output is similar to:
// Value 10 at address 1818345918136
// Value 30 at address 1818345918144

İşaretçi çıkarması
İki işaretçi p1 ve T* türünde p2 , ifade p1 - p2 p1 ve p2 tarafından verilen adresler arasındaki farkı
sizeof(T) tarafından bölünür. Sonucun türü long . Diğer bir deyişle, p1 - p2
((long)(p1) - (long)(p2)) / sizeof(T) olarak hesaplanır.

Aşağıdaki örnekte işaretçi çıkarma gösterilmektedir:

unsafe
{
int* numbers = stackalloc int[] { 0, 1, 2, 3, 4, 5 };
int* p1 = &numbers[1];
int* p2 = &numbers[5];
Console.WriteLine(p2 - p1); // output: 4
}

İşaretçi artışı ve azaltma


++ artım işleci, işaretçi işleneni 1 ekler . -- azaltma işleci, işaretçi işlenenden 1 çıkartır .
İki tür işleç desteklenir: sonek ( p++ ve p-- ) ve önek ( ++p ve --p ). p++ ve p-- sonucu, işlemden önceki p
değeridir. ++p ve --p sonucu, işlem sonrasında p değeridir.
Aşağıdaki örnek, hem sonek hem de önek artırma işleçlerinin davranışını gösterir:

unsafe
{
int* numbers = stackalloc int[] { 0, 1, 2 };
int* p1 = &numbers[0];
int* p2 = p1;
Console.WriteLine($"Before operation: p1 - {(long)p1}, p2 - {(long)p2}");
Console.WriteLine($"Postfix increment of p1: {(long)(p1++)}");
Console.WriteLine($"Prefix increment of p2: {(long)(++p2)}");
Console.WriteLine($"After operation: p1 - {(long)p1}, p2 - {(long)p2}");
}
// Output is similar to
// Before operation: p1 - 816489946512, p2 - 816489946512
// Postfix increment of p1: 816489946512
// Prefix increment of p2: 816489946516
// After operation: p1 - 816489946516, p2 - 816489946516

İşaretçi karşılaştırma işleçleri


<= dahil olmak üzere herhangi bir işaretçi türündeki işlenenleri karşılaştırmak için == , != , < , > , >= ve void*
işleçlerini kullanabilirsiniz. Bu işleçler, iki işlenen tarafından verilen adresleri işaretsiz tamsayılar gibi karşılaştırır.
Diğer türlerin işlenenleri için bu işleçlerin davranışı hakkında daha fazla bilgi için bkz. eşitlik işleçleri ve
karşılaştırma işleçleri makaleleri.

İşleç önceliği
Aşağıdaki liste, işaretçinin ilgili işleçlerini en yüksek öncelikten en düşüğe başlayarak sıralar:
Sonek artırma x++ ve azaltma x-- işleçleri ve -> ve [] işleçleri
Önek artırma ++x ve azaltma --x işleçleri ve & ve * işleçleri
Adli + ve - işleçleri
Karşılaştırma < , > , <= ve >= işleçleri
Eşitlik == ve != işleçleri

İşleç önceliğine göre uygulanan değerlendirmenin sırasını değiştirmek için parantez, () kullanın.
Öncelik düzeyine göre sıralanan C# işleçlerin tüm listesi için, C# işleçler makalesinin operatör önceliği bölümüne
bakın.

Operatör overloadability
Kullanıcı tanımlı bir tür, işaretçi ile ilgili işleçleri & , * , -> ve [] aşırı yükleyemez.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtimininaşağıdaki bölümlerine bakın:
Sabit ve taşınabilir değişkenler
Address-of işleci
İşaretçi yöneltme
İşaretçi üye erişimi
İşaretçi öğesi erişimi
İşaretçi aritmetik
İşaretçi artışı ve azaltma
İşaretçi karşılaştırması

Ayrıca bkz.
C#başvurunun
C# işleçleri
İşaretçi türleri
güvenli olmayan anahtar sözcük
Fixed anahtar sözcüğü
stackalloc işleci
sizeof işleci
Atama işleçleri (C# başvuru)
30.10.2019 • 3 minutes to read • Edit Online

Atama işleci = , sağ işleneninin değerini bir değişkene, özelliğeveya sol tarafından verilen bir Dizin Oluşturucu
öğesine atar. Atama ifadesinin sonucu, sol işlenene atanan değerdir. Sağ işlenenin türü, sol işlenenin türüyle aynı
veya örtülü olarak dönüştürülebilir olmalıdır.
Atama işleci = , doğru ilişkilendirilebilir, diğer bir deyişle, formun bir ifadesidir

a = b = c

şöyle değerlendirilir

a = (b = c)

Aşağıdaki örnek, bir yerel değişken, bir özellik ve bir Dizin Oluşturucu öğesi olan atama işlecinin kullanımını sol
işlenen olarak gösterir:

var numbers = new List<double>() { 1.0, 2.0, 3.0 };

Console.WriteLine(numbers.Capacity);
numbers.Capacity = 100;
Console.WriteLine(numbers.Capacity);
// Output:
// 4
// 100

int newFirstElement;
double originalFirstElement = numbers[0];
newFirstElement = 5;
numbers[0] = newFirstElement;
Console.WriteLine(originalFirstElement);
Console.WriteLine(numbers[0]);
// Output:
// 1
// 5

ref atama işleci


7,3 ' C# den başlayarak ref atama işlecini = ref bir ref yerel veya ref ReadOnly yerel değişkenini yeniden atamak
için kullanabilirsiniz. Aşağıdaki örnek, ref atama işlecinin kullanımını gösterir:
void Display(double[] s) => Console.WriteLine(string.Join(" ", s));

double[] arr = { 0.0, 0.0, 0.0 };


Display(arr);

ref double arrayElement = ref arr[0];


arrayElement = 3.0;
Display(arr);

arrayElement = ref arr[arr.Length - 1];


arrayElement = 5.0;
Display(arr);
// Output:
// 0 0 0
// 3 0 0
// 3 0 5

Ref atama operatörü durumunda, her iki işleneni de aynı türde olmalıdır.

Bileşik atama
Bir ikili işleci için op , formun bileşik atama ifadesi

x op= y

eşdeğerdir

x = x op y

x yalnızca bir kez değerlendirilir.


Bileşik atama Aritmetik, Boole mantıksalve bit düzeyinde mantıksal ve kaydırma işleçleri tarafından desteklenir.

Null birleştirme ataması


8,0 ' C# den başlayarak, sağ işleneninin değerini yalnızca sol taraftaki işlenenin null olarak değerlendirdiği
durumlarda sol işlenenin değerini atamak için null birleşim atama işlecini ??= kullanabilirsiniz. Daha fazla bilgi
için?? ve?? = operatörler makalesi.

Operatör overloadability
Kullanıcı tanımlı bir tür atama işlecini aşırı yükleyemez . Ancak, Kullanıcı tanımlı bir tür, başka bir türe örtük bir
dönüştürme tanımlayabilir. Bu şekilde, Kullanıcı tanımlı bir türün değeri bir değişkene, özelliğe veya başka bir
türün Dizin Oluşturucu öğesine atanabilir. Daha fazla bilgi için bkz. Kullanıcı tanımlı dönüştürme işleçleri.
Kullanıcı tanımlı bir tür, bileşik atama işlecini açıkça aşırı yükleyemez. Ancak, Kullanıcı tanımlı bir tür bir ikili işleci
op aşırı yükle, varsa op= işleci de dolaylı olarak aşırı yüklenmiştir.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin atama işleçleri bölümüne bakın.
Başvuru atama işleci = ref hakkında daha fazla bilgi için bkz. özellik teklifi Not.

Ayrıca bkz.
C#başvurunun
C# işleçleri
ref anahtar sözcüğü
+ ve + = işleçleri (C# başvuru)
25.11.2019 • 3 minutes to read • Edit Online

+ ve += işleçleri, yerleşik integral ve kayan nokta sayısal türleri, dize türü ve temsilci türleri tarafından
desteklenir.
Aritmetik + işleci hakkında daha fazla bilgi için, Aritmetik işleçler makalesinin birli Plus ve eksi işleçleri ve ek işleç
+ bölümlerine bakın.

Dize birleştirme
Bir veya her iki işlenen de dizetüründe olduğunda, + işleci işlenenlerinin dize temsillerini birleştirir:

Console.WriteLine("Forgot" + "white space");


Console.WriteLine("Probably the oldest constant: " + Math.PI);
// Output:
// Forgotwhite space
// Probably the oldest constant: 3.14159265358979

C# 6 ' dan başlayarak dize ilişkilendirme , dizeleri biçimlendirmek için daha kolay bir yol sağlar:

Console.WriteLine($"Probably the oldest constant: {Math.PI:F2}");


// Output:
// Probably the oldest constant: 3.14

Temsilci birleşimi
Aynı temsilci türünün işlenenleri için + işleci, çağrıldığında sol işlenen ve sonra sağ işleneni çağıran yeni bir
temsilci örneği döndürür. İşlenenlerin herhangi biri null ise, + işleci başka bir işlenenin değerini döndürür (Bu
da null olabilir). Aşağıdaki örnek, temsilcilerin + işleçle nasıl birleştirilebilme gösterir:

Action a = () => Console.Write("a");


Action b = () => Console.Write("b");
Action ab = a + b;
ab(); // output: ab

Temsilci kaldırma işlemini gerçekleştirmek için - işlecinikullanın.


Temsilci türleri hakkında daha fazla bilgi için bkz. Temsilciler.

Toplama atama işleci + =


Gibi += işlecini kullanan bir ifade

x += y

eşdeğerdir

x = x + y
x hariç, yalnızca bir kez değerlendirilir.
Aşağıdaki örnek += işlecinin kullanımını gösterir:

int i = 5;
i += 9;
Console.WriteLine(i);
// Output: 14

string story = "Start. ";


story += "End.";
Console.WriteLine(story);
// Output: Start. End.

Action printer = () => Console.Write("a");


printer(); // output: a

Console.WriteLine();
printer += () => Console.Write("b");
printer(); // output: ab

Bir olayaabone olduğunuzda bir olay işleyicisi yöntemi belirtmek için += işlecini de kullanabilirsiniz. Daha fazla
bilgi için bkz. nasıl yapılır: olaylara abone olma ve aboneliği kaldırma.

Operatör overloadability
Kullanıcı tanımlı bir tür + işlecini aşırı yükleyebilir. İkili + işleci aşırı yüklendiğinde, += işleci de örtük olarak aşırı
yüklenmiştir. Kullanıcı tanımlı bir tür += işlecini açıkça aşırı yükleyemez.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin birli Plus işleci ve ekleme işleci bölümlerine bakın.

Ayrıca bkz.
C#başvurunun
C# işleçleri
Birden çok dizeyi birleştirme
Olaylar
Aritmetik işleçler
-ve-= işleçleri
-ve-= işleçleri (C# başvuru)
30.10.2019 • 4 minutes to read • Edit Online

- ve -= işleçleri, yerleşik integral ve kayan nokta sayısal türleri ve temsilci türleri tarafından desteklenir.
Aritmetik - işleci hakkında daha fazla bilgi için, Aritmetik işleçler makalesinin birli Plus ve eksi işleçleri ve
çıkarma işleci bölümlerine bakın.

Temsilci kaldırma
Aynı temsilci türünün işlenenleri için - işleci aşağıdaki şekilde hesaplanan bir temsilci örneği döndürür:
Her iki işlenen de null değilse ve sağ işlenenin çağırma listesi, sol işlenenin çağırma listesinin uygun bir
bitişik alt listesi ise, işlemin sonucu sağ işlenen tarafından alınan yeni bir çağırma listesidir. sol işlenenin
çağırma listesinden girişler. Sağ işlenenin listesi sol işlenenin listesindeki birden çok bitişik alt listeyle
eşleşiyorsa, yalnızca en sağdaki eşleme alt listesi kaldırılır. Kaldırma işlemi boş bir liste ile sonuçlanırsa
sonuç null .

Action a = () => Console.Write("a");


Action b = () => Console.Write("b");

var abbaab = a + b + b + a + a + b;
abbaab(); // output: abbaab
Console.WriteLine();

var ab = a + b;
var abba = abbaab - ab;
abba(); // output: abba
Console.WriteLine();

var nihil = abbaab - abbaab;


Console.WriteLine(nihil is null); // output: True

Sağ işlenenin çağırma listesi, sol işlenenin çağırma listesinin uygun bir bitişik alt listesi değilse, işlemin
sonucu sol işlenenin bir sonucudur. Örneğin, çok noktaya yayın temsilcisinin parçası olmayan bir temsilciyi
kaldırmak, hiçbir şey yapmaz ve değişmeyen çok noktaya yayın temsilcisine neden olur.
Action a = () => Console.Write("a");
Action b = () => Console.Write("b");

var abbaab = a + b + b + a + a + b;
var aba = a + b + a;

var first = abbaab - aba;


first(); // output: abbaab
Console.WriteLine();
Console.WriteLine(object.ReferenceEquals(abbaab, first)); // output: True

Action a2 = () => Console.Write("a");


var changed = aba - a;
changed(); // output: ab
Console.WriteLine();
var unchanged = aba - a2;
unchanged(); // output: aba
Console.WriteLine();
Console.WriteLine(object.ReferenceEquals(aba, unchanged)); // output: True

Yukarıdaki örnek ayrıca temsilci kaldırma temsilci örneklerinin karşılaştırıldığı gösterilmektedir. Örneğin,
aynı lambda ifadelerinin değerlendirmesinden üretilen temsilciler eşit değildir. Temsilci eşitliği hakkında
daha fazla bilgi için, C# dil belirtiminin, eşitlik işleçleri temsilcisi bölümüne bakın.
Sol işlenen null , işlemin sonucu null . Sağ işlenen null , işlemin sonucu sol işlenenin bir sonucudur.

Action a = () => Console.Write("a");

var nothing = null - a;


Console.WriteLine(nothing is null); // output: True

var first = a - null;


a(); // output: a
Console.WriteLine();
Console.WriteLine(object.ReferenceEquals(first, a)); // output: True

Temsilcileri birleştirmek için + işlecinikullanın.


Temsilci türleri hakkında daha fazla bilgi için bkz. Temsilciler.

Çıkarma atama işleci-=


Gibi -= işlecini kullanan bir ifade

x -= y

eşdeğerdir

x = x - y

x yalnızca bir kez değerlendirilir.


Aşağıdaki örnek -= işlecinin kullanımını gösterir:
int i = 5;
i -= 9;
Console.WriteLine(i);
// Output: -4

Action a = () => Console.Write("a");


Action b = () => Console.Write("b");
var printer = a + b + a;
printer(); // output: aba

Console.WriteLine();
printer -= a;
printer(); // output: ab

Bir olaydanabonelik kaldırdığınızda kaldırılacak olay işleyicisi yöntemini belirtmek için -= işlecini de
kullanabilirsiniz. Daha fazla bilgi için bkz. nasıl yapılır: olaylara abone olma ve aboneliği kaldırma.

Operatör overloadability
Kullanıcı tanımlı bir tür - işlecini aşırı yükleyebilir. İkili - işleci aşırı yüklendiğinde, -= işleci de örtük olarak
aşırı yüklenmiştir. Kullanıcı tanımlı bir tür -= işlecini açıkça aşırı yükleyemez.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin birli eksi işleci ve çıkarma işleci bölümlerine bakın.

Ayrıca bkz.
C#başvurunun
C# işleçleri
Olaylar
Aritmetik işleçler
+ ve + = işleçleri
?: işleç (C# başvuru)
30.10.2019 • 4 minutes to read • Edit Online

Üçlü işleç olarak da bilinen koşullu operatör ?: , Boolean ifadesinin true veya false olarak
değerlendirildiğine bağlı olarak bir Boole ifadesi değerlendirir ve iki ifadeden birinin sonucunu döndürür. 7,2
ile C# başlayarak, koşullu başvuru ifadesi iki ifadeden birinin sonucuna başvuruyu döndürür.
Koşullu işlecin sözdizimi şöyledir:

condition ? consequent : alternative

condition ifadesi true veya false olarak değerlendirilmelidir. condition true değerlendirilirse,
consequent ifadesi değerlendirilir ve sonucu işlemin sonucu olur. condition false değerlendirilirse,
alternative ifadesi değerlendirilir ve sonucu işlemin sonucu olur. Yalnızca consequent veya alternative
değerlendirilir.
consequent ve alternative türü aynı olmalıdır veya bir türden diğerine örtük bir dönüştürme olmalıdır.
Koşullu operatör doğru ilişkilendirilebilir, diğer bir deyişle, formun bir ifadesi

a ? b : c ? d : e

şöyle değerlendirilir

a ? b : (c ? d : e)

TIP
Koşullu işlecin nasıl değerlendirildiğini anımsamak için aşağıdaki anımsatıcı cihazı kullanabilirsiniz:

is this condition true ? yes : no

Aşağıdaki örnek, koşullu işlecin kullanımını gösterir:

double sinc(double x) => x != 0.0 ? Math.Sin(x) / x : 1;

Console.WriteLine(sinc(0.1));
Console.WriteLine(sinc(0.0));
// Output:
// 0.998334166468282
// 1

Koşullu başvuru ifadesi


7,2 ' C# den başlayarak, iki ifadeden birinin sonucuna başvuruyu döndürmek için koşullu başvuru ifadesini
kullanabilirsiniz. Bu başvuruyu bir ref yerel veya ref ReadOnly yerel değişkenine atayabilir veya bir Başvuru
dönüş değeri veya ref yöntemi parametresiolarak kullanabilirsiniz.
Koşullu başvuru ifadesi için sözdizimi aşağıdaki gibidir:

condition ? ref consequent : ref alternative

Özgün koşullu operatör gibi, koşullu başvuru ifadesi iki ifadeden yalnızca birini değerlendirir: consequent ya
da alternative .
Koşullu başvuru ifadesi durumunda consequent ve alternative türü aynı olmalıdır.
Aşağıdaki örnek, koşullu başvuru ifadesinin kullanımını gösterir:

var smallArray = new int[] { 1, 2, 3, 4, 5 };


var largeArray = new int[] { 10, 20, 30, 40, 50 };

int index = 7;
ref int refValue = ref ((index < 5) ? ref smallArray[index] : ref largeArray[index - 5]);
refValue = 0;

index = 2;
((index < 5) ? ref smallArray[index] : ref largeArray[index - 5]) = 100;

Console.WriteLine(string.Join(" ", smallArray));


Console.WriteLine(string.Join(" ", largeArray));
// Output:
// 1 2 100 4 5
// 10 20 0 40 50

Koşullu işleç ve bir if..else ekstresi


İf-else ifadesinin yerine koşullu işlecin kullanılması, bir değeri hesaplamak için koşullu olarak bir değer
hesaplamanız gerektiğinde daha kısa kod oluşmasına neden olacaktır. Aşağıdaki örnek, bir tamsayıyı negatif
veya negatif olmayan olarak sınıflandırmanın iki yolunu göstermektedir:

int input = new Random().Next(-5, 5);

string classify;
if (input >= 0)
{
classify = "nonnegative";
}
else
{
classify = "negative";
}

classify = (input >= 0) ? "nonnegative" : "negative";

Operatör overloadability
Kullanıcı tanımlı bir tür, koşullu işleci aşırı yükleyemez.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin koşullu işleç bölümüne bakın.
Koşullu başvuru ifadesi hakkında daha fazla bilgi için bkz. özellik teklifi Note.
Ayrıca bkz.
C#başvurunun
C# işleçleri
if-else beyanı
?. '? [] işleçleri
?? ve?? = işleçleri
ref anahtar sözcüğü
! (null-forverme) işleci (C# başvuru)
30.10.2019 • 3 minutes to read • Edit Online

C# 8,0 ve üzeri sürümlerde bulunan birli sonek ! işleci null-forverme işleçtir. Etkin bir null yapılabilir ek açıklama
bağlamında, bir başvuru türünün ifadesinin x null olmadığını bildirmek için null-forverme işlecini kullanırsınız:
x! . Birli önek ! işleci mantıksal değilleme işleçtir.

Null-forverme işlecinin çalışma zamanında hiçbir etkisi yoktur. Yalnızca ifadenin null durumunu değiştirerek
derleyicinin statik akış analizini etkiler. Çalışma zamanında, x! ifadesi temel alınan x ifadesinin sonucu olarak
değerlendirilir.
Null yapılabilir başvuru türleri özelliği hakkında daha fazla bilgi için bkz. Nullable başvuru türleri.

Örnekler
Null-forverme işlecinin kullanım çalışmalarından biri bağımsız değişken doğrulama mantığını test ediyor. Örneğin,
aşağıdaki sınıfı göz önünde bulundurun:

#nullable enable
public class Person
{
public Person(string name) => Name = name ?? throw new ArgumentNullException(nameof(name));

public string Name { get; }


}

MSTest test çerçevesinikullanarak, oluşturucuda doğrulama mantığı için aşağıdaki testi oluşturabilirsiniz:

[TestMethod, ExpectedException(typeof(ArgumentNullException))]
public void NullNameShouldThrowTest()
{
var person = new Person(null!);
}

Null-forverme işleci olmadan derleyici, önceki kod için şu uyarıyı üretir:


Warning CS8625: Cannot convert null literal to non-nullable reference type . Null-forverme işlecini kullanarak,
derleyiciye null geçtiğini ve hakkında uyarı vermemesini bilgilendirmelisiniz.
Ayrıca, bir ifadenin null olamaz, ancak derleyicinin bunu tanıması için yönetmediğini kesin bir şekilde
öğrendiğinizde null-forverme işlecini de kullanabilirsiniz. Aşağıdaki örnekte, IsValid yöntemi true döndürürse,
bağımsız değişkeni null ' dir ve güvenle başvuru yapabilirsiniz:
public static void Main()
{
Person? p = Find("John");
if (IsValid(p))
{
Console.WriteLine($"Found {p!.Name}");
}
}

public static bool IsValid(Person? person)


{
return person != null && !string.IsNullOrEmpty(person.Name);
}

Null-forverme işleci olmadan derleyici p.Name kodu için şu uyarıyı üretir:


Warning CS8602: Dereference of a possibly null reference .

IsValid yöntemini değiştirebiliyorsanız, derleyiciye IsValid yönteminin bir bağımsız değişkeninin Yöntem true
döndürdüğünde null olmadığını bildirmek için Notnullıf özniteliğini kullanabilirsiniz:

public static void Main()


{
Person? p = Find("John");
if (IsValid(p))
{
Console.WriteLine($"Found {p.Name}");
}
}

public static bool IsValid([NotNullWhen(true)] Person? person)


{
return person != null && !string.IsNullOrEmpty(person.Name);
}

Yukarıdaki örnekte, derleyicinin if bildiriminde null p için yeterli bilgi içerdiğinden, null-forverme işlecini
kullanmanız gerekmez. Bir değişkenin null durumu hakkında ek bilgi sağlamanıza olanak tanıyan öznitelikler
hakkında daha fazla bilgi için bkz. null beklentilerini tanımlamak Için API 'leri özniteliklerle yükseltme.

C# dili belirtimi
Daha fazla bilgi için, Nullable başvuru türleri belirtiminin taslağının null-forverme işleci bölümüne bakın.

Ayrıca bkz.
C#başvurunun
C# işleçleri
Öğretici: null yapılabilir başvuru türleriyle tasarlayın
?? ve?? = işleçleri (C# başvuru)
8.11.2019 • 4 minutes to read • Edit Online

Null birleşim işleci ?? null değilse, sol taraftaki işlenenin değerini döndürür; Aksi takdirde, sağ işleneni
değerlendirir ve sonucunu döndürür. Sol işlenen, null olmayan olarak değerlendirilirse ?? işleci sağ işleneni
değerlendirmez.
C# 8,0 ve sonraki sürümlerde bulunan null birleşim atama işleci ??= sağ işleneninin değerini sol taraftaki
işlenene yalnızca sol işlenen null değerlendirirken atar. Sol işlenen, null olmayan olarak değerlendirilirse ??=
işleci sağ işleneni değerlendirmez.

List<int> numbers = null;


int? a = null;

(numbers ??= new List<int>()).Add(5);


Console.WriteLine(string.Join(" ", numbers)); // output: 5

numbers.Add(a ??= 0);


Console.WriteLine(string.Join(" ", numbers)); // output: 5 0
Console.WriteLine(a); // output: 0

??= işlecinin sol tarafındaki işleneni bir değişken, özellikveya Dizin Oluşturucu öğesi olmalıdır.
C# 7,3 ve önceki sürümlerde ?? işlecinin sol işlenenin türü bir başvuru türü ya da null yapılabilir bir değer
türüolmalıdır. 8,0 ile C# başlayarak, bu gereksinim aşağıdaki değerle değiştirilmiştir: ?? ve ??= işleçlerinin sol
taraftaki işleneninin türü null yapılamayan bir değer türü olamaz. Özellikle, 8,0 ile C# başlayarak, null birleşim
işleçlerini kısıtlanmış olmayan tür parametreleriyle kullanabilirsiniz:

private static void Display<T>(T a, T backup)


{
Console.WriteLine(a ?? backup);
}

Null birleştirme işleçleri doğru ilişkilendirilebilir. Diğer bir deyişle, formun ifadeleri

a ?? b ?? c
d ??= e ??= f

şöyle değerlendirilir

a ?? (b ?? c)
d ??= (e ??= f)

Örnekler
?? ve ??= işleçleri aşağıdaki senaryolarda yararlı olabilir:
Null koşullu işleçlere sahip ifadelerde?. ve? [], null koşullu işlemlere sahip ifadenin sonucu null
olduğunda değerlendirmek için alternatif bir ifade sağlamak üzere ?? işlecini kullanabilirsiniz:
double SumNumbers(List<double[]> setsOfNumbers, int indexOfSetToSum)
{
return setsOfNumbers?[indexOfSetToSum]?.Sum() ?? double.NaN;
}

var sum = SumNumbers(null, 0);


Console.WriteLine(sum); // output: NaN

Null yapılabilir değer türleriyle çalıştığınızda ve temel alınan değer türünde bir değer sağlamanız
gerekiyorsa, null yapılabilir bir tür değeri null olduğunda sağlamak üzere değer belirtmek için ??
işlecini kullanın:

int? a = null;
int b = a ?? -1;
Console.WriteLine(b); // output: -1

Null yapılabilir bir tür değeri null , temel alınan değer türünün varsayılan değeri olması durumunda
kullanılacak değer Nullable<T>.GetValueOrDefault() yöntemi kullanın.
7,0 ' C# den başlayarak bağımsız değişken denetim kodunu daha kısa hale getirmek için ?? işlecinin
sağ işleneni olarak bir throw ifadesini kullanabilirsiniz:

public string Name


{
get => name;
set => name = value ?? throw new ArgumentNullException(nameof(value), "Name cannot be null");
}

Yukarıdaki örnek ayrıca bir özelliği tanımlamak için Expression-Bodied üyelerini nasıl kullanacağınızı
gösterir.
8,0 ile C# başlayarak, form kodunu değiştirmek için ??= işlecini kullanabilirsiniz

if (variable is null)
{
variable = expression;
}

aşağıdaki kodla:

variable ??= expression;

Operatör overloadability
?? ve ??= işleçleri aşırı yüklenemez.

C# dili belirtimi
?? işleci hakkında daha fazla bilgi için, C# dil belirtiminin null birleşim işleci bölümüne bakın.
??= işleci hakkında daha fazla bilgi için bkz. özellik teklifi notunun.

Ayrıca bkz.
C#başvurunun
C# işleçleri
?. '? [] işleçleri
?: işleci
= > işleci (C# başvuru)
30.10.2019 • 3 minutes to read • Edit Online

=> belirteci iki biçimde desteklenir: lambda işleci , bir üye adı ve bir ifade gövdesi tanımındaüye uygulama için
bir ayırıcı olarak.

Lambda işleci
Lambda ifadelerindelambda işleci => sol taraftaki giriş parametrelerini sağ taraftaki lambda gövdesinden ayırır.
Aşağıdaki örnek, lambda ifadelerinin kullanımını göstermek için yöntem sözdizimi ile LINQ özelliğini kullanır:

string[] words = { "bot", "apple", "apricot" };


int minimalLength = words
.Where(w => w.StartsWith("a"))
.Min(w => w.Length);
Console.WriteLine(minimalLength); // output: 5

int[] numbers = { 1, 4, 7, 10 };
int product = numbers.Aggregate(1, (interim, next) => interim * next);
Console.WriteLine(product); // output: 280

Bir lambda ifadesinin giriş parametreleri derleme zamanında kesin olarak yazılmalıdır. Derleyici, giriş
parametrelerinin türlerini, önceki örnekte olduğu gibi çıkarsancan, tür bildirimlerini atlayabilirsiniz. Giriş
parametrelerinin türünü belirtmeniz gerekiyorsa, aşağıdaki örnekte gösterildiği gibi her bir parametre için bunu
yapmanız gerekir:

int[] numbers = { 1, 4, 7, 10 };
int product = numbers.Aggregate(1, (int interim, int next) => interim * next);
Console.WriteLine(product); // output: 280

Aşağıdaki örnek, giriş parametreleri olmadan bir lambda ifadesinin nasıl tanımlanacağını göstermektedir:

Func<string> greet = () => "Hello, World!";


Console.WriteLine(greet());

Daha fazla bilgi için bkz. lambda ifadeleri.

İfade gövdesi tanımı


Bir ifade gövdesi tanımında aşağıdaki genel sözdizimi vardır:

member => expression;

expression geçerli bir ifadedir. expression dönüş türü üyenin dönüş türüne örtük olarak dönüştürülebilir
olmalıdır. Üyenin dönüş türü void veya üye bir Oluşturucu, Sonlandırıcı veya özellik set erişimcisi ise,
expression herhangi bir türde olabilen bir deyim ifadesiolmalıdır.

Aşağıdaki örnekte, bir Person.ToString yöntemi için bir ifade gövde tanımı gösterilmektedir:
public override string ToString() => $"{fname} {lname}".Trim();

Bu, aşağıdaki yöntem tanımının bir toplu sürümüdür:

public override string ToString()


{
return $"{fname} {lname}".Trim();
}

Yöntemler, işleçler ve salt okunurdur özellikleri için ifade gövdesi tanımları C# 6 ' dan başlayarak desteklenir.
Oluşturucular, sonlandırıcılar ve özellik ve Dizin Oluşturucu erişimcileri için ifade gövdesi tanımları 7,0 ile C#
başlayarak desteklenir.
Daha fazla bilgi için bkz. Expression-Bodied Üyeler.

Operatör overloadability
=> işleci aşırı yüklenemez.

C# dili belirtimi
Lambda işleci hakkında daha fazla bilgi için, C# dil belirtiminin anonim işlev ifadeleri bölümüne bakın.

Ayrıca bkz.
C#başvurunun
C# işleçleri
:: işleci (C# başvuru)
30.10.2019 • 2 minutes to read • Edit Online

Ad alanı diğer adı niteleyicisi :: , diğer ad alanının bir üyesine erişmek için kullanın. :: niteleyicisi yalnızca iki
tanımlayıcı arasında kullanılabilir. Sol tanımlayıcı aşağıdaki diğer adların herhangi biri olabilir:
Bir using diğer adı yönergesiile oluşturulmuş bir ad alanı diğer adı:

using forwinforms = System.Drawing;


using forwpf = System.Windows;

public class Converters


{
public static forwpf::Point Convert(forwinforms::Point point) => new forwpf::Point(point.X,
point.Y);
}

Extern diğer adı.


Genel ad alanı diğer adı olan global diğer adı. Genel ad alanı, adlandırılmış bir ad alanı içinde
bildirilmeyen ad alanlarını ve türleri içeren ad alanıdır. :: niteleyicisi ile kullanıldığında, Kullanıcı tanımlı
global ad alanı diğer adı olsa da, global diğer adı her zaman genel ad alanına başvurur.

Aşağıdaki örnek, genel ad alanının bir üyesi olan .NET System ad alanına erişmek için global diğer adını
kullanır. global diğer adı olmadan, MyCompany.MyProduct ad alanının üyesi olan Kullanıcı tanımlı System
ad alanına erişilir:

namespace MyCompany.MyProduct.System
{
class Program
{
static void Main() => global::System.Console.WriteLine("Using global alias");
}

class Console
{
string Suggestion => "Consider renaming this class";
}
}

NOTE
global anahtar sözcüğü, yalnızca :: niteleyicisi sol tarafınında olan genel ad alanı diğer adıdır.

Ayrıca, diğer ad alanının bir üyesine erişmek için üye erişimi . işlecini de kullanabilirsiniz. Ancak, . işleci bir
tür üyesine erişmek için de kullanılır. :: niteleyicisi, aynı ada sahip bir tür veya ad alanı olsa da, sol taraftaki
tanımlayıcının her zaman bir ad alanı diğer adına başvurmasını sağlar.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin ad alanı diğer ad niteleyicileri bölümüne bakın.
Ayrıca bkz.
C#başvurunun
C# işleçleri
Ad alanlarını kullanma
Await işleci (C# başvuru)
25.11.2019 • 5 minutes to read • Edit Online

await işleci, işleneni tarafından temsil edilen zaman uyumsuz işlem tamamlanana kadar kapsayan
zaman uyumsuz metodun değerlendirmesini askıya alır. Zaman uyumsuz işlem tamamlandığında
await işleci, varsa işlemin sonucunu döndürür. await işleci, zaten tamamlanmış bir işlemi temsil eden
işlenene uygulandığında, kapsayan metodun askıya alınması gerekmeden işlemin sonucunu hemen
döndürür. await işleci zaman uyumsuz yöntemi değerlendiren iş parçacığını engellemez. await işleci
kapsayan zaman uyumsuz yöntemi askıya aldığında, denetim yöntemi çağırana döner.
Aşağıdaki örnekte HttpClient.GetByteArrayAsync yöntemi, tamamlandığında bir bayt dizisi üreten
zaman uyumsuz bir işlemi temsil eden Task<byte[]> örneğini döndürür. İşlem tamamlanana kadar
await işleci DownloadDocsMainPageAsync yöntemini askıya alır. DownloadDocsMainPageAsync askıya
alındığında, denetim, DownloadDocsMainPageAsync çağıranı olan Main yöntemine döndürülür. Main
yöntemi, DownloadDocsMainPageAsync yöntemi tarafından gerçekleştirilen zaman uyumsuz işlemin
sonucuna ihtiyaç duyuncaya kadar yürütülür. GetByteArrayAsync tüm baytlar aldığında,
DownloadDocsMainPageAsync yönteminin geri kalanı değerlendirilir. Bundan sonra Main yönteminin geri
kalanı değerlendirilir.

using System;
using System.Net.Http;
using System.Threading.Tasks;

public class AwaitOperator


{
public static async Task Main()
{
Task<int> downloading = DownloadDocsMainPageAsync();
Console.WriteLine($"{nameof(Main)}: Launched downloading.");

int bytesLoaded = await downloading;


Console.WriteLine($"{nameof(Main)}: Downloaded {bytesLoaded} bytes.");
}

private static async Task<int> DownloadDocsMainPageAsync()


{
Console.WriteLine($"{nameof(DownloadDocsMainPageAsync)}: About to start downloading.");

var client = new HttpClient();


byte[] content = await client.GetByteArrayAsync("https://docs.microsoft.com/en-us/");

Console.WriteLine($"{nameof(DownloadDocsMainPageAsync)}: Finished downloading.");


return content.Length;
}
}
// Output similar to:
// DownloadDocsMainPageAsync: About to start downloading.
// Main: Launched downloading.
// DownloadDocsMainPageAsync: Finished downloading.
// Main: Downloaded 27700 bytes.

Yukarıdaki örnekte, 7,1 ile C# başlayan zaman uyumsuz Main yöntemikullanılmaktadır. Daha fazla bilgi
için, ana yöntem bölümünde await işlecine bakın.
NOTE
Zaman uyumsuz programlamaya giriş için bkz. Async ve await Ile zaman uyumsuz programlama. async ve
await ile zaman uyumsuz programlama, görev tabanlı zaman uyumsuz düzeneuyar.

await işlecini yalnızca zaman uyumsuz anahtar sözcük tarafından değiştirilen bir yöntemde, lambda
ifadesindeveya anonim yöntemde kullanabilirsiniz. Zaman uyumsuz bir yöntemde, zaman uyumlu bir
işlevin gövdesinde, bir Lock ifadesininbloğu içinde ve güvenli olmayan bir bağlamda await işlecini
kullanamazsınız.
await işlecinin işleneni genellikle şu .NET türlerinden biridir: Task, Task<TResult>, ValueTaskveya
ValueTask<TResult>. Ancak, herhangi bir zaman awasever ifadesi await işlecinin işleneni olabilir. Daha
fazla bilgi için, C# dil belirtiminin awasever ifadeleri bölümüne bakın.
8,0 ' C# den başlayarak, zaman uyumsuz veri akışını kullanmak için await foreach ifadesini
kullanabilirsiniz. Daha fazla bilgi için C# 8,0 sürümündeki yenilikler makalesindeki zaman uyumsuz
akışlar bölümüne bakın.
İfade türü t Task<TResult> veya ValueTask<TResult>ise await t ifade türü TResult . t türü Task
veya ValueTaskise, await t türü void olur. Her iki durumda da t bir özel durum oluşturursa,
await t özel durumu yeniden oluşturur. Özel durum işleme hakkında daha fazla bilgi için, try-catch
beyanı makalesindeki zaman uyumsuz metotlar bölümünde özel durumlar bölümüne bakın.
async ve await anahtar sözcükleri C# 5 ve sonraki sürümlerde kullanılabilir.

Main yönteminde Await işleci


7,1 ' C# den başlayarak, uygulama giriş noktası olan Main yöntemi Task veya Task<int> döndürebilir,
onun gövdesinde await işlecini kullanabilmeniz için zaman uyumsuz olmasını sağlayabilir. Önceki C#
sürümlerde Main yönteminin zaman uyumsuz bir işlemin tamamlanmasını beklediği için, karşılık gelen
async yöntemi tarafından döndürülen Task<TResult> örneğinin Task<TResult>.Result özelliğinin
değerini alabilirsiniz. Değer üretmeyen zaman uyumsuz işlemler için Task.Wait yöntemini
çağırabilirsiniz. Dil sürümünü seçme hakkında daha fazla bilgi için bkz C# . dil sürümü oluşturma.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin await ifadeleri bölümüne bakın.

Ayrıca bkz.
C#başvurunun
C# işleçleri
async
Görev zaman uyumsuz programlama modeli
Zaman uyumsuz programlama
Zaman uyumsuz, derinlemesine
İzlenecek yol: Async ve await kullanarak Web 'e erişme
Öğretici: 8,0 ve .NET Core 3,0 kullanarak C# zaman uyumsuz akışlar oluşturma ve kullanma
Default işleci (C# başvuru)
30.10.2019 • 2 minutes to read • Edit Online

default işleci, bir türün varsayılan değerini üretir. default işlecinin bağımsız değişkeni bir türün veya tür
parametresinin adı olmalıdır.
Aşağıdaki örnek default işlecinin kullanımını gösterir:

Console.WriteLine(default(int)); // output: 0
Console.WriteLine(default(object) is null); // output: True

void DisplayDefaultOf<T>()
{
var val = default(T);
Console.WriteLine($"Default value of {typeof(T)} is {(val == null ? "null" : val.ToString())}.");
}

DisplayDefaultOf<int?>();
DisplayDefaultOf<System.Numerics.Complex>();
DisplayDefaultOf<System.Collections.Generic.List<int>>();
// Output:
// Default value of System.Nullable`1[System.Int32] is null.
// Default value of System.Numerics.Complex is (0, 0).
// Default value of System.Collections.Generic.List`1[System.Int32] is null.

Ayrıca, bir switch ifadesindevarsayılan Case etiketi olarak default anahtar sözcüğünü kullanırsınız.

Varsayılan sabit değer


7,1 ' C# den başlayarak, derleyici ifade türünü çıkarsdığı zaman bir türün varsayılan değerini oluşturmak için
default değişmez değerini kullanabilirsiniz. default değişmez ifadesi, T çıkarılan tür olduğu default(T)
ifadesiyle aynı değeri üretir. default değişmez değerini aşağıdaki durumlardan herhangi birinde
kullanabilirsiniz:
Bir değişkenin atamasında veya başlatılmasında.
İsteğe bağlı bir yöntem parametresiiçin varsayılan değer bildiriminde.
Bir bağımsız değişken değeri sağlamak için bir yöntem çağrısında.
Bir return deyiminde veya ifade-Bodied üyeiçindeki bir ifade olarak.
Aşağıdaki örnek default değişmez değerinin kullanımını gösterir:
T[] InitializeArray<T>(int length, T initialValue = default)
{
if (length < 0)
{
return default;
}

var array = new T[length];


for (var i = 0; i < length; i++)
{
array[i] = initialValue;
}
return array;
}

void Display<T>(T[] values) => Console.WriteLine($"[ {string.Join(", ", values)} ]");

Display(InitializeArray<int>(3)); // output: [ 0, 0, 0 ]
Display(InitializeArray<bool>(4, default)); // output: [ False, False, False, False ]

System.Numerics.Complex fillValue = default;


Display(InitializeArray(3, fillValue)); // output: [ (0, 0), (0, 0), (0, 0) ]

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin varsayılan değer ifadeleri bölümüne bakın.
default değişmez değeri hakkında daha fazla bilgi için bkz. özellik teklifi notunun.

Ayrıca bkz.
C#başvurunun
C# işleçleri
Varsayılan değerler tablosu
.NET 'teki genel türler
temsilci işleci (C# başvuru)
30.10.2019 • 2 minutes to read • Edit Online

delegate işleci, bir temsilci türüne dönüştürülebilen anonim bir yöntem oluşturur:

Func<int, int, int> sum = delegate (int a, int b) { return a + b; };


Console.WriteLine(sum(3, 4)); // output: 7

NOTE
3 ile C# başlayarak lambda ifadeleri anonim bir işlev oluşturmak için daha kısa ve açıklayıcı bir yol sağlar. Lambda ifadesi
oluşturmak için = > işlecini kullanın:

Func<int, int, int> sum = (a, b) => a + b;


Console.WriteLine(sum(3, 4)); // output: 7

Lambda ifadelerinin özellikleri hakkında daha fazla bilgi için örneğin, dış değişkenleri yakalama, bkz. lambda ifadeleri.

delegate işlecini kullandığınızda parametre listesini atlayabilirsiniz. Bunu yaparsanız, oluşturulan anonim
yöntem, aşağıdaki örnekte gösterildiği gibi, herhangi bir parametre listesiyle bir temsilci türüne
dönüştürülebilir:

Action greet = delegate { Console.WriteLine("Hello!"); };


greet();

Action<int, double> introduce = delegate { Console.WriteLine("This is world!"); };


introduce(42, 2.7);

// Output:
// Hello!
// This is world!

Bu, lambda ifadeleri tarafından desteklenmeyen anonim yöntemlerin tek işlevsellikleridir. Diğer tüm
durumlarda, bir lambda ifadesi satır içi kod yazmak için tercih edilen bir yoldur.
Ayrıca, bir temsilci türübildirmek için delegate anahtar sözcüğünü kullanırsınız.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin anonim işlev ifadeleri bölümüne bakın.

Ayrıca bkz.
C#başvurunun
C# işleçleri
= > işleci
NameOf işleci (C# başvuru)
30.10.2019 • 2 minutes to read • Edit Online

nameof işleci, dize sabiti olarak bir değişkenin, türün veya üyenin adını edinir:

Console.WriteLine(nameof(System.Collections.Generic)); // output: Generic


Console.WriteLine(nameof(List<int>)); // output: List
Console.WriteLine(nameof(List<int>.Count)); // output: Count
Console.WriteLine(nameof(List<int>.Add)); // output: Add

var numbers = new List<int> { 1, 2, 3 };


Console.WriteLine(nameof(numbers)); // output: numbers
Console.WriteLine(nameof(numbers.Count)); // output: Count
Console.WriteLine(nameof(numbers.Add)); // output: Add

Yukarıdaki örnekte gösterildiği gibi, bir tür ve ad alanı durumunda, oluşturulan ad genellikle tam olarak nitelenir.
nameof işleci derleme zamanında değerlendirilir ve çalışma zamanında hiçbir etkiye sahip değildir.
Bağımsız değişken denetim kodunu daha sürdürülebilir hale getirmek için nameof işlecini kullanabilirsiniz:

public string Name


{
get => name;
set => name = value ?? throw new ArgumentNullException(nameof(value), $"{nameof(Name)} cannot be null");
}

nameof işleci C# 6 ve üzeri sürümlerde kullanılabilir.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin NameOf ifadeleri bölümüne bakın.

Ayrıca bkz.
C#başvurunun
C# işleçleri
New işleci (C# başvuru)
30.10.2019 • 3 minutes to read • Edit Online

new işleci, bir türün yeni bir örneğini oluşturur.


new anahtar sözcüğünü üye bildirimi değiştiricisi veya genel tür kısıtlamasıolarak da
kullanabilirsiniz.

Oluşturucu çağırma
Bir türün yeni bir örneğini oluşturmak için, genellikle new işlecini kullanarak bu türdeki
oluşturuculardan birini çağırabilirsiniz:

var dict = new Dictionary<string, int>();


dict["first"] = 10;
dict["second"] = 20;
dict["third"] = 30;

Console.WriteLine(string.Join("; ", dict.Select(entry => $"{entry.Key}: {entry.Value}")));


// Output:
// first: 10; second: 20; third: 30

Aşağıdaki örnekte gösterildiği gibi, tek bir ifadede bir nesne oluşturmak ve başlatmak için new
işleçle bir nesne veya koleksiyon başlatıcısı kullanabilirsiniz:

var dict = new Dictionary<string, int>


{
["first"] = 10,
["second"] = 20,
["third"] = 30
};

Console.WriteLine(string.Join("; ", dict.Select(entry => $"{entry.Key}: {entry.Value}")));


// Output:
// first: 10; second: 20; third: 30

Dizi oluşturma
Aşağıdaki örnekte gösterildiği gibi, bir dizi örneği oluşturmak için new işlecini de kullanabilirsiniz:

var numbers = new int[3];


numbers[0] = 10;
numbers[1] = 20;
numbers[2] = 30;

Console.WriteLine(string.Join(", ", numbers));


// Output:
// 10, 20, 30

Dizi başlatma söz dizimini kullanarak bir dizi örneği oluşturun ve tek bir deyimdeki öğelerle
doldurun. Aşağıdaki örnek, bunu nasıl yapabilmenizin çeşitli yollarını göstermektedir:
var a = new int[3] { 10, 20, 30 };
var b = new int[] { 10, 20, 30 };
var c = new[] { 10, 20, 30 };
Console.WriteLine(c.GetType()); // output: System.Int32[]

Diziler hakkında daha fazla bilgi için bkz. diziler.

Anonim türlerin örneklenmesi


Anonim türünbir örneğini oluşturmak için new işlecini ve nesne Başlatıcısı sözdizimini kullanın:

var example = new { Greeting = "Hello", Name = "World" };


Console.WriteLine($"{example.Greeting}, {example.Name}!");
// Output:
// Hello, World!

Tür örneklerinin yok edilmesi


Önceden oluşturulmuş tür örneklerini yok etmeniz gerekmez. Başvuru ve değer türlerinin örnekleri
otomatik olarak yok edilir. Değer türlerinin örnekleri, bunları içeren bağlam yok edilir oluşturmaz
yok edilir. Başvuru türlerinin örnekleri, en son başvuru kaldırıldıktan sonra, belirlenemeyen sürede
çöp toplayıcı tarafından yok edilir.
Yönetilmeyen kaynakları içeren tür örneklerinde, örneğin bir dosya tanıtıcısı için, içerdikleri
kaynakların mümkün olan en kısa sürede serbest bırakılacağını sağlamak üzere belirleyici
Temizleme kullanılması önerilir. Daha fazla bilgi için bkz. System.IDisposable API başvurusu ve
using açıklaması makalesi.

Operatör overloadability
Kullanıcı tanımlı bir tür new işlecini aşırı yükleyemez.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin Yeni işleç bölümüne bakın.

Ayrıca bkz.
C#başvurunun
C# işleçleri
Nesne ve koleksiyon başlatıcıları
sizeof işleci (C# başvuru)
30.10.2019 • 2 minutes to read • Edit Online

sizeof işleci, verilen türdeki bir değişken tarafından bulunan bayt sayısını döndürür. sizeof işlecinin bağımsız
değişkeni yönetilmeyen bir türün veya yönetilmeyen tür olarak Kısıtlanmış bir tür parametresinin adı olmalıdır.
sizeof işleci güvenli olmayan bir bağlam gerektiriyor. Ancak, aşağıdaki tabloda sunulan ifadeler derleme
zamanında karşılık gelen sabit değerlere değerlendirilir ve güvenli olmayan bir bağlam gerektirmez:

İFADE SABIT DEĞER

sizeof(sbyte) 1.

sizeof(byte) 1.

sizeof(short) 2

sizeof(ushort) 2

sizeof(int) 4

sizeof(uint) 4

sizeof(long) 8

sizeof(ulong) 8

sizeof(char) 2

sizeof(float) 4

sizeof(double) 8

sizeof(decimal) 16

sizeof(bool) 1.

Ayrıca, sizeof işlecinin işleneni bir sabit listesi türünün adı olduğunda güvenli olmayan bir bağlam kullanmanız
gerekmez.
Aşağıdaki örnek sizeof işlecinin kullanımını gösterir:
using System;

public struct Point


{
public Point(byte tag, double x, double y) => (Tag, X, Y) = (tag, x, y);

public byte Tag { get; }


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

public class SizeOfOperator


{
public static void Main()
{
Console.WriteLine(sizeof(byte)); // output: 1
Console.WriteLine(sizeof(double)); // output: 8

DisplaySizeOf<Point>(); // output: Size of Point is 24


DisplaySizeOf<decimal>(); // output: Size of System.Decimal is 16

unsafe
{
Console.WriteLine(sizeof(Point*)); // output: 8
}
}

static unsafe void DisplaySizeOf<T>() where T : unmanaged


{
Console.WriteLine($"Size of {typeof(T)} is {sizeof(T)}");
}
}

sizeof işleci, yönetilen bellekte ortak dil çalışma zamanı tarafından ayrılacak bayt sayısını döndürür. Yapı türleri
için bu değer, yukarıdaki örnekte gösterildiği gibi herhangi bir doldurma içerir. sizeof işlecinin sonucu,
yönetilmeyen bellekteki bir türün boyutunu döndüren Marshal.SizeOf yönteminin sonuçlarından farklı olur.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin sizeof işleci bölümüne bakın.

Ayrıca bkz.
C#başvurunun
C# işleçleri
İşaretçiyle ilgili işleçler
İşaretçi türleri
Bellek ve aralıkla ilgili türler
.NET 'teki genel türler
stackalloc işleci (C# başvuru)
30.10.2019 • 3 minutes to read • Edit Online

stackalloc işleci, yığında bir bellek bloğu ayırır. Yöntem yürütme sırasında oluşturulan bir yığın ayrılmış
bellek bloğu, bu yöntem döndüğünde otomatik olarak atılır. stackalloc işleçle ayrılan belleği açık olarak
serbest bırakılamaz. Yığın tarafından ayrılan bellek bloğu çöp toplamaya tabi değildir ve bir fixed
ifadesiylesabitlenmemelidir.
İfade stackalloc T[E] , T yönetilmeyen bir tür olmalıdır ve E int türünde bir ifade olmalıdır.
stackalloc işlecinin sonucunu aşağıdaki türlerden birinin değişkenine atayabilirsiniz:
Aşağıdaki örnekte C# gösterildiği gibi 7,2, System.Span<T>veyaSystem.ReadOnlySpan<T>ile
başlayarak:

int length = 3;
Span<int> numbers = stackalloc int[length];
for (var i = 0; i < length; i++)
{
numbers[i] = i;
}

Bir Span<T> veya ReadOnlySpan<T> değişkenine bir yığın ayrılmış bellek bloğu atadığınızda,
güvenli olmayan bir bağlam kullanmanız gerekmez.
Bu türlerle çalışırken, aşağıdaki örnekte gösterildiği gibi, koşullu veya atama ifadelerinde stackalloc
bir ifade kullanabilirsiniz:

int length = 1000;


Span<byte> buffer = length <= 1024 ? stackalloc byte[length] : new byte[length];

8,0 ' C# den başlayarak, aşağıdaki örnekte gösterildiği gibi,


birSpan<T>veyaReadOnlySpan<T>değişkenine izin verildiğinde diğer ifadelerin içinde stackalloc bir
ifade kullanabilirsiniz:

Span<int> numbers = stackalloc[] { 1, 2, 3, 4, 5, 6 };


var ind = numbers.IndexOfAny(stackalloc[] { 2, 4, 6 ,8 });
Console.WriteLine(ind); // output: 1

NOTE
Mümkün olduğunda yığın tarafından ayrılan bellekle çalışmak için Span<T> veya ReadOnlySpan<T> türlerini
kullanmanızı öneririz.

Aşağıdaki örnekte gösterildiği gibi bir işaretçi türü:


unsafe
{
int length = 3;
int* numbers = stackalloc int[length];
for (var i = 0; i < length; i++)
{
numbers[i] = i;
}
}

Yukarıdaki örnekte gösterildiği gibi, işaretçi türleriyle çalışırken unsafe bağlamı kullanmanız gerekir.
İşaretçi türleri söz konusu olduğunda, değişkeni başlatmak için yalnızca yerel değişken bildiriminde
bir stackalloc ifadesini kullanabilirsiniz.
Yeni ayrılan belleğin içeriği tanımlı değil. 7,3 ile C# başlayarak, yeni ayrılan belleğin içeriğini tanımlamak için
dizi başlatıcısı sözdizimini kullanabilirsiniz. Aşağıdaki örnek bunu yapmak için çeşitli yollar göstermektedir:

Span<int> first = stackalloc int[3] { 1, 2, 3 };


Span<int> second = stackalloc int[] { 1, 2, 3 };
ReadOnlySpan<int> third = stackalloc[] { 1, 2, 3 };

Güvenlik
stackalloc kullanımı, ortak dil çalışma zamanında (CLR ) arabellek taşması algılama özelliklerini otomatik
olarak sunar. Bir arabellek taşması algılanırsa, kötü amaçlı kodun yürütülmesi olasılığını en aza indirmek için
işlem mümkün olduğunca hızlı bir şekilde sonlandırılır.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin yığın ayırma bölümüne bakın.

Ayrıca bkz.
C#başvurunun
C# işleçleri
İşaretçiyle ilgili işleçler
İşaretçi türleri
Bellek ve aralıkla ilgili türler
true ve false işleçleri (C# başvuru)
29.11.2019 • 4 minutes to read • Edit Online

true işleci, işleneninin kesinlikle doğru olduğunu göstermek için true bool değer döndürür. false işleci,
işleneninin kesinlikle yanlış olduğunu göstermek için bool değer true döndürür. true ve false işleçleri
birbirini tamamlamak için garanti edilmez. Diğer bir deyişle, true ve false işlecinin her ikisi de aynı işlenen
için false bool değeri döndürebilir. Bir tür iki işleçten birini tanımlıyorsa, aynı zamanda başka bir işleç
tanımlamalıdır.

TIP
Üç değerli mantığı desteklemeniz gerekiyorsa (örneğin, üç değerli bir Boolean türünü destekleyen veritabanlarıyla çalışırken)
bool? türünü kullanın. C# bool? işlenenleriyle üç değerli mantığı destekleyen & ve | işleçlerini sağlar. Daha fazla bilgi
için, Boole mantıksal işleçler makalesinin Nullable Boolean mantıksal işleçler bölümüne bakın.

Boole ifadeleri
Tanımlı true işlecine sahip bir tür, IF, Do, whileve for deyimlerinde ve koşullu işleç ?: bir denetim koşullu
ifadesi sonucunun türü olabilir. Daha fazla bilgi için, C# dil belirtiminin Boole ifadeleri bölümüne bakın.

Kullanıcı tanımlı Koşullu mantıksal işleçler


Tanımlı true ve false işleçleriyle bir tür, mantıksal veya işlecini | ya da mantıksal ve işleç & belırlı bir şekilde,
Koşullu mantıksal or işleci || veya Koşullu mantıksal ve işleç && , sırasıyla bu türün işlenenleri için
değerlendirilebilir. Daha fazla bilgi için, C# dil belirtiminin Kullanıcı tanımlı Koşullu mantıksal işleçler bölümüne
bakın.

Örnek
Aşağıdaki örnek hem true hem de false işleçlerini tanımlayan türü gösterir. Bu tür Ayrıca, mantıksal ve işleç
& de, && işlecinin bu türdeki işlenenler için değerlendirilebilecek şekilde de yeniden yükler.
using System;

public struct LaunchStatus


{
public static readonly LaunchStatus Green = new LaunchStatus(0);
public static readonly LaunchStatus Yellow = new LaunchStatus(1);
public static readonly LaunchStatus Red = new LaunchStatus(2);

private int status;

private LaunchStatus(int status)


{
this.status = status;
}

public static bool operator true(LaunchStatus x) => x == Green || x == Yellow;


public static bool operator false(LaunchStatus x) => x == Red;

public static LaunchStatus operator &(LaunchStatus x, LaunchStatus y)


{
if (x == Red || y == Red || (x == Yellow && y == Yellow))
{
return Red;
}

if (x == Yellow || y == Yellow)
{
return Yellow;
}

return Green;
}

public static bool operator ==(LaunchStatus x, LaunchStatus y) => x.status == y.status;


public static bool operator !=(LaunchStatus x, LaunchStatus y) => !(x == y);

public override bool Equals(object obj) => obj is LaunchStatus other && this == other;
public override int GetHashCode() => status;
}

public class LaunchStatusTest


{
public static void Main()
{
LaunchStatus okToLaunch = GetFuelLaunchStatus() && GetNavigationLaunchStatus();
Console.WriteLine(okToLaunch ? "Ready to go!" : "Wait!");
}

static LaunchStatus GetFuelLaunchStatus()


{
Console.WriteLine("Getting fuel launch status...");
return LaunchStatus.Red;
}

static LaunchStatus GetNavigationLaunchStatus()


{
Console.WriteLine("Getting navigation launch status...");
return LaunchStatus.Yellow;
}
}

&& işlecinin kısa devre dışı davranışına dikkat edin. GetFuelLaunchStatus yöntemi LaunchStatus.Red
döndürdüğünde && işlecinin sağ işleneni değerlendirilmez. Bunun nedeni, LaunchStatus.Red kesinlikle false
olur. Sonra mantıksal ve sonucu, sağ işlenenin değerine bağlı değildir. Örneğin çıktısı aşağıdaki gibidir:
Getting fuel launch status...
Wait!

Ayrıca bkz.
C#başvurunun
C# işleçleri
İşleç aşırı yüklemesiC# (başvuru)
30.10.2019 • 6 minutes to read • Edit Online

Kullanıcı tanımlı bir tür önceden tanımlanmış C# bir işleci aşırı yükleyebilir. Diğer bir deyişle, bir tür
işlenenlerinin bir veya her ikisinin de o türden olması durumunda bir işlemin özel uygulamasını
sağlayabilir. Fazla yüklenebilir işleçler bölümünde hangi işleçlerin aşırı C# yüklenmiş olduğu
gösterilmektedir.
Bir işleç bildirmek için operator anahtar sözcüğünü kullanın. Bir işleç bildiriminin aşağıdaki kuralları
karşılaması gerekir:
Hem public hem de static değiştiricisini içerir.
Birli işlecin bir giriş parametresi vardır. İkili işlecin iki giriş parametresi vardır. Her durumda, en az bir
parametre tür T veya T? olmalıdır; burada T işleç bildirimini içeren türdür.
Aşağıdaki örnek, bir Rational Number öğesini temsil eden Basitleştirilmiş yapıyı tanımlar. Yapı, Aritmetik
operatörlerinbazılarını aşırı yükler:
using System;

public readonly struct Fraction


{
private readonly int num;
private readonly int den;

public Fraction(int numerator, int denominator)


{
if (denominator == 0)
{
throw new ArgumentException("Denominator cannot be zero.", nameof(denominator));
}
num = numerator;
den = denominator;
}

public static Fraction operator +(Fraction a) => a;


public static Fraction operator -(Fraction a) => new Fraction(-a.num, a.den);

public static Fraction operator +(Fraction a, Fraction b)


=> new Fraction(a.num * b.den + b.num * a.den, a.den * b.den);

public static Fraction operator -(Fraction a, Fraction b)


=> a + (-b);

public static Fraction operator *(Fraction a, Fraction b)


=> new Fraction(a.num * b.num, a.den * b.den);

public static Fraction operator /(Fraction a, Fraction b)


{
if (b.num == 0)
{
throw new DivideByZeroException();
}
return new Fraction(a.num * b.den, a.den * b.num);
}

public override string ToString() => $"{num} / {den}";


}

public static class OperatorOverloading


{
public static void Main()
{
var a = new Fraction(5, 4);
var b = new Fraction(1, 2);
Console.WriteLine(-a); // output: -5 / 4
Console.WriteLine(a + b); // output: 14 / 8
Console.WriteLine(a - b); // output: 6 / 8
Console.WriteLine(a * b); // output: 5 / 8
Console.WriteLine(a / b); // output: 10 / 4
}
}

int ' den Fraction örtük bir dönüştürme tanımlayarak yukarıdaki örneği genişletebilirsiniz. Daha sonra,
aşırı yüklenmiş işleçler bu iki türün bağımsız değişkenlerini destekleyecektir. Diğer bir deyişle, bir kesire
tamsayı eklemek ve sonuç olarak bir kesir elde etmek mümkün olacaktır.
Ayrıca, özel bir tür dönüştürmesi tanımlamak için operator anahtar sözcüğünü kullanırsınız. Daha fazla
bilgi için bkz. Kullanıcı tanımlı dönüştürme işleçleri.

Fazla yüklenebilir işleçler


Aşağıdaki tabloda C# işleçlerin fazla gözlebilirlik hakkında bilgi verilmektedir:

İŞLEÇLER OVERLOADABILITY

+ x, -x, ! x, ~ x, ++, --, true, false Bu birli işleçler aşırı yüklenebilir.

x + y, x-y, x * y, x/y, x % y, x & y, x | y, x ^ y, x << y, x > Bu ikili işleçler aşırı yüklenebilir. Belirli operatörler çiftler
> y, x = = y, x! = y, x < y, x > y, x <= y, x > = y halinde aşırı yüklenmiş olmalıdır; daha fazla bilgi için bu
tabloyu izleyen nota bakın.

x & & y, x | | y Koşullu mantıksal işleçler aşırı yüklenemez. Ancak, aşırı


yüklenmiş true ve false işleçleriyle bir tür & ya da
| işlecini belirli bir şekilde aşırı yükiyorsa, sırasıyla &&
veya || işleci bu türün işlenenleri için değerlendirilebilir.
Daha fazla bilgi için, C# dil belirtiminin Kullanıcı tanımlı
Koşullu mantıksal işleçler bölümüne bakın.

bir[i] Öğe erişimi aşırı yüklenebilir bir operatör olarak kabul


edilmez, ancak bir Dizin Oluşturucutanımlayabilirsiniz.

(T) x Atama işleci aşırı yüklenemez, ancak yeni dönüştürme


işleçleri tanımlayabilirsiniz. Daha fazla bilgi için bkz.
Kullanıcı tanımlı dönüştürme işleçleri.

+=, -=, *=, /=, %=, &=, |=, ^=, <<=, @no__ t_22_ Bileşik atama işleçleri açık olarak aşırı yüklenemez. Ancak,
bir ikili işleci aşırı yüklerken, varsa buna karşılık gelen
bileşik atama işleci de dolaylı olarak aşırı yüklenmiştir.
Örneğin += , aşırı yüklenmiş olabilecek + kullanılarak
değerlendirilir.

^ x, x = y, x. y, c? t: f, x?? y, x?? = y, x. y, x-> y, =>, f (x), Bu işleçler aşırı yüklenemez.


as, await, Checked, denetimsiz, varsayılan, Delegate ,,,
NameOf, New, sizeof, stackalloc, typeof

NOTE
Karşılaştırma işleçleri çiftler halinde aşırı yüklenmiş olmalıdır. Diğer bir deyişle, bir çiftin işleci aşırı yüklenmişse, diğer
işlecin da aşırı yüklenmesi gerekir. Böyle çiftler aşağıdaki gibidir:
== ve != işleçleri
< ve > işleçleri
<= ve >= işleçleri

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtimininaşağıdaki bölümlerine bakın:
İşleç aşırı yüklemesi
işleçler

Ayrıca bkz.
C#başvurunun
C# işleçleri
Kullanıcı tanımlı dönüştürme işleçleri
Neden aşırı yüklenmiş işleçler ' de C#her zaman statiktir?
C# Özel Karakterleri
31.10.2019 • 2 minutes to read • Edit Online

Özel karakterler önceden tanımlanmıştır, bir program öğesini (değişmez dize, bir tanımlayıcı veya bir öznitelik adı),
bunlara göre değişiklik gösteren bağlamsal karakterlerdir. C#Aşağıdaki özel karakterleri destekler:
tam tanımlayıcı karakteri @.
$, enterpolasyonlu dize karakteri.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
$-dize ilişkilendirme (C# başvuru)
4.11.2019 • 7 minutes to read • Edit Online

$ özel karakter, bir dize sabit değerini, enterpolasyonlu dizeolarak tanımlar. Enterpolasyonlu dize,
enterpolasyon ifadeleriiçerebilen bir dize sabit değeri. Bir enterpolasyonlu dize bir sonuç dizesine
çözümlendiğinde, enterpolasyon ifadesi içeren öğeler, ifade sonuçlarının dize gösterimleriyle
değiştirilmiştir. Bu özellik C# 6 ' dan itibaren kullanılabilir.
Dize ilişkilendirme, dize bileşik biçimlendirme özelliğinden biçimlendirilmiş dizeler oluşturmak için daha
okunabilir ve uygun bir sözdizimi sağlar. Aşağıdaki örnek, aynı çıktıyı üretmek için her iki özelliği de
kullanır:

string name = "Mark";


var date = DateTime.Now;

// Composite formatting:
Console.WriteLine("Hello, {0}! Today is {1}, it's {2:HH:mm} now.", name, date.DayOfWeek, date);
// String interpolation:
Console.WriteLine($"Hello, {name}! Today is {date.DayOfWeek}, it's {date:HH:mm} now.");
// Both calls produce the same output that is similar to:
// Hello, Mark! Today is Wednesday, it's 19:40 now.

Enterpolasyonlu bir dizenin yapısı


Bir dize sabit değerini, enterpolasyonlu bir dize olarak tanımlamak için $ simgesiyle önüne ekleyin. $
ve bir dize sabiti Başlatan " arasında boşluk olamaz.
Enterpolasyon ifadesi içeren bir öğenin yapısı aşağıdaki gibidir:

{<interpolationExpression>[,<alignment>][:<formatString>]}

Köşeli parantezler içindeki öğeler isteğe bağlıdır. Aşağıdaki tabloda her öğe açıklanmaktadır:

ÖĞE AÇIKLAMA

interpolationExpression Biçimlendirilecek bir sonuç üreten ifade. null dize


temsili String.Empty.

alignment Değeri, ifade sonucunun dize temsilinde minimum


karakter sayısını tanımlayan sabit ifade. Pozitif ise, dize
temsili sağa hizalanır; negatifse, sola hizalanır. Daha fazla
bilgi için bkz. Hizalama bileşeni.

formatString İfade sonucunun türü tarafından desteklenen bir biçim


dizesi. Daha fazla bilgi için bkz. Biçim dize bileşeni.

Aşağıdaki örnek, yukarıda açıklanan isteğe bağlı biçimlendirme bileşenlerini kullanır:


Console.WriteLine($"|{"Left",-7}|{"Right",7}|");

const int FieldWidthRightAligned = 20;


Console.WriteLine($"{Math.PI,FieldWidthRightAligned} - default formatting of the pi number");
Console.WriteLine($"{Math.PI,FieldWidthRightAligned:F3} - display only three decimal digits of the pi
number");
// Expected output is:
// |Left | Right|
// 3.14159265358979 - default formatting of the pi number
// 3.142 - display only three decimal digits of the pi number

Özel karakterler
"{" Veya "}" küme ayracı eklemek için, enterpolasyonlu bir dize tarafından üretilen metinde, "{{" veya "}}"
iki küme ayracı kullanın. Daha fazla bilgi için bkz. kaçış ayraçları.
İki nokta üst üste (":"), enterpolasyon ifadesi öğesinde koşullu bir işleç kullanmak için bir ilişkilendirme
ifadesinde özel anlamı olduğundan, bu ifadeyi parantez içine alın.
Aşağıdaki örnek, bir sonuç dizesinde bir küme ayracın nasıl ekleneceğini ve bir ilişkilendirme ifadesinde
koşullu işlecin nasıl kullanılacağını gösterir:

string name = "Horace";


int age = 34;
Console.WriteLine($"He asked, \"Is your name {name}?\", but didn't wait for a reply :-{{");
Console.WriteLine($"{name} is {age} year{(age == 1 ? "" : "s")} old.");
// Expected output is:
// He asked, "Is your name Horace?", but didn't wait for a reply :-{
// Horace is 34 years old.

Enterpolasyonlu bir dize $ karakteriyle başlar ve ardından @ karakteri gelir. Tam dizeler hakkında daha
fazla bilgi için bkz. dize ve tam tanımlayıcı konuları.

NOTE
8,0 ile C# başlayarak, $ ve @ belirteçlerini dilediğiniz sırada kullanabilirsiniz: her iki $@"..." ve @$"..." geçerli bir
ara değerli dizelerdir. Önceki C# sürümlerde $ belirtecinin @ belirtecinden önce görünmesi gerekir.

Örtük dönüştürmeler ve IFormatProvider uygulamasını belirtme


Enterpolasyonlu bir dizeden üç örtük dönüştürme vardır:
1. Enterpolasyonlu bir dizenin, sonuçları doğru biçimli dize gösterimlerine göre değiştirilmekte olan
enterpolasyon ifade öğeleriyle birlikte bulunan bir String örneğine dönüştürülmesi. Bu
dönüştürme, ifade sonuçlarını biçimlendirmek için CurrentCulture kullanır.
2. Enterpolasyonlu bir dizenin, bir bileşik biçim dizesini temsil eden bir FormattableString örneğine
dönüştürülmesi ve bu ifade, biçimlendirilecek ifade sonuçlarıyla birlikte. Bu, tek bir
FormattableString örneğinden kültüre özgü içerikle birden çok sonuç dizesi oluşturmanıza olanak
sağlar. Bunu yapmak için aşağıdaki yöntemlerden birini çağırın:
CurrentCultureiçin sonuç dizesi üreten ToString() aşırı yükleme.
InvariantCultureiçin sonuç dizesi üreten Invariant yöntemi.
Belirtilen kültür için sonuç dizesi üreten ToString(IFormatProvider) yöntemi.
Ayrıca, özel biçimlendirmeyi destekleyen IFormatProvider arabirimine yönelik kullanıcı tanımlı bir
uygulama sağlamak için ToString(IFormatProvider) yöntemini de kullanabilirsiniz. Daha fazla bilgi
için .net makalesindeki biçimlendirme türleri konusunun ICustomFormatter ile özel biçimlendirme
bölümüne bakın.
3. Enterpolasyonlu bir dizenin tek bir IFormattable örneğinden kültüre özgü içerikle birden çok
sonuç dizesi oluşturmanıza olanak sağlayan bir IFormattable örneğine dönüştürülmesi.
Aşağıdaki örnek, kültüre özgü sonuç dizeleri oluşturmak için FormattableString için örtük dönüştürmeyi
kullanır:

double speedOfLight = 299792.458;


FormattableString message = $"The speed of light is {speedOfLight:N3} km/s.";

System.Globalization.CultureInfo.CurrentCulture =
System.Globalization.CultureInfo.GetCultureInfo("nl-NL");
string messageInCurrentCulture = message.ToString();

var specificCulture = System.Globalization.CultureInfo.GetCultureInfo("en-IN");


string messageInSpecificCulture = message.ToString(specificCulture);

string messageInInvariantCulture = FormattableString.Invariant(message);

Console.WriteLine($"{System.Globalization.CultureInfo.CurrentCulture,-10}
{messageInCurrentCulture}");
Console.WriteLine($"{specificCulture,-10} {messageInSpecificCulture}");
Console.WriteLine($"{"Invariant",-10} {messageInInvariantCulture}");
// Expected output is:
// nl-NL The speed of light is 299.792,458 km/s.
// en-IN The speed of light is 2,99,792.458 km/s.
// Invariant The speed of light is 299,792.458 km/s.

Ek kaynaklar
Dize ilişkilendirme konusunda yeni bir adım daha kullanıyorsanız etkileşimli öğreticide dize
ilişkilendirmeyi C# inceleyin. Ayrıca, biçimlendirilen dizeleri oluşturmak için, enterpolasyonlu dizelerin
nasıl kullanılacağını gösteren öğreticideki başka bir dize ilişkilendirmeyi C# da denetleyebilirsiniz.

Enterpolasyonlu dizelerin derlenmesi


Bir enterpolasyonlu dize tür string , genellikle bir String.Format yöntemi çağrısına dönüştürülür.
Çözümlenen davranış birleştirme ile eşdeğer olacaksa, derleyici String.Format String.Concat ile
değiştirebilir.
Enterpolasyonlu bir dize IFormattable veya FormattableStringtür içeriyorsa, derleyici
FormattableStringFactory.Create yöntemine bir çağrı oluşturur.

C# dili belirtimi
Daha fazla bilgi için, C# dil belirtiminin enterpolasyonlu dizeler bölümüne bakın.

Ayrıca bkz.
C#başvurunun
C# özel karakterleri
Dizeler
Sayısal sonuçlar tablosunu biçimlendirme
Bileşik biçimlendirme
String.Format
@ (C# Başvuru)
31.10.2019 • 4 minutes to read • Edit Online

@ özel karakter, tam tanımlayıcı işlevi görür. Aşağıdaki yollarla kullanılabilir:


1. Anahtar kelimeleri C# tanımlayıcı olarak kullanılacak şekilde etkinleştirmek için. @ karakter, derleyicinin
bir C# anahtar sözcük yerine bir tanımlayıcı olarak yorumlanacağı bir kod öğesi ön ekine sahiptir.
Aşağıdaki örnek, bir for döngüsünde kullandığı for adlı bir tanımlayıcıyı tanımlamak için @
karakterini kullanır.

string[] @for = { "John", "James", "Joan", "Jamie" };


for (int ctr = 0; ctr < @for.Length; ctr++)
{
Console.WriteLine($"Here is your gift, {@for[ctr]}!");
}
// The example displays the following output:
// Here is your gift, John!
// Here is your gift, James!
// Here is your gift, Joan!
// Here is your gift, Jamie!

2. Dize sabit değerinin tam olarak yorumlandığını göstermek için. Bu örnekteki @ karakteri, tam bir dize
sabit değeritanımlar. Basit kaçış dizileri (ters eğik çizgi için "\\" gibi), onaltılık kaçış dizileri (büyük A için
"\x0041" gibi) ve Unicode kaçış dizileri (örn. bir büyük harf A için "\u0041" ), tam olarak yorumlanır.
Yalnızca bir tırnak çıkış sırası ( "" ), salt okunur olarak yorumlanmaz; tek tırnak işareti üretir. Ayrıca, tam
olarak bulunan bir dize ayracı kaçış dizileri ( {{ ve }} ) büyük harf olarak yorumlanmaz; tek küme ayracı
karakterleri üretir. Aşağıdaki örnek, biri normal dize değişmez değeri ve diğeri de tam olarak bir dize sabiti
kullanarak iki özdeş dosya yolunu tanımlar. Bu, tam dize değişmez değerlerinin yaygın kullanımlarındaki
bir biridir.

string filename1 = @"c:\documents\files\u0066.txt";


string filename2 = "c:\\documents\\files\\u0066.txt";

Console.WriteLine(filename1);
Console.WriteLine(filename2);
// The example displays the following output:
// c:\documents\files\u0066.txt
// c:\documents\files\u0066.txt

Aşağıdaki örnek, bir normal dize sabit değeri ve özdeş karakter dizileri içeren tam bir dize sabiti
tanımlamanın etkisini gösterir.

string s1 = "He said, \"This is the last \u0063hance\x0021\"";


string s2 = @"He said, ""This is the last \u0063hance\x0021""";

Console.WriteLine(s1);
Console.WriteLine(s2);
// The example displays the following output:
// He said, "This is the last chance!"
// He said, "This is the last \u0063hance\x0021"

3. Derleyicinin, bir adlandırma çakışması durumunda öznitelikleri birbirinden ayırt etmek üzere
etkinleştirmek için. Öznitelik, Attributetüretilen bir sınıftır. Tür adı genellikle sonek özniteliğiniiçerir,
ancak derleyici bu kuralı zorlamaz. Daha sonra bu özniteliğe, tam tür adı (örneğin, [InfoAttribute] veya
kısaltılmış adı (örneğin, [Info] ) ile kod içinde başvurulabilir. Ancak, iki kısaltılmış öznitelik türü adı özdeş
ise ve bir tür adı öznitelik sonekini içeriyorsa ancak diğeri yoksa, bir adlandırma çakışması oluşur.
Örneğin, derleyici Info veya InfoAttribute özniteliğinin Example sınıfına uygulanıp uygulanmadığını
belirleyemediği için aşağıdaki kod derlenemiyor. Daha fazla bilgi için bkz. CS1614 .

using System;

[AttributeUsage(AttributeTargets.Class)]
public class Info : Attribute
{
private string information;

public Info(string info)


{
information = info;
}
}

[AttributeUsage(AttributeTargets.Method)]
public class InfoAttribute : Attribute
{
private string information;

public InfoAttribute(string info)


{
information = info;
}
}

[Info("A simple executable.")] // Generates compiler error CS1614. Ambiguous Info and InfoAttribute.
// Prepend '@' to select 'Info'. Specify the full name 'InfoAttribute' to select it.
public class Example
{
[InfoAttribute("The entry point.")]
public static void Main()
{
}
}

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Özel Karakterleri
C# ön işlemci yönergeleri
23.10.2019 • 2 minutes to read • Edit Online

Bu bölüm aşağıdaki C# Önişlemci yönergeleri hakkında bilgiler içerir:


#if
#else
#elif
#endif
#define
#undef
#warning
#error
#line
#region
#endregion
#pragma
#pragma uyarısı
#pragma sağlama toplamı
Daha fazla bilgi ve örnek için bireysel konulara bakın.
Derleyicinin ayrı bir önişlemcisi olmasa da, bu bölümde açıklanan yönergeler bir gibi işlenir. Koşullu derlemede
yardımcı olmak için kullanılırlar. C ve C++ yönergelerinden farklı olarak, bu yönergeleri makrolar oluşturmak için
kullanamazsınız.
Bir Önişlemci yönergesi, bir satırdaki tek yönerge olmalıdır.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
#if (C# Başvurusu)
29.11.2019 • 4 minutes to read • Edit Online

C# Derleyici bir #if yönergesi ile karşılaştığında, sonunda bir #endif yönergesi ile, yalnızca belirtilen sembol
tanımlanmışsa, yönergeler arasındaki kodu derler. C ve C++' nin aksine, bir simgeye sayısal değer
atayamazsınız. İçindeki C# #if deyimleri Boolean olur ve yalnızca sembolün tanımlanıp tanımlanmadığını sınar.
Örneğin:

#if DEBUG
Console.WriteLine("Debug version");
#endif

== (eşitlik) ve ! = (eşitsizlik) işleçlerini yalnızca bool değerleri true veya false test etmek için kullanabilirsiniz.
Doğru, simgenin tanımlandığı anlamına gelir. Deyimin #if DEBUG #if (DEBUG == true) ile aynı anlamı vardır.
İşleçlerini && (ve), | (veya) ve ! (değil) birden çok sembolün tanımlanıp tanımlanmadığını değerlendirmek için.
Simgeleri ve işleçleri parantez ile de gruplandırabilirsiniz.

Açıklamalar
#if , #else, #elif, #endif, #defineve #undef yönergeleriyle birlikte, bir veya daha fazla simgenin varlığına göre
kodu dahil etmenize veya dışlamanızı sağlar. Bu, hata ayıklama derlemesi için kod derlerken veya belirli bir
yapılandırma için derlenirken yararlı olabilir.
#if yönergesiyle başlayan koşullu bir yönerge açıkça bir #endif yönergesi ile sonlandırılmalıdır.
#define bir simge tanımlamanızı sağlar. Sonra, #if yönergesine geçirilen ifade olarak sembolünü kullanarak,
ifade true olarak değerlendirilir.
Ayrıca, -define derleyici seçeneğiyle bir simge tanımlayabilirsiniz. #Undefbir simge tanımlayabilirsiniz.
-define veya #define ile tanımladığınız bir sembol aynı ada sahip bir değişkenle çakışmaz. Diğer bir deyişle,
bir değişken adı bir Önişlemci yönergesine geçirilmemelidir ve bir sembol yalnızca bir Önişlemci yönergesi
tarafından değerlendirilebilmelidir.
#define ile oluşturulan bir simgenin kapsamı tanımlandığı dosyadır.
Yapı sistemi, SDK stili projelerde farklı hedef çerçeveleri temsil eden önceden tanımlanmış ön işlemci sembolleri
de farkındadır. Birden fazla .NET uygulaması veya sürümü hedefleyebilir uygulamalar oluştururken faydalıdır.

HEDEF ÇERÇEVELER SIMGELER

.NET Framework NETFRAMEWORK , NET20 , NET35 , NET40 , NET45 ,


NET451 , NET452 , NET46 , NET461 , NET462 , NET47 ,
NET471 , NET472 , NET48

.NET Standard NETSTANDARD , NETSTANDARD1_0 , NETSTANDARD1_1 ,


NETSTANDARD1_2 , NETSTANDARD1_3 , NETSTANDARD1_4 ,
NETSTANDARD1_5 , NETSTANDARD1_6 , NETSTANDARD2_0 ,
NETSTANDARD2_1
HEDEF ÇERÇEVELER SIMGELER

.NET Core NETCOREAPP , NETCOREAPP1_0 , NETCOREAPP1_1 ,


NETCOREAPP2_0 , NETCOREAPP2_1 , NETCOREAPP2_2 ,
NETCOREAPP3_0 , NETCOREAPP3_1

NOTE
Geleneksel .NET Framework projelerinde, Visual Studio 'daki farklı hedef çerçeveler için koşullu derleme sembollerini
projenin Özellikler sayfaları aracılığıyla el ile yapılandırmanız gerekir.

Önceden tanımlanmış diğer semboller, hata ayıklama ve Izleme sabitlerini içerir. #define kullanarak proje için
ayarlanan değerleri geçersiz kılabilirsiniz. Örneğin, hata ayıklama sembolü, derleme yapılandırma özelliklerine
("hata ayıklama" veya "yayın" modu) göre otomatik olarak ayarlanır.

Örnekler
Aşağıdaki örnek, bir dosya üzerinde MYTEST sembolünü nasıl tanımlacağınızı ve sonra MYTEST ve hata
ayıklama simgelerinin değerlerini test etmek için size gösterir. Bu örneğin çıktısı, projeyi hata ayıklama veya
sürüm yapılandırma modunda derdığınıza bağlıdır.

#define MYTEST
using System;
public class MyClass
{
static void Main()
{
#if (DEBUG && !MYTEST)
Console.WriteLine("DEBUG is defined");
#elif (!DEBUG && MYTEST)
Console.WriteLine("MYTEST is defined");
#elif (DEBUG && MYTEST)
Console.WriteLine("DEBUG and MYTEST are defined");
#else
Console.WriteLine("DEBUG and MYTEST are not defined");
#endif
}
}

Aşağıdaki örnekte, mümkünse daha yeni API 'Leri kullanabilmeniz için farklı hedef çerçeveler için nasıl test
yapılacağı gösterilmektedir:

public class MyClass


{
static void Main()
{
#if NET40
WebClient _client = new WebClient();
#else
HttpClient _client = new HttpClient();
#endif
}
//...
}

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Ön İşlemci Yönergeleri
Nasıl yapılır: İzleme ve Hata Ayıklama ile Koşullu Derleme
#else (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

#else , yukarıdaki #if veya (isteğe bağlı) #elif yönergelerinden hiçbiri olarak true değerlendiriyorsa, derleyicinin
tüm kodu ve arasındaki #else daha #endif sonra.

Açıklamalar
#endif sonraki ön işlemci yönergesi #else olmalıdır. Öğesinin nasıl kullanılacağına #else ilişkin bir örnek için bkz.
#if.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Ön İşlemci Yönergeleri
#elif (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

#elif bileşik bir koşullu yönerge oluşturmanıza olanak sağlar. Yukarıdaki #if ne de #elif önceki, isteğe bağlı bir
yönerge ifadesi olarak true değerlendiriliyorsa ifadedeğerlendirilir. #elif Bir #elif ifade olarak true
değerlendirilirse, derleyici #elif ve sonraki koşullu yönerge arasındaki tüm kodu değerlendirir. Örneğin:

#define VC7
//...
#if debug
Console.WriteLine("Debug build");
#elif VC7
Console.WriteLine("Visual Studio 7");
#endif

Birden çok sembolü değerlendirmek için == işleçleri (eşitlik) != , (eşitsizlik && ), (ve) ve || (veya)
kullanabilirsiniz. Simgeleri ve işleçleri parantez ile de gruplandırabilirsiniz.

Açıklamalar
#elif , ile eşdeğerdir:

#else
#if

Kullanılması #elif daha basittir çünkü her biri #if bir #endifgerektirir, ancak bir #elif eşleştirme #endif
olmadan kullanılabilir.
Öğesinin nasıl kullanılacağına #elif ilişkin bir örnek için bkz. #if.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Ön İşlemci Yönergeleri
#endif (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

#endif #if yönergesiyle başlayan bir koşul yönergesinin sonunu belirtir. Örneğin,

#define DEBUG
// ...
#if DEBUG
Console.WriteLine("Debug version");
#endif

Açıklamalar
#if Yönergeyle başlayan koşullu yönerge, açıkça bir #endif yönergeyle sonlandırılmalıdır. Öğesinin nasıl
kullanılacağına #endif ilişkin bir örnek için bkz. #if.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Ön İşlemci Yönergeleri
#define (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

Bir sembol #define tanımlamak için kullanırsınız. #İf yönergesine geçirilen ifade olarak sembolünü
kullandığınızda, aşağıdaki örnekte gösterildiği gibi ifade olarak değerlendirilir true .

#define DEBUG

Açıklamalar
NOTE
Yönerge #define , genellikle C ve C++' de yapıldığı gibi sabit değerleri bildirmek için kullanılamaz. İçindeki C# sabitler, bir
sınıfın veya yapının statik üyeleri olarak en iyi şekilde tanımlanır. Bu tür sabitlere sahipseniz, bunları tutmak için ayrı bir
"sabitler" sınıfı oluşturmayı düşünün.

Simgeler, derleme koşullarını belirtmek için kullanılabilir. Sembol için #if ya da #elifile test edebilirsiniz. Koşullu
derleme gerçekleştirmek ConditionalAttribute için öğesini de kullanabilirsiniz.
Bir sembol tanımlayabilirsiniz, ancak bir simgeye değer atayamazsınız. Ayrıca Önişlemci yönergeleri olmayan
herhangi bir yönergeyi kullanmadan önce yönergedosyadagörünmelidir. #define
Ayrıca, -define derleyici seçeneğiyle bir simge tanımlayabilirsiniz. #Undefbir simge tanımlayabilirsiniz.
-define Veya ile #define tanımladığınız bir sembol aynı ada sahip bir değişkenle çakışmaz. Diğer bir deyişle, bir
değişken adı bir Önişlemci yönergesine geçirilmemelidir ve bir sembol yalnızca bir Önişlemci yönergesi
tarafından değerlendirilebilmelidir.
Kullanılarak #define oluşturulan bir simgenin kapsamı, sembolün tanımlandığı dosyadır.
Aşağıdaki örnekte gösterildiği gibi yönergeleri dosyanın en üstüne koymanız #define gerekir.

#define DEBUG
//#define TRACE
#undef TRACE

using System;

public class TestDefine


{
static void Main()
{
#if (DEBUG)
Console.WriteLine("Debugging is enabled.");
#endif

#if (TRACE)
Console.WriteLine("Tracing is enabled.");
#endif
}
}
// Output:
// Debugging is enabled.
Bir simgenin nasıl tanımlanacağını gösteren bir örnek için bkz. #undef.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Ön İşlemci Yönergeleri
const
Nasıl yapılır: Izleme ve hata ayıklama ile koşullu derleme
#undef
#if
#undef (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

#undef bir simge tanımlamanızı sağlar, örneğin, simgeyi bir #if yönergesinde ifade olarak kullanarak ifade edilir
false .
Bir sembol #define yönergesi veya -define derleyici seçeneği ile tanımlanabilir. Ayrıca #undef , yönergesi
olmayan hiçbir deyimi kullanmadan önce yönerge dosyada görünmelidir.

Örnek
// preprocessor_undef.cs
// compile with: /d:DEBUG
#undef DEBUG
using System;
class MyClass
{
static void Main()
{
#if DEBUG
Console.WriteLine("DEBUG is defined");
#else
Console.WriteLine("DEBUG is not defined");
#endif
}
}

Hata ayıklama tanımlı değil

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Ön İşlemci Yönergeleri
#warning (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

#warning kodunuzda belirli bir konumdan bir CS1030 düzeyinde bir derleyici uyarısı oluşturmanıza olanak sağlar.
Örneğin:

#warning Deprecated code in this method.

Açıklamalar
Öğesinin #warning yaygın kullanımı koşullu bir yönergedir. #Errorile Kullanıcı tanımlı bir hata oluşturmak da
mümkündür.

Örnek
// preprocessor_warning.cs
// CS1030 expected
#define DEBUG
class MainClass
{
static void Main()
{
#if DEBUG
#warning DEBUG is defined
#endif
}
}

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Ön İşlemci Yönergeleri
#error (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

#error kodunuzda belirli bir konumdan CS1029 Kullanıcı tanımlı bir hata oluşturmanıza olanak sağlar. Örneğin:

#error Deprecated code in this method.

Açıklamalar
Öğesinin #error yaygın kullanımı koşullu bir yönergedir.
#Warningile Kullanıcı tanımlı bir uyarı oluşturmak da mümkündür.

Örnek
// preprocessor_error.cs
// CS1029 expected
#define DEBUG
class MainClass
{
static void Main()
{
#if DEBUG
#error DEBUG is defined
#endif
}
}

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Ön İşlemci Yönergeleri
#line (C# Başvurusu)
23.10.2019 • 4 minutes to read • Edit Online

#line Derleyicinin satır numaralandırmasını ve (isteğe bağlı olarak) hata ve uyarı için dosya adı çıktısını
değiştirmenize izin verir.
Aşağıdaki örnek, satır numaralarıyla ilişkili iki uyarıyı nasıl bildirekullanacağınızı gösterir. Yönerge, sonraki satırın
numarasını 200 (varsayılan değer #6) olarak zorlar ve sonraki #line yönergeye kadar dosya adı "özel" olarak
raporlanır. #line 200 #line default Yönerge, önceki yönerge tarafından yeniden numaralandırılmış satırları sayan
varsayılan numaralandırmayla satır numaralandırmayı döndürür.

class MainClass
{
static void Main()
{
#line 200 "Special"
int i;
int j;
#line default
char c;
float f;
#line hidden // numbering not affected
string s;
double d;
}
}

Derleme aşağıdaki çıktıyı üretir:

Special(200,13): warning CS0168: The variable 'i' is declared but never used
Special(201,13): warning CS0168: The variable 'j' is declared but never used
MainClass.cs(9,14): warning CS0168: The variable 'c' is declared but never used
MainClass.cs(10,15): warning CS0168: The variable 'f' is declared but never used
MainClass.cs(12,16): warning CS0168: The variable 's' is declared but never used
MainClass.cs(13,16): warning CS0168: The variable 'd' is declared but never used

Açıklamalar
#line Yönergesi, yapı işlemindeki otomatik, ara bir adımda kullanılabilir. Örneğin, satır orijinal kaynak kodu
dosyasından kaldırılmışsa, ancak derleyicinin dosyadaki özgün satır numaralandırmasını temel alarak çıkış
oluşturmasını istiyorsanız, satırları kaldırabilir ve ardından özgün satır numaralandırmasının #line benzetimini
yapabilirsiniz.
Yönerge, hata ayıklayıcıdan ardışık satırları gizler, örneğin, Geliştirici kod içinde, bir ve #line sonraki yönerge
arasındaki herhangi bir #line hidden satır (başka bir #line hidden yönerge olmadığı varsayılarak) #line hidden
ele alınacaktır. Bu seçenek, ASP.NET 'in Kullanıcı tanımlı ve makine tarafından oluşturulan kodla ayırt edilmesine
imkan tanımak için de kullanılabilir. ASP.NET bu özelliğin birincil tüketicisi olsa da, büyük olasılıkla daha fazla
kaynak oluşturanlar bunu kullanacaktır.
Bir #line hidden yönerge, hata raporlamadaki dosya adlarını veya satır numaralarını etkilemez. Diğer bir deyişle,
gizli bir blokta bir hata ile karşılaşılırsa, derleyici geçerli dosya adı ve hatanın satır numarasını bildirir.
#line filename Yönergesi, derleyici çıkışında görünmesini istediğiniz dosya adını belirtir. Varsayılan olarak, kaynak
kodu dosyasının gerçek adı kullanılır. Dosya adı çift tırnak işareti ("") içinde olmalı ve önünde bir satır numarası
gelmelidir.
Kaynak kodu dosyası herhangi bir sayıda #line yönergeler içerebilir.

Örnek 1
Aşağıdaki örnek, hata ayıklayıcının koddaki gizli satırları nasıl yoksaydığı gösterilmektedir. Örneği çalıştırdığınızda
üç satırlık metin görüntülenir. Ancak, örnekte gösterildiği gibi bir kesme noktası ayarladığınızda ve kodun içinde
ilerlemek için F10 'e bastığınızda, hata ayıklayıcının gizli çizgiyi yoksaydığına dikkat edin. Ayrıca, gizli satırda bir
kesme noktası ayarlasanız bile hata ayıklayıcının yok saymaya devam ettiğini unutmayın.

// preprocessor_linehidden.cs
using System;
class MainClass
{
static void Main()
{
Console.WriteLine("Normal line #1."); // Set break point here.
#line hidden
Console.WriteLine("Hidden line.");
#line default
Console.WriteLine("Normal line #2.");
}
}

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Ön İşlemci Yönergeleri
#region (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

#region Visual Studio Code düzenleyicisinin ana hat özelliğini kullanırken genişletebileceğiniz veya
daraltabileceğiniz bir kod bloğu belirtmenize olanak tanır. Daha uzun kod dosyalarında, üzerinde çalışmakta
olduğunuz dosyanın bölümüne odaklanabilmeniz için bir veya daha fazla bölgenin daraltılanması veya gizlenmesi
uygun olabilir. Aşağıdaki örnek, bir bölgenin nasıl tanımlanacağını göstermektedir:

#region MyClass definition


public class MyClass
{
static void Main()
{
}
}
#endregion

Açıklamalar
Bir #region blok, bir #endregion yönergesi ile sonlandırılmalıdır.
Bir #region blok #if bloğuyla çakışamaz. Ancak bir blok bir #if blokta iç içe olabilir ve #if bir blok bir #region
blok içinde iç içe olabilir. #region

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Ön İşlemci Yönergeleri
#endregion (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

#endregion #region bloğunun sonunu işaretler. Örneğin:

#region MyClass definition


class MyClass
{
static void Main()
{
}
}
#endregion

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Ön İşlemci Yönergeleri
#pragma (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

#pragma Derleyicinin göründüğü dosyanın derlenmesi için özel yönergeler sağlar. Yönergeler derleyici tarafından
desteklenmelidir. Diğer bir deyişle, özel ön işleme #pragma yönergeleri oluşturmak için kullanamazsınız. Microsoft
C# derleyicisi aşağıdaki iki #pragma yönergeleri destekler:
#pragma uyarısı
#pragma sağlama toplamı

Sözdizimi
#pragma pragma-name pragma-arguments

Parametreler
pragma-name
Tanınan bir pragma adı.
pragma-arguments
Pragma 'a özgü bağımsız değişkenler.

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Ön İşlemci Yönergeleri
#pragma uyarısı
#pragma sağlama toplamı
#pragma uyarısı (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

#pragma warning Belirli uyarıları etkinleştirebilir veya devre dışı bırakabilir.

Sözdizimi
#pragma warning disable warning-list
#pragma warning restore warning-list

Parametreler
warning-list
Uyarı numaralarının virgülle ayrılmış bir listesi. "CS" ön eki isteğe bağlıdır.
Hiçbir uyarı numarası belirtilmediğinde, disable tüm uyarıları devre dışı bırakır ve restore tüm uyarıları
etkinleştirilir.

NOTE
Visual Studio 'da uyarı numaralarını bulmak için projenizi derleyin ve ardından Çıkış penceresinde uyarı numaralarını arayın.

Örnek
// pragma_warning.cs
using System;

#pragma warning disable 414, CS3021


[CLSCompliant(false)]
public class C
{
int i = 1;
static void Main()
{
}
}
#pragma warning restore CS3021
[CLSCompliant(false)] // CS3021
public class D
{
int i = 1;
public static void F()
{
}
}

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Ön İşlemci Yönergeleri
C# Derleyici Hataları
#pragma sağlama toplamı (C# Başvurusu)
23.10.2019 • 2 minutes to read • Edit Online

ASP.NET sayfalarında hata ayıklamaya yardımcı olmak için kaynak dosyaları için sağlama toplamı üretir.

Sözdizimi
#pragma checksum "filename" "{guid}" "checksum bytes"

Parametreler
"filename"
Değişiklik veya güncelleştirme için izlemeyi gerektiren dosyanın adı.
"{guid}"
Karma algoritma için genel benzersiz tanımlayıcı (GUID ).
"checksum_bytes"
Sağlama toplamı baytlarını temsil eden onaltılık basamakların dizesi. Çift sayıda onaltılık basamak olmalıdır. Tek
sayıda basamak derleme zamanı uyarısına neden olur ve yönerge yok sayılır.

Açıklamalar
Visual Studio hata ayıklayıcı, her zaman doğru kaynağı bulmasını sağlamak için bir sağlama toplamı kullanır.
Derleyici, kaynak dosya için sağlama toplamını hesaplar ve sonra çıktıyı program veritabanı (PDB ) dosyasına
yayar. Hata ayıklayıcı daha sonra kaynak dosya için hesapladığı sağlama toplamıyla karşılaştırmak için PDB 'yi
kullanır.
Hesaplanan sağlama toplamı,. aspx dosyası yerine oluşturulan kaynak dosya için olduğundan, bu çözüm ASP.NET
projelerinde çalışmaz. Bu sorunu #pragma checksum gidermek için ASP.NET sayfaları için sağlama toplamı desteği
sağlar.
Görselde C#bir ASP.NET projesi oluşturduğunuzda oluşturulan kaynak dosya, kaynağın oluşturulduğu. aspx
dosyası için bir sağlama toplamı içerir. Derleyici daha sonra bu bilgileri PDB dosyasına yazar.
Derleyici dosyada hiçbir #pragma checksum yönergeyle karşılaşırsa, sağlama toplamını hesaplar ve değeri pdb
dosyasına yazar.

Örnek
class TestClass
{
static int Main()
{
#pragma checksum "file.cs" "{406EA660-64CF-4C82-B6F0-42D48172A799}" "ab007f1d23d9" // New checksum
}
}

Ayrıca bkz.
C#Başvurunun
C# Programlama Kılavuzu
C# Ön İşlemci Yönergeleri
C# Derleyici Seçenekleri
25.11.2019 • 2 minutes to read • Edit Online

Derleyici yürütülebilir (. exe) dosyalar, dinamik bağlantı kitaplıkları (. dll) veya kod modülleri (. netmodule)
oluşturur.
Her derleyici seçeneği iki biçimde mevcuttur: -Option ve /Option. Belgeler yalnızca -seçenek formunu
gösterir.
Visual Studio 'da, Web. config dosyasında derleyici seçeneklerini ayarlarsınız. Daha fazla bilgi için bkz.
<derleyici > öğesi.

Bu bölümde
CSC. exe Ile komut satırı oluşturma Komut satırından görsel C# uygulama oluşturma hakkında bilgi.
Visual Studio komut satırı için ortam değişkenlerini ayarlama Komut satırı yapılarını etkinleştirmek
için vsvars32. bat dosyasını çalıştırmaya yönelik adımları sağlar.
Kategoriye göre listelenen derleyici seçenekleri C# Derleyici seçeneklerinin kategorik bir listesi.
Alfabetik olarak listelenen derleyici seçenekleri C# Derleyici seçeneklerinin alfabetik bir listesi.

İlgili bölümler
Derleme sayfası, proje Tasarımcısı Projenizin nasıl derlendiğini, oluşturulduğunu ve hata
ayıklandığını yöneten özellikleri ayarlama. Görsel C# projelerdeki özel derleme adımları hakkındaki
bilgileri içerir.
Varsayılan ve özel derlemeler Yapı türleri ve yapılandırmalara ilişkin bilgiler.
Derlemeleri hazırlama ve yönetme Visual Studio geliştirme ortamı içinde oluşturmaya yönelik
yordamlar.
Csc. exe ile komut satırı oluşturma
25.11.2019 • 6 minutes to read • Edit Online

Bir komut isteminde yürütülebilir C# dosyasının adını (CSC. exe) yazarak derleyiciyi çağırabilirsiniz.
Visual Studio için geliştirici komut istemi kullanıyorsanız, tüm gerekli ortam değişkenleri sizin için ayarlanır.
Bu araca erişme hakkında daha fazla bilgi için bkz. Visual Studio için geliştirici komut istemi konusu.
Standart bir komut Istemi penceresi kullanıyorsanız, bilgisayarınızdaki herhangi bir alt dizinden CSC. exe ' yi
çağırabilmeniz için önce yolunu ayarlamanız gerekir. Ayrıca, komut satırı yapılarını desteklemek üzere uygun
ortam değişkenlerini ayarlamak için vsvars32. bat dosyasını çalıştırmanız gerekir. Vsvars32. bathakkında daha
fazla bilgi için, bkz. Visual Studio komut satırı için ortam değişkenlerini ayarlama.
Yalnızca Windows yazılım geliştirme seti (SDK) olan bir bilgisayarda çalışıyorsanız, C# Microsoft .NET
Framework SDK menü seçeneğinden açtığınız SDK komut istemindederleyiciyi kullanabilirsiniz.
Ayrıca C# programlarını program aracılığıyla oluşturmak için MSBuild'i kullanabilirsiniz. Daha fazla bilgi için bkz.
MSBuild.
CSC. exe yürütülebilir dosyası genellikle Windows dizini altındaki Microsoft. NET\Framework\ <sürüm >
klasöründedir. Bu dosyanın yeri, belirli bir bilgisayarın tam yapılandırmasına bağlı olarak değişebilir.
Bilgisayarınızda .NET Framework'ün birden fazla sürümü yüklüyse, bu dosyanın birden fazla sürümünü
bulacaksınız. Bu tür yüklemeler hakkında daha fazla bilgi için bkz. nasıl yapılır: hangi .NET Framework
sürümlerinin yüklendiğini belirleme.

TIP
Visual Studio IDE kullanarak bir proje oluşturduğunuzda, CSC komutunu ve ilgili derleyici seçeneklerini Çıkış penceresinde
görüntüleyebilirsiniz. Bu bilgileri görüntülemek için nasıl yapılır: günlük verilerinin ayrıntı düzeyini normal veya
ayrıntılıolarak değiştirmek üzere derleme günlüğü dosyalarını görüntüleme, kaydetme ve yapılandırma konusundaki
yönergeleri izleyin. Projenizi yeniden oluşturduktan sonra, C# derleyicinin çağrılmasını bulmak Için CSC Çıkış penceresinde
arama yapın.

Bu konuda
Komut satırı söz dizimi için kurallar
Örnek komut satırları
Derleyici ve C# C++ derleyici çıkışı arasındaki farklılıklar

C# Derleyici komut satırı sözdizimi için kurallar


C# Derleyici, işletim sistemi komut satırında verilen bağımsız değişkenleri yorumladığı zaman aşağıdaki kuralları
kullanır:
Bağımsız değişkenler boşluk veya sekme olan boşluk ile sınırlandırılmıştır.
Giriş işareti karakteri (^) bir kaçış karakteri veya sınırlayıcı olarak tanınmıyor. Karakter, programdaki argv
dizisine geçirilmeden önce, işletim sistemindeki komut satırı ayrıştırıcısı tarafından işlenir.
Çift tırnak işaretleri ("String") içine alınmış bir dize, içinde yer alan boşluklardan bağımsız olarak tek bir
bağımsız değişken olarak yorumlanır. Tırnak içine alınmış bir dize bir bağımsız değişkene gömülebilir.
Önünde ters eğik çizgi (\") olan çift tırnak işareti, sabit değer çift tırnak işareti karakteri (") olarak
yorumlanır.
Ters eğik çizgiler, bir çift tırnak işaretinden hemen önce gelmedikleri takdirde tam olarak yorumlanır.
İki ters eğik çizgi daha sonra çift tırnak işaretiyle, bir ters eğik çizgi, her ters eğik çizgi çifti için argv dizisine
konur ve çift tırnak işareti bir dize sınırlayıcısı olarak yorumlanır.
Tek bir ters eğik çizgiden sonra çift tırnak işareti varsa, her ters eğik çizgi çiftinin argv dizisine bir ters eğik
çizgi konur ve çift tırnak işareti geri kalan ters eğik çizgi ile "kaçışdır". Bu, argv bir sabit değer çift tırnak
işareti (") eklenmesine neden olur.

C# Derleyici için örnek komut satırları


File.cs üreten dosya. exe' yi derler:

csc File.cs

File.cs üreten dosyayı derler. dll:

csc -target:library File.cs

File.cs derler ve My. exe dosyasınıoluşturur:

csc -out:My.exe File.cs

Geçerli dizindeki tüm C# dosyaları iyileştirmeler etkin olacak şekilde derler ve hata ayıklama sembolünü
tanımlar. Çıktı, dosya2. exe' dir:

csc -define:DEBUG -optimize -out:File2.exe *.cs

Geçerli dizindeki tüm C# dosyaları, dosya2. dll' nin hata ayıklama sürümünü üreten şekilde derler. Amblem
yoktur ve hiçbir uyarı gösterilmez:

csc -target:library -out:File2.dll -warn:0 -nologo -debug *.cs

Geçerli dizindeki tüm C# dosyaları bir. xyz (bir dll) olarak derler:

csc -target:library -out:Something.xyz *.cs

Derleyici ve C# C++ derleyici çıkışı arasındaki farklılıklar


Derleyiciyi çağırma sonucu olarak oluşturulan nesne ( . obj) dosyaları yoktur; C# çıktı dosyaları doğrudan
oluşturulur. Bunun sonucunda, C# derleyicinin bir bağlayıcıya ihtiyacı yoktur.

Ayrıca bkz.
C# Derleyici Seçenekleri
Alfabetik Listelenmiş C# Derleyici Seçenekleri
Kategorilere Göre Listelenen C# Derleyici Seçenekleri
Ana() ve Komut Satırı Bağımsız Değişkenleri
Komut Satırı Bağımsız Değişkenleri
Nasıl yapılır: komut satırı bağımsız değişkenlerini görüntüleme
Ana() Dönüş Değerleri
Visual Studio komut satırı için ortam değişkenlerini
ayarlama
25.11.2019 • 2 minutes to read • Edit Online

VsDevCmd. bat dosyası, komut satırı yapılarını etkinleştirmek için uygun ortam değişkenlerini ayarlar.

NOTE
VsDevCmd. bat dosyası, Visual Studio 2017 ile sunulan yeni bir dosyadır. Visual Studio 2015 ve önceki sürümleri,
VSVARS32. bat ' i aynı amaçla kullandı. Bu dosya \Program Files\Microsoft Visual Studio\Version\Common7\Tools veya
Program Files (x86) \Microsoft Visual Studio\Version\Common7\Tools. ' de depolandı

Visual Studio 'nun geçerli sürümü, Visual Studio 'nun önceki bir sürümüne de sahip olan bir bilgisayarda
yüklüyse, VsDevCmd. bat ve VSVARS32 kullanmamalısınız. Aynı komut Istemi penceresindeki farklı sürümlerden
BAT. Bunun yerine, her sürüm için komutunu kendi penceresinde çalıştırmalısınız.
VsDevCmd. BAT dosyasını çalıştırmak için
1. Başlangıç menüsünde VS 2017 için geliştirici komut istemiaçın. Visual Studio 2017 klasöründedir.
2. Yüklemenizin \Common7\Tools alt dizinini sunan\Common7\Tools veya \Program Files (x86) \Microsoft
Visual Studio\Sürüm\sunan\Program Files\Microsoft Visual Studio\\sürümüne geçin. (Sürüm , geçerli
sürüm için 2017 . Teklif , Enterprise, Professional veya Community'den biridir.)
3. Vsdevcmd. bat dosyasını vsdevcmdyazarak çalıştırın.
Cau t i on

VsDevCmd. bat bilgisayardan bilgisayara farklılık gösterebilir. Eksik veya hasarlı bir VsDevCmd. bat
dosyasını başka bir bilgisayardan VsDevCmd. bat ile değiştirmeyin. Bunun yerine, eksik dosyayı yerine
koymak için kurulumu yeniden çalıştırın.
VsDevCmd. BAT için kullanılabilir seçenekler
VsDevCmd. BAT için kullanılabilir seçenekleri görmek için, -help seçeneğiyle komutunu çalıştırın:

VsDevCmd.bat -help

Ayrıca bkz.
csc.exe Kullanarak Komut Satırı Derleme
Kategorilere Göre Listelenen C# Derleyici Seçenekleri
25.11.2019 • 6 minutes to read • Edit Online

Aşağıdaki derleyici seçenekleri kategoriye göre sıralanır. Alfabetik bir liste için bkz C# . alfabetik olarak listelenen
derleyici seçenekleri.

İyileştirme
SEÇENEK AMAÇ

-filealign Çıkış dosyasındaki bölümlerin boyutunu belirtir.

-optimize İyileştirmeleri etkinleştirilir/devre dışı bırakır.

Çıkış dosyaları
SEÇENEK AMAÇ

-deterministic Girişlerin özdeş olması halinde, derleyicinin ikili içerik özdeş


olan bir derlemeyi çıkış yapmasına neden olur.

-doc İşlenen belge yorumlarının yazılacağı bir XML dosyası belirtir.

-out Çıkış dosyasını belirtir.

-pathmap Derleyici tarafından çıkış kaynak yolu adları için bir eşleme
belirtin

-pdb Dosya adını ve. pdb dosyasının konumunu belirtir.

-platform Çıkış platformunu belirtin.

-preferreduilang Derleyici çıkışı için bir dil belirtin.

-refout Birincil derlemeye ek olarak bir başvuru bütünleştirilmiş kodu


oluşturun.

-refonly Birincil derleme yerine bir başvuru bütünleştirilmiş kodu


oluşturun.

-target Şu beş seçenekten birini kullanarak çıkış dosyasının biçimini


belirtir: -target: appcontainerexe, -target: exe, -target: Library,
-target: Module, -target: winexeveya -target: winmdobj.

-ModuleName:<String > Kaynak modülünün adını belirtin

.NET Framework derlemeleri


SEÇENEK AMAÇ

-addmodule Bu derlemenin parçası olacak bir veya daha fazla modül


belirtir.

-delaysign Derleyiciye ortak anahtar eklemesini, ancak derlemeyi işaretsiz


olarak bırakmasını söyler.

-keycontainer Şifreleme anahtarı kapsayıcısının adını belirtir.

-keyfile Şifreleme anahtarını içeren dosya adını belirtir.

-lib Başvuruaracılığıyla başvurulan derlemelerin konumunu belirtir.

-nostdlib Derleyiciye standart kitaplığı (mscorlib. dll) içeri aktarmamasını


söyler.

-publicsign Derlemeyi imzalamadan ortak anahtar uygulayın, ancak


derlemenin imzalandığını belirten derlemede bit ayarlayın.

-reference Derleme içeren bir dosyadan meta verileri içeri aktarır.

-çözümleyici Bu derlemeden çözümleyiciler çalıştırın (kısa biçim:/a)

-additionalfile Kod oluşturmayı doğrudan etkilemeyen, ancak hata veya


uyarı üretmek için çözümleyiciler tarafından kullanılabilen ek
dosyaları adlandırır.

-katıştır Tüm kaynak dosyalarını PDB 'ye ekleyin.

-Embed:<dosya listesi > PDB 'ye belirli dosyaları ekleyin.

Hata ayıklama/hata denetimi


SEÇENEK AMAÇ

-bugreport Bir hatayı rapor etmelerini kolaylaştıran bilgiler içeren bir


dosya oluşturur.

-checked Veri türü sınırlarının dışına taşan tamsayı aritmetiğinin çalışma


zamanında bir özel duruma neden olup olmayacağını belirtir.

-debug Derleyiciye hata ayıklama bilgilerini yaymasını bildirin.

-errorreport Hata raporlama davranışını ayarlar.

-fullpaths Derleyici çıkışında dosyanın mutlak yolunu belirtir.

-nowarn Derleyicinin belirtilen uyarıların oluşturulmasını engeller.

-warn Uyarı düzeyini ayarlar.

-warnaserror Hatalara yönelik uyarıları yükseltir.


SEÇENEK AMAÇ

-RuleSet:<Dosya > Belirli tanılamayı devre dışı bırakan bir RuleSet dosyası belirtin.

Ön işlemci
SEÇENEK AMAÇ

-define Önişlemci sembolleri tanımlar.

Kaynaklar
SEÇENEK AMAÇ

-link Belirtilen derlemelerdeki COM türü bilgilerini proje için


kullanılabilir hale getirir.

-linkresource Yönetilen bir kaynağa bir bağlantı oluşturur.

-resource Bir .NET Framework kaynağını çıkış dosyasına katıştırır.

-win32icon Çıktı dosyasına eklenecek bir. ico dosyasını belirtir.

-win32res Çıktı dosyasına eklenecek bir Win32 kaynağı belirtir.

Çeşitli
SEÇENEK AMAÇ

@ Bir yanıt dosyası belirtir.

-? Stdout için derleyici seçeneklerini listeler.

-baseaddress DLL 'nin yükleneceği tercih edilen temel adresi belirtir.

-codepage Derlemedeki tüm kaynak kodu dosyaları için kullanılacak kod


sayfasını belirtir.

-yardım Stdout için derleyici seçeneklerini listeler.

-highentropyva Yürütülebilir dosyanın adres alanı düzeni rastgele seçme


(ASLR) öğesini desteklediğini belirtir.

-langversion Dil sürümünü belirtin: varsayılan, ISO-1, ISO-2, 3, 4, 5, 6, 7,


7,1, 7,2, 7,3 veya en son

-main Main yönteminin konumunu belirtir.

-noconfig Derleyicinin Csc. rsp ile derlenmeyeceğini söyler.

-nologo Derleyici başlık bilgilerini gizler.


SEÇENEK AMAÇ

-recurse Kaynak dosyaları derlemek için alt dizinleri arar.

-subsystemversion Yürütülebilir dosyanın kullanabileceği alt sistemin en düşük


sürümünü belirtir.

-unsafe Unsafe anahtar sözcüğünü kullanan kodun derlemesini sunar.

-utf8output UTF-8 kodlamasını kullanarak derleyici çıkışını görüntüler.

-Parallel [+|-] Eşzamanlı yapı (+) kullanılıp kullanılmayacağını belirtir.

-checksumalgorithm:<alg > PDB 'de depolanan kaynak dosyası sağlama toplamını


hesaplamak için algoritmayı belirtin. Desteklenen değerler
şunlardır: SHA1 (varsayılan) veya SHA256.
SHA1 ile ilgili çakışma sorunları nedeniyle Microsoft SHA256
önerir.

Eski seçenekler
SEÇENEK AMAÇ

-artımlı Artımlı derlemeyi etkinleştirilir.

Ayrıca bkz.
C# Derleyici Seçenekleri
Alfabetik Listelenmiş C# Derleyici Seçenekleri
Visual Studio komut satırı için ortam değişkenlerini ayarlama
Alfabetik Listelenmiş C# Derleyici Seçenekleri
25.11.2019 • 6 minutes to read • Edit Online

Aşağıdaki derleyici seçenekleri alfabetik olarak sıralanır. Kategorik bir liste için, bkz C# . kategoriye göre listelenen
derleyici seçenekleri.

SEÇENEK AMAÇ

@ Daha fazla seçenek için bir yanıt dosyası okur.

-? Stdout için bir kullanım iletisi görüntüler.

-additionalfile Kod oluşturmayı doğrudan etkilemeyen, ancak hata veya


uyarı üretmek için çözümleyiciler tarafından kullanılabilen ek
dosyaları adlandırır.

-addmodule Belirtilen modülleri bu derlemeye bağlar

-çözümleyici Bu derlemeden çözümleyiciler çalıştırın (kısa biçim:-a)

-appconfig Derleme bağlama zamanında app. config dosyasının


konumunu belirtir.

-baseaddress Oluşturulacak kitaplığın temel adresini belirtir.

-bugreport ' Hata raporu ' dosyası oluşturur. Bu dosya,-errorreport:


Prompt veya-errorreport: Send ile kullanılırsa tüm kilitlenme
bilgileriyle birlikte gönderilir.

-checked Derleyicinin taşma denetimleri oluşturmasına neden olur.

-checksumalgorithm:<alg > PDB 'de depolanan kaynak dosyası sağlama toplamını


hesaplamak için algoritmayı belirtir. Desteklenen değerler
şunlardır: SHA256 (varsayılan) veya SHA1.
SHA1 ile ilgili çakışma sorunları nedeniyle Microsoft SHA256
önerir.

-codepage Kaynak dosyalar açılırken kullanılacak kod sayfasını belirtir.

-debug Hata ayıklama bilgilerini yayar.

-define Koşullu derleme sembollerini tanımlar.

-delaysign Derlemeyi yalnızca tanımlayıcı ad anahtarının ortak kısmını


kullanarak imzalar.

-deterministic Girişlerin özdeş olması halinde, derleyicinin ikili içerik özdeş


olan bir derlemeyi çıkış yapmasına neden olur.

-doc Oluşturulacak XML belge dosyasını belirtir.


SEÇENEK AMAÇ

-katıştır Tüm kaynak dosyalarını PDB 'ye ekleyin.

-Embed:<dosya listesi > PDB 'ye belirli dosyaları ekleyin.

-errorendlocation Her hatanın bitiş konumunun çıkış satırı ve sütunu.

-hata günlüğü:<Dosya > Tüm derleyici ve çözümleyici tanılamayı günlüğe kaydetmek


için bir dosya belirtin.

-errorreport İç derleyici hatalarının nasıl işleneceğini belirtir: Prompt, Send


veya None. Varsayılan değer None ' dır.

-filealign Çıkış dosyası bölümleri için kullanılan hizalamayı belirtir.

-fullpaths Derleyicinin tam olarak nitelenmiş yollar oluşturmasına neden


olur.

-yardım Stdout için bir kullanım iletisi görüntüler.

-highentropyva Yüksek entropi ASLR desteklendiğini belirtir.

-artımlı Artımlı derlemeyi [eski] izin vermez.

-keycontainer Bir tanımlayıcı ad anahtar kapsayıcısı belirtir.

-keyfile Tanımlayıcı ad anahtar dosyasını belirtir.

-langversion:<dize > Dil sürümünü belirtin: varsayılan, ISO-1, ISO-2, 3, 4, 5, 6, 7,


7,1, 7,2, 7,3 veya en son

-lib Başvuruların aranacağı ek dizinleri belirtir.

-link Belirtilen derlemelerdeki COM türü bilgilerini proje için


kullanılabilir hale getirir.

-linkresource Belirtilen kaynağı bu derlemeye bağlar.

-main Giriş noktasını içeren türü belirtir (diğer tüm olası giriş
noktalarını yoksayın).

-moduleassemblyname Genel olmayan türleri bir. netmodule 'nin erişebileceği bir


derlemeyi belirtir.

-ModuleName:<String > Kaynak modülünün adını belirtin

-noconfig Derleyiciye CSC 'yi otomatik olarak eklemesi talimatını verir.


RSP dosyası.

-nologo Derleyici telif hakkı iletisini bastırır.

-nostdlib Derleyiciye standart kitaplığa (mscorlib. dll) Başvurmamasını


söyler.
SEÇENEK AMAÇ

-nowarn Belirli uyarı iletilerini devre dışı bırakır

-nowin32manifest Derleyicinin yürütülebilir dosyaya bir uygulama bildirimi


katıştırmamasını sağlar.

-optimize İyileştirmeleri etkinleştirilir/devre dışı bırakır.

-out Çıkış dosyası adını belirtir (varsayılan: Ana sınıf veya ilk dosya
ile dosyanın temel adı).

-Parallel [+|-] Eşzamanlı yapı (+) kullanılıp kullanılmayacağını belirtir.

-pathmap Derleyici tarafından çıkış kaynak yolu adları için bir eşleme
belirtir.

-pdb Dosya adını ve. pdb dosyasının konumunu belirtir.

-platform Bu kodun çalıştırılabileceği platformları sınırlar: x86, Itanium,


x64, anycpu veya anycpu32bitpreferred. Varsayılan değer
anycpu ' dır.

-preferreduilang Derleyici çıktısı için kullanılacak dili belirtir.

-publicsign Derlemeyi imzalamadan ortak anahtar uygulayın, ancak


derlemenin imzalandığını belirten derlemede bit ayarlayın.

-recurse Joker karakter belirtimlerine göre geçerli dizindeki ve alt


dizinlerdeki tüm dosyaları içerir.

-reference Belirtilen derleme dosyalarından meta verilere başvurur.

-refout Birincil derlemeye ek olarak bir başvuru bütünleştirilmiş kodu


oluşturun.

-refonly Birincil derleme yerine bir başvuru bütünleştirilmiş kodu


oluşturun.

-reportanalyzer Yürütme süresi gibi ek çözümleyici bilgilerini bildirin.

-resource Belirtilen kaynağı katıştırır.

-RuleSet:<Dosya > Belirli tanılamayı devre dışı bırakan bir RuleSet dosyası belirtin.

-subsystemversion Yürütülebilir dosyanın kullanabileceği alt sistemin en düşük


sürümünü belirtir.

-target Dört seçenekten birini kullanarak çıkış dosyasının biçimini


belirtir: -target: appcontainerexe, -target: exe, -target: Library,
-target: Module, -target: winexe, -target: winmdobj.

-unsafe Güvenli olmayan koda izin verir.


SEÇENEK AMAÇ

-utf8output Derleyici iletilerini UTF-8 kodlamasında çıkarır.

-sürüm Derleyici sürüm numarasını ve çıkışı görüntüleyin.

-warn Uyarı düzeyini (0-4) ayarlar.

-warnaserror Belirli uyarıları hata olarak raporlar.

-win32icon Çıkış için bu simgeyi kullanır.

-win32manifest Özel bir Win32 bildirim dosyası belirtir.

-win32res Win32 kaynak dosyasını (. res) belirtir.

Ayrıca bkz.
C# Derleyici Seçenekleri
Kategorilere Göre Listelenen C# Derleyici Seçenekleri
Visual Studio komut satırı için ortam değişkenlerini ayarlama
<derleyici > öğesi
@ (C# Derleyici Seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

@ Seçeneği, derlemek için derleyici seçeneklerini ve kaynak kodu dosyalarını içeren bir dosya belirtmenizi sağlar.

Sözdizimi
@response_file

Arguments
response_file
Derlemek için derleyici seçeneklerini veya kaynak kodu dosyalarını listeleyen bir dosya.

Açıklamalar
Derleyici seçenekleri ve kaynak kodu dosyaları, derleyici tarafından, tıpkı komut satırında belirtildikleri gibi
işlenecek şekilde işlenir.
Bir derlemede birden fazla yanıt dosyası belirtmek için, birden çok yanıt dosyası seçeneği belirtin. Örneğin:

@file1.rsp @file2.rsp

Bir yanıt dosyasında, bir satırda birden çok derleyici seçeneği ve kaynak kodu dosyası görünebilir. Tek bir derleyici
seçenek belirtiminin tek bir satırda görünmesi gerekir (birden çok satıra yayılamaz). Yanıt dosyaları # simgesiyle
başlayan açıklamalara sahip olabilir.
Bir yanıt dosyası içinden derleyici seçeneklerinin belirtilmesi, komut satırında bu komutları verme gibidir. Daha
fazla bilgi için bkz. komut satırından oluşturma .
Derleyici komut seçeneklerini karşılaştığı şekilde işler. Bu nedenle, komut satırı bağımsız değişkenleri yanıt
dosyalarındaki daha önce listelenen seçenekleri geçersiz kılabilir. Buna karşılık, bir yanıt dosyasındaki seçenekler,
önceden komut satırında veya diğer yanıt dosyalarında listelenen seçenekleri geçersiz kılar.
C#csc. exe dosyası ile aynı dizinde bulunan CSC. rsp dosyasını sağlar. Csc. rsp hakkında daha fazla bilgi için bkz. -
noconfig .
Bu derleyici seçeneği Visual Studio geliştirme ortamında ayarlanamaz veya program aracılığıyla değiştirilemez.

Örnek
Örnek yanıt dosyasından birkaç satır aşağıda verilmiştir:

# build the first output file


-target:exe -out:MyExe.exe source1.cs source2.cs

Ayrıca bkz.
C# Derleyici Seçenekleri
-addmodule (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

Bu seçenek, target: Module anahtarı geçerli derlemeye ile oluşturulmuş bir modül ekler.

Sözdizimi
-addmodule:file[;file2]

Arguments
file , file2
Meta veri içeren bir çıkış dosyası. Dosya, bütünleştirilmiş kod bildirimi içeremez. Birden fazla dosyayı içeri
aktarmak için, dosya adlarını virgülle veya noktalı virgülle ayırın.

Açıklamalar
-Addmodule ile eklenen tüm modüller, çalışma zamanında çıkış dosyası ile aynı dizinde olmalıdır. Diğer bir
deyişle, derleme zamanında herhangi bir dizinde bir modül belirtebilirsiniz, ancak modülün çalışma zamanında
uygulama dizininde olması gerekir. Modül, çalışma zamanında uygulama dizininde değilse, bir
TypeLoadExceptionalırsınız.
filebütünleştirilmiş kod içeremez. Örneğin, çıkış dosyası -target: Moduleile oluşturulduysa, meta verileri -
addmoduleile içeri aktarılabilir.
Çıkış dosyası -target: Moduledışında bir -target seçeneği ile oluşturulduysa, meta verileri -addmodule ile içeri
aktarılamaz ancak -Referenceile içeri aktarılabilir.
Bu derleyici seçeneği Visual Studio 'da kullanılamaz; bir proje bir modüle başvuramaz. Ayrıca, bu derleyici
seçeneği program aracılığıyla değiştirilemez.

Örnek
Kaynak dosyasını input.cs derleyin, ve ' metad1.netmodule metad2.netmodule dan meta verileri ekleyin out.exe :

csc -addmodule:metad1.netmodule;metad2.netmodule -out:out.exe input.cs

Ayrıca bkz.
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
Çok Dosyalı Bütünleştirilmiş Kodlar
Nasıl yapılır: Çoklu dosya derlemesi oluşturma
-appconfig (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

-Appconfig derleyici seçeneği, bir C# uygulamanın derlemenin uygulama yapılandırma (App. config) dosyasının
konumunu derleme bağlama sırasında ortak DIL çalışma zamanı (CLR ) olarak belirtmesini sağlar.

Sözdizimi
-appconfig:file

Arguments
file
Gerekli. Derleme bağlama ayarlarını içeren uygulama yapılandırma dosyası.

Açıklamalar
Tek appconfig 'in kullanımı, bir derlemenin hem .NET Framework sürümüne hem de aynı anda belirli bir başvuru
derlemesinin Silverlight sürümüne .NET Framework başvurması gereken gelişmiş senaryolardır. Örneğin,
Windows Presentation Foundation (WPF ) içinde yazılmış bir XAML tasarımcısının, tasarımcı 'nın Kullanıcı
arabirimi için hem WPF masaüstüne hem de Silverlight 'ın içerdiği WPF 'nin alt kümesine başvurması gerekebilir.
Aynı tasarımcı derlemesinin her iki derlemeye de erişimi vardır. Varsayılan olarak, derleme bağlaması iki derlemeyi
eşdeğer olarak gördüğü için ayrı başvurular bir derleyici hatasına neden olur.
-Appconfig derleyici seçeneği, aşağıdaki örnekte gösterildiği gibi bir <supportPortability> etiketi kullanarak
varsayılan davranışı devre dışı bırakan bir App. config dosyasının konumunu belirtmenize olanak sağlar.
<supportPortability PKT="7cec85d7bea7798e" enable="false"/>

Derleyici, dosyanın konumunu CLR 'nin derleme bağlama mantığına geçirir.

NOTE
Uygulamanızı derlemek için Microsoft Build Engine (MSBuild) kullanıyorsanız,. csproj dosyasına bir özellik etiketi ekleyerek -
appconfig derleyici seçeneğini belirleyebilirsiniz. Projede zaten ayarlanmış olan App. config dosyasını kullanmak için,. csproj
dosyasına özellik etiketi <UseAppConfigForCompiler> ekleyin ve değerini olarak true ayarlayın. Farklı bir App. config
dosyası belirtmek için, özellik etiketi <AppConfigForCompiler> ekleyin ve değerini dosyanın konumuna ayarlayın.

Örnek
Aşağıdaki örnek, bir uygulamanın hem .NET Framework uygulamasına hem de her iki uygulamada bulunan
herhangi bir .NET Framework derlemesinin Silverlight uygulamasına .NET Framework başvurularına sahip
olmasını sağlayan bir App. config dosyası gösterir. -Appconfig derleyici seçeneği bu app. config dosyasının
konumunu belirtir.
<configuration>
<runtime>
<assemblyBinding>
<supportPortability PKT="7cec85d7bea7798e" enable="false"/>
<supportPortability PKT="31bf3856ad364e35" enable="false"/>
</assemblyBinding>
</runtime>
</configuration>

Ayrıca bkz.
<Supporttaşınabilirlik > öğesi
Alfabetik Listelenmiş C# Derleyici Seçenekleri
-BaseAddress (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

-BaseAddress SEÇENEĞI, dll 'nin yükleneceği tercih edilen temel adresi belirtmenizi sağlar. Bu seçeneğin ne
zaman ve neden kullanıldığı hakkında daha fazla bilgi için bkz. Larry Osterman 'ın Web günlüğü.

Sözdizimi
-baseaddress:address

Arguments
address
DLL 'nin temel adresi. Bu adres ondalık, onaltılık veya sekizlik sayı olarak belirtilebilir.

Açıklamalar
Bir DLL için varsayılan temel adres .NET Framework ortak dil çalışma zamanı tarafından ayarlanır.
Bu adresteki alt sıra sözcüğünün yuvarlanacağını unutmayın. Örneğin, 0x11110001 belirtirseniz, 0x11110000 ' ya
yuvarlanır.
DLL imzalama işlemini gerçekleştirmek için SN 'yi kullanın. EXE ' yi-R seçeneğiyle birlikte.
Bu derleyici seçeneğini Visual Studio geliştirme ortamında ayarlamak için
1. Projenin Özellikler sayfasını açın.
2. Yapı özelliği sayfasına tıklayın.
3. Gelişmiş düğmesine tıklayın.
4. Dll taban adresi özelliğini değiştirin.
Bu derleyici seçeneğini program aracılığıyla ayarlamak için, BaseAddressbkz.

Ayrıca bkz.
ProcessModule.BaseAddress
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-bugreport (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

Hata ayıklama bilgilerinin daha sonra analiz edilmek üzere bir dosyaya yerleştirilmesi gerektiğini belirtir.

Sözdizimi
-bugreport:file

Arguments
file
Hata raporunuzu içermesini istediğiniz dosyanın adı.

Açıklamalar
-Bugreport seçeneği aşağıdaki bilgilerin yerleştirilmesi file gerektiğini belirtir:
Derlemedeki tüm kaynak kodu dosyalarının bir kopyası.
Derlemede kullanılan derleyici seçeneklerinin bir listesi.
Derleyici, çalışma zamanı ve işletim sistemi ile ilgili sürüm bilgileri.
Başvurulan derlemeler ve modüller, .NET Framework ve SDK ile birlikte gelen derlemeler hariç, onaltılık
basamaklar olarak kaydedilir.
Varsa derleyici çıkışı.
Probleme için sizden sorulacak bir açıklama.
Sorunun düzeltilmesi hakkında bir açıklama ve sizden istenir.
Bu seçenek -errorreport: Prompt veya -errorreport: Sendile kullanılırsa, dosyadaki bilgiler Microsoft
Corporation 'a gönderilir.
Tüm kaynak kodu dosyalarının bir kopyası içine file yerleştirilecek, olası en kısa programda şüpheli kod hatasını
yeniden oluşturmak isteyebilirsiniz.
Bu derleyici seçeneği Visual Studio 'da kullanılamaz ve program aracılığıyla değiştirilemez.
Oluşturulan dosyanın içeriğinin, yanlışlıkla bilginin açığa çıkmasına neden olabilecek kaynak kodu kullanıma
sunduğuna dikkat edin.

Ayrıca bkz.
C# Derleyici Seçenekleri
-errorreport (C# derleyici seçenekleri)
Proje ve Çözüm Özelliklerini Yönetme
-Checked (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

-Checked seçeneği, veri türü aralığının dışında olan ve denetlenen veya işaretlenmemiş bir anahtar sözcüğünün
kapsamında olmayan bir değer ile sonuçlanan bir tamsayı aritmetik ifadesinin bir çalışma zamanı özel durumuna
neden olup olmadığını belirtir.

Sözdizimi
-checked[+ | -]

Açıklamalar
checked Or unchecked anahtar sözcüğünün kapsamındaki bir tamsayı aritmetik bildirim, -Checked seçeneğinin
etkisine tabi değildir.
checked Or unchecked anahtar sözcüğünün kapsamında olmayan bir tamsayı aritmetik ifade, veri türü aralığı
dışında bir değer ile sonuçlanır ve -Checked + (veya -Checked) derlemede kullanılırsa, bu ifade bir çalışma
zamanında özel durum. -Checked- derlemede kullanılırsa, bu ifade çalışma zamanında bir özel duruma neden
olmaz.
Bu seçenek için varsayılan değer -denetlenir- ; taşma denetimi devre dışı.
Bazen, büyük uygulamalar oluşturmak için kullanılan otomatikleştirilmiş araçlar + ' a ayarlanır. ' In kullanılmasına
yönelik bir senaryo,-Checked-belirterek aracın genel varsayılanını geçersiz kılmalıdır.
Bu derleyici seçeneğini Visual Studio geliştirme ortamında ayarlamak için
1. Projenin Özellikler sayfasını açın. Daha fazla bilgi için bkz. derleme sayfası, proje TasarımcısıC#().
2. Yapı özelliği sayfasına tıklayın.
3. Gelişmiş düğmesine tıklayın.
4. Aritmetik taşma/yetersiz yer özelliğinin denetimini değiştirin.
Bu derleyici seçeneğine program aracılığıyla erişmek için bkz CheckForOverflowUnderflow.

Örnek
Aşağıdaki komut derlenir t2.cs . Komutunda öğesinin -checked kullanımı, bir checked veya unchecked anahtar
sözcüğünün kapsamında olmayan dosyada herhangi bir tamsayı aritmetik deyimin olduğunu ve veri türü
aralığının dışında bir değer oluşmasına neden olduğunu belirtir ışınızda.

csc t2.cs -checked

Ayrıca bkz.
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-CodePage (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

Bu seçenek, gerekli sayfa sistem için geçerli varsayılan kod sayfası değilse, derleme sırasında kullanılacak kod
sayfasını belirtir.

Sözdizimi
-codepage:id

Arguments
id
Derlemedeki tüm kaynak kodu dosyaları için kullanılacak kod sayfasının kimliği.

Açıklamalar
Derleyici önce tüm kaynak dosyalarını UTF -8 olarak yorumlamaya çalışacaktır. Kaynak kodu dosyalarınız UTF -8
dışındaki bir kodlamadeyse ve 7 bit ASCII karakterlerden farklı karakterler kullanıyorsa, hangi kod sayfasının
kullanılacağını belirtmek için -CodePage seçeneğini kullanın. -CodePage , derinizdeki tüm kaynak kodu dosyaları
için geçerlidir.
Sisteminizde hangi kod sayfalarının desteklendiğini bulma hakkında bilgi için bkz. Getcpınfo .
Bu derleyici seçeneği Visual Studio 'da kullanılamaz ve program aracılığıyla değiştirilemez.

Ayrıca bkz.
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-Debug (C# derleyici seçenekleri)
23.10.2019 • 3 minutes to read • Edit Online

-Debug seçeneği derleyicinin hata ayıklama bilgileri oluşturmasına ve bunu çıkış dosyasına veya dosyalarına
yerleştirmesine neden olur.

Sözdizimi
-debug[+ | -]
-debug:{full | pdbonly}

Arguments
+ | -
Veya + yalnızca hata ayıklamabelirtildiğinde, derleyicinin hata ayıklama bilgileri oluşturmasına ve bir program
veritabanına (. pdb dosyası) yerleştirmesine neden olur. - Hata ayıklamabelirtmezseniz, etkin olan ve hata
ayıklama bilgilerinin oluşturulmasına neden olan öğesini belirtme.
full | pdbonly
Derleyici tarafından oluşturulan hata ayıklama bilgilerinin türünü belirtir. -Debug: pdbonlybelirtmezseniz geçerli
olan tam bağımsız değişken, çalışan programa hata ayıklayıcı iliştirmeyi sağlar. Yalnızca program hata ayıklayıcıda
başlatıldığında, pdbyalnızca kaynak kodu hata ayıklamasına izin verir, ancak çalışan program hata ayıklayıcıya
eklendiğinde yalnızca assembler görüntülenir.

Açıklamalar
Hata ayıklama derlemeleri oluşturmak için bu seçeneği kullanın. - Debug, -Debug + veya -Debug: Full
belirtilmemişse, programınızın çıkış dosyasında hata ayıklayamazsınız.
-Debug: FullKULLANıRSANıZ, JIT ile iyileştirilmiş kodun hız ve boyutunu ve -Debug: Fullile kod kalitesiyle ilgili
küçük bir etkisi olduğunu unutmayın. Hata ayıklamanızı öneririz: yalnızca pdbonly veya sürüm kodu
oluşturmak için pdb yok.

NOTE
-Debug: pdbonly ve -Debug: Full arasında bir farklılık vardır -hata ayıklama: Full derleyici, JIT derleyicisine
DebuggableAttributehata ayıklama bilgilerinin kullanılabilir olduğunu bildirmek için kullanılan bir yayar. Bu nedenle,
DebuggableAttribute -Debug: Fullkullanırsanız kodunuz false olarak ayarla ' yı içeriyorsa bir hata alırsınız.

Bir uygulamanın hata ayıklama performansını yapılandırma hakkında daha fazla bilgi için bkz. bir görüntüyü hata
ayıklamayı kolaylaştırın.
. Pdb dosyasının konumunu değiştirmek için, bkz: -pdb (C# derleyici seçenekleri).
Bu derleyici seçeneğini Visual Studio geliştirme ortamında ayarlamak için
1. Projenin Özellikler sayfasını açın.
2. Yapı özelliği sayfasına tıklayın.
3. Gelişmiş düğmesine tıklayın.
4. Hata ayıklama bilgisi özelliğini değiştirin.
Bu derleyici seçeneğini program aracılığıyla ayarlama hakkında daha fazla bilgi için bkz DebugSymbols.

Örnek
Hata ayıklama bilgilerini çıkış dosyasına app.pdb Yerleştir:

csc -debug -pdb:app.pdb test.cs

Ayrıca bkz.
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-define (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

-Define seçeneği, programınızın name tüm kaynak kodu dosyalarında sembol olarak tanımlar.

Sözdizimi
-define:name[;name2]

Arguments
name , name2
Tanımlamak istediğiniz bir veya daha fazla sembolün adı.

Açıklamalar
-Define seçeneği, derleme seçeneğinin projedeki tüm dosyalar için geçerli olması dışında, #define Önişlemci
yönergesinin kullanılmasıyla aynı etkiye sahiptir. Kaynak dosyadaki bir #undef yönergesi tanımı kaldırana kadar
bir sembol kaynak dosyasında tanımlı kalır. -Define seçeneğini kullandığınızda, bir dosyadaki bir #undef
yönergenin projedeki diğer kaynak kodu dosyaları üzerinde hiçbir etkisi olmaz.
Kaynak dosyaları koşullu olarak derlemek için bu seçenek tarafından oluşturulan sembolleri #if, #else, #elifve
#endif kullanabilirsiniz.
-d , -defineöğesinin kısa biçimidir.
Sembol adlarını ayırmak için noktalı virgül veya virgül kullanarak, -define ile birden çok sembol
tanımlayabilirsiniz. Örneğin:

-define:DEBUG;TUESDAY

Derleyici C# , kaynak kodunuzda kullanabileceğiniz hiçbir sembol veya makroyu tanımlar; Tüm sembol
tanımlarının Kullanıcı tanımlı olması gerekir.

NOTE
C# , #define Bir simgeye, gibi dillerde bir değer verilmesini izin vermez C++. Örneğin, #define bir makro oluşturmak
veya bir sabit tanımlamak için kullanılamaz. Bir sabit tanımlamanız gerekiyorsa, bir enum değişken kullanın. Bir C++ stil
makrosu oluşturmak isterseniz, genel türler gibi alternatifleri göz önünde bulundurun. Makrolar önemli bir hataya açık
olmadığından, kullanmalarına izin vermez C# , ancak daha güvenli alternatifler sağlar.

Bu derleyici seçeneğini Visual Studio geliştirme ortamında ayarlamak için


1. Projenin Özellikler sayfasını açın.
2. Derleme sekmesinde, koşullu derleme sembolleri kutusunda tanımlanacak simgeyi yazın. Örneğin,
aşağıdaki kod örneğini kullanıyorsanız, metin kutusuna yazmanız xx yeterlidir.

Bu derleyici seçeneğini program aracılığıyla ayarlama hakkında daha fazla bilgi için bkz DefineConstants.
Örnek
// preprocessor_define.cs
// compile with: -define:xx
// or uncomment the next line
// #define xx
using System;
public class Test
{
public static void Main()
{
#if (xx)
Console.WriteLine("xx defined");
#else
Console.WriteLine("xx not defined");
#endif
}
}

Ayrıca bkz.
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-delaysign (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

Bu seçenek derleyicinin çıkış dosyasında alan ayırmasını sağlayarak bir dijital imzanın daha sonra eklenebilmesini
sağlar.

Sözdizimi
-delaysign[ + | - ]

Arguments
+ | -

Tam olarak imzalanan bir derlemeyi istiyorsanız -delaysign- kullanın. Yalnızca ortak anahtarı derlemeye
yerleştirmek istiyorsanız -delaysign + kullanın. Varsayılan değer -delaysign- .

Açıklamalar
- Keyfile veya -keycontainerile kullanılmamışsa -delaysign seçeneğinin hiçbir etkisi yoktur.
-Delaysign ve -publicsign seçenekleri birbirini dışlıyor.
Tam olarak imzalanan bir derleme istediğinizde, derleyici bildirimi içeren dosyayı (derleme meta verileri) karma
hale getirir ve bu karmayı özel anahtarla imzalar. Bu işlem, bildirimi içeren dosyada depolanan bir dijital imza
oluşturur. Bir derlemenin gecikmesi gecikmeli kaydolduğunda, derleyici imzayı hesaplamaz ve depolamaz, ancak
imzanın daha sonra eklenebilmesi için dosyada alanı ayırır.
Örneğin, -delaysign + kullanılması, bir sınayıcı 'ın derlemeyi genel önbellekte almasına izin verir. Test ettikten
sonra, derleme bağlayıcı yardımcı programını kullanarak özel anahtarı derlemeye yerleştirerek derlemeyi
tamamen imzalayabilirsiniz.
Daha fazla bilgi için bkz. güçlü adlandırılmış derlemeler oluşturma ve kullanma ve bir derlemeyi imzalamayı
geciktirme.
Bu derleyici seçeneğini Visual Studio geliştirme ortamında ayarlamak için
1. Projenin Özellikler sayfasını açın.
2. Yalnızca gecikmeli imzala özelliğini değiştirin.
Bu derleyici seçeneğini program aracılığıyla ayarlama hakkında daha fazla bilgi için bkz DelaySign.

Ayrıca bkz.
C#-publicsign seçeneği
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-deterministic
4.11.2019 • 2 minutes to read • Edit Online

Derleyicinin bayt çıkışı, aynı girişlerin derlemeleri arasında özdeş olan bir derleme üretmesine neden olur.

Sözdizimi
-deterministic

Açıklamalar
Varsayılan olarak, belirli bir giriş kümesinden Derleyici çıktısı benzersizdir, çünkü derleyici bir zaman damgası ve
rastgele sayıdan oluşturulan bir GUID ekliyor. Değer aynı kaldığı sürece, bir belirleyici derlemeoluşturmak için
-deterministic seçeneğini kullanın.

Derleyici, belirlemeleri için aşağıdaki girişleri dikkate alır:


Komut satırı parametrelerinin sırası.
Derleyicinin. rsp yanıt dosyasının içeriği.
Kullanılan derleyicinin kesin sürümü ve başvurulan derlemeleri.
Geçerli dizin yolu.
Açıkça derleyiciye doğrudan veya dolaylı olarak geçirilen tüm dosyaların ikili içeriği:
Kaynak dosyalar
Başvurulan derlemeler
Başvurulan modüller
Kaynaklar
Tanımlayıcı ad anahtar dosyası
@ Yanıt dosyaları
Çözümleyiciler
RuleSets
Çözümleyiciler tarafından kullanılabilecek ek dosyalar
Geçerli kültür (tanılama ve özel durum iletilerinin oluşturulduğu dil için).
Kodlama belirtilmemişse, varsayılan kodlama (veya geçerli kod sayfası).
Derleyicinin arama yollarındaki dosyaların varlığı, var olmayan ve içeriği (örneğin, -lib veya -recurse
tarafından).
Derleyicinin çalıştırıldığı CLR platformu.
%LIBPATH% değeri, çözümleyici bağımlılığını yüklemeyi etkileyebilecek.

Kaynaklar herkese açık olduğunda, bir ikilinin güvenilir bir kaynaktan derlenip derlenmediğini oluşturmak için
belirleyici derleme kullanılabilir. Ayrıca, bir ikiliye yapılan değişikliklere bağımlı derleme adımlarının yürütülmesi
gerekip gerekmediğini belirlemek için sürekli bir derleme sisteminde de yararlı olabilir.

Ayrıca bkz.
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-Doc (C# derleyici seçenekleri)
4.11.2019 • 2 minutes to read • Edit Online

-Doc seçeneği, belge AÇıKLAMALARıNı bir XML dosyasına eklemenizi sağlar.

Sözdizimi
-doc:file

Arguments
file
Derlemenin kaynak kodu dosyalarındaki yorumlarla doldurulan XML için çıkış dosyası.

Açıklamalar
Kaynak kodu dosyalarında, aşağıdakilerden önce gelen belge açıklamaları işlenebilir ve XML dosyasına
eklenebilir:
Bir sınıf, temsilciveya arabirim olarak Kullanıcı tanımlı türler
Alan, olay, özellikveya yöntem olarak bu Üyeler
Main içeren kaynak kodu dosyası ilk olarak XML 'e çıktı.
IntelliSense özelliğiyle kullanılmak üzere oluşturulan. xml dosyasını kullanmak için,. xml dosyasının
dosya adının desteklemek istediğiniz derlemeyle aynı olmasına izin verin ve. xml dosyasının derlemeyle
aynı dizinde olduğundan emin olun. Bu nedenle, Visual Studio projesinde derlemeye başvuruluyorsa.
xml dosyası da bulunur. Bkz. kod açıklamaları sağlama ve daha fazla bilgi.
-Target: Moduleile derlenmediğiniz takdirde file , derlemenin çıkış dosyası için derleme bildirimini
içeren dosyanın adını belirten <bütünleştirilmiş kod ></assembly > etiketleri içerecektir.

NOTE
-Doc seçeneği tüm giriş dosyaları için geçerlidir; veya proje ayarları 'nda ayarlandıysa, projedeki tüm dosyalar.
Belirli bir dosyanın veya kod bölümünün belge açıklamalarıyla ilgili uyarıları devre dışı bırakmak için #pragma
uyarıkullanın.

Kodunuzda açıklamalardan belge oluşturma yolları için bkz. belge açıklamaları Için önerilen Etiketler .
Bu derleyici seçeneğini Visual Studio geliştirme ortamında ayarlamak için
1. Projenin Özellikler sayfasını açın.
2. Derleme sekmesine tıklayın.
3. XML belge dosyası özelliğini değiştirin.
Bu derleyici seçeneğini program aracılığıyla ayarlama hakkında daha fazla bilgi için bkz.
DocumentationFile.
Ayrıca bkz.
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-errorreport (C# derleyici seçenekleri)
23.10.2019 • 3 minutes to read • Edit Online

Bu seçenek, Microsoft 'a C# iç derleyici hatası bildirmek için kullanışlı bir yol sağlar.

NOTE
Windows Vista ve Windows Server 2008 ' de, Visual Studio için yaptığınız hata raporlama ayarları Windows Hata Bildirimi
(WER) ile yapılan ayarları geçersiz kılmaz. WER ayarları her zaman Visual Studio hata raporlama ayarlarından önceliklidir.

Sözdizimi
-errorreport:{ none | prompt | queue | send }

Arguments
seçim
İç derleyici hataları hakkında raporlar toplanmayacak veya Microsoft 'a gönderilmez.
komut istemi İç derleyici hatası aldığınızda rapor göndermenizi ister. geliştirme ortamında bir uygulama
derlerken varsayılan değer, istem varsayılandır.
kuyruk Hata raporunu sıralar. Yönetici kimlik bilgileriyle oturum açtığınızda, son oturum açtığınız zamandan bu
yana tüm sorunları bildirebilirsiniz. Her üç günde birden çok kez rapor göndermeniz istenmez. komut satırında bir
uygulama derlerken varsayılan kuyruk varsayılandır.
Gönder , İç derleyici hatalarının raporlarını otomatik olarak Microsoft 'a gönderir. Bu seçeneği etkinleştirmek için
öncelikle Microsoft veri toplama ilkesini kabul etmelisiniz. Bir bilgisayarda -errorreport: Send ' i ilk kez
belirttiğinizde, bir derleyici Iletisi sizi Microsoft veri toplama ilkesini Içeren bir Web sitesine başvuracaktır.

Açıklamalar
Derleyici bir kaynak kodu dosyasını işleyeişce bir iç derleyici hatası (ıCE ) oluşur. Bir buz gerçekleştiğinde, derleyici
bir çıkış dosyası ya da kodunuzu onarmak için kullanabileceğiniz yararlı bir tanılama üretmez.
Önceki sürümlerde, bir buz aldığınızda sorunu bildirmek için Microsoft Ürün Destek Hizmetleri 'ne başvurmanız
önerilir. -Errorreportkullanarak, görsel C# ekibe buz bilgileri sağlayabilirsiniz. Hata raporlarınız, gelecekteki
derleyici sürümlerinin artırılmasına yardımcı olabilir.
Kullanıcının raporları gönderebilme özelliği bilgisayar ve Kullanıcı ilkesi izinlerine bağlıdır.
Bu derleyici seçeneğini Visual Studio geliştirme ortamında ayarlamak için
1. Projenin Özellikler sayfasını açın. Daha fazla bilgi için bkz. derleme sayfası, proje TasarımcısıC#().
2. Yapı özelliği sayfasına tıklayın.
3. Gelişmiş düğmesine tıklayın.
4. Iç derleyici hata raporlama özelliğini değiştirin.
Bu derleyici seçeneğini program aracılığıyla ayarlama hakkında daha fazla bilgi için bkz ErrorReport.
Ayrıca bkz.
C# Derleyici Seçenekleri
-filealign (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

-Filealign seçeneği, çıkış dosyanızdaki bölümlerin boyutunu belirtmenizi sağlar.

Sözdizimi
-filealign:number

Arguments
number
Çıkış dosyasındaki bölümlerin boyutunu belirten bir değer. Geçerli değerler 512, 1024, 2048, 4096 ve 8192. Bu
değerler baytlardır.

Açıklamalar
Her bölüm, -filealign değerinin katı olan bir sınıra göre hizalanacaktır. Sabit bir varsayılan yoktur. -Filealign
belirtilmemişse, ortak dil çalışma zamanı derleme zamanında bir varsayılan değer seçer.
Bölüm boyutunu belirterek, çıkış dosyasının boyutunu etkilersiniz. Bölüm boyutunu değiştirmek, daha küçük
cihazlarda çalıştırılacak programlar için yararlı olabilir.
Çıkış dosyanızdaki bölümler hakkındaki bilgileri görmek için dumpbin ' i kullanın.
Bu derleyici seçeneğini Visual Studio geliştirme ortamında ayarlamak için
1. Projenin Özellikler sayfasını açın.
2. Yapı özelliği sayfasına tıklayın.
3. Gelişmiş düğmesine tıklayın.
4. Dosya hizalama özelliğini değiştirin.
Bu derleyici seçeneğini program aracılığıyla ayarlama hakkında daha fazla bilgi için bkz FileAlignment.

Ayrıca bkz.
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-fullpaths (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

-Fullpaths seçeneği derleyicinin derleme hatalarını ve uyarılarını listelerken dosyanın tam yolunu belirtmesini
sağlar.

Sözdizimi
-fullpaths

Açıklamalar
Varsayılan olarak, derlemeden kaynaklanan hatalar ve uyarılar, bir hatanın bulunduğu dosyanın adını belirtir. -
Fullpaths seçeneği derleyicinin dosyanın tam yolunu belirtmesini sağlar.
Bu derleyici seçeneği Visual Studio 'da kullanılamaz ve program aracılığıyla değiştirilemez.

Ayrıca bkz.
C# Derleyici Seçenekleri
-help, -? (C# Derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

Bu seçenek, derleyici seçeneklerinin bir listesini ve STDOUT 'a her bir seçeneğin kısa bir açıklamasını gönderir.

Sözdizimi
-help
-?

Açıklamalar
Bu seçenek bir derlemede yer alıyorsa, hiçbir çıkış dosyası oluşturulmaz ve hiçbir derleme gerçekleşmeyecektir.
Bu derleyici seçeneği Visual Studio 'da kullanılamaz ve program aracılığıyla değiştirilemez.

Ayrıca bkz.
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-highentropyva (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

-Highentropyva derleyici seçeneği Windows çekirdeğine, belirli bir yürütülebilir dosyanın yüksek entropi adres
alanı düzeni rastgele SEÇIMINI (ASLR ) destekleyip desteklemediğini söyler.

Sözdizimi
-highentropyva[+ | -]

Arguments
+ | -
Bu seçenek, 64 bitlik bir yürütülebilir dosyanın veya -Platform: anycpu derleyicisi seçeneği tarafından işaretlenen
bir yürütülebilir dosyanın yüksek bir entropi sanal adres alanını desteklediğini belirtir. Seçenek varsayılan olarak
devre dışıdır. Etkinleştirmek için -highentropyva + veya -highentropyva kullanın.

Açıklamalar
-Highentropyva seçeneği, Windows çekirdeğinin uyumlu sürümlerinin ASLR bir parçası olarak bir işlemin adres
alanı yerleşimini rastgele hale getirmek için daha yüksek bir entropi kullanmasına olanak sağlar. Daha yüksek
serbestlik derecenin kullanılması, yığınlar ve yığınların gibi bellek bölgelerine daha fazla sayıda adresin
ayrılabileceği anlamına gelir. Sonuç olarak, belirli bir bellek bölgesinin konumunu tahmin etmek daha zordur.
-Highentropyva derleyici seçeneği belirtildiğinde, hedef yürütülebilir dosya ve bağımlı olduğu tüm modüller, 64
bitlik bir işlem olarak çalışırken 4 GIGABAYTTAN (GB ) büyük olan işaretçi değerlerini işleyebilmelidir.
-keycontainer (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

Şifreleme anahtarı kapsayıcısının adını belirtir.

Sözdizimi
-keycontainer:string

Arguments
string
Tanımlayıcı ad anahtar kapsayıcısının adı.

Açıklamalar
-Keycontainer seçeneği kullanıldığında, derleyici paylaşılabilir bir bileşen oluşturur. Derleyici, belirtilen
kapsayıcıdan derleme bildirimine ortak bir anahtar ekler ve son derlemeyi özel anahtarla imzalar. Anahtar dosyası
oluşturmak için komut satırına yazın sn -k file . sn -i anahtar çiftini bir kapsayıcıya kurar. Derleyici CoreCLR
üzerinde çalıştırıldığında bu seçenek desteklenmez. CoreCLR üzerinde oluşturma sırasında bir derlemeyi
imzalamak için -keyfile seçeneğini kullanın.
-Target: Moduleile derleme yaparsanız, anahtar dosyasının adı modülde tutulur ve bu modülü -addmoduleile bir
derlemede derlerken derlemeye dahil edilir.
Bu seçeneği, herhangi bir Microsoft ara dili (MSIL )System.Reflection.AssemblyKeyNameAttributemodülünün
kaynak kodunda özel bir öznitelik () olarak da belirtebilirsiniz.
Ayrıca, -keyfileile şifreleme bilgilerinizi derleyiciye geçirebilirsiniz. Ortak anahtarın derleme bildirimine
eklenmesini istiyorsanız, ancak test edilene kadar derlemeyi imzalamak istiyorsanız -delaysign kullanın.
Daha fazla bilgi için bkz. güçlü adlandırılmış derlemeler oluşturma ve kullanma ve bir derlemeyi imzalamayı
geciktirme.
Bu derleyici seçeneğini Visual Studio geliştirme ortamında ayarlamak için
1. Bu derleyici seçeneği, Visual Studio geliştirme ortamında kullanılamaz.
Bu derleyici seçeneğine AssemblyKeyContainerNamearacılığıyla programlı bir şekilde erişebilirsiniz.

Ayrıca bkz.
C#Derleyici-anahtar seçeneği
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-keyfile (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

Şifreleme anahtarını içeren dosya adını belirtir.

Sözdizimi
-keyfile:file

Arguments
TERIM TANIM

file Tanımlayıcı ad anahtarını içeren dosyanın adı.

Açıklamalar
Bu seçenek kullanıldığında, derleyici belirtilen dosyadan ortak anahtarı derleme bildirimine ekler ve ardından
son derlemeyi özel anahtarla imzalar. Anahtar dosyası oluşturmak için komut satırına sn-k file yazın.
-Target: Moduleile derleme yaparsanız, anahtar dosyasının adı modülde tutulur ve -addmoduleile bir derlemeyi
derlerken oluşturulan derlemeye dahil edilir.
Ayrıca, şifreleme bilgilerinizi -keycontainerile derleyiciye geçirebilirsiniz. Kısmen imzalanmış bir derleme
istiyorsanız -delaysign kullanın.
Aynı derlemede hem-keyfile hem de-keycontainer belirtildiğinde (komut satırı seçeneği veya özel öznitelik
tarafından), derleyici ilk olarak anahtar kapsayıcısını dener. Bu başarılı olursa, derleme anahtar kapsayıcısındaki
bilgilerle imzalanır. Derleyici anahtar kapsayıcısını bulamazsa,-keyfile ile belirtilen dosyayı dener. Bu başarılı
olursa, derleme anahtar dosyasındaki bilgilerle imzalanır ve anahtar bilgileri, sonraki derlemede anahtar
kapsayıcısının geçerli olacağı şekilde anahtar kapsayıcısına (sn-ı ' ye benzer) yüklenir.
Anahtar dosyasının yalnızca ortak anahtar içerebileceğini unutmayın.
Daha fazla bilgi için bkz. güçlü adlandırılmış derlemeler oluşturma ve kullanma ve bir derlemeyi imzalamayı
geciktirme.
Bu derleyici seçeneğini Visual Studio geliştirme ortamında ayarlamak için
1. Projenin Özellikler sayfasını açın.
2. İmzalama Özellik sayfasına tıklayın.
3. Tanımlayıcı ad seçin anahtar dosyası özelliğini değiştirin.
Bu derleyici seçeneğine AssemblyOriginatorKeyFilearacılığıyla programlı bir şekilde erişebilirsiniz.

Ayrıca bkz.
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-langversion (C# derleyici seçenekleri)
4.11.2019 • 6 minutes to read • Edit Online

Derleyicinin yalnızca seçilen C# dil belirtiminde bulunan sözdizimini kabul etmesine neden olur.

Sözdizimi
-langversion:option

Arguments
option
Aşağıdaki değerler geçerlidir:

SEÇENEK AÇIKLAMA

Önizleme Derleyici, destekleyebileceği en son önizleme sürümünden


tüm geçerli dil sözdizimini kabul eder.

sürümü Derleyici, destekleyebileceği en son sürümden (ikincil yayınlar


dahil) tüm geçerli dil sözdizimini kabul eder.

Latestana Derleyici, destekleyebileceği en son ana sürümden tüm geçerli


dil sözdizimini kabul eder.

8.0 Derleyici yalnızca C# 8,0 veya daha düşük bir sözdiziminde


bulunan sözdizimini kabul eder.

7,3 Derleyici yalnızca C# 7,3 veya daha düşük bir sözdiziminde


bulunan sözdizimini kabul eder.

7,2 Derleyici yalnızca C# 7,2 veya daha düşük bir sözdiziminde


bulunan sözdizimini kabul eder.

7,1 Derleyici yalnızca C# 7,1 veya daha düşük bir sözdiziminde


bulunan sözdizimini kabul eder.

7 Derleyici yalnızca C# 7,0 veya daha düşük bir sözdiziminde


bulunan sözdizimini kabul eder.

6 Derleyici yalnızca C# 6,0 veya daha düşük bir sözdiziminde


bulunan sözdizimini kabul eder.

5 Derleyici yalnızca C# 5,0 veya daha düşük bir sözdiziminde


bulunan sözdizimini kabul eder.

4 Derleyici yalnızca C# 4,0 veya daha düşük bir sözdiziminde


bulunan sözdizimini kabul eder.
SEÇENEK AÇIKLAMA

3 Derleyici yalnızca C# 3,0 veya daha düşük bir sözdiziminde


bulunan sözdizimini kabul eder.

ISO-2 Derleyici yalnızca ISO/ıEC 23270:2006 C# (2,0) içinde bulunan


söz dizimini kabul eder.

ISO-1 Derleyici yalnızca ISO/ıEC 23270:2003 C# (1.0/1.2) içinde


bulunan söz dizimini kabul eder.

Varsayılan dil sürümü, uygulamanız için hedef çerçeveye ve SDK 'nın veya Visual Studio 'nun yüklü olduğu
sürüme bağlıdır. Bu kurallar, dil sürümü yapılandırma makalesinde tanımlanmıştır.

Açıklamalar
C# Uygulamanız tarafından başvurulan meta veriler, -langversion derleyici seçeneği değildir.
C# Derleyicinin her sürümü dil belirtimine uzantılar içerdiğinden, -langversion size derleyicinin önceki bir
sürümünün eşdeğer işlevlerini sağlamaz.
Ayrıca, sürüm C# güncelleştirmeleri genellikle büyük .NET Framework sürümleriyle aynı olsa da yeni söz dizimi ve
Özellikler ilgili Framework sürümüne bağlı değildir. Yeni özellikler, C# düzeltme ile birlikte yayınlanan yeni bir
derleyici güncelleştirmesini kesinlikle gerektirirken, her bir özellik kendi minimum .NET API 'sine veya BT 'nin alt
düzey çerçeveler üzerinde çalışmasına izin veren ortak dil çalışma zamanı gereksinimlerine sahiptir NuGet
paketleri veya diğer kitaplıklar dahil.
Kullandığınız dil sürümü ayarı ne olursa olsun,. exe veya. dll dosyanızı oluşturmak için ortak dil çalışma zamanının
güncel sürümünü kullanacaksınız. Tek bir özel durum, -langversion: ISO -1altında çalışan arkadaş derlemelerdir
ve -moduleassemblyname (C# derleyici seçeneği).
C# Dil sürümünü belirtmek için diğer yollar için C# dil sürümünü seçme makalesini inceleyin.
Bu derleyici seçeneğini program aracılığıyla ayarlama hakkında daha fazla bilgi için bkz. LanguageVersion.

C# dili belirtimi
VERSION BAĞLANTI AÇIKLAMA

C#7,0 ve üzeri Şu anda kullanılamıyor

C#6,0 Bağlantısının C#Dil belirtimi sürüm 6-resmi olmayan


taslak: .NET Foundation

C#5,0 PDF 'YI indir Standart ECMA-334 5 sürümü

C#3,0 BELGEYI indir C#Dil belirtimi sürüm 3,0: Microsoft


Corporation

C#2,0 PDF 'YI indir Standart ECMA-334 4 sürümü

C#1,2 BELGEYI indir C#Dil belirtimi sürüm 1,2: Microsoft


Corporation
VERSION BAĞLANTI AÇIKLAMA

C#1,0 BELGEYI indir C#Dil belirtimi sürüm 1,0: Microsoft


Corporation

Tüm dil özelliklerini desteklemek için gereken en düşük SDK sürümü


Aşağıdaki tabloda, karşılık gelen dil sürümünü destekleyen C# DERLEYICIYLE SDK 'nın en düşük sürümleri
listelenmiştir:

C#SÜRÜM EN DÜŞÜK SDK SÜRÜMÜ

C# 8.0 Microsoft Visual Studio/derleme araçları 2019, sürüm 16,3


veya .NET Core 3,0 SDK

C# 7.3 Microsoft Visual Studio/derleme araçları 2017, sürüm 15,7

C# 7.2 Microsoft Visual Studio/derleme araçları 2017, sürüm 15,5

C# 7.1 Microsoft Visual Studio/derleme araçları 2017, sürüm 15,3

C# 7.0 Microsoft Visual Studio/derleme araçları 2017

C# 6 Microsoft Visual Studio/derleme araçları 2015

C#e Microsoft Visual Studio/derleme araçları 2012 veya


paketlenmiş .NET Framework 4,5 derleyicisi

C#4 Microsoft Visual Studio/derleme araçları 2010 veya


paketlenmiş .NET Framework 4,0 derleyicisi

C#03 Microsoft Visual Studio/derleme araçları 2008 veya


paketlenmiş .NET Framework 3,5 derleyicisi

C#iki Microsoft Visual Studio/derleme araçları 2005 veya


paketlenmiş .NET Framework 2,0 derleyicisi

C#1.0/1.2 Microsoft Visual Studio/derleme araçları .NET 2002 veya


paketlenmiş .NET Framework 1,0 derleyicisi

Ayrıca bkz.
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-lib (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

-Lib seçeneği, -Reference (C# derleyici seçenekleri) seçeneği aracılığıyla başvurulan derlemelerin konumunu
belirtir.

Sözdizimi
-lib:dir1[,dir2]

Arguments
dir1
Başvurulan bir derlemenin geçerli çalışma dizininde (derleyicisini çağırdığınız dizin) veya ortak dil çalışma
zamanının sistem dizininde bulunamaması halinde derleyicinin aranacağı bir dizin.
dir2
Derleme başvuruları için arama yapılacak bir veya daha fazla dizin. Ek dizin adlarını virgülle ayırın ve aralarında
boşluk olmadan boşluklar koyun.

Açıklamalar
Derleyici, aşağıdaki sırada tam olarak nitelenen derleme başvurularını arar:
1. Geçerli çalışma dizini. Bu, derleyicinin çağrıldığı dizindir.
2. Ortak dil çalışma zamanı sistem dizini.
3. -Libtarafından belirtilen dizinler.
4. LıB ortam değişkeni tarafından belirtilen dizinler.
Derleme başvurusunu belirtmek için -Reference kullanın.
-lib eklenebilir; bir defadan fazla belirtmek önceki değerlere ekler.
-Lib kullanmanın bir alternatifi, gereken tüm derlemeleri çalışma dizinine kopyalamaktır; Bu, yalnızca derleme
adını başvuruyailetmeniz için izin verir. Daha sonra çalışma dizininden derlemeleri silebilirsiniz. Bağımlı
derlemenin yolu bütünleştirilmiş kod bildiriminde belirtilmediğinden, uygulama hedef bilgisayarda başlatılabilir ve
derlemeyi genel derleme önbelleğinde bulabilir ve kullanacaktır.
Derleyici derlemeye başvuru yapabildiğinden, ortak dil çalışma zamanının derlemeyi çalışma zamanında
bulabileceği ve yükleyebilecektir anlamına gelmez. Çalışma zamanının başvurulmuş derlemeleri nasıl arayacağını
görmek için bkz. çalışma zamanının derlemeleri nasıl konumlandırır .
Bu derleyici seçeneğini Visual Studio geliştirme ortamında ayarlamak için
1. Projenin Özellik sayfaları iletişim kutusunu açın.
2. Başvurular yolu Özellik sayfasına tıklayın.
3. Liste kutusunun içeriğini değiştirin.
Bu derleyici seçeneğini program aracılığıyla ayarlama hakkında daha fazla bilgi için bkz ReferencePath.
Örnek
Bir. exe dosyası oluşturmak için t2.cs derleyin. Derleyici, çalışma dizinine ve derleme başvuruları için C
sürücüsünün kök dizinine bakacaktır.

csc -lib:c:\ -reference:t2.dll t2.cs

Ayrıca bkz.
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-Link (C# derleyici seçenekleri)
23.10.2019 • 6 minutes to read • Edit Online

Derleyicinin, belirtilen derlemelerdeki COM tür bilgilerini şu anda derlediğiniz projede kullanılabilir hale
getirmesine neden olur.

Sözdizimi
-link:fileList
// -or-
-l:fileList

Arguments
fileList
Gerekli. Bütünleştirilmiş kod dosyası adlarının virgülle ayrılmış listesi. Dosya adı bir boşluk içeriyorsa, adı tırnak
işaretleri içine alın.

Açıklamalar
-link Seçeneği, gömülü tür bilgilerine sahip bir uygulamayı dağıtmanıza olanak sağlar. Uygulama daha sonra,
çalışma zamanı derlemesine bir başvuruya gerek duymadan gömülü tür bilgilerini uygulayan bir çalışma zamanı
derlemesinde türleri kullanabilir. Çalışma zamanı derlemesinin çeşitli sürümleri yayımlanıyorsa, katıştırılmış tür
bilgilerini içeren uygulama, yeniden derlenmesi gerekmeden çeşitli sürümlerle çalışabilir. Bir örnek için bkz .
İzlenecek yol: Yönetilen derlemelerdentürler ekleme.
-link Seçeneğinin kullanılması özellikle com birlikte çalışabilirliğine çalışırken yararlıdır. Uygulamanızın artık
hedef bilgisayarda bir birincil birlikte çalışma derlemesi (PIA) gerektirmemesi için COM türlerini
katıştırabilirsiniz. -link Seçeneği, derleyicinin başvurulan birlikte çalışma derlemesindeki com tür bilgilerini
sonuçta elde edilen derlenmiş koda katıştırmasını söyler. COM türü, CLSID (GUID ) değeri tarafından tanımlanır.
Sonuç olarak, uygulamanız aynı CLSID değerleriyle aynı COM türlerini yükleyen bir hedef bilgisayarda
çalışabilir. Microsoft Office otomatikleştiren uygulamalar iyi bir örnektir. Office gibi uygulamalar genellikle farklı
sürümlerde aynı CLSID değerini tutacağından, uygulamanız hedef bilgisayarda .NET Framework 4 veya sonraki
bir sürüm yüklendiği sürece başvurulan COM türlerini kullanabilir ve uygulamanız Yöntemler, özellikler veya
uygulamalar kullanır. başvurulan COM türlerine dahil edilen olaylar.
-link Seçeneği yalnızca arabirimleri, yapıları ve temsilcileri katıştırır. COM sınıfları ekleme desteklenmiyor.

NOTE
Kodunuzda gömülü bir COM türünün örneğini oluşturduğunuzda, uygun arabirimi kullanarak örneği oluşturmanız gerekir.
CoClass kullanarak gömülü COM türünün bir örneğini oluşturma girişimi hataya neden olur.

Visual Studio 'da -link seçeneğini ayarlamak için bir derleme başvurusu ekleyin ve Embed Interop Types
özelliği trueolarak ayarlayın. Embed Interop Types Özelliği için varsayılan değer false'dur.
Başka bir COM derlemesine (derleme B ) başvuran bir COM derlemesine (derleme A) bağlarsanız,
aşağıdakilerden biri doğruysa derleme B 'ye de bağlantı oluşturmanız gerekir:
Derleme A 'dan bir tür bir türden devralınır veya derleme B 'den bir arabirim uygular.
B derlemesinden dönüş türü veya parametre türü olan bir alan, özellik, olay veya yöntem çağrılır.
-Reference derleyici seçeneği gibi, -link derleyici seçeneği sık kullanılan .NET Framework derlemelerine
başvuran Csc. rsp yanıt dosyasını kullanır. Derleyicinin Csc. rsp dosyasını kullanmasını istemiyorsanız -noconfig
derleyici seçeneğini kullanın.
-link Öğesinin -l kısa biçimi.

Genel türler ve katıştırılmış türler


Aşağıdaki bölümlerde, birlikte çalışma türlerini gömün uygulamalarda genel türleri kullanma sınırlamaları
açıklanır.
Genel Arabirimler
Birlikte çalışma derlemesinden gömülü genel arabirimler kullanılamaz. Bu, aşağıdaki örnekte gösterilir.

// The following code causes an error if ISampleInterface is an embedded interop type.


ISampleInterface<SampleType> sample;

Genel parametrelere sahip türler


Türü bir birlikte çalışma derlemesinden gömülü olan genel bir parametreye sahip türler, bu tür bir dış
derlemeden ise kullanılamaz. Bu kısıtlama, arabirimler için geçerlidir. Örneğin, Range
Microsoft.Office.Interop.Excel derlemede tanımlanan arabirimi göz önünde bulundurun. Bir kitaplık,
Microsoft.Office.Interop.Excel birlikte çalışma türlerini derlemeden katıştırır ve türü Range arabirim olan bir
parametreye sahip genel bir tür döndüren bir yöntemi ortaya koyar, bu yöntem, aşağıdaki kod örneğinde
gösterildiği gibi genel bir arabirim döndürmelidir.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Office.Interop.Excel;

public class Utility


{
// The following code causes an error when called by a client assembly.
public List<Range> GetRange1() {

// The following code is valid for calls from a client assembly.


public IList<Range> GetRange2() {

}
}

Aşağıdaki örnekte, istemci kodu hata olmadan IList genel arabirimi döndüren yöntemi çağırabilir.
public class Client
{
public void Main()
{
Utility util = new Utility();

// The following code causes an error.


List<Range> rangeList1 = util.GetRange1();

// The following code is valid.


List<Range> rangeList2 = (List<Range>)util.GetRange2();
}
}

Örnek
Aşağıdaki OfficeApp.cs kod, COMData1.dll ve COMData2.dll için kaynakdosyasıvebaşvuruderlemeleriniderler.
OfficeApp.exe

csc -link:COMData1.dll,COMData2.dll -out:OfficeApp.exe OfficeApp.cs

Ayrıca bkz.
C# Derleyici Seçenekleri
İzlenecek yol: Yönetilen derlemelerden tür ekleme
-Reference (C# derleyici seçenekleri)
-noconfig (C# derleyici seçenekleri)
csc.exe Kullanarak Komut Satırı Derleme
Birlikte Çalışabilirliğe Genel Bakış
-linkresource (C# derleyici seçenekleri)
23.10.2019 • 3 minutes to read • Edit Online

Çıkış dosyasındaki bir .NET Framework kaynağına bir bağlantı oluşturur. Kaynak dosyası çıkış dosyasına
eklenmez. Bu, çıkış dosyasına bir kaynak dosyası katıştırabilen -Resource seçeneğinden farklıdır.

Sözdizimi
-linkresource:filename[,identifier[,accessibility-modifier]]

Arguments
filename
Derlemeden bağlamak istediğiniz .NET Framework kaynak dosyası.
identifierseçim
Kaynağın mantıksal adı; kaynağı yüklemek için kullanılan ad. Varsayılan değer, dosyanın adıdır.
accessibility-modifier seçim
Kaynağın erişilebilirliği: public veya Private. Varsayılan değer geneldir.

Açıklamalar
Varsayılan olarak, bağlantılı kaynaklar C# derleyici ile oluşturulduklarında derlemede ortaktır. Kaynakları özel hale
getirmek için erişilebilirlik değiştiricisi private olarak belirtin. public Veya private dışında başka bir değiştirici
kullanılamaz.
-linkresource ,- target: Moduledışındaki -target seçeneklerinden birini gerektiriyor.
, Örneğin Resgen. exe veya geliştirme ortamında oluşturulmuş bir .NET Framework kaynak dosyası ise,
System.Resources ad alanındaki üyelerle erişilebilir. filename Daha fazla bilgi için bkz.
System.Resources.ResourceManager. Diğer tüm kaynaklar için, çalışma zamanında GetManifestResource kaynağa
erişmek üzere Assembly sınıfındaki yöntemleri kullanın.
İçinde filename belirtilen dosya herhangi bir biçimde olabilir. Örneğin, genel derleme önbelleğine yüklenebilmesi
ve derlemedeki yönetilen koddan erişilebilmesi için derlemenin yerel bir DLL parçası yapmak isteyebilirsiniz.
Aşağıdaki örneklerden İkincisi bunun nasıl yapılacağını gösterir. Derleme bağlayıcıda aynı şeyi yapabilirsiniz.
Aşağıdaki örneklerden üçüncüsü bunun nasıl yapılacağını gösterir. Daha fazla bilgi için bkz. al. exe
(bütünleştirilmiş kod bağlayıcı) ve derlemeler ve genel derleme önbelleği ile çalışma.
-linkres , -linkresourceöğesinin kısa biçimidir.
Bu derleyici seçeneği Visual Studio 'da kullanılamaz ve program aracılığıyla değiştirilemez.

Örnek
Derle in.cs ve kaynak dosyasına rf.resource bağla:

csc -linkresource:rf.resource in.cs


Örnek
Bir A.cs dll 'de derleyin, yerel dll N. dll ' ye bağlanın ve çıktıyı genel derleme önbelleği 'ne (GAC ) yerleştirin. Bu
örnekte, hem. dll hem de N. dll GAC 'de yer alır.

csc -linkresource:N.dll -t:library A.cs


gacutil -i A.dll

Örnek
Bu örnek, bir önceki ile aynı şeyi, ancak derleme bağlayıcı seçeneklerini kullanarak yapar.

csc -t:module A.cs


al -out:A.dll A.netmodule -link:N.dll
gacutil -i A.dll

Ayrıca bkz.
C# Derleyici Seçenekleri
Al.exe (Bütünleştirilmiş Kod Bağlayıcı)
Bütünleştirilmiş Kodlar ve Genel Derleme Önbelleği ile Çalışma
Proje ve Çözüm Özelliklerini Yönetme
-Main (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

Bu seçenek, birden fazla sınıf bir Main yöntemi içeriyorsa programa giriş noktasını içeren sınıfı belirtir.

Sözdizimi
-main:class

Arguments
class
Main metodunu içeren tür.
Belirtilen sınıf adı tam olarak nitelenmiş olmalıdır; sınıfını içeren tam ad alanını ve ardından sınıf adını içermelidir.
Örneğin, Main yöntemi MyApplication.Core ad alanındaki Program sınıfının içindeyse, derleyici seçeneğinin
olması gerekir -main:MyApplication.Core.Program .

Açıklamalar
Derlemeniz bir ana yöntemle birden fazla tür içeriyorsa, programa giriş noktası olarak kullanmak istediğiniz ana
yöntemi içeren türü belirtebilirsiniz.
Bu seçenek bir. exe dosyası derlenirken kullanım içindir.
Bu derleyici seçeneğini Visual Studio geliştirme ortamında ayarlamak için
1. Projenin Özellikler sayfasını açın.
2. Uygulama Özellik sayfasına tıklayın.
3. Başlangıç nesnesi özelliğini değiştirin.
Bu derleyici seçeneğini program aracılığıyla ayarlamak için, StartupObjectbkz.

Örnek
Ve t2.cs 'de Test2 Main yönteminin bulunduğunu belirterek derleyin: t3.cs

csc t2.cs t3.cs -main:Test2

Ayrıca bkz.
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-moduleassemblyname (C# derleyici seçeneği)
23.10.2019 • 2 minutes to read • Edit Online

Genel olmayan türleri bir. netmodule 'nin erişebileceği bir derlemeyi belirtir.

Sözdizimi
-moduleassemblyname:assembly_name

Arguments
assembly_name
Genel olmayan türleri. netmodule 'nin erişebileceği derlemenin adı.

Açıklamalar
-moduleassemblyname bir. netmodule oluştururken ve aşağıdaki koşulların doğru olduğu durumlarda
kullanılmalıdır:
. Netmodule, mevcut bir derlemede ortak olmayan türlere erişim gerektirir.
. Netmodule 'nin derolacağı derlemenin adını bilirsiniz.
Mevcut bütünleştirilmiş kod,. netmodule 'nin derolacağı derlemeye arkadaş derleme erişimi verdi.
. Netmodule oluşturma hakkında daha fazla bilgi için bkz. -target: Module (C# derleyici seçenekleri).
Friend derlemeleri hakkında daha fazla bilgi için bkz. arkadaş derlemeler.
Bu seçenek geliştirme ortamının içinden kullanılamaz; yalnızca komut satırından derlerken kullanılabilir.
Bu derleyici seçeneği Visual Studio 'da kullanılamaz ve program aracılığıyla değiştirilemez.

Örnek
Bu örnek, özel bir türü olan ve csman_an_assembly adlı bir derlemeye arkadaş derleme erişimi veren bir derleme
oluşturur.

// moduleassemblyname_1.cs
// compile with: -target:library
using System;
using System.Runtime.CompilerServices;

[assembly:InternalsVisibleTo ("csman_an_assembly")]

class An_Internal_Class
{
public void Test()
{
Console.WriteLine("An_Internal_Class.Test called");
}
}
Örnek
Bu örnek, moduleassemblyname_1. dll derlemesinde genel olmayan bir türe erişen. netmodule 'yi oluşturur. Bu.
netmodule 'nin csman_an_assembly adlı bir derlemede derlenip,. netmodule 'nin csman_an_ 'e arkadaş derleme
erişimi veren bir derlemede genel olmayan türlere erişmesine izin vererek -moduleassemblynamebelirtemez.
derleme.

// moduleassemblyname_2.cs
// compile with: -moduleassemblyname:csman_an_assembly -target:module -reference:moduleassemblyname_1.dll
class B {
public void Test() {
An_Internal_Class x = new An_Internal_Class();
x.Test();
}
}

Örnek
Bu kod örneği, önceden derlenmiş derleme ve. netmodule 'e başvurarak derleme csman_an_assembly oluşturur.

// csman_an_assembly.cs
// compile with: -addmodule:moduleassemblyname_2.netmodule -reference:moduleassemblyname_1.dll
class A {
public static void Main() {
B bb = new B();
bb.Test();
}
}

An_Internal_Class. test çağrıldı

Ayrıca bkz.
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-noconfig (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

-Noconfig seçeneği, derleyicinin ' de bulunan ve CSC. exe dosyası ile aynı dizinden yüklenen csc. rsp dosyası ile
derlenmeyeceğini söyler.

Sözdizimi
-noconfig

Açıklamalar
Csc. rsp dosyası .NET Framework ile gönderilen tüm derlemelere başvurur. Visual Studio .NET geliştirme
ortamının içerdiği gerçek başvurular proje türüne bağlıdır.
Csc. rsp dosyasını değiştirebilir ve CSC. exe ile komut satırından her derlemeye dahil edilecek ek derleyici
seçeneklerini belirtebilirsiniz ( -noconfig seçeneği hariç).
Derleyici, son olarak CSC komutuna geçirilen seçenekleri işler. Bu nedenle, komut satırındaki herhangi bir
seçenek CSC. rsp dosyasında aynı seçeneğin ayarını geçersiz kılar.
Derleyicinin Csc. rsp dosyasındaki ayarları bulup kullanmasını istemiyorsanız -noconfig' i belirtin.
Bu derleyici seçeneği Visual Studio 'da kullanılamaz ve program aracılığıyla değiştirilemez.

Ayrıca bkz.
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-nologo (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

-Nologo seçeneği, derleyici başlatıldığında ve derleme sırasında bilgilendirici iletileri görüntülerken oturum açma
başlığının görüntülenmesini önler.

Sözdizimi
-nologo

Açıklamalar
Bu seçenek geliştirme ortamının içinden kullanılamaz; yalnızca komut satırından derlerken kullanılabilir.
Bu derleyici seçeneği Visual Studio 'da kullanılamaz ve program aracılığıyla değiştirilemez.

Ayrıca bkz.
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-nostdlib (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

-nostdlib , tüm sistem ad alanını tanımlayan mscorlib. dll ' nin içe aktarımını engeller.

Sözdizimi
-nostdlib[+ | -]

Açıklamalar
Kendi sistem ad alanınızı ve nesnelerinizi tanımlamak veya oluşturmak istiyorsanız bu seçeneği kullanın.
-Nostdlibbelirtmezseniz, mscorlib. dll programınıza içeri aktarılır ( -nostdlib- belirtilerek aynı). -Nostdlib
belirtildiğinde -nostdlib + belirtilerek aynıdır.
Visual Studio 'da Bu derleyici seçeneğini ayarlamak için

NOTE
Aşağıdaki yönergeler yalnızca Visual Studio 2015 (ve önceki sürümler) için geçerlidir. Visual Studio 2017 ' de mscorlib. dll
derlemesi oluşturma özelliği yok.

1. Projenin Özellikler sayfasını açın.


2. Yapı özellikleri sayfasına tıklayın.
3. Gelişmiş düğmesine tıklayın.
4. Mscorlib. dll ' nin başvurmayın özelliğini değiştirin.
Bu derleyici seçeneğini program üzerinden ayarlamak için
Bu derleyici seçeneğini program aracılığıyla ayarlama hakkında daha fazla bilgi için bkz NoStdLib.

Ayrıca bkz.
C# Derleyici Seçenekleri
-nowarn (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

-Nowarn seçeneği, derleyicinin bir veya daha fazla uyarı görüntülemesini engellemenize olanak tanır. Birden çok
uyarı numarasını virgülle ayırın.

Sözdizimi
-nowarn:number1[,number2,...]

Arguments
number1 , number2
Derleyicinin görüntülenmesini istediğiniz uyarı numaraları.

Açıklamalar
Uyarı tanımlayıcısının yalnızca sayısal bölümünü belirtmeniz gerekir. Örneğin, CS0028 bastırmak istiyorsanız,
belirtebilirsiniz -nowarn:28 .
Derleyici önceki sürümlerde geçerli -nowarn olan, ancak derleyicisinden kaldırılan uyarı numaralarını sessizce yok
sayacaktır. Örneğin, CS0679 Visual Studio .NET 2002 derleyicisinde geçerliyse, ancak daha sonra kaldırılmıştır.
Aşağıdaki uyarılar -nowarn seçenek tarafından gizlenemez:
Derleyici Uyarısı (düzey 1) CS2002
Derleyici Uyarısı (düzey 1) CS2023
Derleyici Uyarısı (düzey 1) CS2029
Bu derleyici seçeneğini Visual Studio geliştirme ortamında ayarlamak için
1. Projenin Özellikler sayfasını açın. Ayrıntılar için bkz. derleme sayfası, proje Tasarımcısı (C#).
2. Yapı özelliği sayfasına tıklayın.
3. Uyarıları bastır özelliğini değiştirin.
Bu derleyici seçeneğini program aracılığıyla ayarlama hakkında daha fazla bilgi için bkz DelaySign.

Ayrıca bkz.
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
C# Derleyici Hataları
-nowin32manifest (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

Derleyicinin herhangi bir uygulama bildirimini yürütülebilir dosyaya katıştırmamasını sağlamak için -
nowin32manifest seçeneğini kullanın.

Sözdizimi
-nowin32manifest

Açıklamalar
Bu seçenek kullanıldığında, bir Win32 kaynak dosyasında veya sonraki bir derleme adımı sırasında uygulama
bildirimi belirtmediğiniz müddetçe uygulama Windows Vista 'da sanallaştırmaya tabi olacaktır.
Visual Studio 'da, bildirim açılan listesinde bildirim olmadan uygulama oluştur seçeneğini belirleyerek
uygulama özelliği sayfasında bu seçeneği ayarlayın. Daha fazla bilgi için bkz. uygulama sayfası, proje
TasarımcısıC#().
Bildirim oluşturma hakkında daha fazla bilgi için bkz. -win32manifestC# (derleyici seçenekleri).

Ayrıca bkz.
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-optimize (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

-Optimize seçeneği, çıkış dosyanızı daha küçük, daha hızlı ve daha verimli hale getirmek için derleyici tarafından
gerçekleştirilen iyileştirmeleri sağlar veya devre dışı bırakır.

Sözdizimi
-optimize[+ | -]

Açıklamalar
-optimize , ortak dil çalışma zamanına kodu çalışma zamanında iyileştirmek için de bildirir.
Varsayılan olarak, iyileştirmeler devre dışıdır. İyileştirmeleri etkinleştirmek için -optimize + belirtin.
Bir derleme tarafından kullanılacak bir modül oluştururken, derlemeden en iyileştirme ayarlarını kullanın.
-o , en iyileştirmeiçin kısa bir formdur.
-Optimize ve -Debug seçeneklerini birleştirmek mümkündür.
Bu derleyici seçeneğini Visual Studio geliştirme ortamında ayarlamak için
1. Projenin Özellikler sayfasını açın.
2. Yapı özelliği sayfasına tıklayın.
3. Optimizasyon kodu özelliğini değiştirin.
Bu derleyici seçeneğini program aracılığıyla ayarlama hakkında daha fazla bilgi için bkz Optimize.

Örnek
Derleyici t2.cs iyileştirmelerini derleyin ve etkinleştirin:

csc t2.cs -optimize

Ayrıca bkz.
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-Out (C# derleyici seçenekleri)
23.10.2019 • 3 minutes to read • Edit Online

-Out seçeneği, çıktı dosyasının adını belirtir.

Sözdizimi
-out:filename

Arguments
filename
Derleyici tarafından oluşturulan çıkış dosyasının adı.

Açıklamalar
Komut satırında, derlemeniz için birden çok çıkış dosyası belirtmek mümkündür. Derleyici, -Out seçeneğinden
sonra bir veya daha fazla kaynak kodu dosyası bulmayı bekler. Ardından, tüm kaynak kodu dosyaları , bu
seçenek tarafından belirtilen çıkış dosyasına derlenir.
Oluşturmak istediğiniz dosyanın tam adını ve uzantısını belirtin.
Çıkış dosyasının adını belirtmezseniz:
Bir. exe, ana yöntemi içeren kaynak kodu dosyasından adını alır.
Bir. dll veya. netmodule adı ilk kaynak kodu dosyasından alır.
Bir çıkış dosyası derlemek için kullanılan bir kaynak kodu dosyası, başka bir çıkış dosyasının derlenmesi için aynı
derlemede kullanılamaz.
Bir komut satırı derlemesinde birden çok çıkış dosyası üretilirken, yalnızca bir tane çıkış dosyası derleme
olabileceğini ve yalnızca ilk çıkış dosyasının (örtük veya açık olarak ile) derleme olabileceğini aklınızda
bulundurun.
Bir derlemenin parçası olarak üretilen tüm modüller, derlemede oluşturulan herhangi bir derlemeyle ilişkili
dosyalar olur. İlişkili dosyaları görmek üzere derleme bildirimini görüntülemek için ıldadsm. exe ' yi kullanın.
Bir exe 'nin bir arkadaş derlemenin hedefi olması için-out derleyici seçeneği gereklidir. Daha fazla bilgi için bkz.
Friend derlemeleri.
Bu derleyici seçeneğini Visual Studio geliştirme ortamında ayarlamak için
1. Projenin Özellikler sayfasını açın.
2. Uygulama Özellik sayfasına tıklayın.
3. Derleme adı özelliğini değiştirin.
Bu derleyici seçeneğini program aracılığıyla ayarlamak için: OutputFileName , proje türünün (exe, kitaplık,
vb.) ve derleme adının bir birleşimiyle belirlenen salt okunurdur. Bu özelliklerden birinin veya her ikisinin
de değiştirilmesi, çıkış dosyası adını ayarlamak için gerekli olacaktır.
Örnek
Çıkış t.cs dosyasını t.exe derleyin ve oluşturun t2.cs , Ayrıca modül çıkış dosyası mymodule.netmodule
oluşturup oluşturun:

csc t.cs -out:mymodule.netmodule -target:module t2.cs

Ayrıca bkz.
C# Derleyici Seçenekleri
Arkadaş Bütünleştirilmiş Kodları
Proje ve Çözüm Özelliklerini Yönetme
-pathmap (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

-Pathmap derleyici seçeneği, fiziksel yolların derleyicinin çıkış kaynak yol adlarına nasıl eşlendiğini belirtir.

Sözdizimi
-pathmap:path1=sourcePath1,path2=sourcePath2

Arguments
path1 Geçerli ortamdaki kaynak dosyalarının tam yolu
sourcePath1 Her çıkış dosyasında yerine path1 geçen kaynak yol.
Birden çok eşlenmiş kaynak yolunu belirtmek için, her biri virgülle ayırın.

Açıklamalar
Derleyici, kaynak yolunu aşağıdaki nedenlerden dolayı çıktısına yazar:
1. İsteğe bağlı bir parametreye uygulandığında kaynak yolu bir bağımsız değişken CallerFilePathAttribute için
değiştirilir.
2. Kaynak yolu bir PDB dosyasına katıştırılır.
3. PDB dosyasının yolu bir PE (taşınabilir yürütülebilir) dosyasına katıştırılır.
Bu seçenek, derleyicinin çalıştığı makinedeki her fiziksel yolu, çıktı dosyalarında yazılması gereken karşılık gelen
bir yola eşler.

Örnek
t.cs C:\iştestlerinde\ derleyin ve bu dizini çıktıda \publish ile eşleyin:

csc -pathmap:C:\work\tests=\publish t.cs

Ayrıca bkz.
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-pdb (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

-Pdb derleyici seçeneği, hata ayıklama sembolleri dosyasının adını ve konumunu belirtir.

Sözdizimi
-pdb:filename

Arguments
filename
Hata ayıklama sembolleri dosyasının adı ve konumu.

Açıklamalar
-Debug (C# derleyici seçenekleri)belirttiğinizde, derleyici aynı dizinde bir. pdb dosyası oluşturur ve bu, derleyicinin
çıkış dosyasını (. exe veya. dll) çıktı dosyasının adı ile aynı olan bir dosya adı ile oluşturacaktır.
-pdb ,. pdb dosyası için varsayılan olmayan bir dosya adı ve konum belirtmenize olanak tanır.
Bu derleyici seçeneği Visual Studio geliştirme ortamında ayarlanamaz veya program aracılığıyla değiştirilemez.

Örnek
TT t.cs . pdb adlı bir. pdb dosyası derleyin ve oluşturun:

csc -debug -pdb:tt t.cs

Ayrıca bkz.
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-Platform (C# derleyici seçenekleri)
23.10.2019 • 3 minutes to read • Edit Online

Ortak dil çalışma zamanının (CLR ) hangi sürümünün derlemeyi çalıştırabileceği belirtir.

Sözdizimi
-platform:string

Parametreler
string
anycpu (varsayılan), anycpu32bitpreferred, ARM, x64, x86 veya Itanium.

Açıklamalar
anycpu (varsayılan), derlemenizi herhangi bir platformda çalışacak şekilde derler. Uygulamanız mümkün
olduğunda 64 bitlik bir işlem olarak çalışır ve yalnızca bu mod kullanılabilir olduğunda 32 bit 'e geri döner.
anycpu32bitpreferred , derlemenizi herhangi bir platformda çalışacak şekilde derler. Uygulamanız, hem
64 bit hem de 32 bit uygulamaları destekleyen sistemlerde 32 bitlik modda çalışır. Bu seçeneği yalnızca
.NET Framework 4,5 ' i hedefleyen projeler için belirtebilirsiniz.
ARM , derlemenizi GELIŞMIŞ bir RISC MAKINESI (ARM ) işlemcisi olan bir bilgisayarda çalışacak şekilde
derler.
ARM64 , derlemenizi, A64 yönerge kümesini destekleyen GELIŞMIŞ bir RISC MAKINESI (ARM ) işlemcisi
olan bir bilgisayarda 64 bitlik CLR tarafından çalışacak şekilde derler.
x64 , derlemenizi AMD64 veya EM64T yönerge kümesini destekleyen bir bilgisayarda 64 bitlik CLR
tarafından çalıştırılacak şekilde derler.
x86 , derlemenizi 32 bit, x86 uyumlu CLR tarafından çalıştırılacak şekilde derler.
Itanium , derlemenizi Itanium işlemcisi olan bir bilgisayarda 64 bitlik CLR tarafından çalıştırılacak şekilde
derler.
64 bitlik bir Windows işletim sisteminde:
İle derlenen derlemeler -Platform: x86 , WOW64 altında çalışan 32 bitlik clr üzerinde yürütülür.
-Platform: anycpu ile derlenen bir dll, yüklendiği IŞLEMLE aynı CLR üzerinde yürütülür.
-Platform: anycpu ile derlenen yürütülebilir dosyalar 64 bitlik clr üzerinde yürütülür.
-Platform: anycpu32bitpreferred ile derlenen yürütülebilir dosyalar 32 bit clr üzerinde yürütülür.
Anycpu32bitpreferred ayarı yalnızca yürütülebilir dosya için geçerlidir (. EXE ) dosyalarını ve .NET Framework
4,5 gerektirir.
Windows 64 bit işletim sisteminde çalışacak bir uygulama geliştirme hakkında daha fazla bilgi için bkz. 64-bit
uygulamalar.
Bu derleyici seçeneğini Visual Studio geliştirme ortamında ayarlamak için
1. Projenin Özellikler sayfasını açın.
2. Yapı özelliği sayfasına tıklayın.
3. Platform hedefi özelliğini değiştirin ve .NET Framework 4,5 ' i hedefleyen projeler için 32 bit tercih et
onay kutusunu seçin veya temizleyin.

NOTE
-platform Visual C# Express 'teki geliştirme ortamında kullanılamaz.

Bu derleyici seçeneğini program aracılığıyla ayarlama hakkında daha fazla bilgi için bkz PlatformTarget.

Örnek
Aşağıdaki örnek, uygulamanın 64 bitlik bir Windows işletim sisteminde 64 bitlik CLR tarafından çalıştırılması
gerektiğini belirtmek için -Platform seçeneğinin nasıl kullanılacağını gösterir.

csc -platform:anycpu filename.cs

Ayrıca bkz.
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-preferreduilang (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

-preferreduilang Derleyici seçeneğini kullanarak, C# derleyicinin hata iletileri gibi çıktıyı görüntülediği dili
belirtebilirsiniz.

Sözdizimi
-preferreduilang: language

Arguments
language
Derleyici çıktısı için kullanılacak dilin dil adı .

Açıklamalar
Derleyicinin hata iletileri ve -preferreduilang diğer komut satırı çıktıları için kullanmasını istediğiniz dili C#
belirtmek için derleyici seçeneğini kullanabilirsiniz. Dile ait dil paketi yüklü değilse, bunun yerine işletim sisteminin
dil ayarı kullanılır ve hiçbir hata bildirilmemiştir.

csc.exe -preferreduilang:ja-JP

Gereksinimler
Ayrıca bkz.
C# Derleyici Seçenekleri
-publicsign (C# Derleyici Seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

Bu seçenek, bir ortak anahtar uygulamak derleyicinin ancak aslında derlemeyi imzalamayı değil. - Publicsign
seçeneği de ayarlar biraz derlemesinde çalışma zamanı dosyanın gerçekten imzalı olduğunu belirtir.

Sözdizimi
-publicsign

Arguments
Yok.

Açıklamalar
- Publicsign seçeneği kullanılmasını gerektiren - keyfile veya - keycontaıner. Keyfile veya keycontainer
seçeneklerini ortak anahtarı belirtin.
- Publicsign ve - delaysıgn seçenekleri karşılıklı olarak birbirini dışlar.
"Sahte işareti" veya "OSS işareti" olarak da adlandırılır, ortak imzalama çıkış bir derlemede ortak anahtarı içerir ve
"imzalı" bayrağını ayarlar, ancak derlemeyi özel anahtarla gerçekten imzalamak değil. Bu kişiler yayımlanan "tam
olarak imzalı" derlemeleri ile uyumludur, ancak derlemeleri imzalamak için kullanılan özel anahtar erişimi olmayan
derlemeler oluşturmak istediğiniz açık kaynak projeleri için kullanışlıdır. Neredeyse hiçbir tüketiciler derleme tam
olarak imzalı denetlemek gerçekten gerekli olduğundan, bunlar genel olarak derlenen bütünleştirilmiş kodlarda
nerede tam olarak imzalı bir kullanılan neredeyse her senaryoda kendisini adamıştır.
Bu derleyici seçeneğini Visual Studio geliştirme ortamında ayarlamak için
1. Açık özellikleri proje sayfası.
2. Değiştirme gecikme yalnızca oturum özelliği.

Ayrıca bkz.
C# Derleyici - delaysıgn seçeneği
C# derleyicisi - keyfıle seçeneği
C# Derleyici - keycontaıner seçeneği
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-recurse (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

-Recurse seçeneği, belirtilen dizinin (dir) veya proje dizininin tüm alt dizinlerindeki kaynak kodu dosyalarını
derlemenize olanak sağlar.

Sözdizimi
-recurse:[dir\]file

Arguments
dir seçim
Aramanın başlamasını istediğiniz dizin. Bu belirtilmemişse, arama proje dizininde başlar.
file
Aranacak dosya (lar). Joker karakterlere izin verilir.

Açıklamalar
-Recurse seçeneği, kaynak kodu dosyalarını belirtilen dizinin ( dir ) veya proje dizininin tüm alt dizinlerinde
derlemenize olanak tanır.
Proje dizinindeki tüm eşleşen dosyaları -Recursekullanmadan derlemek için dosya adında joker karakterler
kullanabilirsiniz.
Bu derleyici seçeneği Visual Studio 'da kullanılamaz ve program aracılığıyla değiştirilemez.

Örnek
Geçerli dizindeki C# tüm dosyaları derler:

csc *.cs

Dir1\dir2 dizinindeki tüm C# dosyaları ve bunun altındaki dizinleri derler ve dir2. dll oluşturur:

csc -target:library -out:dir2.dll -recurse:dir1\dir2\*.cs

Ayrıca bkz.
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-Reference (C# derleyici seçenekleri)
23.10.2019 • 5 minutes to read • Edit Online

-Reference seçeneği, derleyicinin belirtilen dosyadaki ortak tür bilgilerini geçerli projeye almasına ve böylece
belirtilen derleme dosyalarından meta verilere başvurmasına olanak tanır.

Sözdizimi
-reference:[alias=]filename
-reference:filename

Arguments
filename
Bir derleme bildirimi içeren dosyanın adı. Birden fazla dosyayı içeri aktarmak için her dosya için ayrı bir
başvuru seçeneği ekleyin.
alias
Derlemedeki tüm C# ad alanlarını içerecek bir kök ad alanını temsil edecek geçerli bir tanımlayıcı.

Açıklamalar
Birden fazla dosyadan içeri aktarmak için her dosya için bir -Reference seçeneği ekleyin.
İçeri aktardığınız dosyaların bir bildirim içermesi gerekir; çıkış dosyası -target: Moduledışındaki -target
seçeneklerinden biriyle derlenmiş olmalıdır.
-r -Referenceöğesinin kısa biçimidir.
Derleme bildirimi içermeyen bir çıkış dosyasından meta verileri içeri aktarmak için -addmodule kullanın.
Başka bir derlemeye (derleme B ) başvuran bir derlemeye (derleme A) başvurdıysanız, şu durumlarda derleme B
'ye başvurmanız gerekir:
Derleme A 'dan kullandığınız tür bir türden devralır veya derleme B 'den bir arabirim uygular.
B derlemesinden dönüş türü veya parametre türü olan bir alan, özellik, olay veya yöntem çağırılır.
Bir veya daha fazla derleme başvurularınızın bulunduğu dizini belirtmek için -lib kullanın. -Lib konusu Ayrıca
derleyicinin derlemeleri arayacağı dizinleri de açıklar.
Derleyicinin bir derlemede değil bir derlemede bir tür tanımasını sağlamak için, türün bir örneğini tanımlayarak
yapabileceğiniz, türü çözümlemeye zorlanmalıdır. Derleyici için bir derlemede tür adlarını çözümlemek için
başka yollar vardır: Örneğin, derlemedeki bir türden kalýtýmla, tür adı daha sonra derleyici tarafından
tanınacaktır.
Bazen aynı bileşenin iki farklı sürümüne tek bir derlemede başvurulmasý gerekir. Bunu yapmak için, iki Dosya
arasında ayrım yapmak üzere her bir dosya için -Reference anahtarındaki diğer ad alt öğesini kullanın. Bu
diğer ad, bileşen adı için bir niteleyici olarak kullanılacak ve dosyalardan birindeki bileşene çözümlencektir.
Yaygın olarak kullanılan .NET Framework derlemelerine başvuran Csc yanıt (. rsp) dosyası varsayılan olarak
kullanılır. Derleyicinin Csc. rsp kullanmasını istemiyorsanız -noconfig kullanın.
NOTE
Visual Studio 'da Başvuru Ekle iletişim kutusunu kullanın. Daha fazla bilgi için nasıl yapılır: Başvuru Yöneticisi 'Nikullanarak
başvuruları ekleyin veya kaldırın. -reference Başvuru Ekle iletişim kutusunu kullanarak başvurular ekleme ve
başvuruları ekleme arasındaki denk davranışı sağlamak için, eklemekte olduğunuz derleme için birlikte çalışma türlerini
katıştır özelliğini false olarak ayarlayın. Özellik için varsayılan değer true 'dur.

Örnek
Bu örnek, extern diğer ad özelliğinin nasıl kullanılacağını gösterir.
Kaynak dosyayı derleyip daha önce derlenen ve grid.dll grid20.dll ' dan meta verileri içeri aktarın. İki DLL
aynı bileşenin ayrı sürümlerini içerir ve kaynak dosyayı derlemek için diğer ad seçenekleriyle iki başvuru
kullanırsınız. Seçenekler şöyle görünür:

-reference:GridV1=grid.dll -reference:GridV2=grid20.dll

Bu, programınızda bir GridV1 extern deyime göre kullandığınız GridV2 dış diğer adları ve ' ı ayarlar:

extern alias GridV1;


extern alias GridV2;
// Using statements go here.

Bu işlem tamamlandıktan sonra, aşağıdaki gibi denetim grid.dll GridV1 adının önüne ekleyerek kılavuz
denetimine başvurabilirsiniz:

GridV1::Grid

Ayrıca, aşağıdaki grid20.dll GridV2 gibi denetim adının önüne ekleyerek kılavuz denetimine başvurabilirsiniz:

GridV2::Grid

Ayrıca bkz.
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-refout (C# derleyici seçenekleri)
24.10.2019 • 2 minutes to read • Edit Online

-Refout seçeneği, başvuru derlemesinin çıkış olması gereken bir dosya yolunu belirtir. Bu, yayma API 'sindeki
metadataPeStream çevirir. Bu seçenek, MSBuild 'in ProduceReferenceAssembly Project özelliğine karşılık gelir.

Sözdizimi
-refout:filepath

Arguments
başvuru derlemesi için FilePath filepath . Genellikle birincil derlemenin ile eşleşmelidir. Önerilen kural (MSBuild
tarafından kullanılır), başvuru derlemesini birincil derlemeye göre bir "ref/" alt klasörüne yerleştirmelidir.

Açıklamalar
Başvuru derlemeleri, kitaplığın ortak API yüzeyini göstermek için gereken en düşük meta veri miktarını içeren
özel bir derleme türüdür. Derleme araçlarındaki bir derlemeye başvururken önemli olan tüm Üyeler için
bildirimler içerirler, ancak API sözleşmeleri üzerinde herhangi bir observable etkisi olmayan özel üyelerin tüm üye
uygulamalarını ve bildirimlerini hariç tutar. Daha fazla bilgi için bkz. .NET kılavuzundaki başvuru derlemeleri .
@No__t_0 ve -refonly seçenekleri birbirini dışlıyor.

Ayrıca bkz.
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-refonly (C# derleyici seçenekleri)
24.10.2019 • 2 minutes to read • Edit Online

-Refonly seçeneği, bir başvuru derlemesinin birincil çıktı olarak bir uygulama derlemesi yerine çıkış olması
gerektiğini gösterir. Başvuru derlemeleri yürütülene kadar -refonly parametresi, pdb 'leri çıktısını sessizce devre
dışı bırakır. Bu seçenek, MSBuild 'in ProduceOnlyReferenceAssembly Project özelliğine karşılık gelir.

Sözdizimi
-refonly

Açıklamalar
Başvuru derlemeleri, kitaplığın ortak API yüzeyini göstermek için gereken en düşük meta veri miktarını içeren
özel bir derleme türüdür. Derleme araçlarındaki bir derlemeye başvururken önemli olan tüm Üyeler için
bildirimler içerirler, ancak API sözleşmeleri üzerinde herhangi bir observable etkisi olmayan özel üyelerin tüm üye
uygulamalarını ve bildirimlerini hariç tutar. Daha fazla bilgi için bkz. .NET kılavuzundaki başvuru derlemeleri .
@No__t_0 ve -refout seçenekleri birbirini dışlıyor.

Ayrıca bkz.
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-Resource (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

Belirtilen kaynağı çıkış dosyasına katıştırır.

Sözdizimi
-resource:filename[,identifier[,accessibility-modifier]]

Arguments
filename
Çıkış dosyasına eklemek istediğiniz .NET Framework kaynak dosyası.
identifierseçim
Kaynağın mantıksal adı; kaynağı yüklemek için kullanılan ad. Varsayılan değer, dosya adının adıdır.
accessibility-modifier seçim
Kaynağın erişilebilirliği: public veya Private. Varsayılan değer geneldir.

Açıklamalar
Kaynağı bir derlemeye bağlamak ve kaynak dosyasını çıkış dosyasına eklemek için -linkresource kullanın.
Varsayılan olarak, kaynaklar C# derleyici kullanılarak oluşturulduğunda derlemede ortaktır. Kaynakları özel hale
getirmek için erişilebilirlik değiştiricisi private olarak belirtin. public Veya private dışında başka bir
erişilebilirliği olamaz.
, Örneğin Resgen. exe veya geliştirme ortamında oluşturulmuş bir .NET Framework kaynak dosyası ise,
System.Resources ad alanındaki üyelerle erişilebilir. filename Daha fazla bilgi için bkz.
System.Resources.ResourceManager. Diğer tüm kaynaklar için, çalışma zamanında GetManifestResource kaynağa
erişmek üzere Assembly sınıfındaki yöntemleri kullanın.
-res , -Resource' in kısa biçimidir.
Çıkış dosyasındaki kaynakların sırası, komut satırında belirtilen sırada belirlenir.
Bu derleyici seçeneğini Visual Studio geliştirme ortamında ayarlamak için
1. Projenize bir kaynak dosyası ekleyin.
2. Çözüm Gezginieklemek istediğiniz dosyayı seçin.
3. Özellikler penceresinde dosya Için derleme eylemi ' ni seçin.
4. Derleme eylemini gömülü kaynağaayarlayın.
Bu derleyici seçeneğini program aracılığıyla ayarlama hakkında daha fazla bilgi için bkz BuildAction.

Örnek
Derleme in.cs ve kaynak dosyası rf.resource iliştirme:
csc -resource:rf.resource in.cs

Ayrıca bkz.
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-subsystemversion (C# derleyici seçenekleri)
5.12.2019 • 3 minutes to read • Edit Online

Oluşturulan yürütülebilir dosyanın çalıştırılabileceği alt sistemin en düşük sürümünü belirtir ve bu sayede
yürütülebilir dosyanın çalışacağı Windows sürümlerini belirler. En yaygın olarak, bu seçenek yürütülebilir dosyanın
eski Windows sürümleriyle kullanılamayan belirli güvenlik özelliklerinden yararlanmasını sağlar.

NOTE
Alt sistemin kendisini belirtmek için -target derleyici seçeneğini kullanın.

Sözdizimi
-subsystemversion:major.minor

Parametreler
major.minor

Alt sistemin gerekli en düşük sürümü, birincil ve ikincil sürümler için nokta gösteriminde ifade edilir. Örneğin, bu
seçeneğin değerini 6,01 olarak ayarlarsanız, uygulamanın bu konunun ilerleyen kısımlarında açıklandığı gibi, bir
uygulamanın Windows 7 ' den eski bir işletim sisteminde çalışabilebileceğinizi belirtebilirsiniz. major için
değerleri ve tamsayılar olarak minor belirtmeniz gerekir.
minor sürümünde önde gelen sıfır sürümü değiştirmez, ancak sondaki sıfırları. Örneğin, 6,1 ve 6,01 aynı sürüme
başvurun, ancak 6,10 farklı bir sürüme başvurur. Karışıklığın önüne geçmek için küçük sürümü iki basamakla ifade
etmenizi öneririz.

Açıklamalar
Aşağıdaki tabloda, Windows 'un ortak alt sistem sürümleri listelenmektedir.

WINDOWS SÜRÜMÜ ALT SISTEM SÜRÜMÜ

Windows 2000 5.00

Windows XP 5.01

Windows Server 2003 5.02

Windows Vista 6.00

Windows 7 6.01

Windows Server 2008 6.01

Windows 8 6.02
Varsayılan değerler
-Subsystemversion derleyici seçeneğinin varsayılan değeri aşağıdaki listede yer alan koşullara bağlıdır:
Aşağıdaki listede herhangi bir derleyici seçeneğinin ayarlanmış olması halinde varsayılan değer 6,02 ' dir:
-target:appcontainerexe
-target:winmdobj
-platform:arm
MSBuild kullanıyorsanız varsayılan değer 6,00 ' dir. .NET Framework 4,5 ' i hedefliyorsanız ve bu listede
daha önce belirtilen derleyici seçeneklerinden hiçbirini belirlemediniz.
Önceki koşullardan hiçbiri doğru değilse varsayılan değer 4,00 ' dir.

Bu seçeneği ayarlama
Visual Studio 'da -subsystemversion derleyici seçeneğini ayarlamak için,. csproj dosyasını açmanız ve MSBuild
XML 'teki SubsystemVersion özelliği için bir değer belirtmeniz gerekir. Visual Studio IDE 'de bu seçeneği
ayarlayamazsınız. Daha fazla bilgi için bu konunun önceki kısımlarında "varsayılan değerler" veya genel MSBuild
proje özellikleribölümüne bakın.

Ayrıca bkz.
C# Derleyici Seçenekleri
-target (C# derleyici seçenekleri)
27.11.2019 • 2 minutes to read • Edit Online

-Target derleyici seçeneği dört formdan birinde belirtilebilir:


-target:appcontainerexe
Windows 8. x Mağazası uygulamaları için bir. exe dosyası oluşturmak için.
-target:exe
Bir. exe dosyası oluşturmak için.
-target:library
Bir kod kitaplığı oluşturun.
-target:module
Bir modül oluşturmak için.
-target:winexe
Bir Windows programı oluşturmak için.
-target:winmdobj
Ara. winmdobj dosyası oluşturmak için.
-Target: Modulebelirtmediğiniz takdirde -target bir .NET Framework derleme bildiriminin bir çıkış dosyasına
yerleştirilmesine neden olur. Daha fazla bilgi için bkz. .NET ve ortak özniteliklerde derlemeler .
Derleme bildirimi, derleme içindeki ilk. exe çıkış dosyasına veya. exe çıkış dosyası yoksa ilk DLL 'de yerleştirilir.
Örneğin, aşağıdaki komut satırında, bildirim 1.exe yerleştirilecek:

csc -out:1.exe t1.cs -out:2.netmodule t2.cs

Derleyici, derleme başına yalnızca bir derleme bildirimi oluşturur. Bir derlemedeki tüm dosyalar hakkındaki
bilgiler, derleme bildirimine yerleştirilir. -Target: Module ile oluşturulanlar hariç tüm çıkış dosyaları bir derleme
bildirimi içerebilir. Komut satırında birden çok çıkış dosyası üretilirken, yalnızca bir derleme bildirimi
oluşturulabilir ve komut satırında belirtilen ilk çıkış dosyasına gitmelidir. İlk çıkış dosyasının ne olduğuna
bakılmaksızın ( -target: exe, -target: winexe, -target: Library veya -target: Module), aynı derlemede üretilen
diğer çıkış dosyaları modüller olmalıdır ( -target: Module).
Bir derleme oluşturursanız, kodunuzun tümünün veya bir kısmının CLSCompliantAttribute özniteliğiyle CLS
uyumlu olduğunu belirtebilirsiniz.

// target_clscompliant.cs
[assembly:System.CLSCompliant(true)] // specify assembly compliance

[System.CLSCompliant(false)] // specify compliance for an element


public class TestClass
{
public static void Main() {}
}

Bu derleyici seçeneğini program aracılığıyla ayarlama hakkında daha fazla bilgi için bkz. OutputType.

Ayrıca bkz.
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-subsystemversion (C# derleyici seçenekleri)
-target: appcontainerexe (C# derleyici seçenekleri)
27.11.2019 • 2 minutes to read • Edit Online

-Target: appcontainerexe derleyici seçeneğini kullanırsanız, derleyici bir uygulama kapsayıcısında çalıştırılması
gereken bir Windows çalıştırılabilir (. exe) dosyası oluşturur. Bu seçenek -target: winexe ile eşdeğerdir, ancak
Windows 8. x Mağazası uygulamaları için tasarlanmıştır.

Sözdizimi
-target:appcontainerexe

Açıklamalar
Uygulamanın bir uygulama kapsayıcısında çalışmasını gerektirmek için, bu seçenek taşınabilir yürütülebilir (PE )
dosyasında bir bit ayarlar. Bu bit ayarlandığında, CreateProcess yöntemi bir uygulama kapsayıcısının dışında
yürütülebilir dosyayı başlatmaya çalışırsa bir hata oluşur.
-Out seçeneğini kullanmadığınız takdirde, çıkış dosyası adı Main metodunu içeren giriş dosyasının adını alır.
Bu seçeneği bir komut isteminde belirttiğinizde, yürütülebilir dosyayı oluşturmak için bir sonraki dışarı veya -
hedef seçeneğine kadar tüm dosyalar kullanılır.
Bu derleyici seçeneğini IDE içinde ayarlamak için
1. Çözüm Gezgini' de, projeniz için kısayol menüsünü açın ve ardından Özellikler' i seçin.
2. Uygulama sekmesinde, Çıkış türü listesinde, Windows Mağazası uygulaması' nı seçin.
Bu seçenek yalnızca Windows 8. x Mağazası uygulama şablonları için kullanılabilir.
Bu derleyici seçeneğini program aracılığıyla ayarlama hakkında daha fazla bilgi için bkz. OutputType.

Örnek
Aşağıdaki komut filename.cs , yalnızca bir uygulama kapsayıcısında çalıştırılabilen bir Windows yürütülebilir
dosyasına derler.

csc -target:appcontainerexe filename.cs

Ayrıca bkz.
-target (C# derleyici seçenekleri)
-target: winexe (C# derleyici seçenekleri)
C# Derleyici Seçenekleri
-target: exe (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

-Target: exe seçeneği derleyicinin YÜRÜTÜLEBILIR (exe), konsol uygulaması oluşturmasına neden olur.

Sözdizimi
-target:exe

Açıklamalar
-Target: exe seçeneği varsayılan olarak etkindir. Yürütülebilir dosya,. exe uzantısıyla oluşturulacaktır.
Bir Windows program yürütülebilir dosyası oluşturmak için -target: winexe kullanın.
Aksi belirtilmedikçe, çıkış dosyası adı, ana yöntemi içeren giriş dosyasının adını alır.
Komut satırında belirtildiğinde, bir sonraki -Out veya -target: Module seçeneğine kadar olan tüm dosyalar,. exe
dosyasını oluşturmak için kullanılır
Bir. exe dosyasına derlenen kaynak kodu dosyalarında bir ve yalnızca bir ana Yöntem gereklidir. -Main derleyici
seçeneği, kodunuzun bir Main yöntemi olan birden fazla sınıfa sahip olduğu durumlarda Main yöntemini hangi
sınıfın içerdiğini belirtmenizi sağlar.
Bu derleyici seçeneğini Visual Studio geliştirme ortamında ayarlamak için
1. Projenin Özellikler sayfasını açın.
2. Uygulama Özellik sayfasına tıklayın.
3. Çıktı türü özelliğini değiştirin.
Bu derleyici seçeneğini program aracılığıyla ayarlama hakkında daha fazla bilgi için bkz OutputType.

Örnek
Aşağıdaki komut satırlarından her biri derler in.cs , şunu oluşturur: in.exe

csc -target:exe in.cs


csc in.cs

Ayrıca bkz.
-target (C# derleyici seçenekleri)
C# Derleyici Seçenekleri
-target: Library (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

-Target: Library seçeneği derleyicinin yürütülebilir dosya (exe) yerine bir dinamik bağlantı KITAPLıĞı (dll)
oluşturmasına neden olur.

Sözdizimi
-target:library

Açıklamalar
DLL,. dll uzantısıyla oluşturulacaktır.
Aksi belirtilmediği takdirde, çıkış dosyası adı ilk giriş dosyasının adını alır.
Komut satırında belirtildiğinde, bir sonraki -Out veya -target: Module seçeneğine kadar olan tüm dosyalar,. dll
dosyasını oluşturmak için kullanılır.
Bir. dll dosyası oluştururken Main yöntemi gerekli değildir.
Bu derleyici seçeneğini Visual Studio geliştirme ortamında ayarlamak için
1. Projenin Özellikler sayfasını açın.
2. Uygulama Özellik sayfasına tıklayın.
3. Çıktı türü özelliğini değiştirin.
Bu derleyici seçeneğini program aracılığıyla ayarlama hakkında daha fazla bilgi için bkz OutputType.

Örnek
Derle in.cs , oluşturma in.dll :

csc -target:library in.cs

Ayrıca bkz.
-target (C# derleyici seçenekleri)
C# Derleyici Seçenekleri
-target: Module (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

Bu seçenek derleyicinin bir derleme bildirimi üretmesine neden olur.

Sözdizimi
-target:module

Açıklamalar
Varsayılan olarak, bu seçenekle derleme tarafından oluşturulan çıkış dosyası. netmodule uzantısına sahip
olacaktır.
Derleme bildirimine sahip olmayan bir dosya, .NET Framework ortak dil çalışma zamanı tarafından
yüklenemez. Ancak, bu tür bir dosya, -addmodulearacılığıyla bir derlemenin derleme bildirimine eklenebilir.
Tek bir derlemede birden fazla modül oluşturulduysa, bir modüldeki iç türler derlemedeki diğer modüller için
kullanılabilir olacaktır. Bir modüldeki kod, başka bir internal modüldeki türlere başvurduğunda, her iki
modülün da -addmodulearacılığıyla bir derleme bildirimine dahil olması gerekir.
Visual Studio geliştirme ortamında modül oluşturma desteklenmez.
Bu derleyici seçeneğini program aracılığıyla ayarlama hakkında daha fazla bilgi için bkz OutputType.

Örnek
Derle in.cs , oluşturma in.netmodule :

csc -target:module in.cs

Ayrıca bkz.
-target (C# derleyici seçenekleri)
C# Derleyici Seçenekleri
-target: winexe (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

-Target: winexe seçeneği derleyicinin YÜRÜTÜLEBILIR (exe), Windows programı oluşturmasına neden olur.

Sözdizimi
-target:winexe

Açıklamalar
Yürütülebilir dosya,. exe uzantısıyla oluşturulacaktır. Windows programı, .NET Framework kitaplığından veya
Windows API 'Leriyle bir kullanıcı arabirimi sağlayan bir programdır.
Bir konsol uygulaması oluşturmak için -target: exe ' yi kullanın.
Aksi belirtilmedikçe, çıkış dosyası adı, ana yöntemi içeren giriş dosyasının adını alır.
Komut satırında belirtildiğinde, Windows programını oluşturmak için sonraki dışarı veya -hedef seçeneğine
kadar tüm dosyalar kullanılır.
Bir. exe dosyasına derlenen kaynak kodu dosyalarında bir ve yalnızca bir ana Yöntem gereklidir. -Main seçeneği,
kodunuzun bir Main yöntemi olan birden fazla sınıfa sahip olduğu durumlarda, hangi sınıfın ana yöntemi
içerdiğini belirtmenizi sağlar.
Bu derleyici seçeneğini Visual Studio geliştirme ortamında ayarlamak için
1. Projenin Özellikler sayfasını açın.
2. Uygulama Özellik sayfasına tıklayın.
3. Çıktı türü özelliğini değiştirin.
Bu derleyici seçeneğini program aracılığıyla ayarlama hakkında daha fazla bilgi için bkz OutputType.

Örnek
Bir in.cs Windows programında derle:

csc -target:winexe in.cs

Ayrıca bkz.
-target (C# derleyici seçenekleri)
C# Derleyici Seçenekleri
-target: winmdobj (C# derleyici seçenekleri)
27.11.2019 • 2 minutes to read • Edit Online

-Target: winmdobj derleyici seçeneğini kullanırsanız, derleyici Windows çalışma zamanı ikili (. winmd) dosyasına
dönüştürebileceğiniz bir ara. winmdobj dosyası oluşturur. . Winmd dosyası daha sonra JavaScript ve C++
programlar tarafından, yönetilen dil programlarına ek olarak tüketilebilir.

Sözdizimi
-target:winmdobj

Açıklamalar
Winmdobj ayarı derleyiciye bir ara modülün gerekli olduğunu bildirir. Yanıt olarak, Visual Studio C# sınıf
kitaplığını bir. winmdobj dosyası olarak derler. . Winmdobj dosyası daha sonra bir Windows meta veri (. winmd)
dosyası oluşturmak için WinMDExp dışarı aktarma aracı aracılığıyla beslenebilir. . Winmd dosyası, özgün
kitaplıktan kodu ve JavaScript veya C++ Windows çalışma zamanı tarafından kullanılan winmd meta verilerini
içerir.
-Target: winmdobj derleyici seçeneği kullanılarak derlenen bir dosyanın çıktısı yalnızca Wımmdexp Export aracı
için giriş olarak kullanılmak üzere tasarlanmıştır; . winmdobj dosyasının kendisine doğrudan başvurulmuyor.
-Out seçeneğini kullanmadığınız takdirde, çıkış dosyası adı ilk giriş dosyasının adını alır. Main yöntemi gerekli
değildir.
Bir komut isteminde-target: winmdobj seçeneğini belirtirseniz, Windows programını oluşturmak için bir sonraki -
Out veya -target: Module seçeneği görüntüleninceye kadar tüm dosyalar kullanılır.
Bu derleyici seçeneğini Windows Mağazası uygulaması için Visual Studio IDE'de ayarlamak için
1. Çözüm Gezgini' de, projeniz için kısayol menüsünü açın ve ardından Özellikler' i seçin.
2. Uygulama sekmesini seçin.
3. Çıktı türü listesinde, winmd dosyası' nı seçin.
Winmd dosyası seçeneği yalnızca Windows 8. x Mağazası uygulama şablonları için kullanılabilir.
Bu derleyici seçeneğini program aracılığıyla ayarlama hakkında daha fazla bilgi için bkz. OutputType.

Örnek
Aşağıdaki komut filename.cs bir ara. winmdobj dosyasına derler.

csc -target:winmdobj filename.cs

Ayrıca bkz.
-target (C# derleyici seçenekleri)
C# Derleyici Seçenekleri
-unsafe (C# Derleyici Seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

-Unsafe derleyici seçeneği verir kullanan kod güvenli derlemek için anahtar sözcüğü.

Sözdizimi
-unsafe

Açıklamalar
Güvenli olmayan kod hakkında daha fazla bilgi için bkz: güvenli olmayan kod ve işaretçiler.
Bu derleyici seçeneğini Visual Studio geliştirme ortamında ayarlamak için
1. Projenin açın özellikleri sayfası.
2. Tıklayın derleme özellik sayfası.
3. Seçin güvenli olmayan koda izin ver onay kutusu.
Bu seçenek csproj dosyasında eklemek için
Projesi için .csproj dosyasını açın ve aşağıdaki öğeleri ekleyin:

<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>

Bu derleyici seçeneğini program üzerinden ayarlamak hakkında daha fazla bilgi için bkz. AllowUnsafeBlocks.

Örnek
Derleme in.cs güvenli olmayan modu:

csc -unsafe in.cs

Ayrıca bkz.
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-utf8output (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

-Utf8output seçeneği, DERLEYICI çıkışını utf-8 kodlaması kullanarak görüntüler.

Sözdizimi
-utf8output

Açıklamalar
Bazı uluslararası yapılandırmalarda, Derleyici çıktısı konsolunda doğru şekilde görüntülenemez. Bu
yapılandırmalarda -utf8output ve derleyici çıkışını bir dosyaya yeniden yönlendir ' i kullanın.
Bu derleyici seçeneği Visual Studio 'da kullanılamaz ve program aracılığıyla değiştirilemez.

Ayrıca bkz.
C# Derleyici Seçenekleri
-warn (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

-Warn seçeneği derleyicinin görüntüleyeceği uyarı düzeyini belirtir.

Sözdizimi
-warn:option

Arguments
option
Derleme için görüntülenmesini istediğiniz uyarı düzeyi: Daha düşük sayılar yalnızca yüksek önem derecesine sahip
uyarıları gösterir; daha yüksek numaralar daha fazla uyarı gösterir. Geçerli değerler 0-4 ' dir:

UYARI DÜZEYI AÇIKLAMA

0 Tüm uyarı iletilerinin emisyonunu kapatır.

1. Ciddi uyarı iletileri görüntüler.

2 Düzey 1 uyarılarını ve sınıf üyelerini gizleme hakkında uyarılar


gibi bazı, daha az önemli uyarıları görüntüler.

3 Düzey 2 uyarılarını ve her zaman veya true false olarak


değerlendirme yapan ifadeler hakkında uyarılar gibi bazı, daha
az önemli uyarıları görüntüler.

4 (varsayılan) Tüm düzey 3 uyarılarını ve bilgilendirici uyarıları görüntüler.

Açıklamalar
Bir hata veya uyarı hakkında bilgi almak için yardım dizinindeki hata kodunu arayabilirsiniz. Bir hata veya uyarı
hakkında bilgi almanın diğer yolları için bkz C# . derleyici hataları.
Tüm uyarıları hata olarak değerlendirmek için -warnaserror kullanın. Belirli uyarıları devre dışı bırakmak için -
nowarn kullanın.
-w , -Warnkısa biçimidir.
Bu derleyici seçeneğini Visual Studio geliştirme ortamında ayarlamak için
1. Projenin Özellikler sayfasını açın.
2. Yapı özelliği sayfasına tıklayın.
3. Uyarı düzeyi özelliğini değiştirin.
Bu derleyici seçeneğini program aracılığıyla ayarlama hakkında daha fazla bilgi için bkz WarningLevel.

Örnek
Derleyin in.cs ve derleyicinin yalnızca düzey 1 uyarılarını görüntülemesini sağlayabilirsiniz:

csc -warn:1 in.cs

Ayrıca bkz.
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-warnaserror (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

-Warnaserror + seçeneği tüm uyarıları hata olarak değerlendirir

Sözdizimi
-warnaserror[+ | -][:warning-list]

Açıklamalar
Normalde uyarı olarak bildirilen tüm iletiler, bunun yerine hata olarak bildirilir ve derleme işlemi durdurulur (çıktı
dosyası derlenmemiştir).
Varsayılan olarak, -warnaserror- , bir çıkış dosyasının oluşturulmasını engellemez uyarısı oluşmasına neden olur. -
warnaserror + ile aynı olan warnaserror, uyarıların hata olarak işlenmesine neden olur.
İsteğe bağlı olarak, yalnızca birkaç özel uyarının hata olarak değerlendirilmesini istiyorsanız, hata olarak
değerlendirilecek uyarı numaralarının virgülle ayrılmış bir listesini belirtebilirsiniz.
Derleyicinin görüntülemesini istediğiniz uyarı düzeyini belirtmek için -Warn kullanın. Belirli uyarıları devre dışı
bırakmak için -nowarn kullanın.
Bu derleyici seçeneğini Visual Studio geliştirme ortamında ayarlamak için
1. Projenin Özellikler sayfasını açın.
2. Yapı özelliği sayfasına tıklayın.
3. Uyarıları hata olarak değerlendir özelliğini değiştirin.
Bu derleyici seçeneğini program aracılığıyla ayarlamak için, TreatWarningsAsErrorsbkz.

Örnek
Derle in.cs ve derleyicinin hiçbir uyarı görüntülememe:

csc -warnaserror in.cs


csc -warnaserror:642,649,652 in.cs

Ayrıca bkz.
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-win32icon (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

-Win32icon seçeneği çıkış dosyasına bir. ico dosyası ekler ve bu, çıktı dosyasına dosya Gezgini 'nde istenen
görünümü verir.

Sözdizimi
-win32icon:filename

Arguments
filename
Çıkış dosyanıza eklemek istediğiniz. ico dosyası.

Açıklamalar
Kaynak derleyicisiile bir. ico dosyası oluşturulabilir. Visual C++ program derlerken kaynak derleyicisi çağrılır; . ico
dosyası. rc dosyasından oluşturulur.
Bir .NET Framework kaynak dosyası için bkz. -linkresource (başvuruya) veya -Resource (iliştirilecek). . Res
dosyasını içeri aktarmak için bkz. -win32res .
Bu derleyici seçeneğini Visual Studio geliştirme ortamında ayarlamak için
1. Projenin Özellikler sayfalarını açın.
2. Uygulama Özellik sayfasına tıklayın.
3. Uygulama simgesi özelliğini değiştirin.
Bu derleyici seçeneğini program aracılığıyla ayarlama hakkında daha fazla bilgi için bkz ApplicationIcon.

Örnek
rf.ico Üretmek in.cs için in.exe bir. ico dosyası derleyin ve ekleyin:

csc -win32icon:rf.ico in.cs

Ayrıca bkz.
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
-win32manifest (C# derleyici seçenekleri)
23.10.2019 • 4 minutes to read • Edit Online

Bir projenin Taşınabilir çalıştırılabilir (PE ) dosyasına gömülecek Kullanıcı tanımlı bir Win32 uygulama bildirim
dosyası belirtmek için -win32manifest seçeneğini kullanın.

Sözdizimi
-win32manifest: filename

Arguments
filename
Özel bildirim dosyasının adı ve konumu.

Açıklamalar
Varsayılan olarak, görsel C# derleyici Istenen "asInvoker" yürütme düzeyini belirten bir uygulama bildirimi
katıştırır. Bu, bildirimi, yürütülebilir dosyanın oluşturulduğu klasörde, genellikle Visual Studio kullandığınızda
bin\Debug veya bin\Release klasöründe oluşturur. Örneğin, istenen "highestAvailable" veya
"requireAdministrator" yürütme düzeyini belirtmek için özel bir bildirim sağlamak istiyorsanız, dosyanın adını
belirtmek için bu seçeneği kullanın.

NOTE
Bu seçenek ve -win32res (C# derleyici seçenekleri) seçeneği birbirini dışlıyor. Her iki seçeneği de aynı komut satırında
kullanmayı denerseniz, bir derleme hatası alırsınız.

İstenen bir yürütme düzeyini belirten uygulama bildirimi olmayan bir uygulama, Windows 'daki Kullanıcı hesabı
denetimi özelliği altında dosya/kayıt defteri sanallaştırmaya tabidir. Daha fazla bilgi için bkz. Kullanıcı hesabı
denetimi.
Uygulamanız, bu koşullardan biri doğru olduğunda sanallaştırmaya tabi olacaktır:
-Nowin32manifest seçeneğini kullanın ve -win32res seçeneğini kullanarak sonraki bir derleme adımında
veya Windows kaynak (. res) dosyasının bir parçası olarak bir bildirim sağlamaz.
İstenen yürütme düzeyini belirtmeyen özel bir bildirim sağlarsınız.
Visual Studio varsayılan bir. manifest dosyası oluşturur ve yürütülebilir dosyanın yanı sıra hata ayıklama ve sürüm
dizinlerinde depolar. Herhangi bir metin düzenleyicisinde bir tane oluşturarak ve sonra dosyayı projeye ekleyerek
özel bir bildirim ekleyebilirsiniz. Alternatif olarak, Çözüm Gezgini' de Proje simgesine sağ tıklayıp Yeni öğe
Ekle' ye ve ardından uygulama bildirim dosyası' na tıklayabilirsiniz. Yeni veya mevcut bildirim dosyanızı
ekledikten sonra, bildirim açılan listesinde görünür. Daha fazla bilgi için bkz. uygulama sayfası, proje
TasarımcısıC#().
Uygulama bildirimini özel derleme sonrası bir adım olarak veya bir Win32 kaynak dosyasının parçası olarak -
nowin32manifest (C# derleyici seçenekleri) seçeneğini kullanarak sağlayabilirsiniz. Uygulamanızın Windows Vista
'da dosya veya kayıt defteri sanallaştırmaya tabi olmasını istiyorsanız bu seçeneği kullanın. Bu, derleyicinin
Taşınabilir çalıştırılabilir (PE ) dosyasında varsayılan bir bildirim oluşturmasını ve katıştırmasını engeller.
Örnek
Aşağıdaki örnek, Visual C# DERLEYICISININ bir PE 'ye eklediği varsayılan bildirimi gösterir.

NOTE
Derleyici, XML 'e "MyApplication. app" standart bir uygulama adı ekler. Bu, uygulamaların Windows Server 2003 Service Pack
3 üzerinde çalışmasını sağlamak için geçici bir çözümdür.

<?xml version="1.0" encoding="utf-8" standalone="yes"?>


<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<requestedExecutionLevel level="asInvoker"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>

Ayrıca bkz.
C# Derleyici Seçenekleri
-nowin32manifest (C# derleyici seçenekleri)
Proje ve Çözüm Özelliklerini Yönetme
-win32res (C# derleyici seçenekleri)
23.10.2019 • 2 minutes to read • Edit Online

-Win32res seçeneği çıkış dosyasına bir Win32 kaynağı ekler.

Sözdizimi
-win32res:filename

Arguments
filename
Çıkış dosyanıza eklemek istediğiniz kaynak dosyası.

Açıklamalar
Kaynak derleyicisiIle bir Win32 kaynak dosyası oluşturulabilir. Kaynak Derleyicisi, bir Visual C++ programını
derlerken çağrılır; .rc dosyasından bir .res dosyası oluşturulur.
Bir Win32 kaynağı, uygulamanızı dosya Gezgini 'nde tanımlamanızı sağlayacak sürüm veya bit eşlem (simge)
bilgilerini içerebilir. -Win32resbelirtmezseniz, derleyici derleme sürümünü temel alan sürüm bilgilerini
oluşturacaktır.
Bir .NET Framework kaynak dosyası için bkz. -linkresource (başvuruya) veya -Resource (iliştirilecek).
Bu derleyici seçeneğini Visual Studio geliştirme ortamında ayarlamak için
1. Projenin Özellikler sayfasını açın.
2. Uygulama Özellik sayfasına tıklayın.
3. Kaynak dosyası düğmesine tıklayın ve açılan kutuyu kullanarak bir dosya seçin.

Örnek
rf.res Üretmek in.cs için in.exe bir Win32 kaynak dosyası derleyin ve ekleyin:

csc -win32res:rf.res in.cs

Ayrıca bkz.
C# Derleyici Seçenekleri
Proje ve Çözüm Özelliklerini Yönetme
C# Derleyici Hataları
24.10.2019 • 2 minutes to read • Edit Online

Bazı C# derleyici hatalarının hatanın neden oluşturulduğunu ve bazı durumlarda hatanın nasıl düzeltileceğini
açıklayan ilgili konuları vardır. Belirli bir hata iletisi için yardım 'ın kullanılabilir olup olmadığını görmek için
aşağıdaki adımlardan birini kullanın.
Çıkış penceresihata numarasını (ÖRNEĞIN, CS0029) bulun ve Microsoft docs üzerinde arama yapın.
Çıkış penceresihata numarasını (ÖRNEĞIN, CS0029) seçin ve F1 tuşunu seçin.
Dizinde, Ara kutusuna hata numarasını girin.
Bu adımlardan hiçbiri, hata hakkındaki bilgilere yol açar, bu sayfanın sonuna gidin ve hatanın numarasını veya
metnini içeren geri bildirim gönderin.
' De C#hata ve uyarı seçeneklerinin nasıl yapılandırılacağı hakkında bilgi için, bkz. derleme sayfası, proje
TasarımcısıC#().

NOTE
Bilgisayarınız, aşağıdaki yönergelerde yer alan Visual Studio kullanıcı arabirimi öğelerinden bazıları için farklı adlar veya
konumlar gösterebilir. Sahip olduğunuz Visual Studio sürümü ve kullandığınız ayarlar bu öğeleri belirler. Daha fazla bilgi için
IDE'yi kişiselleştirme.

Ayrıca bkz.
C# Derleyici Seçenekleri
Ne yazık ki bu C# hatayla ilgili bilgiler yok
Derleme Sayfası, Proje Tasarımcısı (C#)
-warn (C# derleyici seçenekleri)
-nowarn (C# derleyici seçenekleri)
Giriş
23.10.2019 • 89 minutes to read • Edit Online

C#("bkz. diyez") basit, modern, nesne odaklı ve tür açısından güvenli bir
programlama dilidir. C#C 'nin dil ailesinde köklerine sahiptir ve hemen C,
C++ve Java programcılarına tanıdık gelecektir. C#ECMA -334 standardı ve
ISO/IEC tarafından ıso/IEC 23270 standardı olarak standartlaştırılmış Ecma
International tarafından standartlaştırılmış olur. Microsoft 'un C# .NET
Framework derleyicisi, bu standartların her ikisinin de uyumlu bir
uygulamasıdır.
C#, nesne odaklı bir dildir, ancak C# daha fazla bileşen odaklı programlama
desteğini içerir. Modern yazılım tasarımı giderek, yazılım bileşenlerini, kendi
kendine içerilen ve kendi kendine açıklayan işlev paketleri biçiminde kullanır.
Bu bileşenlere anahtar, özellikler, Yöntemler ve olaylar içeren bir programlama
modeli sunduklarında; Bunlar, bileşen hakkında bildirime dayalı bilgiler
sağlayan özniteliklere sahiptir; ve kendi belgelerini içerirler. C#, bu kavramları
doğrudan desteklemek için yazılım bileşenlerinin oluşturulması ve C#
kullanılması için çok doğal bir dil sunarak dil yapıları sağlar.
Birçok C# Özellik sağlam ve dayanıklı uygulamaların yapımasına yardımcı
olur: Çöp toplama , kullanılmayan nesneler tarafından kullanılan belleği
otomatik olarak geri kazanır; özel durum işleme , hata algılama ve
kurtarmaya yönelik yapılandırılmış ve genişletilebilir bir yaklaşım sağlar; dilin
tür kullanımı uyumlu tasarımı, başlatılmamış değişkenlerden okumayı,
sınırları ötesinde dizileri dizin haline getirmek veya Denetlenmemiş tür
yayınları gerçekleştirmeyi olanaksız hale getirir.
C#Birleşik bir tür sisteminesahiptir. int Ve object C#
gibitemeltürlerdahilolmaküzeretümtürler,tekbirköktüründendevralınır. double
Bu nedenle, tüm türler ortak işlemler kümesini paylaşır ve herhangi bir türdeki
değerler tutarlı bir şekilde depolanabilir, taşınır ve çalıştırılabilir. Ayrıca, C# hem
Kullanıcı tanımlı başvuru türlerini hem de değer türlerini destekler, bu da
nesnelerin dinamik ayrılmasına ve basit yapıların satır içi depolamamasına
olanak tanır.
Programlar ve kitaplıkların zaman içinde zaman içinde gelişebilmesini
sağlamak için, tasarımına daha fazla vurgu konulmuştur. C# C# Birçok
programlama dili bu sorunla ilgileniyor ve sonuç olarak, bu dillerde yazılmış
programlar, bağımlı kitaplıkların daha yeni sürümleri tanıtıldığında gerekenden
çok daha fazla. C#Sürüm oluşturma konuları tarafından doğrudan etkilenen
tasarımın yönleri, ayrı virtual ve override değiştiriciler, yöntem aşırı
yükleme çözümlemesi kuralları ve açık arabirim üye bildirimleri için destek
içerir.
Bu bölümün geri kalanında C# dilin önemli özellikleri açıklanmaktadır. Sonraki
bölümlerde, kuralları ve özel durumları ayrıntı yönelimli ve bazen matematik
olarak anlasa da, bu bölüm, tamamlanma masrafında açıklık ve kısaltma
açısından çok çaba harcar. Amaç, okuyucuya erken programların yazılmasına
ve sonraki bölümlerin okunmasına yardımcı olacak dile bir giriş sunmaktır.
Merhaba dünya
"Hello, World" programı, genellikle bir programlama dilini tanıtmak için
kullanılır. Burada yer C#verilmiştir:

using System;

class Hello
{
static void Main() {
Console.WriteLine("Hello, World");
}
}

C#Kaynak dosyalar genellikle dosya uzantısına .cs sahiptir. "Hello, World"


programının dosyada hello.cs depolandığını varsayarak, program komut
satırı kullanılarak Microsoft C# derleyicisi ile derlenebilir

csc hello.cs

adında hello.exe bir çalıştırılabilir derleme üreten. Bu uygulama tarafından


çalıştırıldığında üretilen çıkış,

Hello, World

"Hello, World" programı, using System ad alanına başvuran bir yönergeyle


başlar. Ad alanları, programları ve kitaplıkları düzenlemek C# için hiyerarşik bir
yol sağlar. Ad alanları türler ve diğer ad alanlarını içerir — örneğin, System ad
alanı programda başvurulan Console sınıf gibi bir dizi tür içerir ve IO ve
Collections gibi diğer ad alanları vardır. Verilen using bir ad alanına
başvuruda bulunan bir yönerge, bu ad alanının üyesi olan türlerin
nitelenmemiş kullanımını mümkün değildir. Yönergesi nedeniyle program, için
System.Console.WriteLine toplu olarak kullanabilir Console.WriteLine . using

"Hello, World" programı tarafından belirtilen Main


sınıftekbirüyeyesahiptir,yöntemiadlı. Hello Main Yöntemi static değiştiriciyle
birlikte bildirilmiştir. Örnek yöntemleri, anahtar sözcüğünü this kullanarak
belirli bir kapsayan nesne örneğine başvurabilir, ancak statik yöntemler belirli
bir nesneye başvuru olmadan çalışır. Kurala göre, adlı Main statik bir yöntem,
bir programın giriş noktası olarak görev yapar.
Programın çıktısı, WriteLine System ad alanındaki Console sınıfının yöntemi
tarafından üretilir. Bu sınıf, varsayılan olarak Microsoft C# derleyicisi tarafından
otomatik olarak başvurulduğu .NET Framework sınıf kitaplıkları tarafından
sağlanır. C# Kendisinin ayrı bir çalışma zamanı kitaplığı olmadığına unutmayın.
Bunun yerine, .NET Framework çalışma zamanı kitaplığıdır C#.

Program yapısı
' Deki C# temel kurumsal kavramlar, Programlar, ad alanları, türler,
Üyelerve derlemelerdir. C#programlar bir veya daha fazla kaynak dosyadan
oluşur. Programlar, üyeleri içeren ve ad alanları halinde düzenlenebilen türleri
bildirir. Sınıflar ve arabirimler tür örnekleridir. Alanlar, Yöntemler, Özellikler ve
olaylar üye örnekleridir. C# Programlar derlendiğinde, fiziksel olarak
derlemeler halinde paketlenir. Derlemeler .dll , uygulama veya
kitaplıkuygulanıp .exe uygulamadığına bağlı olarak genellikle dosya
uzantısına sahiptir.
Örnek

using System;

namespace Acme.Collections
{
public class Stack
{
Entry top;

public void Push(object data) {


top = new Entry(top, data);
}

public object Pop() {


if (top == null) throw new InvalidOperationException();
object result = top.data;
top = top.next;
return result;
}

class Entry
{
public Entry next;
public object data;

public Entry(Entry next, object data) {


this.next = next;
this.data = data;
}
}
}
}

adlı bir Stack ad alanında adında bir sınıf bildirir. Bu sınıfın


Acme.Collections
Acme.Collections.Stack tam adı. Sınıf birçok top üye içerir: adlı bir alan, Push
ve Pop adlı iki yöntem ve adlı Entry bir iç içe sınıf. Sınıf daha fazla üç üye
içerir: adlı next alan, adlı data alan ve Oluşturucu. Entry Örneğin kaynak
kodunun dosyada acme.cs depolandığını varsayarak, komut satırı

csc /t:library acme.cs

örneği bir kitaplık (bir Main giriş noktası olmayan kod) olarak derler ve adında
acme.dll bir derleme oluşturur.

Derlemeler, ara dil (IL ) yönergeleri biçiminde çalıştırılabilir kodu ve meta


veribiçimindeki sembolik bilgileri içerir. Yürütülmeden önce, bir derlemedeki
IL kodu, .NET ortak dil çalışma zamanının tam zamanında (JıT) derleyicisi
tarafından otomatik olarak işlemciye özgü koda dönüştürülür.
Bir derleme, hem kodu hem de meta verileri içeren bir işlevsellik birimi
olduğundan, içinde #include C#yönergeler ve başlık dosyaları gerekmez.
Belirli bir derlemede yer alan ortak türler ve Üyeler, yalnızca program
derlenirken bu derlemeye C# başvurarak bir programda kullanılabilir hale
getirilir. Örneğin, bu program Acme.Collections.Stack acme.dll derlemeden
sınıfını kullanır:

using System;
using Acme.Collections;

class Test
{
static void Main() {
Stack s = new Stack();
s.Push(1);
s.Push(10);
s.Push(100);
Console.WriteLine(s.Pop());
Console.WriteLine(s.Pop());
Console.WriteLine(s.Pop());
}
}

Program dosyada test.cs depolanıyorsa test.cs , derlendikten sonra


acme.dll /r derlemeye derleyicinin seçeneği kullanılarak başvurulabilir:

csc /r:acme.dll test.cs

Bu, çalıştırıldığında bir çalıştırılabilir derleme test.exe oluşturur; Bu,


çalıştırıldığında çıktıyı üretir:

100
10
1

C#bir programın kaynak metninin birkaç kaynak dosyada depolanmasına izin


verir. Birden çok dosya C# programı derlendiğinde, tüm kaynak dosyalar
birlikte işlenir ve kaynak dosyalar birbirini tamamen başvurabilir — kavramsal
olarak, tüm kaynak dosyaları işlenmeden önce bir büyük dosyada birleştirilmiş
olur. Bildirim sırası çok önemli olduğundan, C# bazı durumlarda ileri
bildirimlere hiçbir şekilde gerek yoktur. C#kaynak dosyayı yalnızca bir ortak tür
bildirmek üzere sınırlamaz veya kaynak dosyanın adının kaynak dosyada
belirtilen bir türle eşleşmesi gerekir.

Türler ve değişkenler
' De C#iki tür tür vardır: değer türleri ve başvuru türleri. Değer türlerinin
değişkenleri doğrudan verilerini içerir, ancak başvuru türündeki değişkenler
verilerine başvuruları depolar, ikincisi ise nesneler olarak bilinir. Başvuru
türleriyle, iki değişkenin aynı nesneye başvurması ve bu nedenle bir
değişkende işlemler için diğer değişken tarafından başvurulan nesneyi
etkilemesi mümkündür. Değer türleriyle, her biri kendi verilerinin kopyasına
sahiptir ve bir üzerindeki işlemler, diğerini ( ref ve out parametre
değişkenleri hariç) etkileyecek şekilde mümkün değildir.
C#değer türleri, basit türler, sabit listesi türleri, yapı türlerive null
yapılabilir türleredaha da bölünür ve C#başvuru türleri, Sınıf türlerine,
arabirim türlerine, diziye daha fazla bölünmüştür türlerve temsilci türleri.
Aşağıdaki tabloda, tür sistemine genel bir C#bakış sağlanmaktadır.
KATEGORI AÇIKLAMA

Değer türleri Basit türler İmzalanan integral:


sbyte , short , int ,
long

İşaretsiz integral: byte ,


ushort , uint , ulong

Unicode karakterler:
char

IEEE kayan nokta: float ,


double

Yüksek duyarlıklı ondalık:


decimal

Boolean bool

Sabit listesi türleri Formun Kullanıcı tanımlı


türleri enum E {...}

Yapı türleri Formun Kullanıcı tanımlı


türleri struct S {...}

Boş değer atanabilir tipler Bir null değere sahip


diğer tüm değer türlerinin
uzantıları

Başvuru türleri Sınıf türleri Diğer tüm türlerin


Ultimate temel sınıfı:
object

Unicode dizeleri: string

Formun Kullanıcı tanımlı


türleri class C {...}

Arabirim türleri Formun Kullanıcı tanımlı


türleri
interface I {...}

Dizi türleri Tek ve çok boyutlu,


örneğin int[] ve
int[,]

Temsilci türleri Formun Kullanıcı tanımlı


türleri örn.
delegate int D(...)

Sekiz integral türü, imzalanmış veya imzasız biçimde 8 bit, 16 bit, 32-bit ve 64
bit değerleri için destek sağlar.
İki kayan nokta türü float ve double , 32-bit tek duyarlıklı ve 64-bit çift
duyarlıklı IEEE 754 biçimleri kullanılarak temsil edilir.
decimal Türü, finansal ve parasal hesaplamalar için uygun olan 128 bitlik bir
veri türüdür.
C#türü, Boole değerlerini ( true veya false olan değerler) temsil etmek için
kullanılır. bool
İçindeki C# karakter ve dize işleme Unicode kodlaması kullanır. Tür bir UTF -16
kod birimini temsil eder string ve tür bir UTF -16 kod birimi dizisini temsil
eder. char
Aşağıdaki tabloda sayısal türler C#özetlenmektedir.

KATEGORI BITLIK TÜR ARALIK/DUYARLIK

İmzalanan integral 8 sbyte -128... 127

16 short -32768... 32, 767

32 int -2147483648... 2,
147, 483, 647

64 long -
92233720368547
75808... 9, 223,
372, 036, 854,
775, 807

İşaretsiz integral 8 byte 0... 255

16 ushort 0... 65,

32 uint 0... 4, 294, 967,


295

64 ulong 0... 18, 446,, 073,


709, 551, 615

Kayan nokta 32 float 1,5 × 10 ^ − 45


ila 3,4 × 10 ^ 38,
7 basamaklı
duyarlık

64 double 5,0 × 10 ^ − 324


ila 1,7 × 10 ^ 308,
15 basamaklı
duyarlık

Decimal 128 decimal 1,0 × 10 ^ − 28


ila 7,9 × 10 ^ 28,
28 basamaklı
duyarlık

C#programlar yeni türler oluşturmak için tür bildirimleri kullanır. Tür


bildiriminde yeni türün adı ve üyeleri belirtilir. C#Türlerin beş kategorisi
Kullanıcı tarafından tanımlanabilir: sınıf türleri, yapı türleri, arabirim türleri,
sabit listesi türleri ve temsilci türleri.
Bir sınıf türü, veri üyeleri (alanlar) ve işlev üyeleri (Yöntemler, Özellikler ve
diğerleri) içeren bir veri yapısını tanımlar. Sınıf türleri, tek devralma ve çok
biçimlilik destekler, türetilmiş sınıfların temel sınıfları genişletebileceği ve
özelleştireceği mekanizmalar.
Yapı türü, veri üyeleri ve işlev üyeleri olan bir yapıyı temsil eden bir sınıf türüne
benzerdir. Ancak, sınıfların aksine yapılar değer türlerdir ve yığın ayırmayı
gerektirmez. Yapı türleri Kullanıcı tarafından belirtilen devralmayı desteklemez
ve tüm yapı türleri örtülü olarak türünden object devralınır.
Arabirim türü, bir sözleşmeyi adlandırılmış bir ortak işlev üyeleri kümesi
olarak tanımlar. Arabirim uygulayan bir sınıf veya yapı, arabirimin işlev
üyelerinin uygulamalarını sağlamalıdır. Bir arabirim birden çok temel
arabirimden devralınabilir ve bir sınıf ya da yapı birden çok arabirim
uygulayabilir.
Bir temsilci türü, belirli bir parametre listesi ve dönüş türü olan yöntemlere
yapılan başvuruları temsil eder. Temsilciler, yöntemleri değişkenlere
atanabilecek ve parametre olarak geçirilen varlıklar olarak işleme olanağı tanır.
Temsilciler, bazı diğer dillerde bulunan işlev işaretçileri kavramına benzerdir,
ancak işlev işaretçilerinden farklı olarak Temsilciler nesne yönelimli ve tür
açısından güvenlidir.
Sınıf, yapı, arabirim ve temsilci türleri tüm genel türleri destekler ve diğer
türlerle parametrelenebilir.
Sabit listesi türü, adlandırılmış sabitleri olan ayrı bir türdür. Her
numaralandırma türünün, sekiz integral türünden biri olması gereken temel bir
türü vardır. Bir sabit listesi türünün değer kümesi, temel alınan türün değerleri
kümesiyle aynıdır.
C#herhangi bir türdeki tek ve çok boyutlu dizileri destekler. Yukarıda listelenen
türlerin aksine,, kullanılmadan önce dizi türlerinin bildirilmesini gerektirmez.
Bunun yerine, dizi türleri Köşeli parantezlerle bir tür adı izleyerek oluşturulur.
Örneğin, int[] tek boyutlu bir int int diziyse, int[,] iki boyutlu bir
dizidir ve int[][] tek boyutlu dizilerinin tek boyutlu dizilerdir int .
Null yapılabilir türler, kullanılmadan önce de bildirilemez. Her null yapılamayan
değer türü T için, karşılık gelen bir null yapılabilir tür T? vardır ve bu, ek bir
değer null tutabilir. Örneğin, int? herhangi bir 32 bit tamsayı veya değeri
null tutabilecek bir türdür.

C#tür sistemi, herhangi bir tür değeri bir nesne olarak işlenemeyeceği şekilde
birleştirilmiştir. Her tür doğrudan C# veya dolaylı olarak object sınıf türünden
türetilir ve object tüm türlerin en son temel sınıfıdır. Başvuru türlerinin
değerleri, yalnızca değerleri tür object olarak görüntüleyerek nesne olarak
değerlendirilir. Değer türlerinin değerleri, kutulama ve kutudan çıkarma
işlemleri gerçekleştirerek nesneler olarak değerlendirilir. Aşağıdaki örnekte, bir
int değeri öğesine object dönüştürülüp öğesine int yeniden döndürülür.
using System;

class Test
{
static void Main() {
int i = 123;
object o = i; // Boxing
int j = (int)o; // Unboxing
}
}

Değer türünde bir değer türüne object dönüştürüldüğünde, "Box" olarak da


bilinen bir nesne örneği değeri tutacak şekilde ayrılır ve değer bu kutuya
kopyalanır. Buna karşılık, bir object başvuru bir değer türüne
dönüştürülzaman, başvurulan nesnenin doğru değer türünün bir kutusu
olması ve denetim başarılı olursa, kutudaki değer kopyalanır.
C#öğesinin Birleşik tür sistemi etkin bir şekilde değer türlerinin "isteğe bağlı"
nesneler olabileceği anlamına gelir. Birleşme nedeniyle, türü object kullanan
genel amaçlı kitaplıklar, başvuru türleri ve değer türleriyle birlikte kullanılabilir.
İçinde C#alanlar, dizi öğeleri, yerel değişkenler ve parametreler dahil olmak
üzere birkaç tür değişken vardır. Değişkenler, depolama konumlarını temsil
eder ve her değişken, aşağıdaki tabloda gösterildiği gibi, değişkende hangi
değerlerin depolanabileceğini belirleyen bir tür içerir.

DEĞIŞKEN TÜRÜ OLASI IÇERIKLER

Null yapılamayan değer türü Bu tam türden bir değer

Null yapılabilir değer türü Null değer veya bu tam tür değeri

object Bir null başvurusu, herhangi bir başvuru


türünün nesnesine başvuru veya herhangi
bir değer türünün paketlenmiş değerine
başvuru

Sınıf türü Null başvurusu, bu sınıf türünün bir


örneğine başvuru veya bu sınıf türünden
türetilmiş bir sınıfın örneğine başvuru

Arabirim türü Null başvurusu, bu arabirim türünü


uygulayan bir sınıf türü örneğine başvuru
veya bu arabirim türünü uygulayan bir
değer türünün paketlenmiş değerine
başvuru

Dizi türü Null başvuru, bu dizi türünün bir örneğine


başvuru veya uyumlu bir dizi türü
örneğine başvuru

Temsilci türü Bu temsilci türünün bir örneğine null


başvuru veya başvuru

İfadeler
İfadeler , işlenenler ve işleçlerdenoluşturulur. Bir ifadenin işleçleri,
işlenenlerin hangi işlemleri uygulanacağını gösterir. + İşleç örnekleri - , / ,,
ve new içerir. * İşlenenlerin örnekleri, sabit değerleri, alanları, yerel
değişkenleri ve ifadeleri içerir.
Bir ifade birden çok işleç içerdiğinde, işleçlerin önceliği ayrı işleçlerin
değerlendirilme sırasını denetler. Örneğin, x + y * z * işleç işleçten + daha
yüksek önceliğe x + (y * z) sahip olduğu için ifade değerlendirilir.
Çoğu işleç aşırıyüklenebilir. İşleç aşırı yüklemesi, Kullanıcı tanımlı operatör
uygulamalarının bir veya her ikisinin de Kullanıcı tanımlı sınıf veya yapı
türünde olduğu işlemler için belirtilmesine izin verir.
Aşağıdaki tabloda, işleç C#kategorilerinin en yüksekten en düşüğe öncelik
sırasına göre listelenmesi ve işleçleri özetlenmektedir. Aynı kategorideki
operatörler eşit önceliğe sahiptir.

KATEGORI İFADESINI AÇIKLAMA

Birincil x.m Üye erişimi

x(...) Yöntem ve temsilci


çağırma

x[...] Dizi ve dizinleyici erişimi

x++ Artırım sonrası

x-- Azaltım sonrası

new T(...) Nesne ve temsilci


oluşturma

new T(...){...} Başlatıcı ile nesne


oluşturma

new {...} Anonim nesne Başlatıcısı

new T[...] Dizi oluşturma

typeof(T) İçin System.Type nesne


al T

checked(x) İşaretli bağlamında ifade


değerlendirme

unchecked(x) İşaretlenmemiş
bağlamında ifade
değerlendirme

default(T) Türün varsayılan değerini


Al T

delegate {...} Anonim işlevi (anonim


yöntemi)
KATEGORI İFADESINI AÇIKLAMA

Li +x Kimlik

-x Olumsuzlama

!x Mantıksal olumsuzlama

~x Bitwise olumsuzlama

++x Artırım öncesi

--x Azaltım öncesi

(T)x Açıkça türe x Dönüştür


T

await x Zaman uyumsuz x


olarak işlemin
tamamlanmasını bekleyin

Çarpma x * y Çarpma

x / y Bölme

x % y Kalan

Msal x + y Toplama, dize bitiştirme,


temsilci birleşimi

x - y Çıkarma, temsilci kaldırma

Shift x << y Sola kaydırma

x >> y Sağa kaydırma

İlişkisel ve tür testi x < y Küçüktür

x > y Büyüktür

x <= y Küçük veya eşittir

x >= y Büyük veya eşittir

x is T Bir true ise T ,


tersidurumda false
döndürün x

x as T Dönüş x olarak T
yazılmış veya null
x``T
KATEGORI İFADESINI AÇIKLAMA

Eşitlik x == y Eşittir

x != y Eşit değildir

Mantıksal VE x & y Tamsayı bit düzeyinde ve,


Boolean mantıksal ve

Mantıksal XOR x ^ y Tamsayı bitwise XOR,


Boolean mantıksal XOR

Mantıksal VEYA x | y Tamsayı bitwise VEYA,


boolean mantıksal VEYA

Koşullu VE x && y Yalnızca y şu


durumlarda x
değerlendirilir true

Koşullu VEYA x || y Yalnızca y şu


durumlarda x
değerlendirilir false

Null birleşim x ?? y y ,Değilse x


olarakdeğerlendirilir
null x

Koşullu x ? y : z Olupolmadığını x
değerlendirir y true
z x``false

Atama veya anonim işlev x = y Atama

x op= y Bileşik atama; Desteklenen


işleçler şunlardır *= /=
%= += -= <<= >>=
&= ^= |=

(T x) => y Anonim işlevi (lambda


ifadesi)

Deyimler
Bir programın eylemleri deyimlerkullanılarak ifade edilir. C#, birden çok farklı
türde deyimi destekler, bu sayı katıştırılmış deyimler bakımından tanımlanır.
Bir blok , tek bir ifadeye izin verilen bağlamlarda birden çok deyimin
yazılmasına izin verir. Bir blok, sınırlayıcılar { ve } arasında yazılmış deyimler
listesinden oluşur.
Bildirim deyimleri yerel değişkenleri ve sabitleri bildirmek için kullanılır.
İfade deyimleri , ifadeleri değerlendirmek için kullanılır. Deyim olarak
kullanılabilecek ifadeler, yöntem etkinleştirmeleri, new işleci kullanılarak nesne
ayırmaları, = ve bileşik atama işleçleri kullanan atamalar, artırma ve azaltma
işlemleri ++ ve -- işleçleri ve await ifadeleri.
Seçim deyimleri , bazı deyimlerin değerine göre yürütme için bir dizi olası
deyimden birini seçmek için kullanılır. Bu grupta if ve switch deyimleri
vardır.
Yineleme deyimleri , gömülü bir deyimi tekrar tekrar yürütmek için kullanılır.
while Bu grupta do ,,ve foreach deyimleribulunur. for

Sıçrama deyimleri , denetimi aktarmak için kullanılır. Bu break grupta


continue , ,, throw , ve deyimleribulunur yield . goto return

try ... Bildiri, bir bloğun yürütülmesi sırasında oluşan özel durumları
yakalamak için kullanılır try ve... catch finally bildirim, her zaman
yürütülen ve özel durumun gerçekleşmediğini belirten sonlandırma kodunu
belirtmek için kullanılır.
checked Ve unchecked deyimleri, tamsayı türü aritmetik işlemler ve
dönüştürmeler için taşma denetimi bağlamını denetlemek için kullanılır.
Bu lock ifade, belirli bir nesne için karşılıklı dışlama kilidini almak, bir ifadeyi
yürütmek ve sonra kilidi serbest bırakmak için kullanılır.
using İfade, kaynak almak, bir ifadeyi yürütmek ve ardından bu kaynağı
atmak için kullanılır.
Aşağıda her bir tür deyimin örnekleri verilmiştir
Yerel değişken bildirimleri

static void Main() {


int a;
int b = 2, c = 3;
a = 1;
Console.WriteLine(a + b + c);
}

Yerel sabit bildirimi

static void Main() {


const float pi = 3.1415927f;
const int r = 25;
Console.WriteLine(pi * r * r);
}

İfade deyimi

static void Main() {


int i;
i = 123; // Expression statement
Console.WriteLine(i); // Expression statement
i++; // Expression statement
Console.WriteLine(i); // Expression statement
}

if Ekstre
static void Main(string[] args) {
if (args.Length == 0) {
Console.WriteLine("No arguments");
}
else {
Console.WriteLine("One or more arguments");
}
}

switch Ekstre

static void Main(string[] args) {


int n = args.Length;
switch (n) {
case 0:
Console.WriteLine("No arguments");
break;
case 1:
Console.WriteLine("One argument");
break;
default:
Console.WriteLine("{0} arguments", n);
break;
}
}

while Ekstre

static void Main(string[] args) {


int i = 0;
while (i < args.Length) {
Console.WriteLine(args[i]);
i++;
}
}

do Ekstre

static void Main() {


string s;
do {
s = Console.ReadLine();
if (s != null) Console.WriteLine(s);
} while (s != null);
}

for Ekstre

static void Main(string[] args) {


for (int i = 0; i < args.Length; i++) {
Console.WriteLine(args[i]);
}
}

foreach Ekstre
static void Main(string[] args) {
foreach (string s in args) {
Console.WriteLine(s);
}
}

break Ekstre

static void Main() {


while (true) {
string s = Console.ReadLine();
if (s == null) break;
Console.WriteLine(s);
}
}

continue Ekstre

static void Main(string[] args) {


for (int i = 0; i < args.Length; i++) {
if (args[i].StartsWith("/")) continue;
Console.WriteLine(args[i]);
}
}

goto Ekstre

static void Main(string[] args) {


int i = 0;
goto check;
loop:
Console.WriteLine(args[i++]);
check:
if (i < args.Length) goto loop;
}

return Ekstre

static int Add(int a, int b) {


return a + b;
}

static void Main() {


Console.WriteLine(Add(1, 2));
return;
}

yield Ekstre
static IEnumerable<int> Range(int from, int to) {
for (int i = from; i < to; i++) {
yield return i;
}
yield break;
}

static void Main() {


foreach (int x in Range(-10,10)) {
Console.WriteLine(x);
}
}

throw ve try deyimleri

static double Divide(double x, double y) {


if (y == 0) throw new DivideByZeroException();
return x / y;
}

static void Main(string[] args) {


try {
if (args.Length != 2) {
throw new Exception("Two numbers required");
}
double x = double.Parse(args[0]);
double y = double.Parse(args[1]);
Console.WriteLine(Divide(x, y));
}
catch (Exception e) {
Console.WriteLine(e.Message);
}
finally {
Console.WriteLine("Good bye!");
}
}

checked ve unchecked deyimleri

static void Main() {


int i = int.MaxValue;
checked {
Console.WriteLine(i + 1); // Exception
}
unchecked {
Console.WriteLine(i + 1); // Overflow
}
}

lock Ekstre
class Account
{
decimal balance;
public void Withdraw(decimal amount) {
lock (this) {
if (amount > balance) {
throw new Exception("Insufficient funds");
}
balance -= amount;
}
}
}

using Ekstre

static void Main() {


using (TextWriter w = File.CreateText("test.txt")) {
w.WriteLine("Line one");
w.WriteLine("Line two");
w.WriteLine("Line three");
}
}

Sınıflar ve nesneler
Sınıflar , türlerin en temel C#larıdır. Bir sınıf, durumu (alanları) ve eylemleri
(Yöntemler ve diğer işlev üyelerini) tek bir birimde birleştiren bir veri yapısıdır.
Sınıf, nesneolarak da bilinen, sınıfının dinamik olarak oluşturulan örnekleri
için bir tanım sağlar. Sınıflar, Devralma ve çok biçimlilikdesteği, türetilmiş
sınıfların temel sınıflarıgenişletebileceği ve özelleştirilebilecek mekanizmalar.
Yeni sınıflar sınıf bildirimleri kullanılarak oluşturulur. Sınıf bildirimi, sınıfın
özniteliklerini ve değiştiricilerini, sınıfın adını, Taban sınıfını (belirtilmişse) ve
sınıf tarafından uygulanan arabirimleri belirten bir üstbilgiyle başlar. Üst bilgi,
sınırlayıcılar { ve } arasında yazılmış üye bildirimlerinin listesinden oluşan
sınıf gövdesinden gelir.
Aşağıda adlı Point basit bir sınıfın bildirimi verilmiştir:

public class Point


{
public int x, y;

public Point(int x, int y) {


this.x = x;
this.y = y;
}
}

Sınıf örnekleri, yeni bir örnek için new bellek ayıran işleç kullanılarak
oluşturulur, örneği başlatmak için bir oluşturucu çağırır ve örneğe bir başvuru
döndürür. Aşağıdaki deyimler iki Point nesne oluşturur ve bu nesnelere
başvuruları iki değişken halinde depolar:

Point p1 = new Point(0, 0);


Point p2 = new Point(10, 20);
Nesne artık kullanımda olmadığında bir nesnenin kapladığı bellek otomatik
olarak geri kazanılır. Üzerinde C#nesneleri açıkça serbest bırakmak gerekli
değildir veya mümkün değildir.
Members
Bir sınıfın üyeleri statik Üyeler veya örnek üyeleridir. Statik Üyeler sınıflara
aittir ve örnek üyeleri nesnelere aittir (sınıf örnekleri).
Aşağıdaki tabloda bir sınıfın içerebileceği üye türlerine genel bakış
sunulmaktadır.

ÜYESIDIR AÇIKLAMA

Sabitler Sınıfla ilişkili sabit değerler

Alanlar Sınıfın değişkenleri

Yöntemler Sınıfı tarafından gerçekleştirilebilecek


hesaplamalar ve eylemler

properties Sınıfın adlandırılmış özelliklerini okuma ve


yazma ile ilişkili eylemler

Dizin Oluşturucular Bir dizi gibi sınıfın dizin oluşturma


örnekleri ile ilişkili eylemler

Events Sınıfı tarafından oluşturulabilecek


bildirimler

İşleçler Sınıf tarafından desteklenen dönüşümler


ve ifade işleçleri

Oluşturucular Sınıfın veya sınıfın örneklerinin örneğini


başlatmak için gereken eylemler

Yıkıcılar Sınıfın örneklerinden önce


gerçekleştirilecek eylemler kalıcı olarak
atılır

Türler Sınıf tarafından tanımlanan iç içe türler

Erişilebilirlik
Bir sınıfın her üyesinin ilişkili bir erişilebilirliği vardır ve bu, üyeye erişebilen
program metni bölgelerini denetler. Olası beş erişilebilirlik biçimi vardır. Bunlar
aşağıdaki tabloda özetlenmiştir.

ERIŞILEBILIRLIK ANLAMINA

public Erişim sınırlı değil

protected Bu sınıftan türetilmiş bu sınıfla veya


sınıflarla sınırlı erişim

internal Bu programla sınırlı erişim


ERIŞILEBILIRLIK ANLAMINA

protected internal Bu sınıftan türetilmiş bu program veya


sınıflarla sınırlı erişim

private Bu sınıfla sınırlı erişim

Tür parametreleri
Sınıf tanımı, tür parametre adlarının bir listesini kapsayan açılı ayraçları olan
sınıf adını izleyerek bir tür parametreleri kümesi belirtebilir. Tür parametreleri,
sınıfının üyelerini tanımlamak için sınıf bildirimlerinin gövdesinde kullanılabilir.
Aşağıdaki örnekte, öğesinin Pair TFirst tür parametreleri ve TSecond :

public class Pair<TFirst,TSecond>


{
public TFirst First;
public TSecond Second;
}

Tür parametrelerini almak için belirtilen bir sınıf türüne genel sınıf türü denir.
Yapı, arabirim ve temsilci türleri de genel olabilir.
Genel sınıf kullanıldığında, tür parametrelerinin her biri için tür bağımsız
değişkenlerinin sağlanması gerekir:

Pair<int,string> pair = new Pair<int,string> { First = 1, Second = "two" };


int i = pair.First; // TFirst is int
string s = pair.Second; // TSecond is string

Yukarıda olduğu gibi Pair<int,string> , tür bağımsız değişkenlerine sahip


genel bir tür, oluşturulmuş bir tür olarak adlandırılır.
Temel sınıflar
Sınıf bildirimi, sınıf adı ve tür parametreleri iki nokta ve temel sınıfın adı ile
birlikte bir temel sınıf belirtebilir. Temel sınıf belirtiminin atlanması, türden
object türetmeye benzer. Point3D Aşağıdaki örnekte, öğesinin Point temel
sınıfı ve öğesinin Point object temel sınıfı:

public class Point


{
public int x, y;

public Point(int x, int y) {


this.x = x;
this.y = y;
}
}

public class Point3D: Point


{
public int z;

public Point3D(int x, int y, int z): base(x, y) {


this.z = z;
}
}
Bir sınıf, temel sınıfının üyelerini devralır. Devralma, bir sınıfın örnek ve statik
oluşturucular ve temel sınıfın yıkıcıları dışında, temel sınıfının tüm üyelerini
örtük olarak içerdiği anlamına gelir. Türetilmiş bir sınıf, devralananlara yeni
üyeler ekleyebilir, ancak devralınmış bir üyenin tanımını kaldıramaz. Önceki
örnekte Point3D , Point3D x z ve alanlarını y öğesinden Point devralır ve
her örnek üç alan y içerir,, ve. x
Bir sınıf türünden, temel sınıf türlerinden herhangi birine örtük bir dönüştürme
vardır. Bu nedenle, bir sınıf türünün değişkeni bu sınıfın bir örneğine veya
türetilmiş herhangi bir sınıfın örneğine başvurabilir. Örneğin, önceki sınıf
bildirimleri verildiğinde, türünde Point bir değişken bir Point veya a
Point3D başvurabilir:

Point a = new Point(10, 20);


Point b = new Point3D(10, 20, 30);

Alanlar
Alan, bir sınıf ile veya bir sınıf örneğiyle ilişkili bir değişkendir.
static Değiştiriciyle belirtilen bir alan statik bir alantanımlar. Statik alan tam
olarak bir depolama konumunu tanımlar. Bir sınıfın kaç örneğinin
oluşturulduğuna bakılmaksızın, bir statik alanın yalnızca bir kopyası vardır.
static Değiştirici olmadan belirtilen bir alan bir örnek alanınıtanımlar. Bir
sınıfın her örneği, bu sınıfın tüm örnek alanlarının ayrı bir kopyasını içerir.
Aşağıdaki örnekte Color , sınıfının her örneği r , g , ve b Black örnek Red
alanlarının ayrı bir kopyasına sahiptir ancak White ,,,,,,,,,,,,,,,,,,, Green ve Blue
statik alanları:

public class Color


{
public static readonly Color Black = new Color(0, 0, 0);
public static readonly Color White = new Color(255, 255, 255);
public static readonly Color Red = new Color(255, 0, 0);
public static readonly Color Green = new Color(0, 255, 0);
public static readonly Color Blue = new Color(0, 0, 255);
private byte r, g, b;

public Color(byte r, byte g, byte b) {


this.r = r;
this.g = g;
this.b = b;
}
}

Önceki örnekte gösterildiği gibi, salt okuma alanları bir readonly değiştirici
ile bildirilebilecek. Bir readonly alana atama yalnızca alanın bildiriminin veya
aynı sınıftaki bir oluşturucunun parçası olarak gerçekleşebilir.
Yöntemler
Bir Yöntem , bir nesne veya sınıf tarafından gerçekleştirilebilecek bir
hesaplama veya eylem uygulayan bir üyesidir. Statik yöntemlere sınıfı
aracılığıyla erişilir. Örnek yöntemlerine , sınıfının örnekleri aracılığıyla erişilir.
Metotlarda (muhtemelen boş) bir parametrelistesi vardır. Bu, yönteme
geçirilen değerleri ya da değişken başvurularını temsil eder ve bir dönüş türü,
hesaplanan ve yöntemi tarafından döndürülen değer türünü belirtir. Bir
yöntemin dönüş türü void bir değer döndürmezse.
Türler gibi yöntemler de bir tür parametreleri kümesine sahip olabilir, bu da
yöntem çağrıldığında tür bağımsız değişkenlerinin belirtilmesi gerekir. Türlerin
aksine, tür bağımsız değişkenleri genellikle yöntem çağrısının bağımsız
değişkenlerinden çıkarsanamıyor ve açıkça verilmemelidir.
Yöntemin imzası , yöntemin bildirildiği sınıfta benzersiz olmalıdır. Bir
yöntemin imzası yöntemin adından, tür parametrelerinin sayısına ve
parametrelerinin sayısına, değiştiricilerine ve türlerine sahiptir. Bir yöntemin
imzası, dönüş türünü içermez.
Parametreler
Parametreler, değerlere veya değişken başvurularını yöntemlere geçirmek için
kullanılır. Bir yöntemin parametreleri, yöntemi çağrıldığında belirtilen
bağımsız değişkenlerden gerçek değerlerini alır. Dört tür parametre vardır:
değer parametreleri, başvuru parametreleri, çıkış parametreleri ve parametre
dizileri.
Giriş parametresi geçirme için bir değer parametresi kullanılır. Değer
parametresi, parametresi için geçirilen bağımsız değişkenden ilk değerini alan
yerel bir değişkene karşılık gelir. Değer parametresindeki değişiklikler,
parametresi için geçirilen bağımsız değişkeni etkilemez.
Değer parametreleri, ilgili bağımsız değişkenlerin atlanabilmesi için varsayılan
bir değer belirtilerek isteğe bağlı olabilir.
Hem giriş hem de çıkış parametresi geçirme için başvuru parametresi
kullanılır. Başvuru parametresi için geçirilen bağımsız değişken bir değişken
olmalıdır ve yöntemin yürütülmesi sırasında başvuru parametresi, bağımsız
değişken değişkeniyle aynı depolama konumunu temsil eder. Bir başvuru
parametresi ref değiştiriciyle birlikte bildirilmiştir. Aşağıdaki örnek ref
parametrelerin kullanımını gösterir.

using System;

class Test
{
static void Swap(ref int x, ref int y) {
int temp = x;
x = y;
y = temp;
}

static void Main() {


int i = 1, j = 2;
Swap(ref i, ref j);
Console.WriteLine("{0} {1}", i, j); // Outputs "2 1"
}
}

Çıkış parametresi geçirme için çıkış parametresi kullanılır. Bir çıktı


parametresi, çağıran tarafından belirtilen bağımsız değişkenin ilk değeri
önemli olmayan bir başvuru parametresine benzerdir. Bir çıkış parametresi
out değiştiriciyle birlikte bildirilmiştir. Aşağıdaki örnek out parametrelerin
kullanımını gösterir.
using System;

class Test
{
static void Divide(int x, int y, out int result, out int remainder) {
result = x / y;
remainder = x % y;
}

static void Main() {


int res, rem;
Divide(10, 3, out res, out rem);
Console.WriteLine("{0} {1}", res, rem); // Outputs "3 1"
}
}

Bir parametre dizisi , bir metoda değişken sayıda bağımsız değişken


geçirilmesine izin verir. Bir parametre dizisi params değiştiriciyle birlikte
bildirilmiştir. Bir yöntemin yalnızca son parametresi bir parametre dizisi olabilir
ve bir parametre dizisinin türü tek boyutlu bir dizi türü olmalıdır. Sınıfının ve
WriteLine yöntemleri Write , parametre dizisi kullanımının iyi örnekleridir.
System.Console Bunlar aşağıdaki gibi bildirilmiştir.

public class Console


{
public static void Write(string fmt, params object[] args) {...}
public static void WriteLine(string fmt, params object[] args) {...}
...
}

Bir parametre dizisi kullanan bir yöntem içinde, parametre dizisi tam olarak bir
dizi türünün normal parametresine benzer şekilde davranır. Ancak, bir
parametre dizisi olan bir yöntem çağrısında, parametre dizisi türünün tek bir
bağımsız değişkenini veya parametre dizisinin öğe türünün herhangi bir sayıda
bağımsız değişkenini geçirmek mümkündür. İkinci durumda, bir dizi örneği
otomatik olarak oluşturulur ve verilen bağımsız değişkenlerle başlatılır. Bu
örnek

Console.WriteLine("x={0} y={1} z={2}", x, y, z);

, aşağıdaki yazma ile eşdeğerdir.

string s = "x={0} y={1} z={2}";


object[] args = new object[3];
args[0] = x;
args[1] = y;
args[2] = z;
Console.WriteLine(s, args);

Yöntem gövdesi ve yerel değişkenler


Yöntemin gövdesi, yöntemi çağrıldığında yürütülecek deyimleri belirtir.
Yöntem gövdesi, yöntemi çağrısına özgü değişkenleri bildirebilir. Bu tür
değişkenlere yerel değişkenlerdenir. Yerel bir değişken bildirimi bir tür adı,
değişken adı ve muhtemelen bir başlangıç değeri belirtir. Aşağıdaki örnek,
başlangıç değeri sıfır olan i yerel bir değişken ve ilk değeri olmayan bir yerel
değişken j bildirir.

using System;

class Squares
{
static void Main() {
int i = 0;
int j;
while (i < 10) {
j = i * i;
Console.WriteLine("{0} x {0} = {1}", i, j);
i = i + 1;
}
}
}

C#değeri alınabilmesi için önce bir yerel değişkenin kesinlikle atanmasını


gerektirir. Örneğin, önceki i bildiriminde bir başlangıç değeri yoksa, derleyici
programın sonraki i kullanımları için bir hata bildirir çünkü i bu,
programda bu noktalarda kesinlikle atanmamalıdır.
Bir yöntem, çağrı return yapana denetim döndürmek için deyimlerini
kullanabilir. void Döndürülen return bir yöntemde deyimler bir ifade
belirtemez. Olmayan void deyimler döndüren bir yöntemde, return dönüş
değerini hesaplayan bir ifade içermelidir.
Statik ve örnek yöntemleri
static Değiştirici ile belirtilen bir yöntem statik bir yöntemdir. Statik bir
yöntem belirli bir örnek üzerinde çalışmaz ve yalnızca statik üyelere doğrudan
erişebilir.
static Değiştirici olmadan bildirildiği bir yöntem bir örnek yöntemidir.
Örnek yöntemi, belirli bir örnek üzerinde çalışır ve hem statik hem de örnek
üyelerine erişebilir. Örnek yönteminin çağrıldığı örnek, olarak this açıkça
erişilebilir. Statik bir yöntemde başvurmak this için bir hatadır.
Aşağıdaki Entity sınıfta hem statik hem de örnek üyeleri vardır.

class Entity
{
static int nextSerialNo;
int serialNo;

public Entity() {
serialNo = nextSerialNo++;
}

public int GetSerialNo() {


return serialNo;
}

public static int GetNextSerialNo() {


return nextSerialNo;
}

public static void SetNextSerialNo(int value) {


nextSerialNo = value;
}
}
Her Entity örnek bir seri numarası içerir (ve burada görünmeyen bazı diğer
bilgileri kabul etmez). Entity Oluşturucu (bir örnek yöntemi gibi) yeni örneği
bir sonraki kullanılabilir seri numarasıyla başlatır. Oluşturucu bir örnek üyesi
olduğundan, hem serialNo örnek alanına nextSerialNo hem de statik alana
erişim izni verilir.
GetNextSerialNo Ve serialNo statik yöntemler
statikalanaerişebilir,ancakörnekalanınadoğrudanerişmesiiçinbirhataolabilir.
nextSerialNo SetNextSerialNo

Aşağıdaki örnek Entity sınıfının kullanımını gösterir.

using System;

class Test
{
static void Main() {
Entity.SetNextSerialNo(1000);
Entity e1 = new Entity();
Entity e2 = new Entity();
Console.WriteLine(e1.GetSerialNo()); // Outputs "1000"
Console.WriteLine(e2.GetSerialNo()); // Outputs "1001"
Console.WriteLine(Entity.GetNextSerialNo()); // Outputs "1002"
}
}

Sınıfının örneklerinde GetSerialNo örnek SetNextSerialNo yöntemi


GetNextSerialNo çağrıldığında, ve statik yöntemlerin sınıfında çağrılabileceğini
unutmayın.
Sanal, geçersiz kılma ve soyut yöntemler
Bir örnek yöntemi bildirimi bir virtual değiştirici içerdiğinde, yöntemi bir
sanal yöntemolarak kabul edilir. Değiştirici yoksa, yöntemi sanal olmayan
bir yöntemolarak kabul edilir. virtual
Bir sanal yöntem çağrıldığında, çağrının gerçekleştiği örneğin çalışma zamanı
türü , çağrılacak gerçek Yöntem uygulamasını belirler. Sanal olmayan bir
yöntem çağrısında, örneğin derleme zamanı türü belirleme faktörü olur.
Bir sanal yöntem, türetilmiş bir sınıfta geçersiz kılınabilir . Bir örnek yöntemi
bildirimi bir override değiştirici içerdiğinde, yöntemi aynı imzaya sahip
devralınmış bir sanal yöntemi geçersiz kılar. Sanal bir yöntem bildiriminde yeni
bir yöntem tanıtıldığı halde, bir geçersiz kılma yöntemi bildirimi, bu yöntemin
yeni bir uygulamasını sağlayarak, var olan bir devralınmış sanal yöntemi
uzmanlık eder.
Soyut bir yöntem, uygulama içermeyen bir sanal yöntemdir. Soyut bir yöntem
abstract değiştiriciyle birlikte bildirilmiştir ve yalnızca da belirtilen abstract
bir sınıfta izin verilir. Soyut olmayan her türetilmiş sınıfta bir soyut yöntem
geçersiz kılınmalıdır.
Aşağıdaki örnek, bir ifade ağaç düğümünü temsil Expression eden bir soyut
sınıfı ve sabitler, değişken için ifade ağacı düğümleri uygulayan Constant üç
VariableReference türetilmiş sınıfı Operation ,, ve ve ' ı tanımlar. başvurular ve
aritmetik işlemler. (Bu şuna benzerdir, ancak ifade ağacı türlerindetanıtılan
ifade ağacı türleriyle karıştırılmamalıdır).
using System;
using System.Collections;

public abstract class Expression


{
public abstract double Evaluate(Hashtable vars);
}

public class Constant: Expression


{
double value;

public Constant(double value) {


this.value = value;
}

public override double Evaluate(Hashtable vars) {


return value;
}
}

public class VariableReference: Expression


{
string name;

public VariableReference(string name) {


this.name = name;
}

public override double Evaluate(Hashtable vars) {


object value = vars[name];
if (value == null) {
throw new Exception("Unknown variable: " + name);
}
return Convert.ToDouble(value);
}
}

public class Operation: Expression


{
Expression left;
char op;
Expression right;

public Operation(Expression left, char op, Expression right) {


this.left = left;
this.op = op;
this.right = right;
}

public override double Evaluate(Hashtable vars) {


double x = left.Evaluate(vars);
double y = right.Evaluate(vars);
switch (op) {
case '+': return x + y;
case '-': return x - y;
case '*': return x * y;
case '/': return x / y;
}
throw new Exception("Unknown operator");
}
}

Önceki dört sınıf aritmetik ifadeleri modellemek için kullanılabilir. Örneğin, bu


sınıfların örneklerini kullanarak, ifadesi x + 3 aşağıdaki gibi gösterilebilir.
Expression e = new Operation(
new VariableReference("x"),
'+',
new Constant(3));

double Bir Evaluate


Örneğinyöntemi,verilenifadeyideğerlendirmekvebirdeğerüretmekiçinçağrılır.
Expression Yöntemi, değişken adlarını (girdilerin anahtarları Hashtable
olarak) ve değerlerini (girdilerin değerleri olarak) içeren bir bağımsız değişken
olarak alır. Evaluate Yöntemi, bir sanal soyut yöntemidir, yani soyut olmayan
türetilmiş sınıfların gerçek bir uygulama sağlamak için onu geçersiz kılması
gerekir.
' Nin uygulanması, yalnızca saklı sabiti döndürür. Constant Bir
Evaluate
VariableReference uygulama, Hashtable 'daki değişken adını arar ve elde
edilen değeri döndürür. Bir Operation uygulama ilk olarak sol ve sağ
işlenenleri değerlendirir ( Evaluate yöntemlerini özyinelemeli olarak
çağırarak) ve ardından verilen aritmetik işlemi gerçekleştirir.
Aşağıdaki program, Expression x ve x * (y + 2) farklı y değerleri için
ifadeyi değerlendirmek için sınıflarını kullanır.

using System;
using System.Collections;

class Test
{
static void Main() {
Expression e = new Operation(
new VariableReference("x"),
'*',
new Operation(
new VariableReference("y"),
'+',
new Constant(2)
)
);
Hashtable vars = new Hashtable();
vars["x"] = 3;
vars["y"] = 5;
Console.WriteLine(e.Evaluate(vars)); // Outputs "21"
vars["x"] = 1.5;
vars["y"] = 9;
Console.WriteLine(e.Evaluate(vars)); // Outputs "16.5"
}
}

Yöntem aşırı yüklemesi


Yöntem aşırı yüklemesi , aynı sınıftaki birden çok metodun benzersiz imzalara
sahip oldukları sürece aynı ada sahip olmasını sağlar. Aşırı yüklenmiş bir
yöntemin çağrılması derlenirken, derleyici çağrılacak özel yöntemi belirlemekte
aşırı yükleme çözümü kullanır. Aşırı yükleme çözümlemesi, bağımsız
değişkenlerle en iyi eşleşen bir yöntemi bulur veya tek bir en iyi eşleşme
bulunamazsa hata bildiriyor. Aşağıdaki örnekte, etkin olan aşırı yükleme
çözümü gösterilmektedir. Main Yöntemi içindeki her çağrının yorumu aslında
hangi yöntemin çağrılacağını gösterir.
class Test
{
static void F() {
Console.WriteLine("F()");
}

static void F(object x) {


Console.WriteLine("F(object)");
}

static void F(int x) {


Console.WriteLine("F(int)");
}

static void F(double x) {


Console.WriteLine("F(double)");
}

static void F<T>(T x) {


Console.WriteLine("F<T>(T)");
}

static void F(double x, double y) {


Console.WriteLine("F(double, double)");
}

static void Main() {


F(); // Invokes F()
F(1); // Invokes F(int)
F(1.0); // Invokes F(double)
F("abc"); // Invokes F(object)
F((double)1); // Invokes F(double)
F((object)1); // Invokes F(object)
F<int>(1); // Invokes F<T>(T)
F(1, 1); // Invokes F(double, double)
}
}

Örnekte gösterildiği gibi belirli bir yöntem her zaman bağımsız değişkenleri
tam parametre türlerine açıkça atayarak ve/veya açıkça tür bağımsız
değişkenleri sunarak seçilebilir.
Diğer işlev üyeleri
Yürütülebilir kod içeren Üyeler topluca bir sınıfın işlev üyeleri olarak bilinir.
Yukarıdaki bölümde, işlev üyelerinin birincil türü olan yöntemler açıklanmıştır.
Bu bölümde, tarafından C#desteklenen diğer işlev üyesi türleri
açıklanmaktadır: oluşturucular, özellikler, Dizin oluşturucular, olaylar, işleçler ve
Yıkıcılar.
Aşağıdaki kod, bir nesne growable listesini uygulayan List<T> adlı bir genel
sınıfı gösterir. Sınıfı, en yaygın işlev üyesi türlerine birkaç örnek içerir.

public class List<T> {


// Constant...
const int defaultCapacity = 4;

// Fields...
T[] items;
int count;

// Constructors...
public List(int capacity = defaultCapacity) {
items = new T[capacity];
}

// Properties...
public int Count {
get { return count; }
}
public int Capacity {
get {
return items.Length;
}
set {
if (value < count) value = count;
if (value != items.Length) {
T[] newItems = new T[value];
Array.Copy(items, 0, newItems, 0, count);
items = newItems;
}
}
}

// Indexer...
public T this[int index] {
get {
return items[index];
}
set {
items[index] = value;
OnChanged();
}
}

// Methods...
public void Add(T item) {
if (count == Capacity) Capacity = count * 2;
items[count] = item;
count++;
OnChanged();
}
protected virtual void OnChanged() {
if (Changed != null) Changed(this, EventArgs.Empty);
}
public override bool Equals(object other) {
return Equals(this, other as List<T>);
}
static bool Equals(List<T> a, List<T> b) {
if (a == null) return b == null;
if (b == null || a.count != b.count) return false;
for (int i = 0; i < a.count; i++) {
if (!object.Equals(a.items[i], b.items[i])) {
return false;
}
}
return true;
}

// Event...
public event EventHandler Changed;

// Operators...
public static bool operator ==(List<T> a, List<T> b) {
return Equals(a, b);
}
public static bool operator !=(List<T> a, List<T> b) {
return !Equals(a, b);
}
}

Oluşturucular
C#hem örnek hem de statik oluşturucuları destekler. Örnek Oluşturucu , bir
sınıfın örneğini başlatmak için gereken eylemleri uygulayan bir üyedir. Statik
Oluşturucu , ilk yüklendiği zaman bir sınıfın kendisini başlatmak için gereken
eylemleri uygulayan bir üyesidir.
Bir Oluşturucu, dönüş türü olmayan bir yöntem ve kapsayan sınıfla aynı adı ile
birlikte bildirilmiştir. Bir Oluşturucu bildiriminde static bir değiştirici varsa,
bir statik oluşturucu bildirir. Aksi takdirde, bir örnek Oluşturucu bildirir.
Örnek oluşturucular aşırı yüklenebilir. Örneğin, List<T> sınıfı, biri int
parametresi olmayan iki örnek Oluşturucu bildirir ve bir parametre alır. Örnek
oluşturucular new işleci kullanılarak çağrılır. Aşağıdaki deyimler, List<string>
List sınıfının oluşturucularının her birini kullanarak iki örnek ayırır.

List<string> list1 = new List<string>();


List<string> list2 = new List<string>(10);

Diğer üyelerin aksine, örnek oluşturucular devralınmaz ve bir sınıfın sınıfta


tanımlananlardan farklı örnek oluşturucuları yoktur. Bir sınıf için örnek
Oluşturucu sağlanmazsa, parametresi olmayan boş bir değer otomatik olarak
sağlanır.
properties
Özellikler , alanlar için doğal bir uzantıdır. Her ikisi de ilişkili türlerin
bulunduğu isimlerdir ve alanlara ve özelliklere erişim için sözdizimi aynıdır.
Ancak, alanların aksine, Özellikler depolama konumlarını göstermiyor. Bunun
yerine, özellikler, değerleri okunmak veya yazıldığında yürütülecek deyimleri
belirten erişimcileri vardır.
Bir getözellik, bildirim bir erişimci ile sona erene ve/ set veya sınırlayıcılar
{ arasında } yazılmış bir erişimciyi ve noktalı virgül ile sona ermek yerine
bir alan olarak belirtilir. Hem get set erişimci get hem de
erişimciyesahipbirözellikokuma-
yazmaözelliğidir,yalnızcabirerişimcisiolanbirözelliksaltokunurdurveyalnızcaerişi
mcisiolanbirözellik set salt yazılır özelliği.
get Erişimci, özellik türünün dönüş değeri olan parametresiz bir yönteme
karşılık gelir. Atama hedefi dışında, bir ifadede bir özelliğe başvurulduğunda,
get özelliğin erişimcisi özelliğin değerini hesaplamak için çağrılır.

Erişimci, adlandırılmış value ve dönüş türü olmayan tek parametreli bir


yönteme karşılık gelir. set Bir özelliğe bir atamanın hedefi veya işleneni ++
-- olarak başvurulduğunda, set erişimci yeni değeri sağlayan bir bağımsız
değişkenle çağrılır.
Sınıfı iki özellik bildirir Capacity ve sırasıyla salt okunurdur ve okuma-yazma
olur. Count List<T> Aşağıda bu özelliklerin kullanılmasına bir örnek
verilmiştir.

List<string> names = new List<string>();


names.Capacity = 100; // Invokes set accessor
int i = names.Count; // Invokes get accessor
int j = names.Capacity; // Invokes get accessor

Alanlar ve yöntemlere benzer şekilde hem C# örnek özelliklerini hem de statik


özellikleri destekler. Statik özellikler static değiştiriciyle, örnek özellikleri ise
bu olmadan tanımlanır.
Bir özelliğin erişimcisi sanal olabilir. Bir özellik bildirimi virtual , abstract ,
veya override değiştiricisini içerdiğinde, özelliğin erişimcilerle geçerli olur.
Dizin Oluşturucular
Dizin Oluşturucu , nesnelerin diziyle aynı şekilde dizinlenmesini sağlayan bir
üyedir. Bir Dizin Oluşturucu, üyenin this adının ardından sınırlayıcılar [ ve
] arasında yazılmış bir parametre listesi gelmesi dışında bir özellik gibi
bildirilmiştir. Parametreler, dizin oluşturucunun erişimcisinde kullanılabilir.
Özelliklere benzer şekilde, Dizin oluşturucular okunabilir-yazılır, salt okunurdur
ve salt yazılır olabilir ve bir dizin oluşturucunun erişimcisi sanal olabilir.
Sınıfı List , bir int parametresi alan tek bir okuma-yazma Dizin Oluşturucu
bildirir. Dizin Oluşturucu, List int örneklerin değerleriyle dizin
oluşturmanızı mümkün kılar. Örneğin:

List<string> names = new List<string>();


names.Add("Liz");
names.Add("Martha");
names.Add("Beth");
for (int i = 0; i < names.Count; i++) {
string s = names[i];
names[i] = s.ToUpper();
}

Dizin oluşturucular aşırı yüklenebilir, yani parametrelerinin sayısı veya türleri


farklı olduğu sürece bir sınıfın birden çok dizin kümesini bildirebileceği
anlamına gelir.
Events
Bir olay , bir sınıf veya nesnenin bildirimler sağlamasını sağlayan bir üyedir.
Bildirimin bir event anahtar sözcük içermesi ve türün bir temsilci türü olması
dışında bir olay, bir alan gibi bildirilmiştir.
Olay üyesini bildiren bir sınıf içinde, olay bir temsilci türünün alanı gibi
davranır (olay soyut değildir ve erişimcileri bildirmez). Bu alan, olaya eklenmiş
olan olay işleyicilerini temsil eden bir temsilciye bir başvuru depolar. Hiçbir
olay tanıtıcısı yoksa, alanı olur null .
Sınıfı, adlı Changed tek bir olay üyesini bildirir ve bu, listeye yeni bir öğe
eklendiğini gösterir. List<T> Olay sanal yöntemi tarafından tetiklenir, bu, önce
olayın null (hiçbir işleyicinin mevcut olmadığı anlamına gelir) olup
olmadığını denetler. OnChanged Changed Bir olayı oluşturma kavramı, olayın
gösterdiği temsilciyi çağırmak için tam olarak eşdeğerdir. bu nedenle, olayları
yükseltmek için özel dil yapıları yoktur.
İstemciler olay işleyicileriaracılığıyla olaylara tepki verir. Olay işleyicileri +=
işleci kullanılarak eklenir ve -= işleci kullanılarak kaldırılır. Aşağıdaki örnek,
olayına bir Changed List<string> olay işleyicisi ekler.
using System;

class Test
{
static int changeCount;

static void ListChanged(object sender, EventArgs e) {


changeCount++;
}

static void Main() {


List<string> names = new List<string>();
names.Changed += new EventHandler(ListChanged);
names.Add("Liz");
names.Add("Martha");
names.Add("Beth");
Console.WriteLine(changeCount); // Outputs "3"
}
}

Bir olayın temeldeki depolamanın denetiminin istendiği Gelişmiş senaryolarda,


bir olay bildirimi açıkça bir özelliğin add set erişenine benzer bir şekilde
sağlayabilir ve remove erişimciler sağlar.
İşleçler
İşleci , bir sınıfın örneklerine belirli bir ifade işlecini uygulamanın anlamını
tanımlayan bir üyesidir. Üç tür işleç tanımlanabilir: Birli İşleçler, ikili işleçler ve
dönüştürme işleçleri. Tüm işleçler ve public static olarak bildirilmelidir.
Sınıfı iki List işleç operator==
bildirirvebunedenlebuişleçleriörneklereuygulayandeyimlereyenianlamıverir.
operator!= List<T> Özellikle, işleçler, içerilen nesnelerin her birini List<T>
Equals yöntemlerini kullanarak karşılaştıran iki örneğin eşitliğini tanımlar.
Aşağıdaki örnek, iki == List<int> örneği karşılaştırmak için işlecini kullanır.

using System;

class Test
{
static void Main() {
List<int> a = new List<int>();
a.Add(1);
a.Add(2);
List<int> b = new List<int>();
b.Add(1);
b.Add(2);
Console.WriteLine(a == b); // Outputs "True"
b.Add(3);
Console.WriteLine(a == b); // Outputs "False"
}
}

Bu iki Console.WriteLine liste True aynı sırada aynı değerleri taşıyan aynı
sayıda nesne içerdiğinden ilk çıktılar. List<T> Tanımlı değil, Console.WriteLine
ilkiçıktıyı False içeriyor ve b farklı örneklere List<int> başvuracaktır. a
operator==

Yıkıcılar
Yıkıcı , bir sınıf örneğinin yapısını kaldırma için gereken eylemleri uygulayan
bir üyesidir. Yok ediciler parametrelere sahip olamaz, erişilebilirlik
değiştiricilerine sahip olamaz ve açıkça çağrılamaz. Örnek için yıkıcısı çöp
toplama sırasında otomatik olarak çağrılır.
Çöp toplayıcısına, nesnelerin toplanması ve yıkıcıları çalıştırma konusunda
karar verirken geniş bir enlem vardır. Özellikle, yıkıcı etkinleştirmeleri
zamanlaması belirleyici değildir ve herhangi bir iş parçacığında yok ediciler
çalıştırılabilir. Bu ve diğer nedenlerden dolayı sınıfların yalnızca başka hiçbir
çözüm uygulanabilir olmadığında Yıkıcılar uygulaması gerekir.
İfade using , nesne yok etme için daha iyi bir yaklaşım sağlar.

Yapılar
Sınıflar gibi yapılar , veri üyeleri ve işlev üyeleri içerebilen veri yapılarıdır,
ancak sınıfların aksine, yapılar değer türlerdir ve yığın ayırmayı gerektirmez.
Yapı türünün bir değişkeni yapının verisini doğrudan depolarken, sınıf
türündeki bir değişken, dinamik olarak ayrılan bir nesneye bir başvuru depolar.
Yapı türleri Kullanıcı tarafından belirtilen devralmayı desteklemez ve tüm yapı
türleri örtülü olarak türünden object devralınır.
Yapılar, özellikle değer semantiği olan küçük veri yapıları için yararlıdır.
Karmaşık sayılar, bir koordinat sistemindeki işaret veya bir sözlükte anahtar-
değer çiftleri, yapı birimlerinin iyi örnekleridir. Küçük veri yapıları için sınıflar
yerine yapıların kullanımı, bir uygulamanın gerçekleştirdiği bellek ayırma
sayısında büyük bir farklılık yapabilir. Örneğin, aşağıdaki program 100
noktadan oluşan bir dizi oluşturur ve başlatır. Sınıf Point olarak uygulanan
101 ayrı nesneler, biri Array için ve her biri 100 öğeleri için oluşturulur.

class Point
{
public int x, y;

public Point(int x, int y) {


this.x = x;
this.y = y;
}
}

class Test
{
static void Main() {
Point[] points = new Point[100];
for (int i = 0; i < 100; i++) points[i] = new Point(i, i);
}
}

Alternatif olarak bir yapı oluşturma Point .

struct Point
{
public int x, y;

public Point(int x, int y) {


this.x = x;
this.y = y;
}
}
Şimdi yalnızca bir nesne örneği oluşturulur — dizi için bir tane ve Point
örnekler dizide satır içinde depolanır.
Struct oluşturucuları new işleçle çağrılır, ancak bu belleğin ayrılmakta
olduğunu göstermez. Bir nesne dinamik olarak tahsis etmek ve ona bir
başvuru döndürmek yerine, bir struct Oluşturucusu yalnızca struct değerinin
kendisini döndürür (genellikle yığındaki geçici bir konumda) ve bu değer,
gereken şekilde kopyalanır.
Sınıflar ile, iki değişkenin aynı nesneye başvurması ve bu nedenle bir
değişkende işlemler için diğer değişken tarafından başvurulan nesneyi
etkilemesi mümkündür. Yapılar ile, her birinin kendi verilerinin bir kopyasına
sahip olduğu ve bir üzerindeki işlemlerin diğerini etkilemesi mümkün değildir.
Örneğin, aşağıdaki kod parçası tarafından üretilen çıkış, bir sınıf veya yapı
olmasına Point bağlıdır.

Point a = new Point(10, 10);


Point b = a;
a.x = 20;
Console.WriteLine(b.x);

Bir sınıfınise, a çıkış olur 20 ve b aynı nesneye başvurur. Point 10 a


a.x Bir struct ise çıktı, öğesinin b atamanın değerin bir kopyasını oluşturması
ve bu kopyanın sonraki atamasından etkilenmemelerdir. Point
Önceki örnek, yapıların sınırlamalarını iki vurgulamaktadır. İlk olarak, bir
yapının tamamını kopyalamak bir nesne başvurusunu kopyalamaya kıyasla
genellikle daha etkilidir, bu nedenle atama ve değer parametresi, yapı ile
başvuru türleriyle daha pahalı olabilir. İkincisi, ref ve parametreleri dışında
out , yapılara başvurular oluşturmak mümkün değildir ve bu sayede
kullanımları bir dizi durumda kurallar oluşturulur.

Diziler
Dizi , hesaplanan dizinler üzerinden erişilen çeşitli değişkenler içeren bir veri
yapısıdır. Bir dizide bulunan değişkenler, dizi öğeleri de denir, hepsi aynı türdür
ve bu tür dizinin öğe türü olarak adlandırılır.
Dizi türleri başvuru türlerdir ve bir dizi değişkeninin bildirimi, bir dizi örneğine
yönelik bir başvuru için yalnızca alan ayırın. Gerçek dizi örnekleri işleci
kullanılarak, new çalışma zamanında dinamik olarak oluşturulur. İşlem, daha
sonra örneğin ömrü boyunca düzeltilen yeni dizi örneğinin uzunluğunu belirtir.
new Bir dizi öğelerinin ' den 0 Length - 1 ' a kadar olan dizinleri. İşleci, bir
dizinin öğelerini otomatik olarak varsayılan değerlerine başlatır. Bu, örneğin,
tüm sayısal türler ve null tüm başvuru türleri için sıfırdır. new
Aşağıdaki örnek, bir dizi int öğe oluşturur, diziyi başlatır ve dizinin içeriğini
yazdırır.
using System;

class Test
{
static void Main() {
int[] a = new int[10];
for (int i = 0; i < a.Length; i++) {
a[i] = i * i;
}
for (int i = 0; i < a.Length; i++) {
Console.WriteLine("a[{0}] = {1}", i, a[i]);
}
}
}

Bu örnek, tek boyutlu bir diziüzerinde oluşturur ve çalışır. C#, çok boyutlu
dizileride destekler. Dizi türünün derecesi olarak da bilinen bir dizi türünün
boyut sayısı, dizi türünün köşeli ayraçları arasına yazılan virgüllerin sayısıdır.
Aşağıdaki örnek tek boyutlu, iki boyutlu ve üç boyutlu bir diziyi ayırır.

int[] a1 = new int[10];


int[,] a2 = new int[10, 5];
int[,,] a3 = new int[10, 5, 2];

Dizi 10 öğe içeriyorsa a2 , dizi 50 (10 × 5 a3 ) öğesi içerir ve dizi 100 (10 × 5
× 2) öğesi içerir. a1
Bir dizinin öğe türü, bir dizi türü de dahil olmak üzere herhangi bir tür olabilir.
Dizi türündeki öğeleri içeren bir dizi, bazen öğe dizilerinin uzunluklarının
tümünün aynı olması gerektiğinden pürüzlü dizi olarak adlandırılır. Aşağıdaki
örnek dizi dizilerini int ayırır:

int[][] a = new int[3][];


a[0] = new int[10];
a[1] = new int[5];
a[2] = new int[20];

İlk satır, her biri türü int[] ve her biri bir başlangıç null değeri olan üç öğe
içeren bir dizi oluşturur. Sonraki satırlar, Farklı uzunluklardaki ayrı dizi
örneklerine yapılan başvurularla üç öğeyi başlatır.
İşleci, dizi öğelerinin başlangıç değerlerinin, sınırlayıcılar { ve } arasında
yazılan ifadelerin listesi olan bir dizi başlatıcısıkullanılarak belirtilmesine izin
verir. new Aşağıdaki örnek, üç öğesi ile bir int[] ayırır ve başlatır.

int[] a = new int[] {1, 2, 3};

Dizi uzunluğunun ve { } arasındaki ifade sayısından çıkarsandığına


unutmayın. Yerel değişken ve alan bildirimleri daha fazla kısaltılarak, dizi
türünün yeniden oluşturulması gerekmez.

int[] a = {1, 2, 3};

Yukarıdaki örneklerin her ikisi de aşağıdaki gibi eşdeğerdir:


int[] t = new int[3];
t[0] = 1;
t[1] = 2;
t[2] = 3;
int[] a = t;

Arabirimler
Arabirim , sınıflar ve yapılar tarafından uygulanabilecek bir sözleşmeyi
tanımlar. Arabirim, Yöntemler, özellikler, olaylar ve Dizin oluşturucular içerebilir.
Arabirim, tanımladığı üyelerin uygulamalarını sağlamaz; yalnızca arabirimini
uygulayan sınıflar veya yapılar tarafından sağlanması gereken üyeleri belirtir.
Arabirimler birden fazla devralmakullanabilir. Aşağıdaki örnekte, arabirimi
IComboBox ITextBox hem hem de öğesinden devralır. IListBox

interface IControl
{
void Paint();
}

interface ITextBox: IControl


{
void SetText(string text);
}

interface IListBox: IControl


{
void SetItems(string[] items);
}

interface IComboBox: ITextBox, IListBox {}

Sınıflar ve yapılar birden çok arabirim uygulayabilir. Aşağıdaki örnekte, sınıfı


EditBox hem hem IDataBound de IControl uygular.

interface IDataBound
{
void Bind(Binder b);
}

public class EditBox: IControl, IDataBound


{
public void Paint() {...}
public void Bind(Binder b) {...}
}

Bir sınıf veya yapı belirli bir arabirimi uygularsa, bu sınıfın veya yapının
örnekleri örtülü olarak bu arabirim türüne dönüştürülebilir. Örneğin:

EditBox editBox = new EditBox();


IControl control = editBox;
IDataBound dataBound = editBox;

Bir örneğin belirli bir arabirimi uygulamak üzere statik olarak bilinmediği
durumlarda dinamik tür atamaları kullanılabilir. Örneğin, aşağıdaki deyimler
bir nesnenin IControl ve IDataBound arabirim uygulamalarının elde edileceği
dinamik tür yayınlarını kullanır. Nesnenin gerçek türü olduğundan EditBox ,
yayınlar başarılı olur.

object obj = new EditBox();


IControl control = (IControl)obj;
IDataBound dataBound = (IDataBound)obj;

Önceki EditBox sınıfta IControl , arabiriminden public yöntemi ve


arabiriminden IDataBound yöntemi, Üyeler kullanılarak uygulanır. Bind Paint
C#Ayrıca, sınıf veya yapının üyeleri public yapmaktan kaçınmasına engel
olabilecek Açık arabirim üye uygulamalarınıdestekler. Açık arabirim üyesi
uygulama, tam nitelikli arabirim üye adı kullanılarak yazılır. Örneğin, EditBox
sınıfı aşağıdaki gibi açık arabirim üye uygulamalarını IDataBound.Bind
kullanarak IControl.Paint ve yöntemlerini uygulayabilir.

public class EditBox: IControl, IDataBound


{
void IControl.Paint() {...}
void IDataBound.Bind(Binder b) {...}
}

Açık arabirim üyelerine yalnızca arabirim türü aracılığıyla erişilebilir. Örneğin,


önceki EditBox sınıf tarafından sağlanmış IControl.Paint olan uygulama,
yalnızca öncelikle IControl arabirim türüne EditBox başvuru
dönüştürülürken çağrılabilir.

EditBox editBox = new EditBox();


editBox.Paint(); // Error, no such method
IControl control = editBox;
control.Paint(); // Ok

Numaralandırmalar
Sabit listesi türü , adlandırılmış sabitler kümesi olan ayrı bir değer türüdür.
Aşağıdaki örnek Color ,,, ve Red Blue üç sabit değeri Green olan adlı bir
sabit listesi türü bildirir ve kullanır.
using System;

enum Color
{
Red,
Green,
Blue
}

class Test
{
static void PrintColor(Color color) {
switch (color) {
case Color.Red:
Console.WriteLine("Red");
break;
case Color.Green:
Console.WriteLine("Green");
break;
case Color.Blue:
Console.WriteLine("Blue");
break;
default:
Console.WriteLine("Unknown color");
break;
}
}

static void Main() {


Color c = Color.Red;
PrintColor(c);
PrintColor(Color.Blue);
}
}

Her sabit listesi türünün, enum türünün temel alınan türü olarak adlandırılan
karşılık gelen bir integral türü vardır. Temel alınan bir türü açıkça bildirmiyor
bir sabit listesi türü, temel alınan int bir tür içerir. Sabit listesi türünün
depolama biçimi ve olası değerlerinin aralığı, temel alınan türüne göre
belirlenir. Bir numaralandırma türünün üzerinde sürebelirlenen değerler
kümesi, sabit listesi üyeleri tarafından sınırlı değildir. Özellikle, bir sabit
listesinin temel alınan türünün herhangi bir değeri, sabit listesi türüne
dönüşebilir ve bu sabit listesi türünün ayrı bir geçerli değeridir.
Aşağıdaki örnek, temel alınan Alignment sbyte türü ile adlı bir sabit listesi
türü bildirir.

enum Alignment: sbyte


{
Left = -1,
Center = 0,
Right = 1
}

Önceki örnekte gösterildiği gibi, enum üye bildirimi üyenin değerini belirten
bir sabit ifade içerebilir. Her sabit listesi üyesinin sabit değeri, sabit listesinin
temel alınan türü aralığında olmalıdır. Sabit listesi üyesi bildirimi açıkça bir
değer belirtmezse, üyeye sıfır değeri verilir (sabit listesi türünde ilk üye ise)
veya metin içeriğini eklemek önceki enum üyesinin değeri ve bir.
Sabit listesi değerleri tamsayı değerlerine dönüştürülebilir ve tür atamaları
kullanılarak tam tersi olabilir. Örneğin:

int i = (int)Color.Blue; // int i = 2;


Color c = (Color)2; // Color c = Color.Blue;

Herhangi bir sabit listesi türünün varsayılan değeri, enum türüne dönüştürülen
tam sayı değeridir. Değişkenlerin otomatik olarak varsayılan bir değere
başlatıldığı durumlarda, bu değer enum türü değişkenlerine verilen değerdir.
Bir sabit listesi türünün varsayılan değerinin kolayca kullanılabilmesi için,
değişmez 0 değer örtülü olarak herhangi bir numaralandırma türüne
dönüştürülür. Bu nedenle, aşağıdakilere izin verilir.

Color c = 0;

Temsilciler
Bir temsilci türü , belirli bir parametre listesi ve dönüş türü olan yöntemlere
yapılan başvuruları temsil eder. Temsilciler, yöntemleri değişkenlere
atanabilecek ve parametre olarak geçirilen varlıklar olarak işleme olanağı tanır.
Temsilciler, bazı diğer dillerde bulunan işlev işaretçileri kavramına benzerdir,
ancak işlev işaretçilerinden farklı olarak Temsilciler nesne yönelimli ve tür
açısından güvenlidir.
Aşağıdaki örnek adlı Function bir temsilci türü bildirir ve kullanır.
using System;

delegate double Function(double x);

class Multiplier
{
double factor;

public Multiplier(double factor) {


this.factor = factor;
}

public double Multiply(double x) {


return x * factor;
}
}

class Test
{
static double Square(double x) {
return x * x;
}

static double[] Apply(double[] a, Function f) {


double[] result = new double[a.Length];
for (int i = 0; i < a.Length; i++) result[i] = f(a[i]);
return result;
}

static void Main() {


double[] a = {0.0, 0.5, 1.0};
double[] squares = Apply(a, Square);
double[] sines = Apply(a, Math.Sin);
Multiplier m = new Multiplier(2.0);
double[] doubles = Apply(a, m.Multiply);
}
}

Temsilci türünün bir örneği Function , double bağımsız değişken alan ve bir
double değer döndüren herhangi bir yönteme başvurabilir. Yöntemi, bir
Function double[] öğesine verilen öğeleri uygular ve sonuçları ile döndürür.
double[] Apply Yönteminde, Apply bir double[] öğesine üç farklı işlev
uygulamak için kullanılır. Main
Bir temsilci, statik bir yönteme (örn. veya Square Math.Sin önceki örnekte
olduğu gibi) ya da bir örnek yöntemine (örneğin, önceki m.Multiply örnekte
olduğu gibi) başvurabilir. Örnek yönteme başvuran bir temsilci belirli bir
nesneye de başvurur ve örnek yöntemi temsilci aracılığıyla çağrıldığında, bu
nesne çağrı içinde olur this .
Temsilciler, anında oluşturulan "satır içi Yöntemler" olan anonim işlevler
kullanılarak da oluşturulabilir. Anonim işlevler, çevresindeki yöntemlerin yerel
değişkenlerini görebilir. Bu nedenle, yukarıdaki çarpan örneği bir Multiplier
sınıf kullanılmadan daha kolay yazılabilir:

double[] doubles = Apply(a, (double x) => x * 2.0);

Bir temsilcinin ilgi çekici ve yararlı bir özelliği, başvurduğu yöntemin sınıfını
bilmez veya ilgilenmez; her önemli şey, başvurulan yöntemin aynı
parametrelere sahip olması ve temsilciyle aynı türde dönüş türüdür.
Öznitelikler
Bir C# programdaki türler, Üyeler ve diğer varlıklar, davranışlarının belirli
yönlerini denetleyen değiştiricilerin özelliklerini destekler. Örneğin, bir public
yöntemin erişilebilirliği internal , protected ,, ve private değiştiricileri
kullanılarak denetlenir. C#Bu özelliği, bildirim temelli bilgilerin Kullanıcı tanımlı
türleri program varlıklarına iliştirilebilecek ve çalışma zamanında alınabilecek
şekilde genelleştirir. Programlar, öznitelikleritanımlayarak ve kullanarak bu ek
bildirime dayalı bilgileri belirtir.
Aşağıdaki örnek, ilişkili belgelerinin HelpAttribute bağlantılarını sağlamak için
program varlıklarına yerleştirilebilecek bir özniteliği bildirir.

using System;

public class HelpAttribute: Attribute


{
string url;
string topic;

public HelpAttribute(string url) {


this.url = url;
}

public string Url {


get { return url; }
}

public string Topic {


get { return topic; }
set { topic = value; }
}
}

Tüm öznitelik sınıfları, .NET Framework tarafından System.Attribute belirtilen


temel sınıftan türetilir. Öznitelikler, ilişkili bildirimden hemen önceki köşeli
parantez içinde, adı ve bağımsız değişkenlerle birlikte uygulanabilir. Bir
özniteliğin adı içinde Attribute biterse, özniteliğe başvuruluyorsa adın bu
bölümü atlanabilir. Örneğin, HelpAttribute özniteliği aşağıdaki gibi
kullanılabilir.

[Help("http://msdn.microsoft.com/.../MyClass.htm")]
public class Widget
{
[Help("http://msdn.microsoft.com/.../MyClass.htm", Topic = "Display")]
public void Display(string text) {}
}

Bu örnek, sınıfına HelpAttribute Widget öğesine ve başka HelpAttribute


Display bir sınıftaki yöntemine bir iliştirir. Öznitelik sınıfının ortak
oluşturucuları, özniteliği bir program varlığına eklendiğinde sağlanması
gereken bilgileri denetler. Öznitelik sınıfının genel okuma-yazma özelliklerine
(daha önce Topic özelliğine başvuru gibi) başvurarak ek bilgiler sunulabilir.
Aşağıdaki örnek, belirli bir program varlığı için öznitelik bilgilerinin yansıma
kullanarak çalışma zamanında nasıl alınamayacağını gösterir.
using System;
using System.Reflection;

class Test
{
static void ShowHelp(MemberInfo member) {
HelpAttribute a = Attribute.GetCustomAttribute(member,
typeof(HelpAttribute)) as HelpAttribute;
if (a == null) {
Console.WriteLine("No help for {0}", member);
}
else {
Console.WriteLine("Help for {0}:", member);
Console.WriteLine(" Url={0}, Topic={1}", a.Url, a.Topic);
}
}

static void Main() {


ShowHelp(typeof(Widget));
ShowHelp(typeof(Widget).GetMethod("Display"));
}
}

Belirli bir öznitelik yansıma aracılığıyla istendiğinde, öznitelik sınıfı için


Oluşturucu program kaynağında sağlanan bilgilerle çağrılır ve sonuçta elde
edilen öznitelik örneği döndürülür. Özellikler aracılığıyla ek bilgiler
sağlanmışsa, öznitelik örneği döndürülmeden önce bu özellikler verilen
değerlere ayarlanır.
C# İzlenecek Yolları
27.11.2019 • 4 minutes to read • Edit Online

İzlenecek yollar, yaygın senaryolar için adım adım yönergeler sunarak ürün veya belirli bir özellik alanı hakkında
öğrenmeye başlamak için iyi bir yer sunar.
Bu bölüm, C# programlama talimatlara bağlantılar içerir.

Bu Bölümde
Async ve await kullanarak Web 'e erişme
Async ve awaitkullanarak zaman uyumsuz bir çözümün nasıl oluşturulacağını gösterir.
Veya Visual Basic içinde C# Windows çalışma zamanı bileşeni oluşturma ve JavaScript 'ten çağırma
Windows Çalışma Zamanı türünün nasıl oluşturulacağını, bir Windows Çalışma Zamanı bileşende nasıl paketleyip,
sonra JavaScript kullanarak Windows için oluşturulan bir Windows 8. x mağaza uygulamasından bileşeni
çağırmayı gösterir.
Office Programlama (C# ve Visual Basic)
Ve Visual Basic kullanarak C# bir Excel çalışma kitabı ve Word belgesi oluşturmayı gösterir.
Dinamik nesneler oluşturma ve kullanma (C# ve Visual Basic)
Bir metin dosyasının içeriğini dinamik olarak sunan özel bir nesne oluşturmayı ve IronPython kitaplığı kullanan bir
projenin nasıl oluşturulacağını gösterir.
Visual ile bileşik denetim yazmaC#
Basit bir bileşik denetim oluşturmayı ve kendi işlevlerini devralma yoluyla genişletmeyi gösterir.
Visual Studio tasarım zamanı özelliklerinden faydalanan bir Windows Forms denetimi oluşturma
Özel bir denetim için özel tasarımcı oluşturmayı gösterir.
Görsel ile Windows Forms denetiminden devralmaC#
Basit bir devralınmış düğme denetimi oluşturmayı gösterir. Bu düğme, standart Windows Forms düğmesinden
işlevselliği devralır ve özel bir üye kullanıma sunar.
Tasarım zamanında özel Windows Forms Denetimlerinde hata ayıklama
Özel denetiminizin tasarım zamanı davranışının nasıl ayıklanacağını açıklar.
Windows Forms Denetimlerinde akıllı etiketleri kullanarak ortak görevleri gerçekleştirme
Bir TabControl sekme ekleme veya kaldırma, üst öğesine denetim yerleştirme ve bir SplitContainer denetiminin
yönünü değiştirme gibi yaygın olarak gerçekleştirilen görevlerden bazılarını gösterir.
Sorgu yazma C# (LINQ )
LINQ sorgu C# ifadeleri yazmak için kullanılan dil özelliklerini gösterir.
Verileri düzenleme (C#) (LINQ to SQL )
Bir veritabanındaki verileri eklemek, değiştirmek ve silmek için bir LINQ - SQL senaryosunu açıklar.
Basit nesne modeli ve sorgu (C#) (LINQ to SQL )
Varlık sınıfını filtrelemek için bir varlık sınıfı ve basit sorgu oluşturmayı gösterir.
Yalnızca saklı yordamları kullanma (C#) (LINQ to SQL )
Yalnızca saklı yordamları yürüterek verilere erişmek için LINQ to SQL nasıl kullanacağınızı gösterir.
Ilişkiler genelinde sorgulama (C#) (LINQ to SQL )
Bir veritabanındaki yabancı anahtar ilişkilerini göstermek için LINQ - SQL ilişkilerinin kullanımını gösterir.
Görselleştiricisi yazmaC#
Kullanılarak C#basit Görselleştirici nasıl yazılacağını gösterir.

İlgili Bölümler
Dağıtım örnekleri ve Izlenecek yollar
Yaygın dağıtım senaryolarına ilişkin adım adım örnekler sağlar.

Ayrıca bkz.
C# Programlama Kılavuzu
Visual Studio Örnekleri

You might also like