如何在C#中统一类似方法

发布于 2025-02-10 23:31:18 字数 1666 浏览 1 评论 0原文

我有各种各样的方法可以做相同的事情。 附在代码下方:

    private async Task<CheckResponse> ManageCheckResponseError(string code)
    {
        await LogErrorResponseAsync(new { StatusCode = code });
        return CheckResponse.GetError(code.ToString());
    }

    private async Task<BalanceResponse> ManageBalanceResponseError(string code)
    {
        await LogErrorResponseAsync(new { StatusCode = code });
        return BalanceResponse.GetError(code.ToString());
    }

    private async Task<DebitResponse> ManageDebitResponseError(string code)
    {
        await LogErrorResponseAsync(new { StatusCode = code });
        return DebitResponse.GetError(code.ToString());
    }

    private async Task<CreditResponse> ManageCreditResponseError(string code)
    {
        await LogErrorResponseAsync(new { StatusCode = code });
        return CreditResponse.GetError(code.ToString());
    }

    private async Task<CancelResponse> ManageCancelResponseError(string code)
    {
        await LogErrorResponseAsync(new { StatusCode = code });
        return CancelResponse.GetError(code.ToString());
    }

这些类的示例如下。除了明显不同的属性外,所有这些都以相同的方式制作:

   public class SampleResponse : ICommonResponseOperations<SampleResponse>
   {
      // Props

      // Error Management
      public ErrorModel ErrorModel { get; set; }

      public static LoginResponse GetError(string code)
      {
        return new LoginResponse
        {
            Entry = "",
            EntryEmbedded = "",
            ErrorModel = ErrorModel.GetError(code)
        };
      }
  }

是否有一种通过使代码更优雅的通用方法来标准化所有内容的方法?谢谢

I have various methods that does the same things.
Attached below the code :

    private async Task<CheckResponse> ManageCheckResponseError(string code)
    {
        await LogErrorResponseAsync(new { StatusCode = code });
        return CheckResponse.GetError(code.ToString());
    }

    private async Task<BalanceResponse> ManageBalanceResponseError(string code)
    {
        await LogErrorResponseAsync(new { StatusCode = code });
        return BalanceResponse.GetError(code.ToString());
    }

    private async Task<DebitResponse> ManageDebitResponseError(string code)
    {
        await LogErrorResponseAsync(new { StatusCode = code });
        return DebitResponse.GetError(code.ToString());
    }

    private async Task<CreditResponse> ManageCreditResponseError(string code)
    {
        await LogErrorResponseAsync(new { StatusCode = code });
        return CreditResponse.GetError(code.ToString());
    }

    private async Task<CancelResponse> ManageCancelResponseError(string code)
    {
        await LogErrorResponseAsync(new { StatusCode = code });
        return CancelResponse.GetError(code.ToString());
    }

An example of these classes is as follows. All are made in the same way apart from the properties that obviously are different :

   public class SampleResponse : ICommonResponseOperations<SampleResponse>
   {
      // Props

      // Error Management
      public ErrorModel ErrorModel { get; set; }

      public static LoginResponse GetError(string code)
      {
        return new LoginResponse
        {
            Entry = "",
            EntryEmbedded = "",
            ErrorModel = ErrorModel.GetError(code)
        };
      }
  }

Is there a way through generics to standardize everything by making the code more elegant? Thank you

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

披肩女神 2025-02-17 23:31:18

在C#(11)的下一个版本中,您将能够定义接口的静态成员。

您可以在最新版本的Visual Studio 2022中尝试一下,通过将以下内容添加到项目文件(假设.NET 6.0):

<EnablePreviewFeatures>True</EnablePreviewFeatures>
<LangVersion>preview</LangVersion>

完成此操作后,您可以将icommonResponsePorseperations与静态成员进行修改:(

public interface ICommonResponseOperations<out TLoginResponse>
{
    static abstract TLoginResponse GetError(string code);
    // ... Other members
}

您可能需要根据> tloginresponse类型在接口中使用

private async Task<TLoginResponse> ManageResponseError<TLoginResponse>(string code) where TLoginResponse : ICommonResponseOperations<TLoginResponse>
{
    await LogErrorResponseAsync(new { StatusCode = code });
    return TLoginResponse.GetError(code);
}

。 :

private async Task<BalanceResponse> ManageBalanceResponseError(string code)
{
    await LogErrorResponseAsync(new { StatusCode = code });
    return BalanceResponse.GetError(code.ToString());
}

您只需调用ManagerSponseError&lt; balanceresponse&gt;(code),而无需指定单独的调用方法。

当然,C#11尚未出现,此功能不能保证可以做到这一点,但是看起来很可能。


您还可以使用C#10简化事情。

您可以编写一个通用方法,该方法接受func&lt; string,tloginresponse&gt;它可以调用以返回必要的对象:

public async Task<TLoginResponse> ManageResponseError<TLoginResponse>(
        string code, 
        Func<string /*code*/, TLoginResponse> getError)
    where TLoginResponse : ICommonResponseOperations<TLoginResponse>
{
    await LogErrorResponseAsync(new { StatusCode = code });
    return getError(code);
}

然后,您可以无需明确指定通用类型即可拨打该方法

await ManageResponseError("some code", SampleResponse.GetError);

:从在呼叫站点中通过的Lambda的类型推断出来。
即使是lambda本身(code =&gt; sampleresponse.getError(code)),因此您只需要指定sampleresponse.getError

In the next version of C# (11) you will be able to define static members of interfaces.

You can try that out in the latest version of Visual Studio 2022 by adding the following to your project file (assuming .NET 6.0):

<EnablePreviewFeatures>True</EnablePreviewFeatures>
<LangVersion>preview</LangVersion>

After doing that you can modify your ICommonResponseOperations interface with a static member like so:

public interface ICommonResponseOperations<out TLoginResponse>
{
    static abstract TLoginResponse GetError(string code);
    // ... Other members
}

(You might need to remove the out depending on how the TLoginResponse type is used in the interface.)

Then you could define a common generic method like so:

private async Task<TLoginResponse> ManageResponseError<TLoginResponse>(string code) where TLoginResponse : ICommonResponseOperations<TLoginResponse>
{
    await LogErrorResponseAsync(new { StatusCode = code });
    return TLoginResponse.GetError(code);
}

Then instead of:

private async Task<BalanceResponse> ManageBalanceResponseError(string code)
{
    await LogErrorResponseAsync(new { StatusCode = code });
    return BalanceResponse.GetError(code.ToString());
}

You could just call ManageResponseError<BalanceResponse>(code) without having to specify a separate method to call.

Of course, C#11 isn't out yet and this feature is not guaranteed to make it, but it's looking pretty likely.


You can also simplify things a little with C#10.

You can write a generic method which accepts a Func<string, TLoginResponse> that it can call to return the necessary object:

public async Task<TLoginResponse> ManageResponseError<TLoginResponse>(
        string code, 
        Func<string /*code*/, TLoginResponse> getError)
    where TLoginResponse : ICommonResponseOperations<TLoginResponse>
{
    await LogErrorResponseAsync(new { StatusCode = code });
    return getError(code);
}

Then you can call the method without having to explicitly specify the generic type:

await ManageResponseError("some code", SampleResponse.GetError);

The generic type is inferred from the type of the lambda passed in at the call site.
Even the lambda itself (code => SampleResponse.GetError(code)) is inferred, so you only need to specify SampleResponse.GetError.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文