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 Object
genel 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 veNamespace
ö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 Object
tanı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 Object
eş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 edenint
birAdd
Add
yöntemi olmasına bakılmaksızın, hiçbir zaman başvuruda bulun olunanint
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 Integer
ReferencedCollectionTypesöğ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 Integer
ReferencedCollectionTypesolması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>, IXmlSerializable
aşağıdaki kurallar uygulanır:Bildirilen tür ise
IList<string>
, tür liste olarak serileştirilir.Bildirilen tür ise
myType
, olarakIXmlSerializable
serileştirilir.Bildirilen tür ise
IXmlSerializable
, olarak serileştirilirIXmlSerializable
, ancak yalnızca bilinen türler listesine eklersenizmyType
.
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 Object bir 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ırachar
,Timespan
veGuid
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 Name
geç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:
özniteliğinin DataContractAttribute uygulandığı bir türe CollectionDataContractAttribute veya türetilmiş türlerinden birine uygulanması.
özniteliğini CollectionDataContractAttribute arabirimini uygulayan bir türe IXmlSerializable uygulama.
Özniteliği koleksiyon CollectionDataContractAttribute olmayan bir türe uygulama.
Sözlük olmayan bir türe uygulanan bir CollectionDataContractAttribute özniteliği ayarlamaya KeyName veya ValueName ayarlamaya çalışılıyor.
Ç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 LibraryItem
türetilirse, dizisini Book
dizisine LibraryItem
atayabilirsiniz. Bu, diğer koleksiyon türleri için geçerli değildir. Örneğin, bir Generic List of Book
öğesine Generic List of LibraryItem
atayamazsı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.