Aracılığıyla paylaş


Veri Sözleşmelerinde Koleksiyon Türleri

Koleksiyon, belirli bir türdeki öğelerin listesidir. .NET Framework'te, bu listeler diziler veya çeşitli diğer türler (Genel Liste, Genel BindingList<T>, StringCollectionveya ArrayList) kullanılarak temsil edilebilir. Örneğin, bir koleksiyon belirli bir Müşteri için Adreslerin listesini tutabilir. Bu koleksiyonlar, gerçek türünden bağımsız olarak liste koleksiyonları olarak adlandırılır.

Bir öğe ("anahtar") ile başka bir ("değer") arasındaki ilişkiyi temsil eden özel bir koleksiyon biçimi vardır. .NET Framework'te, bunlar ve genel sözlüğü gibi Hashtable türler tarafından temsil edilir. Örneğin, bir ilişkilendirme koleksiyonu bir şehri ("anahtar") kendi popülasyonuyla ("değer") eşler. Bu koleksiyonlar, gerçek türleri ne olursa olsun sözlük koleksiyonları olarak adlandırılır.

Koleksiyonlar, veri sözleşmesi modelinde özel işlem alır.

Diziler ve genel koleksiyonlar dahil olmak üzere arabirimini uygulayan IEnumerable türler koleksiyon olarak kabul edilir. Bunlardan, veya Genel IDictionary<TKey,TValue> arabirimlerini uygulayan IDictionary türler sözlük koleksiyonlarıdır; diğerleri liste koleksiyonlarıdır.

Adlı Add bir yönteme ve parametresiz oluşturucuya sahip olmak gibi koleksiyon türleriyle ilgili ek gereksinimler aşağıdaki bölümlerde ayrıntılı olarak ele alınmaktadır. Bu, koleksiyon türlerinin hem seri hale getirilebilmesini hem de seri durumdan çıkarılabilmesini sağlar. Bu, bazı koleksiyonların Genel ReadOnlyCollection<T> gibi doğrudan desteklenmediği anlamına gelir (parametresiz oluşturucuya sahip olmadığından). Ancak, bu kısıtlamaları aşma hakkında bilgi için, bu konunun devamında yer alan "Koleksiyon Arabirimi Türlerini ve Salt Okunur Koleksiyonları Kullanma" bölümüne bakın.

Koleksiyonlarda yer alan türler veri sözleşmesi türleri veya başka bir şekilde serileştirilebilir olmalıdır. Daha fazla bilgi için bkz . Veri Sözleşmesi Seri Hale Getiricisi Tarafından Desteklenen Türler.

Ne olduğu ve nelerin geçerli bir koleksiyon olarak kabul edilmediği ve koleksiyonların nasıl seri hale getirildiği hakkında daha fazla bilgi için, bu konunun "Gelişmiş Koleksiyon Kuralları" bölümündeki koleksiyonları serileştirme hakkındaki bilgilere bakın.

Değiştirilebilir Koleksiyonlar

Aynı türdeki tüm liste koleksiyonlarının aynı veri sözleşmesine sahip olduğu kabul edilir (bu konunun ilerleyen bölümlerinde açıklandığı gibi öznitelik kullanılarak CollectionDataContractAttribute özelleştirilmediği sürece). Bu nedenle, örneğin, aşağıdaki veri sözleşmeleri eşdeğerdir.

[DataContract(Name = "PurchaseOrder")]
public class PurchaseOrder1
{
    [DataMember]
    public string customerName;
    [DataMember]
    public Collection<Item> items;
    [DataMember]
    public string[] comments;
}

[DataContract(Name = "PurchaseOrder")]
public class PurchaseOrder2
{
    [DataMember]
    public string customerName;
    [DataMember]
    public List<Item> items;
    [DataMember]
    public BindingList<string> comments;
}
<DataContract(Name:="PurchaseOrder")>
Public Class PurchaseOrder1

    <DataMember()>
    Public customerName As String

    <DataMember()>
    Public items As Collection(Of Item)

    <DataMember()>
    Public comments() As String

End Class

<DataContract(Name:="PurchaseOrder")>
Public Class PurchaseOrder2

    <DataMember()>
    Public customerName As String

    <DataMember()>
    Public items As List(Of Item)

    <DataMember()>
    Public comments As BindingList(Of String)

End Class

Her iki veri sözleşmesi de aşağıdaki koda benzer xml ile sonuçlanır.

<PurchaseOrder>
    <customerName>...</customerName>
    <items>
        <Item>...</Item>
        <Item>...</Item>
        <Item>...</Item>
        ...
    </items>
    <comments>
        <string>...</string>
        <string>...</string>
        <string>...</string>
        ...
    </comments>
</PurchaseOrder>

Koleksiyon değiştirilebilirliği, örneğin sunucuda performans için iyileştirilmiş bir koleksiyon türü ve istemcideki kullanıcı arabirimi bileşenlerine bağlanacak şekilde tasarlanmış bir koleksiyon türü kullanmanıza olanak tanır.

Liste koleksiyonlarına benzer şekilde, aynı anahtar ve değer türlerine sahip tüm sözlük koleksiyonlarının aynı veri sözleşmesine sahip olduğu kabul edilir (öznitelik tarafından CollectionDataContractAttribute özelleştirilmediği sürece).

.NET türleri için değil, koleksiyon eşdeğerliği söz konusu olduğunda yalnızca veri sözleşmesi türü önemlidir. Başka bir ifadeyle, Type1 ve Type2'nin eşdeğer veri sözleşmeleri varsa, Type1 koleksiyonu Type2 koleksiyonuna eşdeğer olarak kabul edilir.

Genel olmayan koleksiyonların türündeki Objectgenel koleksiyonlar ile aynı veri sözleşmesine sahip olduğu kabul edilir. (Örneğin, ve Genel List<T>Object veri sözleşmeleri ArrayList aynıdır.)

Koleksiyon Arabirimi Türlerini ve Salt Okunur Koleksiyonları Kullanma

Koleksiyon arabirim türleri (IEnumerable, IDictionary, genel IDictionary<TKey,TValue>veya bu arabirimlerden türetilen arabirimler), gerçek koleksiyon türleri için koleksiyon veri sözleşmelerine eşdeğer koleksiyon veri sözleşmelerine sahip olarak da kabul edilir. Bu nedenle, koleksiyon arabirim türü olarak seri hale getirilen türü bildirmek mümkündür ve sonuçlar gerçek bir koleksiyon türü kullanılmış gibi aynıdır. Örneğin, aşağıdaki veri sözleşmeleri eşdeğerdir.

[DataContract(Name="Customer")]
public class Customer1
{
    [DataMember]
    public string customerName;
    [DataMember]
    public Collection<Address> addresses;
}

