0

インターフェイスを実装する2 つのカスタム タイプがCustomerあります。このインターフェイスには、それを実装するオブジェクトのプロパティ名の文字列のリストを返すメソッドが 1 つだけあります。次のようなWebサービスがあります。EmployeeITablefyGetPropertyList

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

CustomerクラスとEmployeeGetPropertyList メソッドをまったく同じに実装したときに問題が発生したときに気付きました。

//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;
        }
    }
}
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. あなたのインターフェースは or のようなより一般的な型を返すべきではありませんIEnumerable<string>ICollection<string>?
  4. 不要なプロパティ名を除外するようにインターフェイスを設計する方がよいのではないでしょうか? そうすれば、そうでないものを除いて、すべてのパブリック プロパティがセットの一部であると想定できます。

インターフェイスを次のようにします。

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

また

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

その後、デフォルトを に初期化できます(prop) => false

そのため、プロパティ名を自動的に 1 か所で収集し、実装によって何が取得され、何が取得されないかを判断できるようになり、取得コードは linq where 句でそのフィルターを使用できます。

于 2013-09-09T18:27:02.090 に答える