Nesne ve Koleksiyon Başlatıcıları (C# Programlama Kılavuzu)

C# bir nesne veya koleksiyon örneği oluşturma ve tek bir deyimde ü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, adlandırılmış bir tür ile nesne başlatıcının nasıl kullanı ve Cat parametresiz oluşturucu çağırmayı gösterir. sınıfında otomatik uygulanan özelliklerin kullanımına dikkat Cat 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öz dizimi bir örnek oluşturmanıza olanak sağlar ve bundan sonra yeni oluşturulan nesneyi atamada değişkene atanmış özellikleriyle atar.

C# 6'dan başlayarak, nesne başlatıcılar alan ve özellik atamaya ek olarak dizineicileri de ayarlayarak. Bu temel sınıfı Matrix düşünün:

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 ayarıcı içeren herhangi bir erişilebilir dizinleyici, bağımsız değişken sayısından veya türlerinden bağımsız değişken sayısından bağımsız olarak bir nesne başlatıcıda ifadelerden biri olarak kullanılabilir. Dizin bağımsız değişkenleri atamanın sol tarafını, değer ise ifadenin sağ tarafını gösterir. Örneğin, bunların hepsi uygun IndexersExample dizine sahipse 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 derlesi için IndexersExample türün aşağıdaki üyelere sahip olması gerekir:

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ılabilir, ancak linq sorgu ifadelerinde özellikle yararlıdır. Sorgu ifadeleri, aşağıdaki bildirimde gösterildiğigibi yalnızca bir nesne başlatıcı kullanılarak başlatılmış olan anonim türleri sık kullanır.

var pet = new { Age = 10, Name = "Fluffy" };  

Anonim türler, linq sorgu ifadesinde yan tümcesini, özgün dizideki nesneleri değeri ve şekli özgünten farklı olan select nesnelere dönüştürmek için 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 ( ) birçok alan ve yöntem içerdiğini ve yalnızca ürün adını ve birim fiyatını içeren bir nesne dizisi p oluşturmakla ilgilendiğinizi varsayalım.

var productInfos =
    from p in products
    select new { p.ProductName, p.UnitPrice };

Bu sorgu yürütülürken değişkeni, bu örnekte gösterildiği gibi deyiminde erişilebilen productInfos foreach bir nesne dizisi içerir:

foreach(var p in productInfos){...}  

Yeni anonim türe sahip her nesne, özgün nesnede bulunan özellikler veya alanlar ile aynı adları alan iki genel özele sahiptir. Anonim tür oluştururken bir alanı yeniden adlandırarak da yeniden adlandırebilirsiniz; Aşağıdaki örnek, alanını olarak UnitPrice yeniden Price adlandırıyor.

select new {p.ProductName, Price = p.UnitPrice};  

Koleksiyon başlatıcıları

Koleksiyon başlatıcıları, uygulayan ve bir örnek yöntemi veya uzantı yöntemi olarak uygun imzaya sahip bir koleksiyon türünü başlatarak bir veya daha fazla öğe IEnumerable Add başlatıcısı belirtmenize izin verir. Öğ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ı belirtmenize gerek yok; derleyici çağrıları otomatik olarak ekler.

Aşağıdaki örnekte iki basit koleksiyon başlatıcısı gösterir:

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 sınıfın nesnelerini Cat başlatmak için nesne başlatıcılarını 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 yöntemi izin verdiyse, null değerini koleksiyon başlatıcıda bir öğe Add olarak belirtebilirsiniz.

List<Cat> moreCats = new List<Cat>
{
    new Cat{ Name = "Furrytail", Age=5 },
    new Cat{ Name = "Peaches", Age=4 },
    null
};

Koleksiyon okuma/yazma dizinle yazmayı destekliyorsa, dizine sahip öğeleri belirtsiniz.

var numbers = new Dictionary<int, string>
{
    [7] = "seven",
    [9] = "nine",
    [13] = "thirteen"
};

Yukarıdaki örnek, değerleri ayarlamak için Item[TKey] çağrısında bulunduran kod üretir. C# 6'dan önce, aşağıdaki söz dizimlerini kullanarak sözlükleri ve diğer ilgili kapsayıcıları başlatebilirsiniz. Dizin oluşturma söz dizimi yerine parantez ve atama ile birden çok değer içeren bir nesne kullandığına dikkat eder:

var moreNumbers = new Dictionary<int, string>
{
    {19, "nineteen" },
    {23, "twenty-three" },
    {42, "forty-two" }
};

Bu başlatıcı örneği, Add(TKey, TValue) sözlüğüne üç öğe eklemek için çağrır. Bu iki farklı şekilde, derleyici tarafından oluşturulan yöntem çağrıları nedeniyle, ilgili koleksiyonları başlatmanın biraz farklı davranışı vardır. Her iki çeşitleme de sınıfıyla Dictionary birlikte çalışır. Diğer türler, genel API'lerine göre yalnızca birini veya diğerlerini destekleyene.

Koleksiyon salt okunur özellik başlatma ile Nesne Başlatıcıları

Bazı sınıflar, özelliğinin salt okunur olduğu koleksiyon özelliklerine sahip olabilir, aşağıdaki örnekteki özelliği Cats CatOwner gibi:

public class CatOwner
{
    public IList<Cat> Cats { get; } = new List<Cat>();
}

Özellik yeni bir liste atanamadığından şu ana kadar ele alınan koleksiyon başlatıcı söz dizimi kullanamayacak:

CatOwner owner = new CatOwner
{
    Cats = new List<Cat>
    {
        new Cat{ Name = "Sylvester", Age=8 },
        new Cat{ Name = "Whiskers", Age=2 },
        new Cat{ Name = "Sasha", Age=14 }
    }
};

Ancak, yeni girişler yine de liste oluşturma ( ) atarak başlatma söz dizimi kullanılarak bir sonraki gibi Cats new List<Cat> eklenebilir:

CatOwner owner = new CatOwner
{
    Cats =
    {
        new Cat{ Name = "Sylvester", Age=8 },
        new Cat{ Name = "Whiskers", Age=2 },
        new Cat{ Name = "Sasha", Age=14 }
    }
};

Eklenecek giriş kümesi, küme ayraçları ile çevrelenmiştir. Yukarıdakiler, yazma ile aynıdır:

CatOwner owner = new CatOwner();
owner.Cats.Add(new Cat{ Name = "Sylvester", Age=8 });
owner.Cats.Add(new Cat{ Name = "Whiskers", Age=2 });
owner.Cats.Add(new Cat{ Name = "Sasha", Age=14 });

Ö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 örnekte, birden çok parametreye sahip bir yöntem uygulayan ve içeren bir nesne gösterir. Bu, listede yöntemin imzasını karşılık gelen öğe başına birden çok öğe içeren bir koleksiyon IEnumerable Add başlatıcısı Add 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öntemleri, aşağıdaki örnekte gösterildiği gibi değişken sayıda bağımsız params değişken almak için anahtar sözcüğünü kullanabilir. Bu örnek ayrıca dizinleri kullanarak bir koleksiyonu başlatmak için dizin oluşturmanın özel uygulamasını da gösteriyor.

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();

        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}: ");

            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.