[英]Extension methods for multiple types
我有一个Product
类型和Variant
类型的对象。 Variant
和Product
具有相同的结构,但是有两种不同的类型,因此我不能只使用一种方法来包含它们。 是否可以制作一个接受这两种类型的扩展方法?
除非Product
和Variant
具有公共基类或接口,否则不能这样做。
如果他们有共同的基类或接口,那么你可以尝试为它编写扩展方法,例如
public static void MyMethod(this ICommonInterface obj) {}
否则,您将不得不创建两个单独的扩展方法。 您可以尝试将公共代码提取到一个单独的方法,该方法将从您的扩展方法中调用。
史蒂夫,
从Commerce Server的角度来看这个问题的两个可能的答案。 取决于您是在谈论Core Systems API还是Commerce Foundation API。 我将在下面解决两个问题:
选项1:Commerce Server核心系统API
不幸的是,Product和Variant这两个类不共享一个公共基类(除非你计算System.Object ;-)。 虽然Microsoft.CommerceServer.Catalog.Product继承自Microsoft.CommerceServer.Catalog.CatalogItem,但Variant不会从CatalogItem或任何其他公共基类继承。 Variant直接从System.Object继承。
因此,您无法编写可由两个类利用的扩展方法。
可以在此处找到所有Catalog System对象(针对Core Systems API)的类定义文档http://msdn.microsoft.com/en-us/library/microsoft.commerceserver.catalog(v=cs.70).aspx
选项2:Commerce Foundation API如果您在从对Commerce Foundation的调用返回的对象方面引用Product和Variant,则使用Commerce Server Operation Service的请求返回的所有对象将作为类型ICommerceEntity返回。
如果您使用具体数据类型来包装CommerceEntity,那么您仍然可以使用.ToCommerceEntity()方法,并且可以从ICommerceEntity编写扩展。 该方法的唯一问题是从ICommerceEntity继承的所有类都可以使用扩展方法。
有关Commerce Foundation中具体数据类型的更多信息,请查看http://msdn.microsoft.com/en-us/library/dd451701.aspx 。
您可以利用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 。 对于上面的示例Product
和Variant
示例类型,您必须使用以下类型定义成员映射,该类型共享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
类型定义扩展方法。
您不能更改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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.