C# 有可能专门化泛型吗

C# 有可能专门化泛型吗,c#,generics,casting,C#,Generics,Casting,我有一个通用的转换器类 public class Converter { public static TargetType[] Convert<SourceType, TargetType>(SourceType[] data) where SourceType : struct where TargetType : struct { int N = data.Length;

我有一个通用的转换器类

public class Converter
{
       public static TargetType[] Convert<SourceType, TargetType>(SourceType[] data)
            where SourceType : struct
            where TargetType : struct
        {
            int N = data.Length;
            TargetType[] result = new TargetType[N];

            for (int i = 0; i < N; i++)
            {
                // We does this not work, what can I do else
                result[i] = (TargetType)data[i];
            }

            return result;
        }
}
公共类转换器
{
公共静态TargetType[]转换(SourceType[]数据)
其中SourceType:struct
其中TargetType:struct
{
int N=数据长度;
TargetType[]结果=新的TargetType[N];
对于(int i=0;i
问题1:为什么不可能做演员?我还能做什么?Convert.ChangeType将变慢

由于总体性能低下,我决定使用不安全的代码。不幸的是,不可能创建指向泛型的指针——众所周知。出于这个原因,我创建了一个转换器,它在运行时决定类型,并使用大量if执行强制转换

没有人提出问题。我是否可以创建一个通用转换例程并以某种方式对其进行专门化,在某些情况下,我已经定义了数据类型。我现在不知道怎么做,但也许我读过这个例子,你会得到一个线索:

public static double[] Convert<double, int>(int[] data)
        {
            int N = data.Length;
            double[] result = new double[N];

            unsafe
            {
                fixed (int* data_pinned = data)
                fixed (double* out_pinned = result)
                {
                    int* A = data_pinned;
                    double* B = out_pinned;

                    for (int i = 0; i < N; i++, A++, B++)
                    {
                        *B = ((double)*A);
                    }
                }
            }

            return result;
        }
公共静态双[]转换(int[]数据)
{
int N=数据长度;
双精度[]结果=新双精度[N];
不安全的
{
固定(int*data\u=data)
固定(双*外固定=结果)
{
int*A=数据_;
double*B=外销;
对于(int i=0;i
您可以在下面找到一个“小型”演示项目,其中显示了不同类型转换的性能值:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace ConsoleApplication1
{
    public static class CastTest
    {
        public static unsafe double[] Cast1(int[] input)
        {
            int N = input.Length;
            double[] output = new double[N];

            for (int i = 0; i < N; i++) output[i] = (double)(input[i]);

            return output;
        }

        public static unsafe double[] Cast2(int[] input)
        {
            int N = input.Length;
            double[] output = new double[N];

            fixed (double* output_pinned = output)
            {
                double* outp = output_pinned;

                fixed (int* input_pinned = input)
                {
                    int* inp = input_pinned;

                    for (int i = 0; i < N; i++, inp++, outp++) *outp = (double)(*inp);
                }

                return output;
            }
        }

        public static unsafe double[] Cast3(int[] input)
        {
            int N = input.Length;
            double[] output = new double[N];

            fixed (double* output_pinned = output)
            {
                double* outp = output_pinned;

                fixed (int* input_pinned = input)
                {
                    int* inp = input_pinned;

                    for (int i = 0; i < N; i++) outp[i] = (double)(inp[i]);
                }

                return output;
            }
        }

        public static unsafe double[] Cast4(int[] input)
        {
            int N = input.Length;
            double[] output = new double[N];
            fixed (double* output_pinned = output)
            {
                fixed (int* input_pinned = input)
                {
                    for (int i = 0; i < N; i++) output_pinned[i] = (double)(input_pinned[i]);
                }
            }

            return output;
        }

        public static unsafe double[] Cast5(int[] input)
        {
            double[] output = new double[input.Length];

            for (int i = 0; i < input.Length; i++) output[i] = (input[i]);

            return output;
        }

        public static unsafe double[] Cast6(int[] input)
        {
            Converter<int, double> converter = (A) =>
                {
                    return A;
                };

            return Array.ConvertAll<int, double>(input, converter);
        }

        public static void StartTest()
        {
            int[] A = new int[100000];
            int N = 10000;

            var w1 = Stopwatch.StartNew();
            for (int i = 0; i < N; i++) { double[] A1 = Cast1(A); }
            w1.Stop();
            Console.WriteLine(String.Format("{0}: {1}ms", 1, w1.ElapsedMilliseconds));

            var w2 = Stopwatch.StartNew();
            for (int i = 0; i < N; i++) { double[] A2 = Cast2(A); }
            w2.Stop();
            Console.WriteLine(String.Format("{0}: {1}ms", 2, w2.ElapsedMilliseconds ));

            var w3 = Stopwatch.StartNew();
            for (int i = 0; i < N; i++) { double[] A3 = Cast3(A); }
            w3.Stop();
            Console.WriteLine(String.Format("{0}: {1}ms", 3, w3.ElapsedMilliseconds));

            var w4 = Stopwatch.StartNew();
            for (int i = 0; i < N; i++) { double[] A4 = Cast4(A); }
            w4.Stop();
            Console.WriteLine(String.Format("{0}: {1}ms", 4, w4.ElapsedMilliseconds));

            var w5 = Stopwatch.StartNew();
            for (int i = 0; i < N; i++) { double[] A5 = Cast5(A); }
            w5.Stop();
            Console.WriteLine(String.Format("{0}: {1}ms", 5, w5.ElapsedMilliseconds));

            var w6 = Stopwatch.StartNew();
            for (int i = 0; i < N; i++) { double[] A6 = Cast6(A); }
            w6.Stop();
            Console.WriteLine(String.Format("{0}: {1}ms", 6, w6.ElapsedMilliseconds));
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用系统诊断;
命名空间控制台应用程序1
{
公共静态类测试
{
公共静态不安全双[]Cast1(int[]输入)
{
int N=输入长度;
double[]输出=新的double[N];
对于(inti=0;i
{
返回A;
};
返回数组.ConvertAll(输入,转换器);
}
公共静态无效开始测试()
{
int[]A=新int[100000];
int N=10000;
var w1=秒表.StartNew();
对于(inti=0;i
我们非常感谢任何帮助来提高性能。 数组大小和重复的大小对我来说是真实的值。事实上,出于测试目的,这些值也比通常使用的值稍低

有可能吗
public static TTarget[] Convert<TSource, TTarget>(TSource[] data,
    Func<TSource, TTarget> conversion)
{
    TargetType[] result = new TargetType[data.Length];

    for (int i = 0; i < data.Length; i++)
    {
        result[i] = conversion(data[i]);
    }

    return result;
}