2

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

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

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

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

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

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

编辑:我不想创建新数组或新列表,而是想尽可能避免使用 new 关键字

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);
}
4

5 回答 5

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.

于 2013-05-06T10:25:28.310 回答
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;
    }
}
于 2013-05-06T11:02:31.100 回答
1

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

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"}}))

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

于 2013-05-06T10:30:12.307 回答
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
        }
    }
于 2013-05-06T10:23:58.163 回答
-1

请使用字典作为参数。

于 2019-09-26T07:21:23.160 回答