Я не обеспокоился необработанным каналом, но я попытался делать все ссылки в, Возможно, монада:
public static class ReferenceExtensions
{
public static TOut IfNotNull<TIn, TOut>(this TIn v, Func<TIn, TOut> f)
where TIn : class
where TOut: class
{
if (v == null)
return null;
return f(v);
}
}
Затем предполагают, что у Вас есть объектная модель, которая позволяет Вам поиск RecordCompany по имени и затем поиск Полоса в том, что RecordCompany, член Полосы и любой из них могли бы возвратить пустой указатель, таким образом, это могло бы бросить NullReferenceException:
var pixiesDrummer = Music.GetCompany("4ad.com")
.GetBand("Pixes")
.GetMember("David");
Мы можем зафиксировать это:
var pixiesDrummer = Music.GetCompany("4ad.com")
.IfNotNull(rc => rc.GetBand("Pixes"))
.IfNotNull(band => band.GetMember("David"));
Эй престо, если какой-либо из тех переходов возвращает пустой указатель, pixiesDrummer будет пустым.
Разве не было бы замечательно, если мы могли бы сделать дополнительные методы, которые являются перегрузками оператора?
public static TOut operator| <TIn, TOut>(TIn v, Func<TIn, TOut> f)
Затем я мог передать по каналу вместе свои лямбды перехода как это:
var pixiesDrummer = Music.GetCompany("4ad.com")
| rc => rc.GetBand("Pixes")
| band => band.GetMember("David");
Также не был бы это быть большим если Система. Пусто был определен как тип, и Действием был действительно просто Func<..., Пусто>?
Обновление: я вел блог немного о теории позади этого .
Обновление 2: альтернативный ответ на исходный вопрос, который является примерно, "Как Вы выразили бы оператор канала вперед F# в C#?"
Канал вперед:
let (|>) x f = f x
, Другими словами, это позволяет Вам записать функцию и ее первый аргумент в противоположном порядке: аргумент сопровождается функцией. Это - просто синтаксический помощник, который помогает с удобочитаемостью, позволяя Вам использовать инфиксную нотацию с любой функцией.
Это точно, для чего дополнительные методы в C#. Без них мы должны были бы записать:
var n = Enumerable.Select(numbers, m => m * 2);
С ними, мы можем записать:
var n = numbers.Select(m => m * 2);
(Игнорируют то, что они также позволяют нам опустить имя класса - это - премия, но могло также быть сделано доступным для недополнительных методов, как это находится в Java).
, Таким образом, C# уже решает ту же проблему по-другому.
В то время как это - не совсем то же самое, Вы могли бы интересоваться моим платформа LINQ Нажатия. В основном то, где IEnumerable<T>
требует, чтобы заинтересованная сторона вытянула данные из источника, Нажатие, LINQ позволяет Вам продвинуть данные до источник, и заинтересованные стороны могут подписаться на события, соответствующие "другому элементу, только что пошло мимо", и "данные закончились".
Marc Gravell и я реализовали большинство стандартных операторов запроса LINQ, что означает, что можно записать выражения запроса против источников данных и сделать забавный материал как потоковая передача группировки, нескольких агрегирований и т.д.