[DataContract(Name="Customer")]
public class Customer2
{
    [DataMember]
    public string customerName;
    [DataMember]
    public ICollection<Address> addresses;
}
<DataContract(Name:="Customer")>
Public Class Customer1

    <DataMember()>
    Public customerName As String

    <DataMember()>
    Public addresses As Collection(Of Address)

End Class

<DataContract(Name:="Customer")>
Public Class Customer2

    <DataMember()>
    Public customerName As String

    <DataMember()>
    Public addresses As ICollection(Of Address)

End Class

Serileştirme sırasında, bildirilen tür bir arabirim olduğunda, kullanılan gerçek örnek türü bu arabirimi uygulayan herhangi bir tür olabilir. Daha önce açıklanan kısıtlamalar (parametresiz oluşturucu ve Add yönteme sahip olma) geçerli değildir. Örneğin, Genel türünde bir veri üyesini doğrudan bildiremeseniz bile, Customer2'deki adresleri Genel ReadOnlyCollection<T>Adres örneğine ReadOnlyCollection<T> ayarlayabilirsiniz.

Seri durumdan çıkarma sırasında, bildirilen tür bir arabirim olduğunda, serileştirme altyapısı bildirilen arabirimi uygulayan bir tür seçer ve tür örneği oluşturulur. Bilinen türler mekanizmasının (Veri Sözleşmesi Bilinen Türler bölümünde açıklanmıştır) burada hiçbir etkisi yoktur; tür seçimi WCF'de yerleşiktir.

Koleksiyon Türlerini Özelleştirme

Çeşitli kullanımları olan özniteliğini CollectionDataContractAttribute kullanarak koleksiyon türlerini özelleştirebilirsiniz.

Koleksiyon türlerini özelleştirmenin koleksiyon değiştirilebilirliğini tehlikeye attığını, bu nedenle genellikle mümkün olduğunda bu özniteliğin uygulanmasını önlemenin önerildiğini unutmayın. Bu sorun hakkında daha fazla bilgi için bu konunun devamında yer alan "Gelişmiş Koleksiyon Kuralları" bölümüne bakın.

Koleksiyon Veri Sözleşmesi Adlandırma

Koleksiyon türlerini adlandırma kuralları, Veri Sözleşmesi Adları'nda açıklandığı gibi normal veri sözleşmesi türlerini adlandırmaya yönelik kurallara benzer, ancak bazı önemli farklılıklar vardır:

  • CollectionDataContractAttribute özniteliği, özniteliği yerine adı özelleştirmek DataContractAttribute için kullanılır. Özniteliğin CollectionDataContractAttribute ve Namespace özellikleri de vardırName.

  • CollectionDataContractAttribute Öznitelik uygulanmadığında, koleksiyon türleri için varsayılan ad ve ad alanı koleksiyon içinde yer alan türlerin adlarına ve ad alanlarına bağlıdır. Koleksiyon türünün adından ve ad alanından etkilenmez. Bir örnek için aşağıdaki türlere bakın.

    public CustomerList1 : Collection<string> {}
    public StringList1 : Collection<string> {}
    

Her iki türün de veri sözleşmesi adı "CustomerList1" veya "StringList1" değil "ArrayOfstring" şeklindedir. Bu, bu türlerden herhangi birinin kök düzeyinde seri hale getirildiğinin aşağıdaki koda benzer XML'ye sahip olduğu anlamına gelir.

<ArrayOfstring>
    <string>...</string>
    <string>...</string>
    <string>...</string>
    ...
</ArrayOfstring>

Bu adlandırma kuralı, bir dize listesini temsil eden özelleştirilmemiş türlerin aynı veri sözleşmesine ve XML gösterimine sahip olduğundan emin olmak için seçilmiştir. Bu, koleksiyon değiştirilebilirliğini mümkün kılar. Bu örnekte CustomerList1 ve StringList1 tamamen değiştirilebilir.

Ancak, öznitelik uygulandığında CollectionDataContractAttribute , öznitelikte hiçbir özellik ayarlı olmasa bile koleksiyon özelleştirilmiş bir koleksiyon veri sözleşmesi haline gelir. Koleksiyon veri sözleşmesinin adı ve ad alanı, koleksiyon türünün kendisine bağlıdır. Bir örnek için aşağıdaki türe bakın.

[CollectionDataContract]
public class CustomerList2 : Collection<string> {}
<CollectionDataContract()>
Public Class CustomerList2
    Inherits Collection(Of String)
End Class

Seri hale getirildiğinde, sonuçta elde edilen XML aşağıdakine benzer.

<CustomerList2>
    <string>...</string>
    <string>...</string>
    <string>...</string>
    ...
</CustomerList2>

Bunun artık özelleştirilmemiş türlerin XML gösterimiyle eşdeğer olmadığına dikkat edin.

  • adlandırmayı Name daha fazla özelleştirmek için ve Namespace özelliklerini kullanabilirsiniz. Aşağıdaki sınıfa bakın.

    [CollectionDataContract(Name="cust_list")]
    public class CustomerList3 : Collection<string> {}
    
    <CollectionDataContract(Name:="cust_list")>
    Public Class CustomerList3
        Inherits Collection(Of String)
    End Class
    

Sonuçta elde edilen XML aşağıdakine benzer.

<cust_list>
    <string>...</string>
    <string>...</string>
    <string>...</string>
    ...
</cust_list>

Daha fazla bilgi için bu konunun devamında yer alan "Gelişmiş Koleksiyon Kuralları" bölümüne bakın.

Liste Koleksiyonlarında Yinelenen Öğe Adını Özelleştirme

Liste koleksiyonları yinelenen girdiler içerir. Normalde, yinelenen her girdi, koleksiyonda yer alan türün veri sözleşmesi adına göre adlı bir öğe olarak temsil edilir.

Örneklerde CustomerList koleksiyonlar dizeler içeriyordu. Dize ilkel türünün veri sözleşmesi adı "string" olduğundan yinelenen öğe "<string>" idi.

Ancak özniteliğindeki ItemNameCollectionDataContractAttribute özelliği kullanılarak bu yinelenen öğe adı özelleştirilebilir. Bir örnek için aşağıdaki türe bakın.

[CollectionDataContract(ItemName="customer")]
public class CustomerList4 : Collection<string>  {}
<CollectionDataContract(ItemName:="customer")>
Public Class CustomerList4
    Inherits Collection(Of String)
End Class

Sonuçta elde edilen XML aşağıdakine benzer.

<CustomerList4>
    <customer>...</customer>
    <customer>...</customer>
    <customer>...</customer>
    ...
</CustomerList4>

Yinelenen öğenin ad alanı, daha önce açıklandığı gibi özelliği kullanılarak özelleştirilebilen koleksiyon veri sözleşmesinin ad alanıyla Namespace her zaman aynıdır.

Sözlük Koleksiyonlarını Özelleştirme

Sözlük koleksiyonları temelde her girdinin bir anahtarı ve ardından bir değeri olan girdilerin listesidir. Normal listelerde olduğu gibi, özelliğini kullanarak ItemName yinelenen öğeye karşılık gelen öğe adını değiştirebilirsiniz.

