如何在c#中将两个参数作为一个参数发送?

时间:2013-05-06 10:13:52

标签: c# parameters tuples

我的问题在于我有一个采用可变数量参数的方法。

这些参数中的每一个都是一个对象,真正的问题在于,为该方法中的每个参数编写new ClassName(p1, p2)都会非常冗长。

有没有办法以p1p2的形式将{p1, p2}(p1, p2)作为单个参数发送?

这样我就可以写Insert(("John", "Doe"), ("Sherlock", "Holmes"), ... etc)然后将这些内容传递给方法本身的新闻,而不是写Insert(new Person("John", "Doe"), new Person("Sherlock", "Holmes"), ... etc)

我知道F#中的元组和scala可以这样做,但在C#中使用元组只会使代码更长

有没有办法让它不那么冗长?

编辑:我不打算改为创建新数组或新列表 我想尽可能避免使用新关键字

Edit2:有些人要求查看我的Insert方法是什么样的;目前它看起来像这样:

public void Insert(params Person[] arr)
{
    //inserts the person in a hash table
    Action<Person> insert = (person) => _table[hasher(person.Name)].Add(person);

    // calls the insert function/action for each person in the parameter array
    Array.ForEach(arr, insert);
}

5 个答案:

答案 0 :(得分:5)

您可以创建一个支持初始化程序语法的集合,并将其作为方法的参数提供。这将允许以下内容:

void Main()
{
    SomeMethod(new PersonCollection{{1, 2}, {3, 4}, {5, 6}});
}
void SomeMethod(PersonCollection pc)
{
}

//...
class Person
{
    public Person(int a, int b)
    {
    }
}
class PersonCollection:IEnumerable
{
    IList<Person> personList = new List<Person>();
    public void Add(int a, int b)
    {
        personList.Add(new Person(a,b));
    }

    public IEnumerator GetEnumerator()
    {
        return personList.GetEnumerator();
    }
}

支持此类构造所需的所有内容都是合适的void Add方法并实现IEnumerable

答案 1 :(得分:1)

在C#中除了类和结构之外没有办法进行分组。如果您对简洁代码的要求超出常识,则可以使用“逻辑”方法。调用方法如下:

Insert("John", "Doe", "Sherlock", "Holmes")

并像这样处理:

    void Insert(params string[] names)
    {
        if (names.Length % 2 != 0) throw new ArgumentException();

        for (int i = 0; i < names.Length; i += 2)
        {
            string name = names[i];

            string surname = names[i + 1];

            // use it
        }
    }

答案 2 :(得分:1)

您可以编写辅助方法来处理样板代码。因此,假设想要传递使用2个参数初始化的多个ClassName实例,您可以编写如下内容:

public ClassName[] CreateClassNames(string[,] list)
{
     List<ClassName> result = new List<ClassName>()
     for ( int i = 0 ; i < list.GetLength(0); i++ )
     {
        result.Add(new ClassName(list[i][0], list[i][1]));
     }
     return result.ToArray();
}

然后调用您的Insert方法:

Insert(CreateClassNames(new string[]{{"John", "Doe"}, {"Sherlock", "Holmes"}}))

编辑:将参数更改为2维数组,以便对字符串进行分组。仍然不完美,但更好。

答案 3 :(得分:1)

看哪!我创造了一个怪物!

它可以让你编写这样的代码:

Insert(new People()["John", "Doe"]["Sherlock", "Holmes"]["Fred", "Flintsone"]);

但实际上,这是令人厌恶的不是吗?

using System;
using System.Collections.Generic;

namespace Demo
{
    class Program
    {
        static void Main()
        {
            new Program().test();
        }

        void test()
        {
            Insert(new People()["John", "Doe"]["Sherlock", "Holmes"]["Fred", "Flintsone"]);
        }

        public void Insert(params Person[] persons)
        {
            foreach (var person in persons)
            {
                Console.WriteLine(person);
            }
        }
    }

    public class People
    {
        public static implicit operator Person[](People people)
        {
            return people.people.ToArray();
        }

        public People this[string firstName, string lastName]
        {
            get
            {
                people.Add(new Person(firstName, lastName));
                return this;
            }
        }

        private readonly List<Person> people = new List<Person>();
    }

    public class Person
    {
        public Person(string firstName, string lastName)
        {
            FirstName = firstName;
            LastName = lastName;
        }

        public override string ToString()
        {
            return FirstName + " " + LastName;
        }

        public readonly string FirstName, LastName;
    }
}

答案 4 :(得分:-1)

请使用字典作为参数。