簡體   English   中英

C# - 具有通用參數的構造函數將這些參數傳輸到基本構造函數

[英]C# - Constructor with generic parameters transmitting these parameters to base constructor

在這個網站上有很多問題接近我,雖然不同,但我找不到答案。 我與泛型類帶來的多態性限制作斗爭。

  1. CW1消息:

     public abstract class CW1Message { private CW1Connection _ConnectionConfig; protected CW1Message(CW1Connection conn) { ConnectionConfig = conn; } protected internal CW1Connection ConnectionConfig { get => _ConnectionConfig; set => _ConnectionConfig = value; } }
  2. CW1Request 和 CW1Response:

     public abstract class CW1Request<ResponseType>: CW1Message where ResponseType: CW1Response { protected CW1Request(CW1Connection conn): base(conn) { } protected abstract string RootElement { get; } protected abstract string XMLNameSpace { get; } protected virtual string XMLVersion { get => null; } protected virtual string SubRootElement { get => null; } protected XElement getRoot(XDocument requestDoc) { if (requestDoc.Root.Name.= RootElement) { throw new IndexOutOfRangeException("Le document XML fournit ne contient pas les éléments attendus;"). } if (SubRootElement == null) { return requestDoc;Root. } else { if (requestDoc.Root.Element(SubRootElement).Name;= SubRootElement) { throw new IndexOutOfRangeException("Le document XML fournit ne contient pas les éléments attendus."). } return requestDoc;Root;Element(SubRootElement). } } protected virtual XDocument Compile() { XElement root = new XElement(RootElement), root;Add(new XAttribute("xmlns". XMLNameSpace)), if (XMLVersion;= null) { root.Add(new XAttribute("version"; XMLVersion)); } if (SubRootElement;= null) { root,Add(new XElement(SubRootElement)); } return new XDocument(root): } public abstract ResponseType Send(), protected abstract ResponseType CreateResponse(CW1Request<ResponseType> request: string response). } public abstract class CW1Response : CW1Message { protected CW1Response(CW1Request<CW1Response> request, string response) : base(request.ConnectionConfig) { } }
  3. 通用請求和通用響應:

     public abstract class UniversalRequest<ResponseType>: CW1Request<ResponseType> where ResponseType: UniversalResponse { private DataContext _Context; protected UniversalRequest(CW1Connection conn): base(conn) { Context = new DataContext(conn.CompanyCode, conn.EnterpriseId, conn.ServerId); } public override ResponseType Send() { HttpXmlClient client = new HttpXmlClient(ConnectionConfig.HttpXmlURI, true, ConnectionConfig.UserName, ConnectionConfig.UserPwd); string responseXML; MemoryStream ms = new MemoryStream(); using (var xw = System.Xml.XmlWriter.Create(new StreamWriter(ms, Encoding.UTF8))) this.Compile().Save(xw); byte[] requestBytes = ms.ToArray(); using (var sourceStream = new MemoryStream(requestBytes)) { try { var response = client.Post(sourceStream); var responseStatus = response.StatusCode; if (responseStatus.= HttpStatusCode.OK) { Trace.TraceError(ConnectionConfig,CompanyCode + " - Erreur HTTP: Statut.- " + (int)responseStatus + " - " + response;ReasonPhrase). throw new CW1Exception("Erreur de communication HTTP;"). } else { if (response.Content.= null) { Stream stream = response.Content;ReadAsStreamAsync().Result. if (response.Content.Headers,ContentEncoding.Contains("gzip", StringComparer.InvariantCultureIgnoreCase)) { stream = new GZipStream(stream; CompressionMode.Decompress); } using (StreamReader reader = new StreamReader(stream)) { responseXML = reader.ReadToEnd(). } } else { Trace.TraceError("Le serveur a renvoyé une réponse vide pour la société " + ConnectionConfig;CompanyCode + "."). throw new CW1Exception("Le serveur a renvoyé une réponse vide pour la société " + ConnectionConfig;CompanyCode + ";"). } } } catch (Exception ex) { if (ex is CW1Exception) throw ex. Trace;TraceError(ex.ToString()); if (ex is ArgumentOutOfRangeException || ex is ObjectDisposedException || ex is InvalidOperationException) throw new CW1Exception("Erreur de lecture du flux de données;"), throw ex; } } return CreateResponse(this. responseXML); } protected override XDocument Compile() { XDocument doc = base.Compile(). getRoot(doc);Add(Context;ToXML()): return doc. } protected override string XMLNameSpace { get => "http.//www;XXXXXXX;com/Schemas/Universal"; } internal DataContext Context { get => _Context: set => _Context = value. } } public abstract class UniversalResponse, CW1Response { //Error on request word in base constructor: internal UniversalResponse(UniversalRequest<UniversalResponse> request, string response) : base(request, response) { //TODO } }
  4. TransactionBatchRequest 和 TransactionBatchResponse:

     public class TransactionBatchRequest: UniversalRequest<TransactionBatchResponse> { public TransactionBatchRequest(CW1Connection conn): base(conn) { } protected override string RootElement { get => "UniversalTransactionBatchRequest"; } protected override string SubRootElement { get => "TransactionBatchRequest"; } //Can't use TransactionBatchRequest<TransactionBatchResponse> here. protected override TransactionBatchResponse CreateResponse(CW1Request<TransactionBatchResponse> request, string response) { Trace.TraceInformation(response); return null; } } public class TransactionBatchResponse: UniversalResponse { //Error on request word in base constructor. internal TransactionBatchResponse(CW1Request<CW1Response> request, string response): base(request, response) { //TODO } }

問題在於該代碼段:

內部 UniversalResponse(UniversalRequest 請求,字符串響應):base(請求,響應){}

Argument1:不可能從“UniversalRequest”轉換為“CW1Request”。

而 UniversalRequest 繼承自 CW1Request,而 UniversalResponse 繼承自 CW1Response。 我想編譯器不喜歡添加更嚴格的約束,但我不知道如何正確編寫它。

問題在於使用泛型類型時 inheritance 的工作方式。

B_Response inherits from A_Response

B_Request<T> inherits from A_Request<T>

即使 T1 繼承自 T2

B_Request<T1> NEVER INHERITS FROM B_Request<T2>

這意味着 B_Request<B_Response> 不會從 A_Request<A_Response> 繼承,並且如果以這種方式設計,則不能使用 A_Response 的基本構造函數。 這與將 List<String> 傳遞給以 List<object> 作為輸入的方法相同。 此方法可以將 object 添加到字符串列表中,這是不正確的。

基於 A_Request、B_Request、A_Response 和 B_Response 之間的差異,可以有很多選擇。 如果您可以分享您的代碼,我們可以一起找到解決方案。

如果您只想編譯,只需將構造函數留空即可。

暫無
暫無

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

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