我有一个数据访问库,我想返回不同的数据格式(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)传递给每个方法调用。
答案 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("");