0

次のクラスとファクトリがあります(不要なコードは省略)。IManageableEntryDao の 3 つの個別の実装と、createDao メソッドでアクセスされる文字列/型マップがあります。

「ManageableEntry.IManageableEntryDao' には '1' 型引数が必要です」というコンパイル エラーが発生します。この問題を解決するためのベストプラクティスは何ですか? どうにかして何が何であるかを特定したいですか?または、代替ソリューションはありますか?

public interface IManageableEntryDao<T> where T : IManageableEntry {
    T findById(long id);
    T findByName(string name);

    int findUnapprovedCount();
    List<T> findUnapproved(ManageableEntryCriteria criteria);

    long insert(T manageableEntry);
    bool update(T manageableEntry);
    bool delete(T manageableEntry);
}

public class ManageableEntryDaoFactory {
    public IManageableEntryDao createDao(string manageableEntryType) {
            manageableEntryType = manageableEntryType.ToLower();
            Type type = daoTypes[manageableEntryType];
            if (type != null) {
                object dao = Activator.CreateInstance(type);                    
                return dao as IManageableEntryDao;
            }
            throw new NotImplementedException("Failed to find DAO for type: " + manageableEntryType);
        }
}
4

2 に答える 2

1

メソッド呼び出しで型を指定する必要があります。これは、文字列の必要性をおそらく回避できることを意味します。

public IManageableEntryDao<T> CreateDao<T>() where T : IManageableEntry
{
        Type manageableEntryType = typeof(T);

        // You'll need to modify daoTypes to be a HashSet<Type> (or List<Type>) of allowable types, or something similar, instead of using a dictionary lookup
        if (daoTypes.Contains(manageableEntryType) {
            object dao = Activator.CreateInstance(type);                    
            return dao as IManageableEntryDao<T>;
        }
        throw new NotImplementedException("Failed to find DAO for type: " + manageableEntryType);
    }
于 2012-06-08T20:16:00.183 に答える
0

あなたは出来る:

  • メソッド (またはそれ自体) をジェネリックIManageableEntryDao<T>にすることで、 に型引数を提供します。または、CreateDaoManagableEntryDaoFactory
  • ジェネリックを返す代わりにIManagableEntry、メソッドからインターフェイスを返します。CreateDaoIManagableEntryDao<T>

編集:コメントに基づく

CreateDao残念ながら、入力文字列に基づいてメソッドから特定の型を返すことはできません。最善の方法は、リスト内のすべての型に共通の基本型またはインターフェイスを返すことですdaoTypes

もう 1 つのアイデアは、非ジェネリック インターフェイスを返し、実装されたメソッドの特定の型にインターフェイスをキャストすることです。この点を説明するための小さなプログラムを次に示します。

class Program
{
    static void Main(string[] args)
    {
        var customerEntry = ManageableEntryDaoFactory.CreateDao("customer");
        var orderEntry = ManageableEntryDaoFactory.CreateDao("order");
        customerEntry.Update(new Customer() { Name = "John Doe" });
        orderEntry.Update(new Order() { OrderId = 123 });
        Console.ReadKey();
    }
}

public class Customer
{
    public string Name { get; set; }
}

public class Order
{
    public int OrderId { get; set; }
}

public class CustomerEntry : IManageableEntryDao
{
    public void Update(object objCustomer)
    {
        var customer = objCustomer as Customer;  // now you have a Customer type...
        Console.WriteLine("Updated customer: " + customer.Name);
    }
}

public class OrderEntry : IManageableEntryDao
{
    public void Update(object objOrder)
    {
        var order = objOrder as Order; // now you have an Order type... 
        Console.WriteLine("Updated order: " + order.OrderId);
    }
}

public interface IManageableEntryDao
{
    void Update(object entry);
    // ...other methods, properties, events...
}

public static class ManageableEntryDaoFactory
{
    private static readonly Dictionary<string, Type> daoTypes = new Dictionary<string, Type>() 
    {
        {"customer", typeof(CustomerEntry) }, 
        {"order", typeof(OrderEntry) }
    };

    public static IManageableEntryDao CreateDao(string manageableEntryType)
    {
        manageableEntryType = manageableEntryType.ToLower();
        Type type = daoTypes[manageableEntryType];
        if (type == null)
            throw new NotImplementedException("Failed to find DAO for type: " + manageableEntryType);

        return Activator.CreateInstance(type) as IManageableEntryDao;
    }
}
于 2012-06-08T20:36:09.517 に答える