C#获取具有相同属性的类型列表的方法

时间:2014-10-28 21:18:57

标签: c# list

我有几种不同类型的共同属性:

public class A {
  public int SomeCommonProperty { get; set; }

   /*
    * some other stuff
    */
}

public class B {
  public int SomeCommonProperty { get; set; }

  /*
   * some other stuff
   */
}

我希望有一个方法,可以使用此属性获取任何这些对象的列表,以便我可以遍历列表并将该属性与另一个参数进行比较,如:

public static List<T> MethodToTakeListOfAboveTypes<T>(this List<T> destinationList, List<T> sourceList, string someProp)
{
  if (sourceList != null && sourceList.Exists(tab => tab.SomeCommonProperty  == someProp))
  {
    destinationList = sourceList.Where(tab => tab.SomeCommonProperty == someProp).ToList();
  }
  return destinationList;
}

上面的代码不起作用,因为T没有“SomeCommonProperty”的定义,这是有道理的。 我想简单地使用该属性传递一个更通用的对象,这样我就不必为每种类型创建相同的方法。我只是无法正确使用语法。这有意义吗?

我知道我应该将SomeCommonProperty字段放入基类并继承,但由于某种原因,这似乎不起作用。

5 个答案:

答案 0 :(得分:4)

让所有类实现一些接口(或从某个基类继承此属性),例如

public interface ICommonInterface
{
   int SomeCommonProperty { get; set; }
}

然后你可以在通用参数类型上放置接口/类约束:

public static List<T> MethodToTakeListOfAboveTypes<T>(          
   this List<T> destinationList, List<T> sourceList, string someProp)
    where T: ICommonInterface
{
   // ...
}

注意:您可以避免检查源中是否存在带有someProp的任何项目(在最坏的情况下,您必须两次枚举sourceList)。只需过滤并检查是否有任何结果

public static List<T> MethodToTakeListOfAboveTypes<T>(
     this List<T> destinationList, List<T> sourceList, string someProp)
     where T: ICommonInterface
{
    if (sourceList == null)
        return destinationList;

    var filtered = sourceList.Where(s => s.SomeCommonProperty == someProp).ToList();
    return filtered.Any() ? filtered : destinationList;
}

答案 1 :(得分:2)

  

我知道我应该将SomeCommonProperty字段放入基类并继承,但由于某种原因,这似乎不起作用。

你需要添加一个通用约束,然后才能正常工作

where T : CommonType

答案 2 :(得分:1)

如果基类包含具有该名称的属性,那么您唯一需要做的就是告诉泛型方法该类型必须从该基类继承:

public static List<T> MethodToTakeListOfAboveTypes<T>(this List<T> destinationList, List<T> sourceList, string someProp) where T : BaseClass

请注意使用where T :实际上说T必须来自... {/ p>

BaseClass替换为您的实际基类名称。

public class BaseClass
{
   public string SomeCommonProperty { get; set; }
}

答案 3 :(得分:1)

使用每个类实现的属性创建一个接口,然后向您的泛型方法添加一个约束:

public interface ICommonProperty
{
    int SomeCommonProperty {get;set;}
}

public class A : ICommonProperty
{
    public int SomeCommonProperty { get; set; }
}

public class B : ICommonProperty
{
    public int SomeCommonProperty { get; set; }
}

public static List<T> MethodToTakeListOfAboveTypes<T>(this List<T> destinationList, List<T> sourceList, string someProp) where T : ICommonProperty

答案 4 :(得分:0)

如果你可以继承(正如你所说的那样),你应该这样做。但是,如果由于某种原因你需要遍历一堆你没有源代码的对象并访问你知道的属性,你可以使用dynamic

class foo
{
    public string myProp = "foo";
}

class bar
{
    public string myProp = "bar";
}


class Program
{
    static void Main(string[] args)
    {
        List<dynamic> list = new List<dynamic>();
        list.Add(new foo());
        list.Add(new bar());

        foreach (dynamic o in list)
        {
            Console.WriteLine(o.myProp);
        }
    }
}

您还可以在dynamic上调用任意方法。如果属性/方法不存在,则会出现异常。