3

我有一个 typeProduct和 type的对象VariantVariant并且Product具有相同的结构,但是是两种不同的类型,所以我不能只用一种方法来涵盖两者。是否可以创建一个可以接受这两种类型的扩展方法?

4

4 回答 4

6

Product除非并且Variant具有通用的基类或接口,否则您不能这样做。

如果他们有共同的基类或接口,那么你可以尝试为它编写扩展方法,例如

public static void MyMethod(this ICommonInterface obj) {}

否则,您将不得不创建两个单独的扩展方法。您可以尝试将通用代码提取到一个单独的方法中,该方法将从您的扩展方法中调用。

于 2013-10-30T16:09:53.800 回答
1

史蒂夫,

从 Commerce Server 的角度来看,这个问题有两个可能的答案。取决于您是在谈论核心系统 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。

因此,您不能编写两个类都可以使用的扩展方法。

所有目录系统对象(用于核心系统 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 。

于 2013-11-03T08:56:21.363 回答
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类型定义扩展方法。

于 2013-10-30T16:23:45.100 回答
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

于 2017-06-08T09:31:16.873 回答