簡體   English   中英

沒有泛型參數的C#泛型工廠返回

[英]C# Generic factory return without generic argument

我有以下課程和一個工廠(省略了不必要的代碼)。 我有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);
        }
}

您需要在方法調用中指定類型。 這確實意味着您可以避免使用字符串:

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

你可以:

  • 通過使CreateDao方法(或ManagableEntryDaoFactory本身)通用,為IManageableEntryDao<T>提供類型參數。 要么,
  • CreateDao方法返回IManagableEntry接口,而不是返回通用的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;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM