2013-01-23 19 views
6

Burada küçük bir desen yönüne ihtiyacım var. Yeni C#.İki üçüncü taraf sınıfı için ortak arabirim denetlemiyorum. Dış Polimorfizm?

ben bir web hizmeti sarar bir üçüncü şahıs dev kiti ile çalışıyorum. Göreceli olarak benzer olsa da, devkitte iki farklı isim alanında yer alan ve ortak bir temel sınıf bulunmayan iki özel sınıf vardır. Her ikisi için de ortak bir arayüze karşı program yapmak isterim. Ayrıcalıklı bir şekilde sargıyı saran bir uygulamayı bir araya getirdim ama inişli tipteki dökümden dolayı en etkili yöntem olmadığını düşünüyorum.

ben vb adaptörleri, arabirimler, uzatma yöntemleri makalelere kazıyoruz .. ama büyük takdir ediyorum tek yönde bir itme alabilir bu yüzden zamanında düşük koşuyorum.

using ThirdParty.TypeA.Employee; 
using ThirdParty.TypeB.Employee; 

public class Employee 
{ 
    private object genericEmployee; 

    private EmployeeType empType; 

    public enum EmployeeType 
    { 
      TypeA = 0; 
      TypeB = 1; 
    } 

    public Employee(Object employee, EmployeeType type) 
    { 
     genericEmployee = employee; 
     empType = type; 
    } 

    public String Name 
    { 
     if (empType == EmployeeType.TypeA) 
      return (ThirdParty.TypeA.Employee)genericEmployee.Name; 
     else 
      return (ThirdParty.TypeB.Employee)genericEmployee.Name; 
    } 

    public String Age 
    { 
     if (empType == EmployeeType.TypeA) 
      return (ThirdParty.TypeA.Employee)genericEmployee.Age; 
     else 
      return (ThirdParty.TypeB.Employee)genericEmployee.Age; 
    } 
} 

Rev 2:

class EmployeeTypeAAdapter : TypeA, IEmployeeAdapter 
{ 
    TypeA _employee; 
    public EmployeeTypeAAdapter(TypeA employee) 
    { 
     _employee = employee 
    } 

    public String Name 
    { 
     get { return _employee.Name; } 
     set { _employee.Name = value; } 
    } 

     public String Balance 
     { 
     get 
     { 
      if (_employee.Balance != null) 
      { 
       decimal c = _employee.Balance.Amount; 
       return String.Format("{0:C}", c); 
      } 
      else 
      { 
       return ""; 
      } 
      } 
     } 

     //... 
} 

class EmployeeTypeBAdapter : TypeB, IEmployeeAdapter 
{ 
    TypeB _employee; 
    public EmployeeTypeAAdapter(TypeB employee) 
    { 
     _employee = employee 
    } 

    public String Name 
    { 
     get { return _employee.Name; } 
     set { _employee.Name = value; } 
    } 

     public String Balance 
     { 
     get 
     { 
      if (_employee.Balance != null) 
      { 
       decimal c = _employee.Balance.Amount; 
       return String.Format("{0:C}", c); 
      } 
      else 
      { 
       return ""; 
      } 
      } 
     } 

    //.... 
} 
+0

Are Genel bir yoldan gidebilirsin. – abatishchev

+0

TypeA ve TypeB türleri nedir, sınıflar nasıl ilan edilir? Sadece eşit özellikler ve temel sınıf yok mu? Yani onları sadece 'object' ile genelleştirebilirsiniz? – abatishchev

+0

Üçüncü parti kitaplığında taban sınıfı yok. Enum, bir mülke her eriştiğimde nesne türünü (TypeA veya TypeB) belirlemek için TypeOf veya IS kullanmak zorunda kalmamak için yarattığım bir kolaylık özelliği idi. – RyanMac

cevap

8

bu yaklaşımı deneyin: Eğer tercih olarak

public interface IEmployeeAdapter 
{ 
    string Age { get; set; } 
    string Name { get; set; } 
} 

class EmployeeTypeAAdapter : TypeA, IEmployeeAdapter 
{ 
    public EmployeeTypeAAdapter(TypeA employee) { } 
} 

class EmployeeTypeBAdapter : TypeB, IEmployeeAdapter 
{ 
    public EmployeeTypeBAdapter(TypeB employee) { } 
} 

public static class EmployeeAdapterFactory 
{ 
    public static IEmployeeAdapter CreateAdapter(object employee, EmployeeType type) 
    { 
     switch (type) 
     { 
      case EmployeeType.TypeA: return new EmployeeTypeAAdapter((TypeA)employee); 
      case EmployeeType.TypeB: return new EmployeeTypeBAdapter((TypeB)employee); 
     } 
    } 

    // or without enum 

    public static IEmployeeAdapter CreateAdapter(object employee) 
    { 
     if (employee is TypeA) return new EmployeeTypeAAdapter((TypeA)employee); 
     if (employee is TypeB) return new EmployeeTypeABdapter((TypeB)employee); 
    } 

    // or better introduce sort of type map 
} 

başka uygun ad EmployeeProxy vardır. Eğer yapmaya çalıştığını ne

+0

Daha sonra, yukarıda açıklanan adaptörlerde özellikleri mi döndürürdüm? İki nesnenin (TypeA ve TypeB)% 99 özdeş olduğunu göz önünde bulundurarak (farklı bir ada sahip 30 özellik/yöntemden biri veya ikisi olabilir) ve yalnızca türden bir farklılık (bir tanesi ThirdPartyAdaptor.TypeA.Employee) ve diğeri ise ThirdPartyAdaptor.TypeB.Employee) bu neredeyse görünen iki sınıf oluşturur. Yukarıdaki Rev 2'ye bakınız. – RyanMac

+0

@RyanMac: Peki zorluklar nedir? Üzgünüm seni takip etme. Paylaşılan tüm özellikleri arayüze koyarsanız, otomatik olarak uygulanır. Bir özellik adı altta yatan türde ve arayüzde farklıysa, uygun şekilde uygulamak/eşleştirmek için "yardım" edebilirsiniz. – abatishchev

+0

@RyanMac: Kaçırdığım bazı OO kavramı varsa Ayrıca paylaşılan özellikleri ve diğer yardımcı yöntemler – abatishchev

2

Duck typing olarak bilinir. Bunu adaptör sınıfları ve paylaşılan bir arayüz kullanarak yapabilirsiniz, ancak bu adaptörleri manuel olarak oluşturmak çok sayıda tekrarlı tutkal kodu gerektirir. Tutkal kodunu yazmanın bir yolu, adaptör tipini dinamik olarak oluşturmaktır. Bunu, IL Emit (kendinizle daha önce hiç oynama şansınız olmasa da değerli bir alıştırma yaparak yapabilirsiniz), ancak bunu düşünmeniz gereken birkaç sınır durumu olabilir. Ancak, başlamak için this project adresini kontrol edebilirsiniz. C# 'dinamik' türü de kullanılabilir (ve sahne arkasında aynı kod nesnesinin bir kısmını yapmaktan vazgeçer), ancak bir arabirim gibi dinamik olmayan bir kodun etrafından geçebileceğiniz bir referans vermez. yazın. TypeA ve TypeB kamu ve tanınmış, bence gerçekten enum uygulamaya koyması gerekmektedir yapabilecek?

İlgili konular