Метод-цепочка в С#

Я действительно не знаю, как это называется на С#. Но я хочу добавить функциональность в свой класс, чтобы добавить несколько элементов одновременно.

myObj.AddItem(mItem).AddItem(mItem2).AddItem(mItem3);

Ответ 1

Указанная техника называется цепными методами. Он обычно используется при создании DSL или плавных интерфейсов на С#.

Типичный шаблон заключается в том, чтобы ваш метод AddItem() возвращал экземпляр класса (или интерфейса), частью которого он является. Это позволяет привязывать последующие вызовы к ней.

public MyCollection AddItem( MyItem item )
{
   // internal logic...

   return this;
}

Некоторые альтернативы цепочке методов для добавления элементов в коллекцию включают:

Использование синтаксиса params, чтобы позволить нескольким элементам передаваться вашему методу в виде массива. Полезно, если вы хотите скрыть создание массива и предоставить синтаксис переменных аргументов вашим методам:

public void AddItems( params MyItem[] items )
{
    foreach( var item in items )
        m_innerCollection.Add( item );
}

// can be called with any number of arguments...
coll.AddItems( first, second, third );
coll.AddItems( first, second, third, fourth, fifth );

Предоставление перегрузки типа IEnumerable или IEnumerable, чтобы несколько элементов могли быть переданы вместе с вашим классом коллекции.

public void AddItems( IEnumerable<MyClass> items )
{
    foreach( var item in items )
         m_innerCollection.Add( item );
}

Используйте синтаксис инициализатора коллекции .NET 3.5. Класс должен предоставить единственный параметр Add( item ), реализовать IEnumerable и должен иметь конструктор по умолчанию (или вы должны вызвать конкретный конструктор в инструкции инициализации). Затем вы можете написать:

var myColl = new MyCollection { first, second, third, ... };

Ответ 2

Используйте этот трюк:

public class MyClass
{
    private List<MyItem> _Items = new List<MyItem> ();

    public MyClass AddItem (MyItem item)
    {
        // Add the object
        if (item != null)
            _Items.Add (item)

        return this;
    }
}

Он возвращает текущий экземпляр, который позволит вам цеплять вызовы методов (таким образом, одновременно добавляя несколько объектов).

Ответ 3

"На самом деле я понятия не имею, что это называется в С#"

Свободный API; StringBuilder является наиболее распространенным примером .NET:

var sb = new StringBuilder();
string s = sb.Append("this").Append(' ').Append("is a ").Append("silly way to")
     .AppendLine("append strings").ToString();

Ответ 4

Другие ответили в терминах прямой цепочки методов, но если вы используете С# 3.0, вам могут быть интересны инициализаторы коллекции... они доступны только при вызове конструктора, и только если ваш метод имеет соответствующие Add и реализует IEnumerable, но тогда вы можете сделать:

MyClass myClass = new MyClass { item1, item2, item3 };

Ответ 5

Почему вы не используете ключевое слово params?

public void AddItem (params MyClass[] object)
{
    // Add the multiple items
}

Ответ 6

Как насчет

AddItem(ICollection<Item> items);

или

AddItem(params Item[] items);

Вы можете использовать их как это

myObj.AddItem(new Item[] { item1, item2, item3 });
myObj.AddItem(item1, item2, item3);

Это не цепочка методов, но добавляет несколько элементов к вашему объекту за один вызов.

Ответ 7

Вы можете добавить метод расширения для поддержки этого, если ваш класс наследуется от ICollection:

[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void CanChainStrings()
    {
        ICollection<string> strings = new List<string>();

        strings.AddItem("Another").AddItem("String");

        Assert.AreEqual(2, strings.Count);
    }
}
public static class ChainAdd
{
    public static ICollection<T> AddItem<T>(this ICollection<T> collection, T item)
    {
        collection.Add(item);
        return collection;
    }
}

Ответ 8

Если ваш элемент действует как список, вы можете реализовать интерфейс, такой как iList или iEnumerable/iEnumerable.

Независимо от того, ключ к цепочке вызовов, как вы хотите, возвращает желаемый объект.

public Class Foo
{
   public Foo AddItem(Foo object)
   {
        //Add object to your collection internally
        return this;
   }
}

Ответ 9

Что-то вроде этого?

class MyCollection
{
    public MyCollection AddItem(Object item)
    {
        // do stuff
        return this;
    }
}