【发布时间】:2023-03-07 04:45:01
【问题描述】:
在这个网站上,有很多问题在逼近我,虽然不同,但我找不到答案。 我为泛型类带来的多态性限制而苦恼。
-
CW1消息:
public abstract class CW1Message { private CW1Connection _ConnectionConfig; protected CW1Message(CW1Connection conn) { ConnectionConfig = conn; } protected internal CW1Connection ConnectionConfig { get => _ConnectionConfig; set => _ConnectionConfig = value; } } -
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) { } } -
UniversalRequest 和 UniversalResponse:
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 } } -
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 } }
问题在于代码 sn-p:
内部 UniversalResponse(UniversalRequest request, string response) : base(request, response) {}
Argument1:无法从“UniversalRequest”转换为“CW1Request”。
UniversalRequest 继承自 CW1Request,UniversalResponse 继承自 CW1Response。我想编译器不喜欢添加更严格的约束,但我不知道如何正确编写。
【问题讨论】:
标签: c# generics inheritance polymorphism