简体   繁体   English

C# - 具有通用参数的构造函数将这些参数传输到基本构造函数

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

There are so many problems approaching mine on this site, while being different, that I cannot find the answer.在这个网站上有很多问题接近我,虽然不同,但我找不到答案。 I struggle with the restrictions on polymorphism brought about by generic classes.我与泛型类带来的多态性限制作斗争。

  1. CW1Message: 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 and CW1Response: 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. UniversalRequest and 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 } }
  4. TransactionBatchRequest and TransactionBatchResponse: 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 } }

The issue is in that code snippet:问题在于该代码段:

internal UniversalResponse(UniversalRequest request, string response): base( request , response) {}内部 UniversalResponse(UniversalRequest 请求,字符串响应):base(请求,响应){}

Argument1:impossible conversion from 'UniversalRequest' to 'CW1Request'. Argument1:不可能从“UniversalRequest”转换为“CW1Request”。

Whereas UniversalRequest inherits from CW1Request, and UniversalResponse inherits from CW1Response.而 UniversalRequest 继承自 CW1Request,而 UniversalResponse 继承自 CW1Response。 I imagine the compiler doesn't like adding a more restrictive constraint, but I don't know how to write this correctly.我想编译器不喜欢添加更严格的约束,但我不知道如何正确编写它。

The problem lays within how inheritance works when using generic types.问题在于使用泛型类型时 inheritance 的工作方式。

B_Response inherits from A_Response

B_Request<T> inherits from A_Request<T>

even if T1 inherits from T2即使 T1 继承自 T2

B_Request<T1> NEVER INHERITS FROM B_Request<T2>

this means that B_Request<B_Response> does not inherit from A_Request<A_Response> and you can't use the base constructor of A_Response if designed in this way.这意味着 B_Request<B_Response> 不会从 A_Request<A_Response> 继承,并且如果以这种方式设计,则不能使用 A_Response 的基本构造函数。 This is the same of passing a List< String> to a method who has a List< object> as input.这与将 List<String> 传递给以 List<object> 作为输入的方法相同。 This method could add an object to the list of strings and this is not correct.此方法可以将 object 添加到字符串列表中,这是不正确的。

Based on the differences between A_Request, B_Request, A_Response and B_Response there could be many options.基于 A_Request、B_Request、A_Response 和 B_Response 之间的差异,可以有很多选择。 If you can share your code we could find a solution together.如果您可以分享您的代码,我们可以一起找到解决方案。

If you just want to compile, just leave the constructors empty.如果您只想编译,只需将构造函数留空即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM