c#泛型:使用泛型的不同返回类型

时间:2011-11-08 10:38:50

标签: c# generics interface return-type

我有一个数据访问库,我想返回不同的数据格式(XML,Json,DataTable)。我试图用Generics来实现这个目标。

public interface IDBInteractor<T>
{
    T ExecuteDSQuery(string myQuery)
}

public class DBInteractorDT : IDBInteractor<DataTable>
{
    public DataTable ExecuteDSQuery(string myQuery)
    {
        return new DataTable();
    }
}

public class DBInteractorJson : IDBInteractor<JsonString>
{
    public JsonString ExecuteDSQuery(string myQuery)
    {
        return new JsonString();
    }
}

我无法调用正确的方法。理想情况下,我会声明像

这样的东西
     SomeClass<DataTable> dt = new SomeClass<DataTable>();
     SomeClass<JsonString> js = new SomeClass<JsonString>();

     DataTable myDT = dt.ExecuteDSQuery(myQuery);
     JsonString myJson = js.ExecuteDSQuery(myQuery);

我不确定如何声明SomeClass。我知道我可以做点什么

    public class SomeClass<T> where T : IDBInteractor <T>
    {
        public T ExecuteQuery(T dtobject, string myQuery)
        {
           return dtobject.ExecuteDSQuery(myQuery);
        }
    }

但我不想将对象实例(dtobject)传递给每个方法调用。

5 个答案:

答案 0 :(得分:0)

如果您的泛型参数具有无参数构造函数,则可以创建新的Object T();

但你必须定义你的T必须有一个无参数构造函数 使用泛型约束new()强制执行:

public class SomeClass<T> where T : IDBInteractor <T> , new()

答案 1 :(得分:0)

您可以将new()约束添加到类定义中,以便您的类变为:

public class SomeClass<T> where T : IDBInteractor <T>, new()
{
    public T ExecuteQuery(string myQuery)
    {
       return new T().ExecuteDSQuery(myQuery);
    }
}

然后,您可以在公共无参数构造函数中进行任何设置。

答案 2 :(得分:0)

您的SomeClass<T>依赖IDBInteractor<T>。您可以添加new()约束,以便在需要时可以在SomeClass<T>中创建实例。

但为什么不使用依赖性注射的力量呢?只需在IDBInteractor<T>的构造函数中接受SomeClass<T>作为参数?

代码

public class SomeClass<T> where T : IDBInteractor <T>
{
    private IDBInteractor<T> _interactor;

    public SomeClass(IDBInteractor<T> interactor)
    {
        _interactor = interactor;
    }

    public T ExecuteQuery(string myQuery)
    {
       return _interactor.ExecuteDSQuery(myQuery);
    }
}

另见

http://www.theserverside.com/news/1321158/A-beginners-guide-to-Dependency-Injection

答案 3 :(得分:0)

你到底想要做什么?这段代码工作正常:

using System.Data;

namespace ConsoleApplication7
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            IDBInteractor<DataTable> dt = new SomeClass<DataTable>(new DBInteractorDT());
            IDBInteractor<JsonString> js = new SomeClass<JsonString>(new DBInteractorJson());
            /*
            or you can write 

            IDBInteractor<DataTable> dt = new DBInteractorDT();
            IDBInteractor<JsonString> js = new DBInteractorJson();

             */

            DataTable myDT = dt.ExecuteDSQuery("");
            JsonString myJson = js.ExecuteDSQuery("");
        }
    }

    public interface IDBInteractor<T>
    {
        T ExecuteDSQuery(string myQuery);
    }

    public class DBInteractorDT : IDBInteractor<DataTable>
    {
        #region IDBInteractor<DataTable> Members

        public DataTable ExecuteDSQuery(string myQuery)
        {
            return new DataTable();
        }

        #endregion
    }

    public class DBInteractorJson : IDBInteractor<JsonString>
    {
        #region IDBInteractor<JsonString> Members

        public JsonString ExecuteDSQuery(string myQuery)
        {
            return new JsonString();
        }

        #endregion
    }

    public class SomeClass<T> : IDBInteractor<T>
    {
        private IDBInteractor<T> interactor;

        public SomeClass(IDBInteractor<T> interactor)
        {
            this.interactor = interactor;
        }

        public T ExecuteDSQuery(string myQuery)
        {
            return interactor.ExecuteDSQuery(myQuery);
        }
    }

    public class JsonString
    {
    }
}

答案 4 :(得分:0)

我同意fix_likes_coding。如果您只想创建一个类来执行查询,则可以查看扩展方法。这可能不适合事物的方案,但如果你想保持简单,可能会有所帮助。

public static class InteractorUtils
{
    public static T ExecuteQuery(this IDBInteractor<T> interactor, string myQuery)
    {
        return interactor.ExecuteDSQuery(myQuery);
    }
}

你可以像这样使用它:

IDBInteractor<DataTable> dt = new DBInteractorDT();

dt.ExecuteQuery("");