Ayrıca ve özelliklerini kullanarak KeyNameValueName anahtarı ve değeri temsil eden öğe adlarını değiştirebilirsiniz. Bu öğelerin ad alanları, koleksiyon veri sözleşmesinin ad alanıyla aynıdır.

Bir örnek için aşağıdaki türe bakın.

[CollectionDataContract
    (Name = "CountriesOrRegionsWithCapitals",
    ItemName = "entry",
    KeyName = "countryorregion",
    ValueName = "capital")]
public class CountriesOrRegionsWithCapitals2 : Dictionary<string, string> { }
<CollectionDataContract(Name:="CountriesOrRegionsWithCapitals",
                        ItemName:="entry", KeyName:="countryorregion",
                        ValueName:="capital")>
Public Class CountriesOrRegionsWithCapitals2
    Inherits Dictionary(Of String, String)
End Class

Seri hale getirildiğinde, sonuçta elde edilen XML aşağıdakine benzer.

<CountriesOrRegionsWithCapitals>
    <entry>
        <countryorregion>USA</countryorregion>
        <capital>Washington</capital>
    </entry>
    <entry>
        <countryorregion>France</countryorregion>
        <capital>Paris</capital>
    </entry>
    ...
</CountriesOrRegionsWithCapitals>

Sözlük koleksiyonları hakkında daha fazla bilgi için bu konunun devamında yer alan "Gelişmiş Koleksiyon Kuralları" bölümüne bakın.

Koleksiyonlar ve Bilinen Türler

Diğer koleksiyonlar veya koleksiyon arabirimleri yerine çok biçimli kullanıldığında bilinen türlere koleksiyon türleri eklemeniz gerekmez. Örneğin, türünde IEnumerable bir veri üyesi bildirir ve örneğini ArrayListgöndermek için kullanırsanız, bilinen türlere eklemeniz ArrayList gerekmez.

Koleksiyon olmayan türler yerine çok biçimli koleksiyonlar kullandığınızda, bunların bilinen türlere eklenmesi gerekir. Örneğin, türünde Object bir veri üyesi bildirir ve örneğini ArrayListgöndermek için kullanırsanız, bilinen türlere ekleyin ArrayList .

Bu, eşdeğer koleksiyonları çok biçimli olarak seri hale getirmenize izin vermez. Örneğin, önceki örnekte bilinen türler listesine eklediğinizde ArrayList , eşdeğer bir veri sözleşmesi olsa bile bu, sınıfı atamanıza Array of Object izin vermez. Bu, koleksiyon olmayan türler için serileştirmede bilinen normal tür davranışından farklı değildir, ancak koleksiyonların eşdeğer olması çok yaygın olduğundan koleksiyonlar söz konusu olduğunda anlaşılması özellikle önemlidir.

Serileştirme sırasında, belirli bir veri sözleşmesi için belirli bir kapsamda yalnızca bir tür bilinebilir ve eşdeğer koleksiyonların tümü aynı veri sözleşmelerine sahiptir. Bu, önceki örnekte aynı kapsamda hem hem de ArrayListArray of Object bilinen türleri ekleyemeyeceğiniz anlamına gelir. Bu, koleksiyon dışı türler için bilinen tür davranışına eşdeğerdir, ancak koleksiyonları anlamak özellikle önemlidir.

Koleksiyonların içeriği için bilinen türler de gerekebilir. Örneğin, bir ArrayList gerçekten ve Type2örneklerini Type1 içeriyorsa, bu türlerin her ikisi de bilinen türlere eklenmelidir.

Aşağıdaki örnekte koleksiyonlar ve bilinen türler kullanılarak düzgün bir şekilde leştirilmiş bir nesne grafı gösterilmektedir. Örnek biraz karmaşıktır, çünkü gerçek bir uygulamada normalde aşağıdaki veri üyelerini olarak Objecttanımlamazsınız ve bu nedenle bilinen bir tür/polimorfizm sorunu yoktur.

[DataContract]
public class Employee
{
    [DataMember]
    public string name = "John Doe";
    [DataMember]
    public Payroll payrollRecord;
    [DataMember]
    public Training trainingRecord;
}

[DataContract]
[KnownType(typeof(int[]))] //required because int[] is used polymorphically
[KnownType(typeof(ArrayList))] //required because ArrayList is used polymorphically
public class Payroll
{
    [DataMember]
    public object salaryPayments = new int[12];
    //float[] not needed in known types because polymorphic assignment is to another collection type
    [DataMember]
    public IEnumerable<float> stockAwards = new float[12];
    [DataMember]
    public object otherPayments = new ArrayList();
}

[DataContract]
[KnownType(typeof(List<object>))]
//required because List<object> is used polymorphically
//does not conflict with ArrayList above because it's a different scope,
//even though it's the same data contract
[KnownType(typeof(InHouseTraining))] //Required if InHouseTraining can be used in the collection
[KnownType(typeof(OutsideTraining))] //Required if OutsideTraining can be used in the collection
public class Training
{
    [DataMember]
    public object training = new List<object>();
}

[DataContract]
public class InHouseTraining
{
    //code omitted
}

[DataContract]
public class OutsideTraining
{
    //code omitted
}
<DataContract()>
Public Class Employee

    <DataMember()>
    Public name As String = "John Doe"

    <DataMember()>
    Public payrollRecord As Payroll

    <DataMember()>
    Public trainingRecord As Training

End Class

<DataContract(), KnownType(GetType(Integer())), KnownType(GetType(ArrayList))>
Public Class Payroll

    <DataMember()>
    Public salaryPayments As Object = New Integer(11) {}

    'float[] not needed in known types because polymorphic assignment is to another collection type
    <DataMember()>
    Public stockAwards As IEnumerable(Of Single) = New Single(11) {}

    <DataMember()>
    Public otherPayments As Object = New ArrayList()

End Class

'required because List<object> is used polymorphically
'does not conflict with ArrayList above because it's a different scope, 
'even though it's the same data contract
<DataContract(), KnownType(GetType(List(Of Object))),
                 KnownType(GetType(InHouseTraining)),
                 KnownType(GetType(OutsideTraining))>
Public Class Training
    <DataMember()>
    Public training As Object = New List(Of Object)()
End Class

<DataContract()>
Public Class InHouseTraining
    'code omitted…
End Class

<DataContract()>
Public Class OutsideTraining
    'code omitted…
End Class

Seri durumdan çıkarmada, bildirilen tür bir koleksiyon türüyse, bildirilen tür gerçekten gönderilen türden bağımsız olarak örneği oluşturulur. Bildirilen tür bir koleksiyon arabirimiyse, seri durumdan çıkarıcı bilinen türler dikkate alınmadan örneği oluşturulacak bir tür seçer.

