代码之家  ›  专栏  ›  技术社区  ›  Vijay

C#泛型问题

  •  0
  • Vijay  · 技术社区  · 16 年前

    我有什么?

    我有一个抽象类, QueryExecutor SqlQueryExecutor 如下所示。

    abstract class QueryExecutor<T>
    {
        public abstract T Execute();
    }
    
    class SqlQueryExecutor<T> : QueryExecutor<T> where T:ICollection
    {
        public override T Execute()
        {
            Type type = typeof(T);
    
            // Do common stuff
            if (type == typeof(ProfileNodeCollection))
            {
                ProfileNodeCollection nodes = new ProfileNodeCollection();
                // Logic to build nodes
                return (T)nodes;
            }
            else
            {
                TreeNodeCollection nodes = new TreeNodeCollection();
                Logic to build nodes
    
                return (T)nodes;                
            }
        }
    }
    

    我想做什么?

    Execute() ICollection 对象并返回它。

    执行() 方法,路线,, return (T)nodes; 显示以下编译时错误:

    无法将类型“WebAppTest.ProfileNodeCollection”转换为“T”

    你知道我该怎么解决这个问题吗?

    2 回复  |  直到 16 年前
        1
  •  4
  •   Jon Skeet    16 年前

    好的,一个简单的修复方法就是制作编译器 较少的 了解正在发生的事情,以便将其推迟到CLR:

    return (T)(object)nodes;
    

    您可以将其放在一个地方,并使用隐式转换 object

    object ret;
    // Do common stuff
    if (type == typeof(ProfileNodeCollection))
    {
        ProfileNodeCollection nodes = new ProfileNodeCollection();
        // Logic to build nodes
        ret = nodes;
    }
    else
    {
        TreeNodeCollection nodes = new TreeNodeCollection();
        Logic to build nodes
    
        ret = nodes;
    }
    return (T)ret;
    

    这不太令人愉快,但应该行得通。不过,为不同的集合类型创建单独的派生类可能更好——可能将公共代码放在抽象基类中。

        2
  •  1
  •   bruno conde    16 年前

    我会选择在这里分开关注点。你甚至可以喝一杯 QueryExecutor 将提供权利的工厂 根据收集的类型而定。

    class ProfileSqlQueryExecutor : QueryExecutor<ProfileNodeCollection>
    {
        public override ProfileNodeCollection Execute()
        {
            ProfileNodeCollection nodes = new ProfileNodeCollection();
            // Logic to build nodes
            return nodes;
        }
    }
    
    class TreeSqlQueryExecutor : QueryExecutor<TreeNodeCollection>
    {
        public override TreeNodeCollection Execute()
        {
            TreeNodeCollection nodes = new TreeNodeCollection();
            Logic to build nodes
            return nodes;                
        }
    }