2009-05-09 34 views
16

Durum güncellemeleri etrafında bir WCF hizmeti aldım:WPF neden bir nesnenin özelliklerini değil, alanların özelliklerini destekliyor?

[DataContract] 
public struct StatusInfo 
{ 
    [DataMember] public int Total; 
    [DataMember] public string Authority; 
} 
... 
public StatusInfo GetStatus() { ... } 

ViewModel'de bir özelliği şu şekilde gösteriyorum:

public class ServiceViewModel : ViewModel 
{ 
    public StatusInfo CurrentStatus 
    { 
     get{ return _currentStatus; } 
     set 
     { 
      _currentStatus = value; 
      OnPropertyChanged(() => CurrentStatus); 
     } 
    }  
} 

Ve XAML şöyle ki:

<TextBox Text="{Binding CurrentStatus.Total}" /> 

Uygulamayı çalıştırdığımda, çıktı penceresindeki Toplam özelliğinin bulunamadığını belirten hatalar görüyorum. Kontrol ettim ve çifte kontrol ettim ve doğru yazdım. Hataların, özellikle 'özellik' bulunamadığını belirttiği ortaya çıktı. Yani yapısına bir özellik ekleyerek bunu iyi çalışır. Ancak bu, WPF'nin alanlara tek yönlü bağlanmayı başaramayacağı garip görünüyor. Sözdizimsel olarak kodda onlara aynı erişirsiniz ve sadece StatusInfo yapısına özel bir görünüm modeli oluşturmak zorunda kalmanız aptalca görünür. WPF bağlama hakkında bir şey özledim mi? Bir alana bağlanabilir misiniz yoksa tek yolu bağlama mı?

cevap

21

genellikle alanlara çalışmaz Bağlama. Çoğu bağlama, kısmen (varsayılan olarak) özelliklerde çalışan ComponentModel PropertyDescriptor modeline dayanır. Bu, bildirimler, doğrulama, vb. (Hiçbiri alanlarla çalışmaz) sağlar. Ben geçebiliriz daha nedenlerden dolayı

, kamu alanları kötü bir fikir. Onlar gerçek olmalı. Aynı şekilde, değişken yapılar bir çok kötü bir düşüncedir. En önemlisi, beklenmedik veri kaybına karşı (genellikle değişken yapılarla ilişkili) korur. Bu bir sınıf olmalıdır: 0 olması gerektiği gibi davranacaktır. Eğer bir değişmez yapı olmak istiyorsan, sorun olurdu (ama veri bağlama elbette sadece tek yönlü olacaktır): Ancak

[DataContract] 
public struct StatusInfo 
{ 
    [DataMember] public int Total {get;private set;} 
    [DataMember] public string Authority {get;private set;} 

    public StatusInfo(int total, string authority) : this() { 
     Total = total; 
     Authority = authority; 
    } 
} 

, bunun yapı neden ilk soru olur ilk sırada. .NET dillerinde bir yapı yazmak için çok nadir'dur. WCF "mex" proxy katmanının, onu zaten bir sınıf olarak (derleme paylaşımı kullanmıyorsanız) bir sınıf olarak yaratacağını unutmayın. "Neden kullanım yapılar" yanıtı ("bilinmeyen (google)") cevap olarak


:

bu benim soruya cevap ise, pek çok yönden yanlıştır. İlk olarak, değişken olarak değer türleri yaygın (ilk) yığında tahsis edilir. Yığın üzerine itildiyse (örneğin bir dizide/listede), bir sınıftan fazla bir fark yoktur - küçük bir nesne başlığı artı bir referans. Yapılar her zaman küçük olmalıdır. Birden fazla alan içeren bir şey fazla büyüklükte olacak ve ya yığınınızı öldürecek ya da sadece blöf nedeniyle yavaşlamaya neden olacak. Ayrıca, yapılar değişmez olmalıdır - Eğer gerçekten ne yaptığınızı biliyor unlesss. Bir nesneyi temsil

hemen her şeyin immuatable olmalıdır.