Ayrıca seri durumdan çıkarmada, bildirilen tür bir koleksiyon türü değilse ancak koleksiyon türü gönderiliyorsa, bilinen türler listesinden eşleşen bir koleksiyon türü seçilir. Seri durumdan çıkarma sırasında bilinen türler listesine koleksiyon arabirimi türleri eklemek mümkündür. Bu durumda seri durumdan çıkarma altyapısı yeniden örneklenecek bir tür seçer.

Collections ve NetDataContractSerializer Sınıfı

NetDataContractSerializer Sınıf kullanımda olduğunda, dizi olmayan özelleştirilmemiş koleksiyon türleri (özniteliği olmadanCollectionDataContractAttribute) özel anlamlarını kaybeder.

özniteliğiyle SerializableAttribute işaretlenmiş özelleştirilmemiş koleksiyon türleri yine de özniteliğine SerializableAttribute veya ISerializable arabirim kurallarına göre sınıf tarafından NetDataContractSerializer seri hale getirilebilir.

Özelleştirilmiş koleksiyon türleri, koleksiyon arabirimleri ve diziler, sınıf kullanımda olsa bile koleksiyon olarak değerlendirilmeye NetDataContractSerializer devam eder.

Koleksiyonlar ve Şema

Tüm eşdeğer koleksiyonlar XML Şema tanım dili (XSD) şemasında aynı temsile sahiptir. Bu nedenle, normalde oluşturulan istemci kodunda sunucudakiyle aynı koleksiyon türünü almazsınız. Örneğin, sunucu Tamsayı veri üyesinin Geneli List<T> ile bir veri sözleşmesi kullanabilir, ancak oluşturulan istemci kodunda aynı veri üyesi bir tamsayı dizisi haline gelebilir.

Sözlük koleksiyonları, sözlük olduklarını belirten WCF'ye özgü bir şema ek açıklamasıyla işaretlenir; aksi takdirde, anahtar ve değer içeren girdiler içeren basit listelerden ayırt edilemez. Koleksiyonların veri sözleşmesi şemasında nasıl temsil edildiklerine ilişkin tam bir açıklama için bkz . Veri Sözleşmesi Şema Başvurusu.

Varsayılan olarak, içeri aktarılan koddaki özelleştirilmemiş koleksiyonlar için türler oluşturulmaz. Liste koleksiyonu türlerinin veri üyeleri diziler olarak, sözlük koleksiyonu türlerinin veri üyeleri de Genel Sözlük olarak içeri aktarılır.

Ancak, özelleştirilmiş koleksiyonlar için özniteliğiyle CollectionDataContractAttribute işaretlenmiş ayrı türler oluşturulur. (Şemadaki özelleştirilmiş koleksiyon türü, varsayılan ad alanını, adı, yinelenen öğe adını veya anahtar/değer öğesi adlarını kullanmayan bir koleksiyon türüdür.) Bu türler, liste türleri için Genel List<T> ve sözlük türleri için Genel Sözlük'ten türetilen boş türlerdir.

Örneğin, sunucuda aşağıdaki türlere sahip olabilirsiniz.

[DataContract]
public class CountryOrRegion
{
    [DataMember]
    public Collection<string> officialLanguages;
    [DataMember]
    public List<DateTime> holidays;
    [DataMember]
    public CityList cities;
    [DataMember]
    public ArrayList otherInfo;
}

public class Person
{
    public Person(string fName, string lName)
    {
        this.firstName = fName;
        this.lastName = lName;
    }

    public string firstName;
    public string lastName;
}

public class PeopleEnum : IEnumerator
{
    public Person[] _people;

    // Enumerators are positioned before the first element
    // until the first MoveNext() call.
    int position = -1;

    public PeopleEnum(Person[] list)
    {
        _people = list;
    }

    public bool MoveNext()
    {
        position++;
        return (position < _people.Length);
    }

    public void Reset()
    {
        position = -1;
    }

    public object Current
    {
        get
        {
            try
            {
                return _people[position];
            }
            catch (IndexOutOfRangeException)
            {
                throw new InvalidOperationException();
            }
        }
    }
}

[CollectionDataContract(Name = "Cities", ItemName = "city", KeyName = "cityName", ValueName = "population")]
public class CityList : IDictionary<string, int>, IEnumerable<System.Collections.Generic.KeyValuePair<string, int>>
{
    private Person[] _people = null;

    public bool ContainsKey(string s) { return true; }
    public bool Contains(string s) { return true; }
    public bool Contains(KeyValuePair<string, int> item) { return (true); }
    public void Add(string key, int value) { }
    public void Add(KeyValuePair<string, int> keykValue) { }
    public bool Remove(string s) { return true; }
    public bool TryGetValue(string d, out int i)
    {
        i = 0; return (true);
    }

    /*
    [TypeConverterAttribute(typeof(SynchronizationHandlesTypeConverter))]
    public ICollection<string> SynchronizationHandles {
        get { return (System.Collections.Generic.ICollection<string>) new Stack<string> (); }
        set { }
    }*/

    public ICollection<string> Keys
    {
        get
        {
            return (System.Collections.Generic.ICollection<string>)new Stack<string>();
        }
    }

    public int this[string s]
    {
        get
        {
            return 0;
        }
        set
        {
        }
    }

    public ICollection<int> Values
    {
        get
        {
            return (System.Collections.Generic.ICollection<int>)new Stack<string>();
        }
    }

    public void Clear() { }
    public void CopyTo(KeyValuePair<string, int>[] array, int index) { }
    public bool Remove(KeyValuePair<string, int> item) { return true; }
    public int Count { get { return 0; } }
    public bool IsReadOnly { get { return true; } }

    IEnumerator<KeyValuePair<string, int>>
        System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, int>>.GetEnumerator()
    {
        return (IEnumerator<KeyValuePair<string, int>>)new PeopleEnum(_people); ;
    }

    public IEnumerator GetEnumerator()
    {
        return new PeopleEnum(_people);
    }
}

<DataContract()>
Public Class CountryOrRegion

    <DataMember()>
    Public officialLanguages As Collection(Of String)

    <DataMember()>
    Public holidays As List(Of DateTime)

    <DataMember()>
    Public cities As CityList

    <DataMember()>
    Public otherInfo As ArrayList

End Class

Public Class Person
    Public Sub New(ByVal fName As String, ByVal lName As String)
        Me.firstName = fName
        Me.lastName = lName
    End Sub

    Public firstName As String
    Public lastName As String
End Class

Public Class PeopleEnum
    Implements IEnumerator

    Public _people() As Person
    ' Enumerators are positioned before the first element
    ' until the first MoveNext() call.
    Private position As Integer = -1

    Public Sub New(ByVal list() As Person)
        _people = list
    End Sub

    Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext
        position += 1
        Return position < _people.Length
    End Function

    Public Sub Reset() Implements IEnumerator.Reset
        position = -1
    End Sub

    Public ReadOnly Property Current() As Object Implements IEnumerator.Current
        Get
            Try
                Return _people(position)
            Catch e1 As IndexOutOfRangeException
                Throw New InvalidOperationException()
            End Try
        End Get
    End Property
