2013-10-30 151 views
1

我有一個Product類型的對象和Variant類型的對象。 VariantProduct具有相同的結構,但是是兩種不同的類型,所以我不能只用一種方法來包含兩者。是否有可能制定一種可接受這兩種類型的擴展方法?多種類型的擴展方法

+4

如果他們有相同的「結構」,然後創建一個接口定義的結構,並同時擁有你的類實現該接口。 – mbeckish

+0

產品和變體類型來自第三方API,我無權訪問其上的接口。 – sk099

+0

您可以定義自己的實現此接口的類,並在該類上提供方法以將屬性值從'Product'或'Variant'複製到其自己的屬性中。 – mbeckish

回答

6

除非ProductVariant具有公共基類或接口,否則不能這樣做。

如果他們有共同的基類或接口,那麼你可以嘗試寫它的擴展方法,例如,

public static void MyMethod(this ICommonInterface obj) {} 

否則,您將不得不創建兩個單獨的擴展方法。您可以嘗試將通用代碼提取到將從您的擴展方法調用的單獨方法中。

0

你可以採取dynamic類型的優勢:

using System.Linq; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     var myList = new object[] { 
      new Product(){Id=1}, 
      new Variant(){Id=1} 
     }; 
     Process(myList); 
    } 

    static void Process(object[] myList) 
    { 
     foreach (dynamic item in myList) 
     { 
      item.Id += 1; 
     } 
    } 
} 

class Product 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public string Foo { get; set; } 
} 
class Variant 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public string Bar { get; set; } 
} 
pub 

使用擴展方法:

public static class X 
{ 
    public static void Process(this object[] myList) 
    { 
     foreach (dynamic item in myList) 
     { 
      item.Id += 1; 
     } 
    } 
} 

和樣本用法:

myList.Process(); 

另一種選擇

...是使用對象對象映射器,如AutoMapper。對於樣品上方ProductVariant樣品類型,你將不得不與以下類型這股2類的共同成員定義成員映射:

public class MyMapper 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

成員映射如下所示:

Mapper.CreateMap<Product, MyMapper>() 
    .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Id)) 
    .ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Name)); 
Mapper.CreateMap<Variant, MyMapper>() 
    .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Id)) 
    .ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Name)); 

,你可能會得到一個工作List<MyMapper>這樣的:

var myMapperList = myList.Select(item => item.Map()).ToList(); 

Map<T>前拉法:

public static MyMapper Map<T>(this T obj) 
{ 
    return (MyMapper)Mapper.Map(obj, obj.GetType(), typeof(MyMapper)); 
} 

從這個角度進一步,你將定義爲MyMapper類型的擴展方法。

0

Steve,

從Commerce Server的角度來看這個問題的兩個可能的答案。取決於您是在討論Core Systems API還是Commerce Foundation API。我會在下面兩個地址:

選項1:商業服務器核心系統API

不幸的是,這兩類產品和變體不共享一個公共基類(除非你把System.Object的;-) 。儘管Microsoft.CommerceServer.Catalog.Product繼承自Microsoft.CommerceServer.Catalog.CatalogItem,但Variant不會繼承自CatalogItem或任何其他常見基類。變體直接從System.Object繼承。

因此,您無法編寫兩個類都可以使用的擴展方法。

類定義文檔中的所有目錄系統對象(核心系統API),可以在這裏找到http://msdn.microsoft.com/en-us/library/microsoft.commerceserver.catalog(v=cs.70).aspx

enter image description here

選項2:商會基金API 如果你指的是產品和對於從對Commerce Commerce的調用返回的對象的變體,則使用Commerce Server操作服務請求返回的所有對象作爲ICommerceEntity類型返回。

如果您使用具體的數據類型來包裝CommerceEntity,那麼您仍然可以使用.ToCommerceEntity()方法,並且您可以從ICommerceEntity編寫擴展。這種方法唯一的問題是從ICommerceEntity繼承的所有類將能夠使用擴展方法。

enter image description here

查看http://msdn.microsoft.com/en-us/library/dd451701.aspx爲了瞭解更多關於商會基金的具體數據類型。

0

您不能更改Product和Variant類,但可以對它們進行子類化並將接口應用於子類。此接口可用於擴展方法:

using System; 

public class Program 
{ 
    public static void Main() 
    { 
     var p = new MyProduct(); 
     p.Name = "test"; 
     Console.WriteLine(p.GetName()); 
    } 
} 


public class Product 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public string Foo { get; set; } 
} 
public class Variant 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public string Bar { get; set; } 
} 

public class MyProduct: Product, IType { 
} 

public class MyVariant: Variant, IType { 
} 


public static class Extensions { 
    public static string GetName(this IType type){ 
     return type.Name; 
    } 
} 

public interface IType { 
    string Name {get; set; } 
} 

參見:https://dotnetfiddle.net/u1JJmJ