C#中的通用方法,带有两个通用参数

时间:2014-02-04 06:03:42

标签: c# .net wcf generics

我想为这种类型的方法创建泛型方法,它采用两种类型的泛型值?

我不想让审计的重载方法做同样的冗余工作。

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

3 个答案:

答案 0 :(得分:2)

可能你应该提取接口而不是在这里使用泛型

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);
  }
  ...
}

答案 1 :(得分:0)

我的想法与德米特里的答案完全相同。我在撰写作品时没有看到回应。

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");
    }
}

答案 2 :(得分:0)

我是这样做的:

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);
    }