0

我有以下课程和工厂(省略了不必要的代码)。我有 3 个独立的 IManageableEntryDao 实现,以及在 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>通过使CreateDao方法(或ManagableEntryDaoFactory本身)泛型来为 提供类型参数。或者,
  • IManagableEntry从方法返回接口CreateDao,而不是返回泛型IManagableEntryDao<T>

编辑:基于评论

不幸的是,您不能从CreateDao基于输入字符串的方法返回特定类型。您可以做的最好的事情是返回一个基类型或一个对daoTypes列表中所有类型通用的接口。

另一个想法是返回一个非泛型接口,并将接口转换为实现方法中的特定类型。这是一个小程序来说明这一点:

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 回答