使用interface方法获取属性名称列表

时间:2013-09-09 18:03:10

标签: c# visual-studio interface

我有两个自定义类型CustomerEmployee,它们实现了接口ITablefy。此接口只有一个方法GetPropertyList,它返回实现它的对象的属性名称的字符串列表。我有一个Web服务,看起来像:

public string ReturnPropertyNames(ITablefy i)
{
    List<string> propList = new List<string>();
    TableFactory factory = new TableFactory();
    ITablefy table = factory.CreateTable(i);
    propList = table.GetPropertyList(table);
    return propList[1];
}

所以在这个例子中,Factory创建了一个实现ITablefy

的具体类型

当我的两个类CustomerEmployee实现了他们的GetPropertyList方法完全相同时,我意识到我遇到了问题:

//property list is a private member variable in each class
    public List<string> GetPropertyList(ITablefy i)
    {
        TableFactory factory = new TableFactory();
        ITablefy table = factory.CreateTable(i);
        foreach (var propInfo in table.GetType().GetProperties())
        {
            propertyList.Add(propInfo.Name);
        }
        return propertyList;
    }

我没有复制并粘贴该代码,而是在寻找更好的解决方案。如果我只想让某些类型使用GetPropertyList方法,我怎么能控制它而不必复制和粘贴这个相同的代码?在每个类中编写要创建的类型对我来说似乎不是一个好的解决方案。员工和客户在逻辑上也没有意义使用继承。什么是这样的适当解决方案?

工厂:

public class TableFactory
{
    public ITablefy CreateTable(ITablefy i)
    {
        if (i is Employee)
        {
            return new Employee();
        }
        else if (i is Customer)
        {
            return new Customer();
        }
        else
        {
            return null;
        }
    }
}

2 个答案:

答案 0 :(得分:1)

public static List<string> GetPropertyNames(this Object o)
{
    List<string> names = new List<string>

    foreach (PropertyInfo prop in o.GetType().GetProperties())
        names.Add(prop.Name);
    return names;
}

现在,您可以使用上面的扩展方法在任何object.GetPropertyNames()方面实施ITablefy。

我想到了一些问题:

  1. 如果一般来说这么容易,为什么还要使用界面?
  2. 您是否应该检查公共访问者的属性?
  3. 您的界面不应该返回更常规的类型,例如IEnumerable<string>ICollection<string>吗?
  4. 界面是否更适合过滤掉您不想要的属性名称?这样你可以假设所有公共属性都是集合的一部分,除非那些不是。
  5. 您将界面设为:

    public interface IPropertyInfoFilterProvider {
        public Func<PropertyInfo, bool> PropertyInfoSkipFilter { get; set; }
    }
    

    public interface IPropertyNameFilterProvider {
        public Func<string, bool> PropertyNameSkipFilter { get; set; }
    }
    

    然后您可以将默认值初始化为(prop) => false

    所以现在你可以在一个地方自动收集属性名称并让实现确定采取什么和不采用什么,你的收获代码可以在linq where子句中使用该过滤器。

答案 1 :(得分:1)

您可以将其作为ITablefy的扩展方法。 或ITablefy上的静态方法