Veritabanına isabet ediyorsanız, sınıfa göre yapı hızının, işlem dışı kalması ve büyük olasılıkla ağ üzerinden yapılması nedeniyle bir sorun olmaması gerekir.Biraz daha yavaş olsa bile, bu, onu doğru bulma noktasına kıyasla hiçbir şey ifade etmemektedir - yani nesneleri nesneler olarak ele alır. Bazı metrik olarak

üzerinde 1M nesneleri:
struct/field: 50ms 
class/property: 229ms 

aşağıdaki gibidir (özelliği vs hız farkı nesne tahsisi değil, alanı) göre. Yani yaklaşık 5x daha yavaş, ama yine de çok, çok hızlı. Bu sizin darboğaz olmayacağından, bunu erken optimize etmeyin!

using System; 
using System.Collections.Generic; 
using System.Diagnostics; 
struct MyStruct 
{ 
    public int Id; 
    public string Name; 
    public DateTime DateOfBirth; 
    public string Comment; 
} 
class MyClass 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public DateTime DateOfBirth { get; set; } 
    public string Comment { get; set; } 
} 
static class Program 
{ 
    static void Main() 
    { 
     DateTime dob = DateTime.Today; 
     const int SIZE = 1000000; 
     Stopwatch watch = Stopwatch.StartNew(); 
     List<MyStruct> s = new List<MyStruct>(SIZE); 
     for (int i = 0; i < SIZE; i++) 
     { 
      s.Add(new MyStruct { Comment = "abc", DateOfBirth = dob, 
        Id = 123, Name = "def" }); 
     } 
     watch.Stop(); 
     Console.WriteLine("struct/field: " 
        + watch.ElapsedMilliseconds + "ms"); 

     watch = Stopwatch.StartNew(); 
     List<MyClass> c = new List<MyClass>(SIZE); 
     for (int i = 0; i < SIZE; i++) 
     { 
      c.Add(new MyClass { Comment = "abc", DateOfBirth = dob, 
        Id = 123, Name = "def" }); 
     } 
     watch.Stop(); 
     Console.WriteLine("class/property: " 
        + watch.ElapsedMilliseconds + "ms"); 
     Console.ReadLine(); 
    } 
} 
+4

Bir C++ programcısı olarak, yukarıdaki yorumlarınızı çok zor buluyorum. Aynı zamanda farklı sonuçlara varmış gibi görünüyorum. Örneğin, "Yani yaklaşık 5x daha yavaş, ama yine de çok hızlı" diyorsunuz. Gördüğüm kadarıyla, "Yapıların kullanımı yaklaşık 5x daha hızlı, ama yine de çok yavaş." –

+7

@Daniel sigh, yine başlıyoruz, "C++ her şeyden daha hızlı, her zaman ve her zaman kullanılmalı" (iç çekiş). Çok çeşitli uygulamalarda, doğru bir şekilde elde edilmesi önemli bir kolaylıktan başka kayda değer bir fark yoktur. –

+0

C++ daha hızlı olduğunu söylemedim! Sonuç olarak, bazı ciddi önyargılara (veya belki de yanlış anlamalara) sahip olduğunuz belirtildi. "Çok çeşitli uygulamalarda, bir diğeri de doğru olmak için önemli ölçüde daha kolay bir fark yoktur - bu yüzden C++ 'nın daha hızlı olmasına rağmen, bu önemli değil - ancak C++' nın doğru olması kolaylaşıyor." bu önemli. Ya da sadece argümanımı desteklemek için söylediklerini yanlış yorumladım ... Gerçekten iç. –

0

onlar sadece özelliklerini desteklemek neden sadece tahmin edebilirsiniz: o .NET çerçevesinde evrensel bir kongre (probably to safeguard binary compatibility) değişken alanları ortaya çıkarmak için asla görünüyor belki de, ve bir şekilde bütün programcılar aynı izlemesi bekleniyor Kongre.

Ayrıca, alanlar ve özelliklere aynı sözdizimi ile erişilse de, veri bağlama yansımayı kullanır ve (duyduğum gibi) yansıma alanlara erişmek için özelliklere erişmek yerine farklı şekilde kullanılmalıdır.

İlgili konular