Так что я до сих пор не уверен, что значило обновление до 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));
}
Кроме того, более простой пример:
return (T)Activator.CreateInstance(typeof(T), new object[] { weight });
Обратите внимание, что использование ограничения new () для T предназначено только для компиляции проверяйте общедоступный беспараметрический конструктор во время компиляции, фактический код, используемый для создания типа, является классом Activator.
Вы должны будете убедиться в том, что конкретный существующий конструктор существует, и этим требованием может быть запах кода (или скорее то, чего вам следует избегать в текущей версии на c #).
Вы не можете использовать какой-либо параметризованный конструктор. Вы можете использовать конструктор без параметров, если у вас есть ограничение « где T: new ()
».
Это боль, но такова жизнь: (
Это одна из вещей, которую я ' Я хотел бы обратиться к «статическим интерфейсам» . Затем вы сможете ограничить T включением статических методов, операторов и конструкторов, а затем вызывать их.
Как указал Джон, это жизнь для ограничения беспараметрического конструктора. Однако другое решение заключается в использовании заводского шаблона. Это легко ограничить.
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);
}
Да; измените ваше местоположение:
where T:BaseFruit, new()
Однако, это работает только с безпараметрическими конструкторами. У вас должны быть другие способы настройки вашего свойства (настройка самого свойства или чего-то подобного).
это работает только с беспараметрическими конструкторами. У вас должны быть другие способы настройки вашего свойства (настройка самого свойства или чего-то подобного). это работает только с беспараметрическими конструкторами. У вас должны быть другие способы настройки вашего свойства (настройка самого свойства или чего-то подобного).Вы можете сделать это с помощью отражения:
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) });
}