C# несколько аргументов в одном для Иссякания передачи параметров

Я не знаю, возможно ли это, но в некоторых моих модульных тестах, я заканчиваю тем, что инициализировал различные объекты с теми же аргументами. Я хотел бы смочь сохранить те аргументы в некоторой переменной и просто инициализировать конструктора мультиобъекта параметра с той переменной так вместо выполнения:

Thing thing1 = new Thing(arg1, arg2, arg3, arg4);
Thing thing2 = new Thing(arg1, arg2, arg3, arg4);
Thing thing3 = new Thing(arg1, arg2, arg3, arg4);

Я мог сделать следующее:

MagicalArgumentsContainer args = (arg1, arg2, arg3, arg4);
Thing thing1 = new Thing(args);
Thing thing2 = new Thing(args);
Thing thing3 = new Thing(args);

Есть ли любой способ сделать это без переопределения Thingконструктор для взятия списка, из которого это вручную взрывает и щипает аргументы? Возможно, немного синтаксического сахара C#?

8
задан Sarah Vessels 11 January 2010 в 21:08
поделиться

6 ответов

Я имею в виду, есть это:

Func<Thing> f = () => new Thing(arg1, arg2, arg3, arg4);
Thing thing1 = f();
Thing thing2 = f();
Thing thing3 = f();
Thing thing4 = f();

просто осторожны в семантике закрытия .

13
ответ дан 5 December 2019 в 08:24
поделиться

Я бы предложил посмотреть в тестовый построитель данных . Он работает очень хорошо, когда у вас есть много параметров, которые вы хотите варьироваться независимо, повторно использовать и так далее.

Вы можете использовать Свойства + инициализаторы объекта для «плоских» классов или метод жидкости в качестве альтернативы. Я играл с обоими, и у каждого есть свои преимущества.

Преимущества:

  • Вы можете захватить переменные / значения которые использовались для построения объекта
  • , вы можете повторно использовать экземпляр построителя, если Значения, которые требуется простые типы и / или неизменные (типы значений, Струны и т. Д.)
  • Вы можете варьироваться каждый CTOR Параметр самостоятельно без шума / Дублирование кода Это делает тесты читать действительно хорошо, как, вместо Чтобы помнить, какой CTOR PARAL это что, вы видите имя.

Если вам нужно создать новые экземпляры каждого параметра, проверьте ответ Бангкера.

Во всяком случае, вот какой-то код:

public class ThingBuilder
{
   // set up defaults so that we don't need to set them unless required
   private string m_bongoName = "some name";
   private DateTime m_dateTime = new DateTime(2001, 1, 1);
   private int m_anotherArg = 5;
   private bool m_isThisIsGettingTedious = true;

   public ThingBuilder BongoName(string bongoName)
   {
      m_bongoName = bongoName;
      return this;
   }

   public ThingBuilder DateTime(DateTime dateTime)
   {
      m_dateTime = dateTime;
      return this;     
   }

   // etc. for properties 3...N

   public Thing Build()
   {    
      return new Thing(m_bongoName, m_dateTime, m_anotherArg, m_isThisGettingTedious);
   }
}

Использование (однажды экземпляр):

// notice that the parameters are now explicitly named + readable!
Thingy builtInstance = new ThingBuilder()
                           .BongoName("um bongo")
                           .DateTime(DateTime.Now)
                           .GettingTedious(true)
                           .Build();

Несколько экземпляров:

var builder = new ThingBuilder()
                  .BongoName("um bongo")
                  .DateTime(DateTime.Now)
                  .GettingTedious(true);

// let's make multiple objects
Thing builtThing = builder.Build();
Thing anotherBuiltThing = builder.Build();
1
ответ дан 5 December 2019 в 08:24
поделиться

Вы могли бы переписать Thimiting к чему-то вроде Thimiting <11> , используя немного универсальных?

public class MagicalArgumentsContainer
    {
            object[] _myParams;

            public MagicalArgumentsContainer (params object[] myParams)
            {
            _myParams = myParams;
            }

            public Thing GimmieAThing()
            {
    return new Thing(_myParams[0], _myParams[1], _myParams[2], _myParams[3]);
        }
    }
1
ответ дан 5 December 2019 в 08:24
поделиться

Ну, я думаю, вы можете использовать контейнер IOC, поскольку несколько из этого также предлагают объектную продукцию, то есть вы сообщете IOC, как сделать новый экземпляр типа T, а затем вы просто задаете IOC, чтобы дать вам экземпляр Отказ

Однако, если вы не хотите получить IOC, вы можете сделать себя небольшим заводским классом

public MagicFactory
{
   T arg1, T2 arg2,  T3 arg3,.., TN argN;

   public MagicFactory(T1 a1,..., TN aN)
   {
      this.arg1=a1;
       ...
      this.argN = an;
   }

   public Thing GimmeDaThing()
   {
      return new Thing(this.arg1,...,this.argN);
   }
}

, однако имейте в виду, что если аргументы не имеют значения значений, то все ваши экземпляры вещь У вас будут ссылки на те же объекты, поэтому, хотя у вас есть разные случаи вещей, все они будут указывать на то же ARG1. То, что вы могли бы сделать, чтобы исправить, это фактически принимать в функции в параметре, поэтому вы действительно можете создать новый:

public MagicFactory
{
   Func<T1> arg1, ,.., Func<TN> argN;

   public MagicFactory(Func<T1> a1,..., Func<TN> aN)
   {
      this.arg1=a1;
       ...
      this.argN = an;
   }

   public Thing GimmeDaThing()
   {
      return new Thing(this.arg1(),...,this.argN());
   }
}

, и вы бы назвали так:

var magicContainer = new MagicFactory(()=> new T1(...),..., ()=>new T2(..);


var thing1 = magicContainer.GimmeDaThing();
var thing1 = magicContainer.GimmeDaThing();
var thing1 = magicContainer.GimmeDaThing();
var thing1 = magicContainer.GimmeDaThing();

, и вы получите новый экземпляр вещей Каждый раз каждый со своими собственными объектами собственности.

3
ответ дан 5 December 2019 в 08:24
поделиться

Если ваш класс действительно такой большой, то звучит так, будто вы должны разбивать вспомогательные объекты , а не только вспомогательные методы (хотя извлечение методов часто является шагом на этом пути). После того, как вы сделали это, ваш старый класс становится проще и проще для тестирования (возможно, с издевками, возможно, нет), и вы можете проверить методы на новых вспомогательных классов непосредственно.

Я предпочитаю проверять объект через открытый API. Если это слишком сложно, то это намек на то, что объект должен быть разбит.

-121--2596291-

Это также, предполагая, что ваш Thing1 является тривиальным объектом, и вам просто нужна неглубокая копия:

Thing thing1 = new Thing(arg1, arg2, arg3, arg4);
Thing thing2 = (Thing)thing1.MemberwiseClone();
-121--3572510-

Вы также можете использовать массив объектов и цикл for, если вам нужно сделать это много раз.

0
ответ дан 5 December 2019 в 08:24
поделиться

Также есть это, предполагая, что ваша вещь1 является тривиальным объектом, и вам просто нужна неглубокая копия:

Thing thing1 = new Thing(arg1, arg2, arg3, arg4);
Thing thing2 = (Thing)thing1.MemberwiseClone();
1
ответ дан 5 December 2019 в 08:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: