Yapılar arabirimleri uygulamak için güvenli mi?
Yapılar C) CLR arabirimleri uygulamak için kötü olduğu hakkında bir şey okuma hatırlıyorum# ama bunun için bir şey bulmak için görünmüyor olabilir. Kötü bir şey mi? Böylece istenmeyen sonuçları var mıdır?
public interface Foo { Bar GetBar(); }
public struct Fubar : Foo { public Bar GetBar() { return new Bar(); } }
CEVAP
Kimse açıkça bu cevap verilir beri şu: ekleyeceğiz
Uygulamabir yapı üzerinde bir arayüz hiçbir olumsuz sonuçları yoktur.
Herhangi birdeğişkenarabirim türü için kullanılan bir yapı bu yapı kutulu bir değer kullanılıyor neden olur. Eğer bu yapı değişmez (iyi bir şey) daha sonra ise bu sürece en kötü performans sorunu
- amaçlar kilitleme için edilen nesne (son derece kötü bir fikir, herhangi bir şekilde) kullanarak
- başvuru eşitlik mantığı kullanarak ve aynı yapı iki kutulu değerleri çalışmak için bekliyor.
Bunların her ikisi de aşağıdakilerden birini yapıyor olması muhtemel yerine Olası olurdu:
Jenerik
Belki de yapılar arabirimleri uygulamak için çok makul bir sebep içinde kullanılabilirjenerikbağlam ileconstraints. Bu şekilde kullanılan çok gibi: değişken
class Foo<T> : IEquatable<Foo<T>> where T : IEquatable<T>
{
private readonly T a;
public bool Equals(Foo<T> other)
{
return this.a.Equals(other.a);
}
}
- Türü bir parametre olarak yapı kullanımını etkinleştir
new()
class
gibi başka hiçbir kısıtlama kullanılır.
- Yapılar bu şekilde kullanılan boks kaçınma sağlar.
Bu daha sonra.bir şeyin içine bir kutu neden olmaz böylece arayüzü bir referans DEĞİL. Daha fazla zaman c# derleyicisi örnek yöntemleri constrained işlem kodu kullanabilirsiniz Type parametresi T örnekleri üzerinde tanımlanan Ekle çağırmaları için jenerik sınıflar ve ihtiyaçlarını derler:
ThisType türü ve thisType uygulayan yöntem daha sonra DNS olarak değiştirilmemiş geçirilen bir değerdir 'bu' thisType tarafından yöntemin uygulanması için yöntemi çağrısı Yönerge işaretçisi.
Bu boks önler ve değer türü uygulama olduğu için arayüzgerekiryöntemi uygulamak, böylece hiçbir boks ortaya çıkar. Yukarıdaki örnekte Equals()
çağırma bu konuda herhangi bir kutu ile yapılır.bir1.
Düşük sürtünme API
En yapılar bit aynı değerleri eşit olarak kabul edildiği ilkel gibi bir mantığı vardır2. Çalışma zamanı, örtülü olarak bu tür davranışları bu yavaş olabilir Equals()
ama tedarik edecek. Ayrıca bu örtülü eşitliktirdeğilIEquatable<T>
ve böylece bir uygulama olarak maruz engeller yapılar onlar açıkça kendilerini uygulamak sürece kolayca Sözlükler tuşları olarak kullanılıyor. Bu nedenle ortak pek çok ortak yapı türleri bildirin onlar uygulamak IEquatable<T>
(T
onları kendine) bu daha kolay ve daha iyi performans gösteren yanı sıra tutarlı davranışlar var olan birçok değer türleri içinde CLR BBA.
KORUYUCU tüm öğeler en azından uygulamak:
IComparable
IConvertible
IComparable<T>
IEquatable<T>
(Ve böyleceIEquatable
)
Çok da Sisteminin birçok DateTime, zaman aralığı ve Guıd gibi değer türleri bunların çoğu uyguluyor tanımlanan daha fazla IFormattable
, uygulamak. Eğer uygulama benzer 'yaygın olarak yararlı' türü gibi bir karmaşık sayı yapı veya sabit genişlik metin değerleri, daha sonra pek çok uygulama bu ortak arabirimler (doğru) yapar yapı daha yararlı ve kullanışlı.
İstisnalar
Eğer arayüzü ima ediyor açıkçasımutability(gibi ICollection
) sonra uyguluyor kötü bir fikir gibi olur yani tat ya da yapılmış bir yapı değişken (lider için bu tür hatalar tarif zaten nereye değişiklikler meydana üzerinde kutulu değeri yerine orijinal) kafa karıştırmak ve kullanıcılar tarafından görmezden etkileri ve yöntemleri gibi Add()
atma ya da özel durumlar.
Çok arayüz mutability (IFormattable
gibi) anlamına gelmez; yol olarak hizmet tutarlı bir biçimde belirli özellikler göstermek için. Genellikle bu yapı kullanıcı böyle bir davranış için herhangi bir boks havai umurumda değil.
Özet
Dikkatli yapıldığında, değişmez bir değer türleri, kullanışlı arayüzleri uygulamaya iyi bir fikirdir
Notlar:
1: derleyici hangi değişkenler üzerinde sanal bir yöntem çağrılırken bu kullanabileceğini Unutmayınbilinenbelirli bir yapı türü olarak ama sanal bir yöntemi çağırmak için gereklidir. Örneğin:
List<int> l = new List<int>();
foreach(var x in l)
;//no-op
Numaralandırıcısı Listesi tarafından döndürülen bir yapı listesi (consequences bazı ilginç) numaralandırma sırasında bir ayırma önlemek için bir iyileştirme. Ancak dosyalarda grup semantiği eğer numaralandırıcısı IDisposable
Dispose()
adı verilecek uygulayan bir kez yineleme tamamlanmış olduğunu belirtin. Belli ki bu kutulu bir çağrı ile meydana sahip numaralandırıcısı bir yapı olmanın herhangi bir faydası (aslında daha kötü olurdu) ortadan kaldıracaktır. Eğer atın arayın bir şekilde numaralandırıcısı durumu değiştirir daha kötü, o zaman bu kutulu örneği olacağını ve çok ince hataların karmaşık durumlarda tanıttı olabilir. Bu nedenle IL Meksika'ya duyulur:
IL_0001: newobj System.Collections.Generic.List..ctor IL_0006: stloc.0 IL_0007: nop IL_0008: ldloc.0 IL_0009: callvirt System.Collections.Generic.List.GetEnumerator IL_000E: stloc.2 IL_000F: br.s IL_0019 IL_0011: ldloca.s 02 IL_0013: call System.Collections.Generic.List.get_Current IL_0018: stloc.1 IL_0019: ldloca.s 02 IL_001B: call System.Collections.Generic.List.MoveNext IL_0020: stloc.3 IL_0021: ldloc.3 IL_0022: brtrue.s IL_0011 IL_0024: leave.s IL_0035 IL_0026: ldloca.s 02 IL_0028: constrained. System.Collections.Generic.List.Enumerator IL_002E: callvirt System.IDisposable.Dispose IL_0033: nop IL_0034: endfinally
Böylece IDisposable uygulanması herhangi bir performans sorunları neden olmaz ve numaralandırıcısı (üzücü) değişken yönü yöntemi aslında her şeyi İmha edilmelidir korunur!
2: çift ve yüzer NaN değerleri eşit kabul edilir. bu kuralın istisnaları vardır
Nasıl güvenli bir DİNLENME node.js API...
Güvenli karma ve PHP şifreler için tuz...
Koşullu bir sınıf uygulamak için en iy...
Java singleton deseni uygulamak için e...
Git bir şube birleştirmek için en iyi ...