C# 如何使方法适用于不同对象的列表?

C# 如何使方法适用于不同对象的列表?,c#,visual-studio-2010,list,object,C#,Visual Studio 2010,List,Object,我有几个不同类的列表,其中可能包含重复项。因此,我需要一种方法,可以在其中传递这些列表以删除所有重复项(基于子属性id)并返回列表。对于一个特定的类对象,这是没有问题的,但是对于不同的类型(所有类型都有属性id),这怎么可能呢 现在,我得到的是这个(不起作用): 静态类产品 { Guid id{get;set;} 字符串名称{get;set;} 整数价格{get;set;} } 静态类客户 { Guid id{get;set;} 字符串名{get;set;} 字符串lastname{get;se

我有几个不同类的列表,其中可能包含重复项。因此,我需要一种方法,可以在其中传递这些列表以删除所有重复项(基于子属性id)并返回列表。对于一个特定的类对象,这是没有问题的,但是对于不同的类型(所有类型都有属性id),这怎么可能呢

现在,我得到的是这个(不起作用):

静态类产品
{
Guid id{get;set;}
字符串名称{get;set;}
整数价格{get;set;}
}
静态类客户
{
Guid id{get;set;}
字符串名{get;set;}
字符串lastname{get;set;}
}
班级计划
{
公共空间控制器()
{
List pl=GenerateList1();
List cl=GenerateList2();
pl=减少(pl);
cl=减少(cl);
}
私有列表生成器列表1()
{
//我知道这些内容填写不正确,但应该足够理解
List pl=新列表();
pl.Add(新产品(“60c031f9-9a9b-4cd9-9e4c-3bde8f5e4665”“汽车”,2000年);
新增(新产品(“b786db8a-a55e-49aa-9a8d-c9c6f1c757c8”pc),500);
新增(新产品(“b786db8a-a55e-49aa-9a8d-c9c6f1c757c8”,“pc”,500);
}
私有void GenerateList2()
{
List cl=新列表();
pl.Add(新客户(“176b628a-bc66-44b5-a842-ec81ef7fb0e0”、“保罗”、“亚当”);
pl.Add(新客户(“db439316-1d73-47b7-8462-f815966a6394”“弗兰克”“史密斯”);
pl.Add(新客户(“176b628a-bc66-44b5-a842-ec81ef7fb0e0”、“保罗”、“亚当”);
}
私有列表减少(列表低)
{
List lg=新列表();
List lo2=新列表();
foreach(lo中的对象o)
{
如果(!lg.包含(o.id)
{
lg.添加(o.id);
lo2.加入(o);
}
}
返回lo2;
}
}
编辑: 该工作解决方案是在Adam Houldsworth的帮助下制定的:

    lv = Reduce(lv, v=>v.id);

    private static List<T> Reduce<T, TProp>(List<T> listTold, Func<T, TProp> getId)
    {
        List<Guid> lGuid = new List<Guid>();
        List<T> listTnew = new List<T>();
        foreach (T singleT in listTold)
        {
            if (!lGuid.Contains(Guid.Parse(getId(singleT).ToString())))
            {
                lGuid.Add(Guid.Parse(getId(singleT).ToString()));
                listTnew.Add(singleT);
            }
        }
        return listTnew;
    }
lv=Reduce(lv,v=>v.id);
私有静态列表缩减(列表ListToll,Func getId)
{
List lGuid=新列表();
List listTnew=新列表();
foreach(列表中的T单态)
{
如果(!lGuid.Contains(Guid.Parse(getId(singleT.ToString()))
{
lGuid.Add(Guid.Parse(getId(singleT.ToString()));
listTnew.Add(单重态);
}
}
返回列表新建;
}

实现这一点的一种可能非常简单的方法是提供一种方法,该方法使用函数检索要比较的项目。类似于:

private List<T> Reduce<T, TProp>(List<T> list, Func<T, TProp> getId)
{
}
编译器中对类型推断的支持通常只会让您:

customers = Reduce(customers, c => c.CustomerId);
products = Reduce(products, p => p.ProductId);
您可能必须使用
IEquatable
或其他东西来约束
TProp
,以使其与
Contains
实现一起工作,但这是我首先要探索的路线:

private List<T> Reduce<T, TProp>(...) where TProp : IEquatable<TProp>
private List Reduce(…),其中TProp:IEquatable


另一种方法是使用公开ID的接口在类上泛化功能。面对
Func
,如果我追溯进行更改,我现在倾向于偏离这条路线。

实现这一点的一种可能非常简单的方法是提供一种方法,该方法使用函数检索要比较的项.例如:

private List<T> Reduce<T, TProp>(List<T> list, Func<T, TProp> getId)
{
}
编译器中对类型推断的支持通常只会让您:

customers = Reduce(customers, c => c.CustomerId);
products = Reduce(products, p => p.ProductId);
您可能必须使用
IEquatable
或其他东西来约束
TProp
,以使其与
Contains
实现一起工作,但这是我首先要探索的路线:

private List<T> Reduce<T, TProp>(...) where TProp : IEquatable<TProp>
private List Reduce(…),其中TProp:IEquatable


另一种方法是使用公开ID的接口在类上泛化功能。面对
Func
,如果我追溯更改,我现在倾向于偏离此路线。

您必须声明两个类都包含ID属性:

interface IhasGUIDId
{
    Guid id {get; set;}
}

class Product : IhasGUIDId
{
    Guid id {get; set;}
    string name {get; set;}
    int price {get; set;}
}
class Customer : IhasGUIDId
{
    Guid id {get; set;}
    string firstname {get; set;}
    string lastname {get; set;}
}
然后您将能够比较指定接口的所有对象:

private List<IhasGUIDId> Reduce(List<IhasGUIDId> lo)
    {
        List<Guid> lg = new List<Guid>();
        List<IhasGUIDId> lo2 = new List<IhasGUIDId>();
        foreach(IhasGUIDIdo in lo)
        {
            if(!lg.contains(o.id)
            {
                lg.add(o.id);
                lo2.add(o);
            }
        }
        return lo2;
    }
私有列表减少(列表低)
{
List lg=新列表();
List lo2=新列表();
foreach(洛城的IhasGUIDIdo)
{
如果(!lg.包含(o.id)
{
lg.添加(o.id);
lo2.加入(o);
}
}
返回lo2;
}

您必须声明两个类都包含id属性:

interface IhasGUIDId
{
    Guid id {get; set;}
}

class Product : IhasGUIDId
{
    Guid id {get; set;}
    string name {get; set;}
    int price {get; set;}
}
class Customer : IhasGUIDId
{
    Guid id {get; set;}
    string firstname {get; set;}
    string lastname {get; set;}
}
然后您将能够比较指定接口的所有对象:

private List<IhasGUIDId> Reduce(List<IhasGUIDId> lo)
    {
        List<Guid> lg = new List<Guid>();
        List<IhasGUIDId> lo2 = new List<IhasGUIDId>();
        foreach(IhasGUIDIdo in lo)
        {
            if(!lg.contains(o.id)
            {
                lg.add(o.id);
                lo2.add(o);
            }
        }
        return lo2;
    }
私有列表减少(列表低)
{
List lg=新列表();
List lo2=新列表();
foreach(洛城的IhasGUIDIdo)
{
如果(!lg.包含(o.id)
{
lg.添加(o.id);
lo2.加入(o);
}
}
返回lo2;
}

只需使用id属性定义一个接口并从中派生实体类:

public interface IHasID
{
    public Guid id {get; set;}
}

public class Product: IHasId
{
    Guid id {get; set;}
    string name {get; set;}
    int price {get; set;}
}
public class Customer: IHasId
{
    Guid id {get; set;}
    string firstname {get; set;}
    string lastname {get; set;}
}
然后,您可以合并列表并在此接口上迭代,而不是具体的类:

public void Controller()
{
     List<Product> pl = GenerateList1();
     List<Customer> cl = GenerateList2();

     List<IHasId> = Reduce(p1, cl);
}
private List<IHasId> Reduce(List<IHasId> l1, List<IHasId> l2)
{
    List<Guid> lg = new List<Guid>();
    List<IHasId> l = l1.AddRange(l2).ToList();
    foreach(IHasId i in l)
    {
        if(!lg.contains(i.id)
        {
            lg.add(i.id);
            l.add(i);
        }
    }
    return l;
}
public void Controller()
{
List pl=GenerateList1();
List cl=GenerateList2();
列表=减少(p1,cl);
}
私有列表减少(列表l1、列表l2)
{
List lg=新列表();
列表l=l1.AddRange(l2.ToList();
foreach(i在l中为i)
{
如果(!lg.包含(i.id)
{
lg.添加(i.id);
l、 加(i);
}
}
返回l;
}

只需使用id属性定义一个接口并从中派生实体类:

public interface IHasID
{
    public Guid id {get; set;}
}

public class Product: IHasId
{
    Guid id {get; set;}
    string name {get; set;}
    int price {get; set;}
}
public class Customer: IHasId
{
    Guid id {get; set;}
    string firstname {get; set;}
    string lastname {get; set;}
}
然后,您可以合并列表并在此接口上迭代,而不是具体的类:

public void Controller()
{
     List<Product> pl = GenerateList1();
     List<Customer> cl = GenerateList2();

     List<IHasId> = Reduce(p1, cl);
}
private List<IHasId> Reduce(List<IHasId> l1, List<IHasId> l2)
{
    List<Guid> lg = new List<Guid>();
    List<IHasId> l = l1.AddRange(l2).ToList();
    foreach(IHasId i in l)
    {
        if(!lg.contains(i.id)
        {
            lg.add(i.id);
            l.add(i);
        }
    }
    return l;
}
public void Controller()
{
List pl=GenerateList1();
List cl=GenerateList2();
列表=减少(p1,cl);
}
私有列表减少(列表l1、列表l2)
{
List lg=新列表();
列表l=l1.AddRange(l2.ToList();
foreach(i在l中为i)
{
如果(!lg.包含(i.id)
{
lg.添加(i.id);
l、 加(i);
}