0

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

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];
}

所以在这个例子中,工厂创建了一个具体的类型来实现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 方法,我如何控制它而无需复制和粘贴相同的代码?对要在每个类中创建的类型进行编码对我来说似乎不是一个好的解决方案。Employee 和 Customer 在逻辑上也没有使用继承的意义。像这样的事情有什么合适的解决方案?

工厂:

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;
        }
    }
}
4

2 回答 2

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>orICollection<string>吗?
  4. 界面设计不是更好地过滤掉您不想要的属性名称吗?这样你就可以假设所有公共属性都是集合的一部分,除了那些不是的。

您使界面类似于:

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

或者

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

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

因此,现在您可以在一个地方自动收集属性名称,并让实现确定哪些被采用,哪些不被采用,并且您的收集代码可以在 linq where 子句中使用该过滤器。

于 2013-09-09T18:27:02.090 回答
1

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

于 2013-09-09T18:27:27.413 回答