大数跨境
0
0

C# 14 Extension 实现更简单高效的扩展

C# 14 Extension 实现更简单高效的扩展 amazingdotnet
2025-12-07
9
导读:利用 C# 14 Extension 特性实现更简单高效的扩展

 

利用 C# 14 Extension 特性实现更简单高效的扩展

Intro

C# 14 支持了扩展成员 C# 14 Extensions 来了,我们可以更灵活地扩展了,对于多框架的扩展方法来说可以更加简单,对于方法调用的性能来说也会更加简单,让我们来看一个简单的示例吧

Sample

传统的一个扩展方法可能会这样定义,扩展方法定义如下:


   
    
   public static class MyExtensions
{
    public static string CustomHexStringLower(this byte[] bytes)
    {
#if NET9_0_OR_GREATER

        return
 Convert.ToHexStringLower(bytes);
#else

        return
 Convert.ToHexString(bytes).ToLowerInvariant();
#endif

    }
    //...

}

这里是一个方法将字节数组转换成十六进制的字符串,在 .NET 9 及之后的框架使用新的 Convert.ToHexStringLower 对于之前的框架使用 Convert.ToHexString().ToLowerInvariant()

使用示例:


   
    
   var bytes = "Hello, World!"u8.ToArray();
Console.WriteLine(bytes.CustomHexStringLower());

我们的示例定义两个框架 net8.0/net10.0

这应该是一个很普遍的用法吧,在 C# 14 里我们就可以使用 extension 来简化了,为 .NET 9.0 以下的框架扩展 Console 类型


   
    
   public static class MyExtensions
{
#if !NET9_0_OR_GREATER

    extension(Convert)
    {
        public static string ToHexStringLower(byte[] bytes)
        {
            return
 Convert.ToHexString(bytes).ToLowerInvariant();
        }
    }
#endif

}

使用时可以直接使用新的 API 了


   
    
   var bytes = "Hello, World!"u8.ToArray();
Console.WriteLine(Convert.ToHexStringLower(bytes));

这样我们在旧版本的 .NET 框架中也可以使用新的 API 而且性能会更好一些,尤其是对于高版本框架少一层方法调用,调用堆栈少一些

.NET 8.0 反编译结果:


`net8.0 extension`

`net8.0 sample`

.NET 10.0 反编译


`net10.0 extension`

`net10.0 sample`

从上面的反编结果可以清晰地看到新的 extension 方式就简单了很多

执行结果

微软在 .NET 框架里也有一些类似的用法,比如针对 exception throw helpers ,可以参考 PR:

https://github.com/dotnet/runtime/pull/114644


   
    
   
namespace
 System;
/// <summary>Provides downlevel polyfills for static methods on Exception-derived types.</summary>

internal
 static class ExceptionPolyfills
{
    extension(ArgumentNullException)
    {
        public static void ThrowIfNull([NotNull] object? argument, [CallerArgumentExpression(nameof(argument))] string? paramName = null)
        {
            if
 (argument is null)
            {
                ThrowArgumentNullException(paramName);
            }
        }
    }

    [DoesNotReturn]
    private static void ThrowArgumentNullException(string? paramName) =>
        throw
 new ArgumentNullException(paramName);
}

ThrowHelper 也就不需要了


`ThrowHelper`

`exception extension 1`

`Exception extension 2`

使用这种方式之后我们去做一些低版本框架的 polyfill 的时候就会更简单更高效,如果你也有针对低版本框架的类库型应用也可以尝试以下新的扩展方式来简化一些代码~~

References

  • • https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-14#extension-members
  • • https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/extension?WT.mc_id=DT-MVP-5004222
  • • https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/extension-methods?WT.mc_id=DT-MVP-5004222
  • • https://github.com/dotnet/runtime/pull/114644
  • C# 14 Extensions 来了

 

【声明】内容源于网络
0
0
amazingdotnet
dotnet 开发知识库,了不起的 dotnet,dotnet 奇淫怪巧
内容 539
粉丝 0
amazingdotnet dotnet 开发知识库,了不起的 dotnet,dotnet 奇淫怪巧
总阅读240
粉丝0
内容539