簡體   English   中英

C#中具有兩個通用參數的通用方法

[英]Generic method in C# with two generic parametres

我想為這種類型的方法創建泛型方法,它采用兩種類型的泛型值?

我不想讓審計的重載方法做同樣的冗余工作。

public class UserProfile : IUserProfile
{
    private static void GetAudit(ChangePasswordRequest changePasswordRequest, ChangePasswordResponse changePasswordResponse,
        int memberId, RemoteEndpointMessageProperty endpointProperty)
    {
        string auditText = "ChangePassword Req:";
        auditText += Util.Serialize(changePasswordRequest).ToString(CultureInfo.InvariantCulture);
        auditText += "Res:";
        auditText += Util.Serialize(changePasswordResponse).ToString(CultureInfo.InvariantCulture);
        Audit.Add(AuditEventType.UpdatePassword, Severity.Normal, memberId,
            changePasswordRequest.TokenId,
            auditText,
            endpointProperty.Address, changePasswordRequest.IpAddress);
    }
    private static void GetAudit(LoadSupplierRequest loadSupplierRequest, LoadSupplierResponse loadSupplierResponse,int memberID,
        RemoteEndpointMessageProperty endpointProperty)
    {
        string auditText = "LoadSupplier Req:";
        auditText += Util.Serialize(loadSupplierRequest).ToString(CultureInfo.InvariantCulture);
        auditText += "Res:";
        auditText += Util.Serialize(loadSupplierResponse).ToString(CultureInfo.InvariantCulture);
        Audit.Add(AuditEventType.LoadSupplier, Severity.Normal, memberID, loadSupplierRequest.TokenId,
            auditText,
            endpointProperty.Address, loadSupplierRequest.IpAddress);
    }
}

以下是類和接口的結構

public class ChangePasswordResponse : IResponse
{
    /// <summary>
    ///     Gets or sets the status.
    /// </summary>
    /// <value>
    ///     The status.
    /// </value>
    [DataMember]
    public ChangePasswordResponseStatus Status { get; set; }

    /// <summary>
    ///     Gets or sets the error.
    /// </summary>
    /// <value>
    ///     The error.
    /// </value>
    [DataMember]
    public Error Error { get; set; }

    /// <summary>
    ///     Gets or sets the token identifier.
    /// </summary>
    /// <value>
    ///     The token identifier.
    /// </value>
    [DataMember]
    public string TokenId { get; set; }
}
public interface IResponse
{
    [DataMember]
    Error Error { get; set; }

    [DataMember]
    string TokenId { get; set; }
}

public interface IRequest
{
    /// <summary>
    ///     Gets or sets the ip address.
    /// </summary>
    /// <value>
    ///     The ip address.
    /// </value>
    [DataMember(IsRequired = true)]
    string IpAddress { get; set; }

    /// <summary>
    ///     Gets or sets the token identifier.
    /// </summary>
    /// <value>
    ///     The token identifier.
    /// </value>
    [DataMember(IsRequired = true)]
    string TokenId { get; set; }
}
[Serializable]
public class ChangePasswordRequest : IRequest
{
    /// <summary>
    ///     Gets or sets the old password.
    /// </summary>
    /// <value>
    ///     The old password.
    /// </value>
    [DataMember(IsRequired = true)]
    public string OldPassword { get; set; }

    /// <summary>
    ///     Gets or sets the new password.
    /// </summary>
    /// <value>
    ///     The new password.
    /// </value>
    [DataMember(IsRequired = true)]
    public string NewPassword { get; set; }

    /// <summary>
    ///     Gets or sets the ip address.
    /// </summary>
    /// <value>
    ///     The ip address.
    /// </value>
    [DataMember(IsRequired = true)]
    public string IpAddress { get; set; }

    /// <summary>
    ///     Gets or sets the token identifier.
    /// </summary>
    /// <value>
    ///     The token identifier.
    /// </value>
    [DataMember(IsRequired = true)]
    public string TokenId { get; set; }
}

可能你應該在這里提取接口而不是使用泛型

public interface IRequest {
  String TokenId {get;}
  String IpAddress {get;}
  ... 
} 

public interface IResponse {
  ...
} 

public class LoadSupplierResponse: IResponse {...}

public class ChangePasswordResponse: IResponse {...}

public class LoadSupplierRequest: IRequest {...}

public class ChangePasswordRequest: IRequest {...}

public static class Util {
  ...
  public static String Serialize(IRequest value) {...} 
  public static String Serialize(IResponse value) {...} 
} 

public class UserProfile : IUserProfile {
  private static void GetAudit(IRequest request, 
                               IResponse response,
                               int memberID,
                               RemoteEndpointMessageProperty endpointProperty) {
    string auditText = "LoadSupplier Req:";
    auditText += Util.Serialize(request).ToString(CultureInfo.InvariantCulture);
    auditText += "Res:";
    auditText += Util.Serialize(response).ToString(CultureInfo.InvariantCulture);
    Audit.Add(AuditEventType.LoadSupplier, 
              Severity.Normal, 
              memberID, 
              request.TokenId,
              auditText,
              endpointProperty.Address, 
              request.IpAddress);
  }
  ...
}

我和Dmitry的回答完全相同。 當我寫作我的時候,我沒有看到回應。

private static void GetAudit<TRequest, TResponse>(TRequest request, TResponse response, int memberId, RemoteEndpointMessageProperty endpointProperty)
{
    var auditSB = new StringBuilder();
    auditSB.Append("Req:");
    auditSB.Append(Util.Serialize(request).ToString(CultureInfo.InvariantCulture));
    auditSB.Append("Res:");
    auditSB.Append(Util.Serialize(response).ToString(CultureInfo.InvariantCulture));

    if (request is ChangePasswordRequest)
    {
        // check if TResponse is ChangePasswordResponse
        // throw ArgumentException if TResponse is not right type

        var changePasswordRequest = TRequest as ChangePasswordRequest;
        Audit.Add(AuditEventType.UpdatePassword, Severity.Normal, memberId,
            changePasswordRequest.TokenId,
            auditSB.ToString(),
            endpointProperty.Address, changePasswordRequest.IpAddress);
    }
    else if (request is LoadSupplierRequest)
    {
        // check if TResponse is LoadSupplierResponse
        // throw ArgumentException if TResponse is not right type

        // do Auditing
    }
    else
    {
        throw new ArgumentException("Invalid Request type");
    }
}

我是這樣做的:

private static void LogNormalAudit<TRequest, TResponse>(TRequest request, TResponse response,
        IRequest objRequest, int memberId, AuditEventType eventType)
    {
        bool isNormalSeverityOn = Convert.ToBoolean(ConfigurationSystem.SharedApiConfig["normal"]);
        if (!isNormalSeverityOn) return;
        var auditText = string.Format("Req: {0} |Rsp: {1}", Util.Serialize(request), Util.Serialize(response));
        Audit.Add(eventType, Severity.Normal, memberId, objRequest.TokenId, auditText, GetClientIp(),
            objRequest.IpAddress);
    }

暫無
暫無

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

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