2016-04-13 71 views
2

Bu konuyla ilgili bir soru olup olmadığını öğrenmek için arama yaptım.Bir hiyerarşide farklı sınıfları aynı özelliklerle ele almanın en etkili yolu nedir?

Bir xml şemada xsd.exe dosyasını çalıştırarak oluşturduğum bağlamalardan koduma gömdüğüm karmaşık bir yapıya sahibim, bu yüzden yapıyı oluşturmadım ama onunla uğraşmak zorundayım.

Hiyerarşideki sınıflar içinde çoğaltılan bazı özellikler vardır. Asıl kodu gizlilik nedenlerinden dolayı yayınlayamıyorum, ancak örneğin onlardan biri WidgetValue adında bir mülkü olan 10 sınıflı bir temel sınıfım varsa, bununla nasıl en verimli şekilde başa çıkabilirim?

Şu anda, devralma sınıflarının her birinin türünü kontrol etmem ve WidgetValue özelliğine erişmek için her birine dağıtmam gerektiğini düşünüyorum.

Buna rağmen yaklaşabileceğim daha iyi bir yolu var mı?

+0

: gibi

var classA = new ClassA { WidgetValue = "The Value" }; var classB = new ClassB { WidgetValue = "The Other Value" }; var classD = new ClassD(); GetWidgetValue(classA); // The Value GetWidgetValue(classB); // The Other Value GetWidgetValue(classD); // Object don't have property 'WidgetValue' GetWidgetValueWithReflection(classA); // The Value GetWidgetValueWithReflection(classB); // The Other Value GetWidgetValueWithReflection(classD); // Object don't have property 'WidgetValue' 

Sonra bir şey yapıyor önlemek ama somut bir örnek. Ayrıca, "verimli" detaylandırma gerektirir. Zaman verimliliği? Uzay verimliliği? Geliştirme süresi verimliliği? İfadenin Parsimonyosu? Daha fazla bilgi olmadan, tek yapabildiğimiz, aşağıdaki gibi alternatifleri önermektir: (1) Çoğaltma ile yaşamak; (2) “WidgetValue” öğesini ana gruba kaldırmak ancak isteğe bağlı yapmak; (3) 'WidgetValue' gerektiren 8 sınıf için bir ara sınıf oluşturun. Bunlardan hangisinin sizin amaçlarınız için daha "verimli" olacağını belirsizdir. – kjhughes

+0

Net olmamak için özür dilerim. Gelişim zamanı verimliliği açısından demek istiyorum. Ve daha az bir ölçüde, kodun ne kadar karmaşık hale geldiğini anladı. Çünkü bu tür şeylerin olduğu sınıflarda sayısız yer vardır, dolayısıyla ne yaparsam yapayım çok fazla şey yapmak zorundayım. Eğer 2 veya 3 yaparsam, o zaman XSD'nin yeniden piyasaya sürüldüğü her zaman bunu yapmak anlamına gelen sınıfları değiştirmek zorunda kalacağım. Ayrıca, şemaya uygun olarak XML'de çıktı vermem gerekeceği gerçeğiyle ilgili bir sorun da olabilir ve bununla uyumluluğunu kırmak istemiyorum. – TH1974

+0

İhtiyacınız olmadıkça el ile değiştirmeyin. Aksi takdirde bir dahaki sefere dersleri herhangi bir nedenle yenilemek için ihtiyacınız olacak. –

cevap

0

Daha önce de belirtildiği gibi, oluşturulan sınıfları değiştirmemelisiniz, çünkü herhangi bir nedenle bunları yeniden oluşturmanız gerekirse, bunları da agaim olarak değiştirmeniz gerekecektir.

Yani, yapardım ya:

public class MainClass 
{ 
    public string MainProp { get; set; } 
} 

public class ClassA : MainClass 
{ 
    public string SomeProp { get; set; } 

    public string WidgetValue { get; set; } 
} 

public class ClassB : MainClass 
{ 
    public string SomeOtherProp { get; set; } 

    public string WidgetValue { get; set; } 
} 

public class ClassC : MainClass 
{ 
    public string AnotherProp { get; set; } 

    public string WidgetValue { get; set; } 
} 

public class ClassD : MainClass 
{ 
    public string Different { get; set; } 
} 
:

  • kullanın dynamic veya
  • Kullanım Reflection

Ama her şeyden önce, bu benim testler için kullanılan modeldir

Ve bu şekilde'yi kullanarak WidgetValue'yi alabilirsiniz.veya Reflection:

static void GetWidgetValue(MainClass obj) 
    { 
     Type[] typesThatHaveWidgetValue = new Type[] { typeof(ClassA), typeof(ClassB), typeof(ClassC) }; 

     if (typesThatHaveWidgetValue.Contains(obj.GetType())) 
     { 
      dynamic o = obj; 
      Console.WriteLine(o.WidgetValue); 
     } 
     else 
     { 
      Console.WriteLine("Object don't have property 'WidgetValue'"); 
     } 
    } 

    static void GetWidgetValueWithReflection(MainClass obj) 
    { 
     var type = obj.GetType(); 
     var widgetValueProp = type.GetProperty("WidgetValue"); 
     if (widgetValueProp != null) 
     { 
      var widgetValue = widgetValueProp.GetValue(obj); 
      Console.WriteLine(widgetValue); 
     } 
     else 
     { 
      Console.WriteLine("Object don't have property 'WidgetValue'"); 
     } 
    } 

Ve bu test edebilirsiniz: Gizlilik basitleştirilmiş sağlayarak sizi engellemez

if (obj.GetType() == typeof(ClassA)) 
{ 
    var classA = (ClassA)obj; 
    Console.WriteLine(classA.WidgetValue); 
} 
else if (obj.GetType() == typeof(ClassB)) 
{ 
    var classB = (ClassB)obj; 
    Console.WriteLine(classB.WidgetValue); 
} ... 
+0

Yansıma yöntemi çok iyi çalıştı. Steer için teşekkürler.Onu oy verdim ancak şu anda herkese açık olarak saymak için yeterli puanım yok! – TH1974