Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
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, Hashtable ve genel sözlük gibi türler tarafından temsil edilir. Örneğin, bir ilişkilendirme koleksiyonu bir şehri ("anahtar") nüfusuyla ("değer") eşleştirir. 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, sırasıyla IDictionary veya Genel IDictionary<TKey,TValue> arabirimlerini uygulayan türler, sözlük koleksiyonlarıdır; diğer türler 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 Arabirim Türlerini ve Read-Only 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, ArrayList ve List<T> için veri sözleşmeleri ile Object Generic veri sözleşmeleri aynıdır.)
Koleksiyon Arayüzü Türlerini ve Read-Only Koleksiyonlarını 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, Generic ReadOnlyCollection<T> türünde bir veri üyesini doğrudan bildiremeseniz bile, Customer2'deki adresleri Generic ReadOnlyCollection<T> türünde bir Adres örneğine ayarlayabilirsiniz.
Seri durumdan çıkarma sırasında, bildirilen tür bir arabirim olduğunda, serileştirme motoru 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ürleri 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:
Adı özelleştirmek için CollectionDataContractAttribute özniteliği kullanılır, DataContractAttribute özniteliği yerine. Özniteliğin CollectionDataContractAttribute,
NameveNamespaceözellikleri de vardır.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 biri kök düzeyinde seri hale getirildiğinde, aşağıdaki koda benzer XML oluşur.
<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.
NameveNamespaceözelliklerini kullanarak adlandırmayı daha fazla özelleştirebilirsiniz. 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, her yinelenen girdi, koleksiyonda bulunan türün veri sözleşmesi adına uygun bir şekilde adlandırılmış 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 KeyName ve ValueName özelliklerini kullanarak 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 bunu ArrayList örneğini göndermek için kullanırsanız, ArrayList'yi bilinen türlere eklemeniz gerekmez.
Koleksiyon olmayan türler yerine çok biçimli koleksiyonlar kullandığınızda, bunların bilinen türlere eklenmesi gerekir. Örneğin, türü Object olan bir veri üyesi bildirir ve bunu ArrayList örneğini göndermek için kullanırsanız, ArrayList'yi bilinen türlere ekleyin.
Bu, eşdeğer koleksiyonları çok biçimli olarak seri hale getirmenize izin vermez. Örneğin, önceki örnekte ArrayList'yi bilinen türler listesine eklediğinizde, sınıfın Array of Object eşdeğer bir veri sözleşmesi olmasına rağmen onu atamanıza 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 hem ArrayList hem de Array of Object bilinen türleri aynı kapsamda 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, Type1 ve Type2 örneklerini gerçekten 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
Serileştirme işlemi sırasında, bildirilen tür bir koleksiyon türüyse, gerçekten iletilen türden bağımsız olarak bu bildirilen türün örneği oluşturulur. Bildirilen tür bir koleksiyon arabirimiyse, seri durumdan çıkarıcı bilinen türleri dikkate almadan örneklenmek üzere bir tür seçer.
Ayrıca seri durumdan çıkarmada, bildirilen tür bir koleksiyon türü değilse ancak bir 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 motoru yeniden örneklenecek bir tür seçer.
Koleksiyonlar 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.
Özelleştirilmemiş koleksiyon türleri, SerializableAttribute özniteliğiyle işaretlendiklerinde yine de NetDataContractSerializer özniteliği veya SerializableAttribute arabirim kurallarına göre ISerializable sınıfı tarafından serileştirilebilir.
Ö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 üyesi içeren bir Genel List<T> 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 atıfta bulunulan 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.
Uyarı
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şvurulan 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 : IListveya MyType<T> : IListwhere T= int |
kapalı jenerik Object (örneğin, IList<object>) |
| Genel olmayan veya kapalı genel (koleksiyon türüyle eşleşmesi gerekmeyen herhangi bir sayıda parametre) | Kapalı jenerik | MyType : IList<string>veya MyType<T> : IList<string> where T=int |
Kapalı genel (örneğin, IList<string>) |
| Herhangi bir sayıda parametreyle kapalı genellik | 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 |
Açık genel (ö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ş arayüzlerini) farklı türler için birden çok kez uygularsa, tür geçerli bir referans 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, IEnumerable<T> ve T'nin
intGenel'ini ve IEnumerable<T> Uygulayan bir tür, türünintveya başka bir tür üzerinde başvurulan koleksiyon olarak hiçbir zaman kullanılmaz. Bu,Addyöntemiintkabul etmiş veyaAddyönteminde T türünde bir parametre kabul etmiş veya her ikisine sahip olsa bile böyledir.Tür, IList ile birlikte genel bir koleksiyon arabirimini de uyguluyorsa, genel koleksiyon arabirimi Object türünde kapalı bir genellik olmadığı sürece tür asla başvurulan bir koleksiyon türü olarak kullanılmaz.
Sözlük koleksiyonları için yalnızca aşağıdaki tabloda yer alan durumlar desteklenir.
| Başvurulan tür | Başvurulan 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 : IDictionaryveya 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=boolveya 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>) |
| Açık jenerik (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 |
Açık genel (örneğin, IDictionary<K,V>) |
Tür, hem IDictionary hem de Genel IDictionary<TKey,TValue> uygularsa, yalnızca Genel IDictionary<TKey,TValue> dikkate alınır.
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, hem List<T>'ın Integer'i hem de Integer'nin Genel Koleksiyonu ReferencedCollectionTypes içinde bulunabilir, ancak bunlardan hiçbirinin 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 (koleksiyonlardan oluşan koleksiyonlar) izin verilir. Düzensiz diziler, koleksiyonların 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 dizi XmlNode'nin nasıl ele alındığı hakkında 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
myTypeise,IXmlSerializableolarak serileştirilir.Bildirilen tür
IXmlSerializableise,IXmlSerializableolarak serileştirilir, ancak yalnızcamyTypebilinen türler listesine eklerseniz.
Koleksiyonlar, aşağıdaki tabloda gösterilen yöntemler kullanılarak seri hale getirilir ve seri durumdan çıkarılır.
| Koleksiyon türü uygulamalara sahiptir | Serileştirme sırasında çağrılan yöntem(ler) | Seri durumdan çıkarmada (deserialization) ç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). Bir koleksiyon türünü seri hale getirme ve seri durumdan çıkarma sırasında koleksiyon olarak ele almak için böyle bir yöntem mevcut olmalıdır. |
| IEnumerable (ve bu nedenle ICollection, ondan türetilir) | GetEnumerator |
Statik olmayan ve Add türünde bir parametre alan Object adlı bir yöntem. Bir koleksiyon türünü seri hale getirme ve seri durumdan çıkarma sırasında 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 IList hem de Genel IEnumerable<T> uygularsa, koleksiyon IList kurallarına göre serileştirilir ve seri durumdan çıkarılır.
Seri durumdan çıkarma işlemi sırasında, tüm koleksiyonlar önce parametresiz oluşturucu çağrılarak türün bir örneği oluşturularak seri durumdan çıkarılır. Bu parametresiz oluşturucu, serileştirme ve seri durumdan çıkarma sırasında seri hale getiricinin bir koleksiyon türünü koleksiyon olarak ele alabilmesi için mevcut olmalıdır.
Aynı genel koleksiyon arabirimi birden çok kez uygulanıyorsa (örneğin, bir tür hem Genel ICollection<T>
Integerhem de Genel ICollection<T>Stringolarak uygulanıyorsa) ve daha yüksek öncelikli arabirim bulunamazsa, koleksiyon geçerli bir koleksiyon olarak kabul edilmez.Koleksiyon tipleri SerializableAttribute özelliğini taşıyabilir ve ISerializable arabirimini uygulayabilir. Bunların ikisi de yoksayılır. Ancak, tür koleksiyon türü gereksinimlerini tam olarak karşılamıyorsa (örneğin,
Addyö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.Bir koleksiyonu özelleştirmek için CollectionDataContractAttribute özniteliğini uygulamak, önceden SerializableAttribute geri dönüş mekanizmasını kaldırır. 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ı, Namespace kullanılarak geçersiz kılınmadığı sürece
http://schemas.microsoft.com/2003/10/Serialization/Arrays’dir. Yerleşik XSD türlerinin yanı sırachar,TimespanveGuidtü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 temel türler değilse, veri sözleşmesinin anahtar ve değer türlerine ait ad alanlarından elde edilen ad alanı karması, adın sonuna 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; yani, 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, koleksiyondaki türler yerine genel parametrelere başvurur.
Koleksiyon Özelleştirme
özniteliğinin CollectionDataContractAttribute aşağıdaki kullanımları yasaklanmıştır ve bir InvalidDataContractException özel durumla sonuçlanır:
DataContractAttribute özniteliğinin daha önce CollectionDataContractAttribute özniteliği uygulanmış bir türe veya onun türetilmiş türlerinden birine uygulanması.
Bir CollectionDataContractAttribute özniteliğini IXmlSerializable arabirimini uygulayan bir türe uygulamak.
Bir koleksiyon tipi olmayan bir türe CollectionDataContractAttribute özelliğini uygulama.
Bir sözlük dışı türe uygulanan bir KeyName özniteliğine ValueName veya CollectionDataContractAttribute ayarlamaya teşebbüs ediliyor.
Ç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, bir Marks1 örneği testMarks'ye atanabilir. 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ş bir koleksiyonun atanması |
|---|---|---|
| Nesne | 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.** |
NetDataContractSerializer sınıfı kullanılarak bu durumda özelleştirme yapı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ş türden bir dizinin, temel türden bir diziye atanması mümkündür. Bu durumda, türetilen türün sözleşme adı, yinelenen her öğe için serileştirilir. Örneğin, bir Book türü LibraryItem türünden türetilirse, Book dizisini LibraryItem dizisine atayabilirsiniz. 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 Generic List of LibraryItem örnekleri içeren bir Book atayabilirsiniz. Hem dizide hem de dizi dışı durumda, Book bilinen türler listesinde olmalıdır.
Koleksiyonlar Koruması ve Nesne Referansı Korunması
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.