簡體   English   中英

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

[英]c# Generics: Different Return Types using Generics

我有一個數據訪問庫,我想返回不同的數據格式(XML,Json,DataTable)。 我試圖使用泛型來實現這一目標。

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)傳遞給每個方法調用。

如果您的通用參數具有無參數構造函數,則可以創建一個新的Object T();

但是您必須定義T必須具有無參數構造函數,並使用通用約束new()強制執行以下操作:

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

您可以將new()約束添加到類定義中,這樣您的類將變為:

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

然后,您可以在公共無參數構造函數中進行任何設置。

您的SomeClass<T>IDBInteractor<T>有依賴關系。 您可以添加new()約束,以便在需要時在SomeClass<T>創建一個實例。

但是,為什么不使用依賴注入的功能呢? 只是在SomeClass<T>的構造函數中接受IDBInteractor<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

您到底想做什么? 這段代碼可以正常工作:

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
    {
    }
}

我同意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("");

暫無
暫無

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

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