End Class

<CollectionDataContract(Name:="Cities",
                        ItemName:="city",
                        KeyName:="cityName",
                        ValueName:="population")>
Public Class CityList
    Implements IDictionary(Of String, Integer), IEnumerable(Of System.Collections.Generic.KeyValuePair(Of String, Integer))

    Private _people() As Person = Nothing

    Public Function ContainsKey(ByVal s As String) As Boolean Implements IDictionary(Of String, Integer).ContainsKey
        Return True
    End Function

    Public Function Contains(ByVal s As String) As Boolean
        Return True
    End Function

    Public Function Contains(ByVal item As KeyValuePair(Of String, Integer)) As Boolean Implements IDictionary(Of String, Integer).Contains
        Return (True)
    End Function

    Public Sub Add(ByVal key As String,
                   ByVal value As Integer) Implements IDictionary(Of String, Integer).Add
    End Sub

    Public Sub Add(ByVal keykValue As KeyValuePair(Of String, Integer)) Implements IDictionary(Of String, Integer).Add
    End Sub

    Public Function Remove(ByVal s As String) As Boolean Implements IDictionary(Of String, Integer).Remove
        Return True
    End Function

    Public Function TryGetValue(ByVal d As String,
                                <System.Runtime.InteropServices.Out()> ByRef i As Integer) _
                                As Boolean Implements IDictionary(Of String, Integer).TryGetValue
        i = 0
        Return (True)
    End Function

    Public ReadOnly Property Keys() As ICollection(Of String) Implements IDictionary(Of String, Integer).Keys
        Get
            Return CType(New Stack(Of String)(), System.Collections.Generic.ICollection(Of String))
        End Get
    End Property

    Default Public Property Item(ByVal s As String) As Integer Implements IDictionary(Of String, Integer).Item
        Get
            Return 0
        End Get
        Set(ByVal value As Integer)
        End Set
    End Property

    Public ReadOnly Property Values() As ICollection(Of Integer) Implements IDictionary(Of String, Integer).Values
        Get
            Return CType(New Stack(Of String)(), System.Collections.Generic.ICollection(Of Integer))
        End Get
    End Property

    Public Sub Clear() Implements IDictionary(Of String, Integer).Clear
    End Sub

    Public Sub CopyTo(ByVal array() As KeyValuePair(Of String, Integer),
                      ByVal index As Integer) Implements IDictionary(Of String, Integer).CopyTo
    End Sub

    Public Function Remove(ByVal item As KeyValuePair(Of String, Integer)) As Boolean Implements IDictionary(Of String, Integer).Remove
        Return True
    End Function

    Public ReadOnly Property Count() As Integer Implements IDictionary(Of String, Integer).Count
        Get
            Return 0
        End Get
    End Property

    Public ReadOnly Property IsReadOnly() As Boolean Implements IDictionary(Of String, Integer).IsReadOnly
        Get
            Return True
        End Get
    End Property

    Private Function IEnumerable_GetEnumerator() As IEnumerator(Of KeyValuePair(Of String, Integer)) _
        Implements System.Collections.Generic.IEnumerable(Of System.Collections.Generic.KeyValuePair(Of String, Integer)).GetEnumerator

        Return CType(New PeopleEnum(_people), IEnumerator(Of KeyValuePair(Of String, Integer)))
    End Function

    Public Function GetEnumerator() As IEnumerator Implements System.Collections.IEnumerable.GetEnumerator

        Return New PeopleEnum(_people)

    End Function

End Class

Şema dışarı aktarılıp yeniden içeri aktarıldığında, oluşturulan istemci kodu aşağıdakine benzer (okuma kolaylığı için özellikler yerine alanlar gösterilir).

[DataContract]
public class CountryOrRegion2
{
    [DataMember]
    public string[] officialLanguages;
    [DataMember]
    public DateTime[] holidays;
    [DataMember]
    public Cities cities;
    [DataMember]
    public object[] otherInfo;
}

[CollectionDataContract(ItemName = "city", KeyName = "cityName", ValueName = "population")]
public class Cities : Dictionary<string, int> { }
<DataContract()>
Public Class CountryOrRegion2
    <DataMember()>
    Public officialLanguages() As String
    <DataMember()>
    Public holidays() As DateTime
    <DataMember()>
    Public cities As Cities
    <DataMember()>
    Public otherInfo() As Object
End Class

<CollectionDataContract(ItemName:="city", KeyName:="cityName", ValueName:="population")>
Public Class Cities
    Inherits Dictionary(Of String, Integer)
End Class

Oluşturulan kodda varsayılan kodlardan farklı türler kullanmak isteyebilirsiniz. Örneğin, veri üyelerinizi kullanıcı arabirimi bileşenlerine bağlamayı kolaylaştırmak için normal diziler yerine Genel BindingList<T> kullanmak isteyebilirsiniz.

Oluşturulacak koleksiyon türlerini seçmek için, şemayı içeri aktarırken kullanmak istediğiniz koleksiyon türlerinin listesini nesnenin özelliğine ReferencedCollectionTypesImportOptions geçirin. Bu türlere başvurulan koleksiyon türleri denir.

Genel türlere başvurulduğunda, bunların tamamen açık genel türler veya tamamen kapalı genel türler olması gerekir.

Not

Svcutil.exe aracı kullanılırken, bu başvuru /collectionType komut satırı anahtarı (kısa form: /ct) kullanılarak gerçekleştirilebilir. /reference anahtarını (kısa form: /r) kullanarak başvuruda bulunılan koleksiyon türleri için derlemeyi de belirtmeniz gerektiğini unutmayın. Tür genelse, arkasına bir geri tırnak işareti ve genel parametre sayısı gelmelidir. Geri tırnak işareti (') tek tırnak (') karakteriyle karıştırılmamalıdır. /collectionType anahtarını birden çok kez kullanarak birden çok başvuruda bulunan koleksiyon türü belirtebilirsiniz.

Örneğin, tüm listelerin Genel List<T>olarak içeri aktarılmasına neden olmak için.

