Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 函数获取c中任意类型的数组#_C#_Arrays_Object_Types - Fatal编程技术网

C# 函数获取c中任意类型的数组#

C# 函数获取c中任意类型的数组#,c#,arrays,object,types,C#,Arrays,Object,Types,我制作了一个处理对象数组的函数,process(Object[])。它适用于任何类型,包括整数和浮点数,只要您先将每个元素装箱。我希望该函数也可以接受未绑定的元素,如果只是在处理之前将其自身装箱的话。我该怎么做 我可以用一些函数包装,比如process(int[])和process(float[]),但这似乎也很麻烦。我尝试了process(ValueType[]),但编译器仍然选择process(Object[]) 我有C#2.0,但如果有一个很好的3.0解决方案,我想看看。简短回答:你不能(

我制作了一个处理对象数组的函数,process(Object[])。它适用于任何类型,包括整数和浮点数,只要您先将每个元素装箱。我希望该函数也可以接受未绑定的元素,如果只是在处理之前将其自身装箱的话。我该怎么做

我可以用一些函数包装,比如process(int[])和process(float[]),但这似乎也很麻烦。我尝试了process(ValueType[]),但编译器仍然选择process(Object[])

我有C#2.0,但如果有一个很好的3.0解决方案,我想看看。

简短回答:你不能(有效地)这样做。泛型似乎是解决这一问题的一种方法,但一旦您实际使用泛型实例,您就会将其传递给必须接受类对象的方法-因此它将被装箱(更糟的是,可能会被装箱多次,具体取决于您的代码)


如果希望通过避免常规装箱来获得性能,则需要研究如何处理这些实例,并确保所有处理都可以以类型安全的方式进行,尽管采用了常规方法,但这并不容易(例如,请参见),并且在很大程度上取决于需要执行的处理。

装箱是隐式的。例如:

 static void T(Array a)
    {
        if (a is int[])
            Console.WriteLine("Int");
        else
            if (a is float[])
                Console.WriteLine("Float");
            else
                ....

    }
    static void Main(){
        T(new int[]{30});
        float[] a = { 11 };
        T(a);
    }
using System;

namespace MyProg
{
  class Program
  {

    private static void ParamTest(params object[] args)
    {
      foreach (object o in args)
      {
        Console.Write(o);
        Console.WriteLine(", ");
      }
      Console.WriteLine();
    }

    static void Main(string[] args)
    {
      ParamTest(1, "abc", 2.4, new object());
    }
  }
}
将打印

1, abc, 2.4, System.Object, 1. 美国广播公司, 2.4, 系统对象,,
看不到通用的

处理是如何工作的?最明显的方法签名是:

void ProcessArray<T>(T[] data)
void ProcessArray(T[]数据)
这就是字面上的“任意类型的数组”——尽管调用者需要在编译时知道该类型

但是,根据您使用元素的方式,最终可能还是会装箱。也许这没关系,因为你的问题中有一部分是这样的:“如果只是在处理之前把它自己装箱就好了”。如果你对此感到满意,那太好了:)


如果您能提供您所做工作的更多细节,我们可能会提供更多帮助。

好吧,从技术上讲,这是可能的。但由于明显的原因,它不被推荐,也没有用处。请注意,它的性能也很差,不允许直接传递数组

出于好奇和古怪的缘故,这里有个窍门。它使用
TypedReference
和未记录的C#关键字

public void Process(__arglist)
{
    var iterator = new ArgIterator(__arglist);
    do
    {
        TypedReference typedReference = iterator.GetNextArg();
        Type type = __reftype(typedReference);
        if (type == typeof(int))
        {
            int value = __refvalue( typedReference,int);
            // value is an int
        }
        else if (type == typeof(string))
        {
            string value = __refvalue( typedReference,string);
            // value is a string
        }
        else if (type == typeof(double))
        {
            double value = __refvalue( typedReference,double);
            // value is a double
        }
        // etc.
    }
    while (iterator.GetRemainingCount() > 0);
}
您可以这样调用该方法:

Process(__arglist(45, "lol", 42.5));

它将框/取消框值类型。但是,好吧,忘了…

这比OP已经拥有的没有装箱的方法T无法访问数组元素好不了多少。(为了避免混淆,我不会将T的名称用于一个用于许多类型的方法-通常用作泛型类型参数).net中的数组是System.Array的类型。OP对数组有误解。您是出于语法原因还是出于性能原因而试图避免装箱?为了回答这个问题,我们确实需要知道您为什么喜欢这样做(更详细)。如果你只是想要一个单一功能的便利,那么Jon下面的答案就行了。如果您担心装箱的开销,那么,正如我的回答所说,您可能还需要在方法体上做一些工作,因为将装箱移动到方法体内部并不是一个自动的性能胜利。但是您不能传递一个已经是
float[]
的数组。例如,但问题是关于非固定元素的——我认为这通常意味着标量类型。@Vinjay:我不确定你的意思。OP谈论为
int[]
float[]
添加重载的事实表明,他希望能够接受这种值……也许他会接受——让我们等待他的消息。我只是说我是如何解释这个问题的;大家都知道我错了;-)问题明确地说,他不一定介意在方法中使用拳击。您可以有效地使方法接受任何数组(使用
array
或泛型方法),而不必创建包含装箱副本的
object[]
类型的新数组。这可能在方便性和性能方面都有好处——一次只有一个“活动”装箱值很可能意味着它们只能在gen0中生存,而事先装箱整个数组可能最终会将它们推到gen1中。这是可能的,尽管不太可能。没有看到代码,很难说。一般来说,如果性能是拳击发挥作用的一个问题,那么鼓励重复的、不必要的拳击和内部循环中的拆箱对我来说并不明智。在任何情况下,OP都需要一个更具体的问题。这里的快速测试(在每个数组元素上计算
intx(objecto){returno==null?0:o.GetHashCode();}
)会导致int[]数组所用的时间略少于包含装箱整数的object[]数组的两倍。在基准测试中包含GC.Collect会增加总体计时,但object[]数组的速度更快。当然,“预装箱”数组的峰值内存消耗更高……相比之下,仅处理int[]数组的非泛型方法(避免
o==null
check)所需时间约为一半。我不知道int.GetHashCode的性能——尽管您可能会认为它的速度快得惊人。