SORU
15 EYLÜL 2008, PAZARTESİ


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
17 AĞUSTOS 2009, PAZARTESİ


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);
    }
}
  1. Türü bir parametre olarak yapı kullanımını etkinleştir
    • new() class gibi başka hiçbir kısıtlama kullanılır.
  2. 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öylece IEquatable)

Ç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

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • discokatze

    discokatze

    23 EYLÜL 2009
  • metallmanutza13

    metallmanutz

    13 NİSAN 2007
  • RayperEnglishKnight

    RayperEnglis

    24 Kasım 2008