svcutil.exe MyService.wsdl MyServiceSchema.xsd /r:C:\full_path_to_system_dll\System.dll /ct:System.Collections.Generic.List`1

Herhangi bir koleksiyonu içeri aktarırken, başvurulan koleksiyon türlerinin listesi taranır ve en iyi eşleşen koleksiyon, veri üyesi türü (özelleştirilmemiş koleksiyonlar için) veya türetilmesi gereken temel tür (özelleştirilmiş koleksiyonlar için) olarak bulunursa kullanılır. Sözlükler yalnızca sözlüklerle eşleştirilirken, listeler listelerle eşleştirilir.

Örneğin, Genel'i BindingList<T> ve Hashtable başvuruda bulunan türler listesine eklerseniz, önceki örnek için oluşturulan istemci kodu aşağıdakine benzer.

[DataContract]
public class CountryOrRegion3
{
    [DataMember]
    public BindingList<string> officialLanguages;
    [DataMember]
    public BindingList<DateTime> holidays;
    [DataMember]
    public Cities cities;
    [DataMember]
    public BindingList<object> otherInfo;
}

[CollectionDataContract(ItemName = "city", KeyName = "cityName", ValueName = "population")]
public class Cities3 : Hashtable { }
<DataContract()>
Public Class CountryOrRegion3

    <DataMember()>
    Public officialLanguages As BindingList(Of String)

    <DataMember()>
    Public holidays As BindingList(Of DateTime)

    <DataMember()>
    Public cities As Cities

    <DataMember()>
    Public otherInfo As BindingList(Of Object)

End Class

<CollectionDataContract(ItemName:="city",
                        KeyName:="cityName",
                        ValueName:="population")>
Public Class Cities3
    Inherits Hashtable
End Class

Başvurulan koleksiyon türlerinizin bir parçası olarak koleksiyon arabirimi türlerini belirtebilirsiniz, ancak geçersiz koleksiyon türleri belirtemezsiniz (yöntem veya ortak oluşturucu olmayan Add türler gibi).

Kapalı genel, en iyi eşleşme olarak kabul edilir. (Genel olmayan türler, 'nin kapalı genel türlerine Objecteşdeğer olarak kabul edilir). Örneğin, Genel List<T>DateTimeBindingList<T> (açık genel) türleri ve ArrayList başvuruda bulunan koleksiyon türleriyse, aşağıdakiler oluşturulur.

[DataContract]
public class CountryOrRegion4
{
    [DataMember]
    public string[] officialLanguages;
    [DataMember]
    public DateTime[] holidays;
    [DataMember]
    public Cities cities;
    [DataMember]
    public object[] otherInfo;
}

[CollectionDataContract(ItemName = "city", KeyName = "cityName", ValueName = "population")]
public class Cities4 : Dictionary<string, int> { }
<DataContract()>
Public Class CountryOrRegion4

    <DataMember()>
    Public officialLanguages() As String

    <DataMember()>
    Public holidays() As DateTime

    <DataMember()>
    Public cities As Cities

    <DataMember()>
    Public otherInfo() As Object

End Class

<CollectionDataContract(ItemName:="city",
                        KeyName:="cityName",
                        ValueName:="population")>
Public Class Cities4
    Inherits Dictionary(Of String, Integer)
End Class

Liste koleksiyonları için yalnızca aşağıdaki tabloda yer alan durumlar desteklenir.

Başvurulan tür Başvuruldu türü tarafından uygulanan arabirim Örnek Tür olarak ele alındı:
Genel olmayan veya kapalı genel (herhangi bir sayıda parametre) Genel olmayan MyType : IList

veya

MyType<T> : IList

where T= int
kapalı genel Object (örneğin, IList<object>)
Genel olmayan veya kapalı genel (koleksiyon türüyle eşleşmesi gerekmeyen herhangi bir sayıda parametre) Kapalı genel MyType : IList<string>

veya

MyType<T> : IList<string> where T=int
Kapalı genel (örneğin, IList<string>)
Herhangi bir sayıda parametreyle kapalı genel Türün parametrelerinden herhangi birini kullanarak genel'i açın MyType<T,U,V> : IList<U>

where T=int, U=string, V=bool
Kapalı genel (örneğin, IList<string>)
Tek bir parametreyle genel'i açma Türün parametresini kullanarak genel'i açın MyType<T> : IList<T>, T açık Genel açık (örneğin, IList<T>)

Bir tür birden fazla liste koleksiyonu arabirimi uygularsa, aşağıdaki kısıtlamalar geçerlidir:

  • Tür, Genel IEnumerable<T> (veya türetilmiş arabirimlerini) farklı türler için birden çok kez uygularsa, tür geçerli başvuruda bulunan koleksiyon türü olarak kabul edilmez ve yoksayılır. Bazı uygulamalar geçersiz olsa veya açık genel değerler kullansa bile bu durum geçerlidir. Örneğin, T'nin int Genel ve Genel'ini IEnumerable<T>IEnumerable<T> uygulayan bir tür, türün kabul eden bir yöntemi veya T türünde bir parametreyi kabul eden bir yöntemi ya da her ikisini birden kabul eden int bir AddAdd yöntemi olmasına bakılmaksızın, hiçbir zaman başvuruda bulun olunan int koleksiyonu veya başka bir türü olarak kullanılmaz.

  • Türü de genel bir koleksiyon arabirimi uygularsa, genel koleksiyon arabirimi IListtürü kapalı bir genel olmadığı sürece türü hiçbir zaman başvurulan koleksiyon türü Objectolarak kullanılmaz.

Sözlük koleksiyonları için yalnızca aşağıdaki tabloda yer alan durumlar desteklenir.

Başvurulan tür Başvuruldu türü tarafından uygulanan arabirim Örnek Tür olarak ele alındı
Genel olmayan veya kapalı genel (herhangi bir sayıda parametre) IDictionary MyType : IDictionary

veya

MyType<T> : IDictionary where T=int
Kapalı genel IDictionary<object,object>
Kapalı genel (herhangi bir sayıda parametre) IDictionary<TKey,TValue>Kapalı MyType<T> : IDictionary<string, bool> where T=int Kapalı genel (örneğin, IDictionary<string,bool>)
Kapalı genel (herhangi bir sayıda parametre) Genel IDictionary<TKey,TValue>, anahtar veya değerlerden biri kapalı, diğeri açık ve türün parametrelerinden birini kullanıyor MyType<T,U,V> : IDictionary<string,V> where T=int, U=float,V=bool

veya

MyType<Z> : IDictionary<Z,bool> where Z=string
Kapalı genel (Örneğin, IDictionary<string,bool>)
Kapalı genel (herhangi bir sayıda parametre) Genel IDictionary<TKey,TValue>, hem anahtar hem de değer açıktır ve her biri türün parametrelerinden birini kullanır MyType<T,U,V> : IDictionary<V,U> where T=int, U=bool, V=string Kapalı genel (örneğin, IDictionary<string,bool>)
Genel açma (iki parametre) Genel IDictionary<TKey,TValue>, open, türün genel parametrelerinin her ikisini de göründükleri sırayla kullanır MyType<K,V> : IDictionary<K,V>, K ve V her ikisi de açık Genel açık (örneğin, IDictionary<K,V>)

Tür hem hem de IDictionary Genel IDictionary<TKey,TValue>uygularsa, yalnızca Genel IDictionary<TKey,TValue> kabul edilir.

Kısmi genel türlere başvuruda bulunmak desteklenmez.

Çoğaltmalara izin verilmez, örneğin, hem Genel List<T> hem Integer de Genel Koleksiyonu'nu IntegerReferencedCollectionTypesöğesine ekleyemezsiniz, çünkü bu, şemada bir tamsayı listesi bulunduğunda hangisinin kullanılacağını belirlemeyi imkansız hale getirir. Yinelemeler yalnızca şemada yinelenenler sorununu ortaya çıkaran bir tür varsa algılanır. Örneğin, içeri aktarılan şema tamsayı listeleri içermiyorsa, içinde hem Genel List<T> hem Integer de Genel Koleksiyonu'nun IntegerReferencedCollectionTypesolmasına izin verilir, ancak hiçbir etkisi yoktur.

Gelişmiş Koleksiyon Kuralları

Koleksiyonları Seri Hale Getirme

Serileştirme için koleksiyon kurallarının listesi aşağıdadır:

  • Koleksiyon türlerini birleştirmeye (koleksiyon koleksiyonları içeren) izin verilir. Pürüzlü diziler koleksiyon koleksiyonu olarak değerlendirilir. Çok boyutlu diziler desteklenmez.

  • Bayt dizileri ve dizileri XmlNode , koleksiyonlar değil, ilkel olarak ele alınan özel dizi türleridir. Bayt dizisini seri hale getirme işlemi, her bayt için ayrı bir öğe yerine Base64 ile kodlanmış veri öbeği içeren tek bir XML öğesiyle sonuçlanır. Bir dizisinin nasıl işlendiğinden XmlNode daha fazla bilgi için bkz . Veri Sözleşmelerinde XML ve ADO.NET Türleri. Elbette, bu özel türler koleksiyonlara katılabilir: bayt dizisi dizisi, her biri Base64 ile kodlanmış veri öbeği içeren birden çok XML öğesiyle sonuçlanır.

  • DataContractAttribute Öznitelik bir koleksiyon türüne uygulanırsa, tür koleksiyon olarak değil normal bir veri sözleşmesi türü olarak değerlendirilir.

  • Bir koleksiyon türü arabirimini uygularsa IXmlSerializable , türüne göre myType:IList<string>, IXmlSerializableaşağıdaki kurallar uygulanır:

    • Bildirilen tür ise IList<string>, tür liste olarak serileştirilir.

    • Bildirilen tür ise myType, olarak IXmlSerializableserileştirilir.

    • Bildirilen tür ise IXmlSerializable, olarak serileştirilir IXmlSerializable, ancak yalnızca bilinen türler listesine eklerseniz myType .

  • Koleksiyonlar, aşağıdaki tabloda gösterilen yöntemler kullanılarak seri hale getirilir ve seri durumdan çıkarılır.

Koleksiyon türü uygular Serileştirmede çağrılan yöntemler Seri durumdan çıkarmada çağrılan yöntemler
Genel IDictionary<TKey,TValue> get_Keys, get_Values Genel Ekle
IDictionary get_Keys, get_Values Add
Genel IList<T> Genel IList<T> dizin oluşturucu Genel Ekle
Genel ICollection<T> Numaralayıcı Genel Ekle
IList IList Dizinleyici Add
Genel IEnumerable<T> GetEnumerator Adlı Add statik olmayan bir yöntem, uygun türde bir parametre alır (genel parametrenin türü veya temel türlerinden biri). Seri hale getirme ve seri durumdan çıkarma sırasında bir koleksiyon türünü koleksiyon olarak ele almak için böyle bir yöntem mevcut olmalıdır.
IEnumerable (ve bu nedenle ICollection, ondan türetilir) GetEnumerator türünde Objectbir parametre alan adlı Add statik olmayan bir yöntem. Seri hale getirme ve seri durumdan çıkarma sırasında bir koleksiyon türünü koleksiyon olarak ele almak için böyle bir yöntem mevcut olmalıdır.

Yukarıdaki tabloda koleksiyon arabirimleri azalan öncelik sırasına göre listeleniyor. Örneğin, bir tür hem hem de IList Genel IEnumerable<T>uygularsa koleksiyonun kurallara göre seri hale getirildiği ve seri durumdan IList çıkarıldığı anlamına gelir:

  • Seri durumdan çıkarma sırasında, seri hale getirme ve seri durumdan çıkarma sırasında bir koleksiyon türünü koleksiyon olarak ele alması için seri hale getiricinin mevcut olması gereken parametresiz oluşturucu çağrılarak önce türün bir örneği oluşturularak tüm koleksiyonlar seri durumdan çıkarılır.

  • Aynı genel koleksiyon arabirimi birden çok kez uygulanıyorsa (örneğin, bir tür hem Genel ICollection<T>Integer hem de Genel ICollection<T>Stringolarak uygulanıyorsa) ve daha yüksek öncelikli arabirim bulunamazsa, koleksiyon geçerli bir koleksiyon olarak kabul edilmez.

  • Koleksiyon türlerinin SerializableAttribute bunlara uygulanan özniteliği olabilir ve arabirimini ISerializable uygulayabilir. Bunların ikisi de yoksayılır. Ancak, tür koleksiyon türü gereksinimlerini tam olarak karşılamıyorsa (örneğin, Add yöntem eksikse), tür koleksiyon türü olarak kabul edilmez ve bu nedenle türün SerializableAttributeISerializable serileştirilip serileştirilemeyeceğini belirlemek için öznitelik ve arabirim kullanılır.

  • Özniteliğini CollectionDataContractAttribute özelleştirmek için bir koleksiyona uygulamak, önceki geri dönüş mekanizmasını kaldırır SerializableAttribute . Bunun yerine, özelleştirilmiş bir koleksiyon koleksiyon türü gereksinimlerini karşılamıyorsa, bir InvalidDataContractException özel durum oluşturulur. Özel durum dizesi genellikle belirli bir türün neden geçerli bir koleksiyon olarak kabul edilmediğini açıklayan bilgiler içerir (yöntem yok Add , parametresiz oluşturucu yok vb.), bu nedenle hata ayıklama amacıyla özniteliğini CollectionDataContractAttribute uygulamak genellikle yararlıdır.

Koleksiyon Adlandırma

Koleksiyon adlandırma kurallarının listesi aşağıdadır:

  • Tüm sözlük koleksiyonu veri sözleşmeleri ve ilkel türler içeren liste koleksiyonu veri sözleşmeleri için varsayılan ad alanı, Ad Alanı kullanılarak geçersiz kılınmadığı sürece.http://schemas.microsoft.com/2003/10/Serialization/Arrays Yerleşik XSD türlerinin yanı sıra char, Timespanve Guid türleriyle eşlenen türler, bu amaçla ilkel olarak kabul edilir.

  • Ad Alanı kullanılarak geçersiz kılınmadığı sürece, ilkel olmayan türler içeren koleksiyon türleri için varsayılan ad alanı, koleksiyonda yer alan türün veri sözleşmesi ad alanıyla aynıdır.

  • Ad kullanılarak geçersiz kılınmadığı sürece, liste koleksiyonu veri sözleşmelerinin varsayılan adı, koleksiyonda yer alan türün veri sözleşmesi adıyla birleştirilen "ArrayOf" dizesidir. Örneğin, Genel Tamsayı listesi için veri sözleşmesi adı "ArrayOfint" şeklindedir. Veri sözleşmesi adının Object "anyType" olduğunu, dolayısıyla genel olmayan listelerin ArrayList veri sözleşmesi adının "ArrayOfanyType" olduğunu unutmayın.

kullanılarak Namegeçersiz kılınmadığı sürece sözlük koleksiyonu veri sözleşmeleri için varsayılan ad, anahtar türünün veri sözleşmesi adı ve ardından değer türünün veri sözleşmesi adıyla birleştirilen "ArrayOfKeyValueOf" dizesidir. Örneğin, Dize ve Tamsayı genel sözlüğü için veri sözleşmesi adı "ArrayOfKeyValueOfstringint" şeklindedir. Ayrıca, anahtar veya değer türleri ilkel türler değilse, adın sonuna anahtarın ve değer türlerinin veri sözleşmesi ad alanlarının ad alanı karması eklenir. Ad alanı karmaları hakkında daha fazla bilgi için bkz . Veri Sözleşmesi Adları.

Her sözlük toplama veri sözleşmesi, sözlükteki bir girişi temsil eden bir yardımcı veri sözleşmesine sahiptir. "ArrayOf" ön eki dışında adı sözlük veri sözleşmesiyle aynıdır ve ad alanı sözlük veri sözleşmesiyle aynıdır. Örneğin, "ArrayOfKeyValueOfstringint" sözlük veri sözleşmesi için "KeyValueofstringint" veri sözleşmesi sözlükteki bir girişi temsil eder. Bu veri sözleşmesinin adını, sonraki bölümde açıklandığı gibi özelliğini kullanarak ItemName özelleştirebilirsiniz.

Veri Sözleşmesi Adlarında açıklandığı gibi genel tür adlandırma kuralları koleksiyon türlerine tam olarak uygulanır; diğer bir ifadeyle, genel tür parametrelerini belirtmek için Ad içindeki küme ayraçlarını kullanabilirsiniz. Ancak küme ayraçları içindeki sayılar genel parametrelere başvurur ve koleksiyonda yer alan türlere başvurmaz.

Koleksiyon Özelleştirme

özniteliğinin CollectionDataContractAttribute aşağıdaki kullanımları yasaklanmıştır ve bir InvalidDataContractException özel durumla sonuçlanır:

Çok biçimlilik Kuralları

Daha önce de belirtildiği gibi, özniteliğini kullanarak koleksiyonları CollectionDataContractAttribute özelleştirmek koleksiyonların değiştirilebilirliğini etkileyebilir. İki özelleştirilmiş koleksiyon türü yalnızca adları, ad alanları, öğe adları, anahtar ve değer adları (sözlük koleksiyonlarıysa) eşleşiyorsa eşdeğer olarak kabul edilebilir.

Özelleştirmeler nedeniyle, bir toplama veri sözleşmesini yanlışlıkla başka bir toplama veri sözleşmesinin beklendiği yerde kullanmak mümkündür. Bundan kaçınılmalıdır. Aşağıdaki türlere bakın.

[DataContract]
public class Student
{
    [DataMember]
    public string name;
    [DataMember]
    public IList<int> testMarks;
}
public class Marks1 : List<int> {}
[CollectionDataContract(ItemName="mark")]
public class Marks2 : List<int> {}
<DataContract()>
Public Class Student

    <DataMember()>
    Public name As String

    <DataMember()>
    Public testMarks As IList(Of Integer)

End Class

Public Class Marks1
    Inherits List(Of Integer)
End Class

<CollectionDataContract(ItemName:="mark")>
Public Class Marks2
    Inherits List(Of Integer)
End Class

Bu durumda, örneğine Marks1 atanabilir testMarks. Ancak, Marks2 veri sözleşmesi veri sözleşmesiyle IList<int> eşdeğer olarak kabul edilmediğinden kullanılmamalıdır. Veri sözleşmesi adı "ArrayOfint" değil "Marks2" ve yinelenen öğe adı "int>" değil "<<mark>" olur.

Aşağıdaki tabloda yer alan kurallar, koleksiyonların çok biçimli ataması için geçerlidir.

Bildirilen tür Özelleştirilmemiş koleksiyon atama Özelleştirilmiş koleksiyon atama
Object Sözleşme adı seri hale getirilir. Sözleşme adı seri hale getirilir.

Özelleştirme kullanılır.
Koleksiyon arabirimi Sözleşme adı serileştirilmemiş. Sözleşme adı serileştirilmemiş.

Özelleştirme kullanılmaz.*
Özelleştirilmemiş koleksiyon Sözleşme adı serileştirilmemiş. Sözleşme adı seri hale getirilir.

Özelleştirme kullanılır.**
Özelleştirilmiş koleksiyon Sözleşme adı seri hale getirilir. Özelleştirme kullanılmaz.** Sözleşme adı seri hale getirilir.

Atanan türün özelleştirmesi kullanılır.**

*Sınıfıyla NetDataContractSerializer bu durumda özelleştirme kullanılır. sınıfı NetDataContractSerializer da bu durumda gerçek tür adını serileştirir, bu nedenle seri durumdan çıkarma beklendiği gibi çalışır.

**Bu durumlar şema geçersiz örneklerle sonuçlanır ve bu nedenle kaçınılmalıdır.

Sözleşme adının seri hale getirildiği durumlarda, atanan koleksiyon türü bilinen türler listesinde olmalıdır. Tam tersi de geçerlidir: Adın serileştirilmediği durumlarda, türü bilinen türler listesine eklemek gerekli değildir.

Türetilmiş bir tür dizisi, temel tür dizisine atanabilir. Bu durumda, türetilen türün sözleşme adı, yinelenen her öğe için serileştirilir. Örneğin, bir tür Book türünden LibraryItemtüretilirse, dizisini Book dizisine LibraryItematayabilirsiniz. Bu, diğer koleksiyon türleri için geçerli değildir. Örneğin, bir Generic List of Book öğesine Generic List of LibraryItematayamazsınız. Ancak örnekleri içeren Book bir Generic List of LibraryItem atayabilirsiniz. Hem dizide hem de dizi dışı durumda, Book bilinen türler listesinde olmalıdır.

Koleksiyonlar ve Nesne Başvurusu Koruması

Seri hale getirici, nesne başvurularını koruduğu bir modda çalıştığında, nesne başvurusu koruması koleksiyonlar için de geçerlidir. Özellikle, nesne kimliği hem koleksiyonların tamamı hem de koleksiyonlarda yer alan tek tek öğeler için korunur. Sözlükler için nesne kimliği hem anahtar/değer çifti nesneleri hem de tek tek anahtar ve değer nesneleri için korunur.

Ayrıca bkz.