通用参数的动态长度

本文关键字:动态 参数 | 更新日期: 2023-09-27 18:17:17

我编写了一个方法,该方法获取对象数组,数组内容的类型为泛型,并尝试将每种类型强制转换为交付的泛型:

    public static void GetMultipleObjectsFromParameters<T, U>(
        object parameterArray, out T parameter1, out U parameter2)
    {
        parameter1 = default(T);
        parameter2 = default(U);
        try
        {
            object[] arr = parameterArray as object[];
            if (arr == null)
            {
                Debug.WriteLine("array not valid");
                return;
            }
            if (arr.Length != 2)
            {
                Debug.WriteLine("arr.Length != 2");
                return;
            }
            parameter1 = (T)arr[0];
            parameter2 = (U)arr[1];
        }
        catch (Exception ex)
        {
            Debug.Write(ex);
        }
    }

我认为这个方法可能是非常有用的,如果我使用BackgroundWorker,并希望提供不同类型的多个参数(例如,第一个参数为字符串,第二个为整数…)。

现在我想知道是否有一种方法来编写这个方法而不强制固定大小的参数。这将防止我为每个参数计数编写这样的方法。

我希望这个问题是可以理解的。有没有简单的方法?谢谢你的帮助。

通用参数的动态长度

编辑:这个答案针对的是最初的问题,而不是背后的动机。在将工作传递给BackgroundWorker等方面,使用lambda表达式是完全有意义的。

现在我想知道是否有一种方法来编写这个方法而不强制固定大小的参数。

不,恐怕不行。你正在寻找的是高阶类型,我认为1 -但它们在。net中不存在(这就是为什么Func<>, Tuple<>, Action<>等有如此多的"泛型性重载")。


1老实说,我自己对这些事情了解不多。Joe Duffy有一篇博客文章让我有些震惊,但可能很有用。

是否有一种方法可以在不强制参数固定大小的情况下编写此方法

你不需要用可变大小的参数来编写这个方法。你需要Tuple:

        var myParams = Tuple.Create(100, "Hello, world!");
        var worker = new BackgroundWorker();
        worker.DoWork += (sender, args) =>
        {
            var arg = (Tuple<int, string>)args.Argument;
            if (arg.Item2.Length > 5)
            {
                var foo = arg.Item1 + 200;
            }
            // etc ...
        };
        worker.RunWorkerAsync(myParams);

或带闭包的lambdas:

        var someIntParam = 100;
        var someStringParam = "Hello, world!";
        var worker = new BackgroundWorker();
        worker.DoWork += (sender, args) =>
        {
            if (someStringParam.Length > 5)
            {
                var foo = someIntParam + 200;
            }
            // etc ...
        };
        worker.RunWorkerAsync();

这取决于你在实际代码中如何使用BackgroundWorker