2013-10-30 115 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