gpt4 book ai didi

c# - 为扩展方法创建特定于硬件的委托(delegate)

转载 作者:行者123 更新时间:2023-11-30 17:26:41 24 4
gpt4 key购买 nike

我正在为原始数值数组编写一个扩展方法库。扩展方法有常规版本和硬件加速版本。我正在尝试使用委托(delegate),以便每个方法都有一个入口点。例如,考虑一个对数组求和的简单扩展方法:

public static class ArrayExtensions
{

#region Data Members

private delegate TResult SumArrayDelegate<in TIn, out TResult>( TIn[] array );
private static SumArrayDelegate<sbyte,int> SumArraySByte_;
private static SumArrayDelegate<byte,int> SumArrayByte_;
private static SumArrayDelegate<short,int> SumArrayShort_;
private static SumArrayDelegate<ushort,int> SumArrayUShort_;
private static SumArrayDelegate<int,int> SumArrayInt32_;
private static SumArrayDelegate<uint,uint> SumArrayUInt32_;
private static SumArrayDelegate<long,long> SumArrayInt64_;
private static SumArrayDelegate<ulong,ulong> SumArrayUInt64_;
private static SumArrayDelegate<float,float> SumArrayFloat_;
private static SumArrayDelegate<double,double> SumArrayDouble_;


#endregion

#region Constructor

static ArrayExtensions()
{
if( Avx2.IsSupported )
{
SumArraySByte_ = Avx2Utilities.Sum;
SumArrayByte_ = Avx2Utilities.Sum;
SumArrayShort_ = Avx2Utilities.Sum;
SumArrayUShort_ = Avx2Utilities.Sum;
SumArrayInt32_ = Avx2Utilities.Sum;
SumArrayUInt32_ = Avx2Utilities.Sum;
SumArrayInt64_ = Avx2Utilities.Sum;
SumArrayUInt64_ = Avx2Utilities.Sum;
SumArrayFloat_ = Avx2Utilities.Sum;
SumArrayDouble_ = Avx2Utilities.Sum;
}
else if( Avx.IsSupported )
{
SumArraySByte_ = AvxUtilities.Sum;
SumArrayByte_ = AvxUtilities.Sum;
SumArrayShort_ = AvxUtilities.Sum;
SumArrayUShort_ = AvxUtilities.Sum;
SumArrayInt32_ = AvxUtilities.Sum;
SumArrayUInt32_ = AvxUtilities.Sum;
SumArrayInt64_ = AvxUtilities.Sum;
SumArrayUInt64_ = AvxUtilities.Sum;
SumArrayFloat_ = AvxUtilities.Sum;
SumArrayDouble_ = AvxUtilities.Sum;
}
else
{
SumArraySByte_ = ArrayUtilities.Sum;
SumArrayByte_ = ArrayUtilities.Sum;
SumArrayShort_ = ArrayUtilities.Sum;
SumArrayUShort_ = ArrayUtilities.Sum;
SumArrayInt32_ = ArrayUtilities.Sum;
SumArrayUInt32_ = ArrayUtilities.Sum;
SumArrayInt64_ = ArrayUtilities.Sum;
SumArrayUInt64_ = ArrayUtilities.Sum;
SumArrayFloat_ = ArrayUtilities.Sum;
SumArrayDouble_ = ArrayUtilities.Sum;
}
}

#endregion

public static int Sum( this sbyte[] array ) => SumArraySByte_( array );
public static int Sum( this byte[] array ) => SumArrayByte_( array );
public static int Sum( this short[] array ) => SumArrayShort_( array );
public static int Sum( this ushort[] array ) => SumArrayUShort_( array );
public static int Sum( this int[] array ) => SumArrayInt32_( array );
public static uint Sum( this uint[] array ) => SumArrayUInt32_( array );
public static long Sum( this long[] array ) => SumArrayInt64_( array );
public static ulong Sum( this ulong[] array ) => SumArrayUInt64_( array );
public static float Sum( this float[] array ) => SumArrayFloat_( array );
public static double Sum( this double[] array ) => SumArrayDouble_( array );

}

这看起来非常丑陋、多余,并且违反了 DRY 原则。这只是我正在实现的数十种方法中的一种,继续当前的模式将产生大量的 ArrayExtensions 类。

有没有不需要明确定义的方法来解决这个问题?或者更确切地说,有没有办法使它成为通用的,但仅限于受支持的类型?扩展方法将仅适用于上述代码中存在的类型。

最佳答案

您可以使用继承来稍微简化一下。这将消除其中的大部分。

作为额外奖励,虚拟调用比委托(delegate)调用稍快。使用抽象基类而不是接口(interface)来提高性能。

这样做的一个缺点是,您在选择要使用的各个方法时灵 active 较低。

作为替代方案,您可以考虑使用 T4 模板生成此死记硬背的 C# 代码。它们很好地集成到 IDE 中。

另一种可能是反射。这不会消除所有这些,但会消除一些。

关于c# - 为扩展方法创建特定于硬件的委托(delegate),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55961472/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com