Есть ли способ вернуть ссылку из функции без аргументов?
blockquote>Нет (кроме ссылок на статические значения, но здесь это не полезно).
Однако вы можете посмотреть
OpenOptions::create
. Если вы измените свою первую строку вmain
наlet f = OpenOptions::new().write(true).create(true).open(b"foo.txt");
, файл будет создан, если он еще не существует, что должно решить вашу исходную проблему.
C # не допускает отклонения от классов, только интерфейсы и делегаты, которые параметризуются ссылочными типами. Task<T>
является классом.
Это несколько неудачно, так как Task<T>
является одним из тех редких классов, которые могли [2] сделать безопасным ковариантным.
Однако достаточно легко преобразовать Task<Derived>
в Task<Base>
. Просто создайте вспомогательный метод / лямбда, который берет Task<Derived>
и возвращает Task<Base>
, ждет переданную задачу и возвращает значение, отличное от Base
. Компилятор C # позаботится об остальном. Конечно, вы теряете ссылочную идентификацию, но вы никогда не узнаете это с классом.
Кажется, что получил более чистый способ сделать это, но можно создать задачу упаковки правильного типа. Я ввел новую функцию под названием GeneralizeTask()
.
Task<TBase> GeneralizeTask<TBase, TDerived>(Task<TDerived> task)
where TDerived : TBase
{
var newTask = new Task<TBase>(() => {
if (task.Status == TaskStatus.Created) task.Start();
task.Wait();
return (TBase)task.Result;
});
return newTask;
}
Edit:
Как указывает @EricLippert, это может быть значительно упрощено. Сначала я попытался найти такой способ реализации этого метода, но не смог найти тот, который был скомпилирован. Как оказалось, реальное решение было еще проще, чем я себе представлял.
async Task<TBase> GeneralizeTask<TBase, TDerived>(Task<TDerived> task)
where TDerived : TBase
{
return (TBase) await task;
}
Затем вы можете вызвать Bar()
следующим образом.
Bar(m => GeneralizeTask<IResult, Result>(DoSomething((Message)m)));
Task
конструктор вообще, когда-либо), вы также неправильно обрабатываете случаи ошибок / аннулирования для сложенной задачи.
– Servy
14 June 2016 в 20:11
await
? Похоже, async Task<B> Cast<B, D>(Task<D> t) where D : B => (B) await t;
намного проще.
– Eric Lippert
14 June 2016 в 22:19
CS4010 Cannot convert async lambda expression to delegate type 'Func<TBase>'. An async lambda expression may return void, Task or Task<T>, none of which are convertible to 'Func<TBase>'.
. По-видимому, я не понимаю задачи, как я и думал.
– recursive
15 June 2016 в 00:02
Func<Task<TBase>>
Что такое лямбда? функция. Что возвращает асинхронная функция? Задача. Какую ценность делает эта задача? ТБаза. Так что это функция задачи tbase.
– Eric Lippert
15 June 2016 в 16:36