Создать экземпляр универсального типа?

Так что я до сих пор не уверен, что значило обновление до Gulp 4.0 с точки зрения того, как обрабатывается glob-parent / glob-base, однако мне удалось получить то, что мне было нужно, используя опцию base.

Эта опция фактически аннулировала дополнительную жестко закодированную ссылку пути src перед / ** / в пути.

function other() {

var fileFilter = plugins.filter(function(file) {
    return file.stat.isFile();
});

var appFilter = plugins.filter(function(file) {
    return file.path.indexOf("\\src\\app\\") === -1;
});

return src(path.join(conf.paths.src, "/**/*"), { base: conf.paths.src })
    .pipe(appFilter)
    .pipe(fileFilter)
    .pipe(dest(conf.paths.dist));
}
212
задан Recep 26 May 2015 в 02:42
поделиться

5 ответов

Кроме того, более простой пример:

return (T)Activator.CreateInstance(typeof(T), new object[] { weight });

Обратите внимание, что использование ограничения new () для T предназначено только для компиляции проверяйте общедоступный беспараметрический конструктор во время компиляции, фактический код, используемый для создания типа, является классом Activator.

Вы должны будете убедиться в том, что конкретный существующий конструктор существует, и этим требованием может быть запах кода (или скорее то, чего вам следует избегать в текущей версии на c #).

306
ответ дан Jason Evans 23 November 2019 в 04:30
поделиться

Вы не можете использовать какой-либо параметризованный конструктор. Вы можете использовать конструктор без параметров, если у вас есть ограничение « где T: new () ».

Это боль, но такова жизнь: (

Это одна из вещей, которую я ' Я хотел бы обратиться к «статическим интерфейсам» . Затем вы сможете ограничить T включением статических методов, операторов и конструкторов, а затем вызывать их.

90
ответ дан shA.t 23 November 2019 в 04:30
поделиться

Как указал Джон, это жизнь для ограничения беспараметрического конструктора. Однако другое решение заключается в использовании заводского шаблона. Это легко ограничить.

interface IFruitFactory<T> where T : BaseFruit {
  T Create(int weight);
}

public void AddFruit<T>( IFruitFactory<T> factory ) where T: BaseFruit {    
  BaseFruit fruit = factory.Create(weight); /*new Apple(150);*/    
  fruit.Enlist(fruitManager);
}

Еще один вариант - использовать функциональный подход. Передайте фабричный метод.

public void AddFruit<T>(Func<int,T> factoryDel) where T : BaseFruit { 
  BaseFruit fruit = factoryDel(weight); /* new Apple(150); */
  fruit.Enlist(fruitManager);
}
17
ответ дан JaredPar 23 November 2019 в 04:30
поделиться

Да; измените ваше местоположение:

where T:BaseFruit, new()

Однако, это работает только с безпараметрическими конструкторами. У вас должны быть другие способы настройки вашего свойства (настройка самого свойства или чего-то подобного).

это работает только с беспараметрическими конструкторами. У вас должны быть другие способы настройки вашего свойства (настройка самого свойства или чего-то подобного).

это работает только с беспараметрическими конструкторами. У вас должны быть другие способы настройки вашего свойства (настройка самого свойства или чего-то подобного).

54
ответ дан Roman Marusyk 23 November 2019 в 04:30
поделиться

Вы можете сделать это с помощью отражения:

public void AddFruit<T>()where T: BaseFruit
{
  ConstructorInfo constructor = typeof(T).GetConstructor(new Type[] { typeof(int) });
  if (constructor == null)
  {
    throw new InvalidOperationException("Type " + typeof(T).Name + " does not contain an appropriate constructor");
  }
  BaseFruit fruit = constructor.Invoke(new object[] { (int)150 }) as BaseFruit;
  fruit.Enlist(fruitManager);
}

РЕДАКТИРОВАТЬ: Добавлен конструктор == проверка нуля.

РЕДАКТИРОВАТЬ: Более быстрый вариант с использованием кэша:

public void AddFruit<T>()where T: BaseFruit
{
  var constructor = FruitCompany<T>.constructor;
  if (constructor == null)
  {
    throw new InvalidOperationException("Type " + typeof(T).Name + " does not contain an appropriate constructor");
  }
  var fruit = constructor.Invoke(new object[] { (int)150 }) as BaseFruit;
  fruit.Enlist(fruitManager);
}
private static class FruitCompany<T>
{
  public static readonly ConstructorInfo constructor = typeof(T).GetConstructor(new Type[] { typeof(int) });
}
11
ответ дан mmmmmmmm 23 November 2019 в 04:30
поделиться
Другие вопросы по тегам:

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