Product
typeと typeのオブジェクトがありますVariant
。 Variant
とProduct
は同じ構造ですが、2 つの異なるタイプであるため、1 つのメソッドだけで両方を網羅することはできません。これらのタイプの両方を受け入れる拡張メソッドを作成することは可能ですか?
4 に答える
共通の基本クラスまたはインターフェイスがない限りProduct
、それを行うことはできません。Variant
それらが共通の基本クラスまたはインターフェースを持っている場合は、そのための拡張メソッドを作成してみることができます。
public static void MyMethod(this ICommonInterface obj) {}
それ以外の場合は、2 つの別個の拡張メソッドを作成する必要があります。拡張メソッドから呼び出される別のメソッドに共通コードを抽出することを試みることができます。
スティーブ、
Commerce Server の観点から、この質問に対する 2 つの回答が考えられます。Core Systems API について話しているのか、Commerce Foundation API について話しているのかによって異なります。以下の両方に対処します。
オプション 1 : Commerce Server コア システム API
残念ながら、Product と Variant の 2 つのクラスは共通の基本クラスを共有していません (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を参照してください。
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
。