РЕДАКТИРОВАТЬ: ознакомьтесь с моим сообщением ниже о моем отношении к Null в C#8.0, прежде чем давать мне варианты шаблонов и тому подобное
Исходный вопрос
Я пытаюсь обновить свои базовые библиотеки, чтобы они были «нулевыми», иначе используя флаг С# 8.0 <Nullable>enable</Nullable>
.
При попытке работать с абстракциями и в конкретных дженериках я столкнулся с некоторыми проблемами. Рассмотрим следующий фрагмент кода, который принимает Action
и преобразует его в Func<TResult>
. Это включение предварительного обнуления:
public static Func<TResult> ToFunc<TResult>(this Action action)
=> () => { action(); return default; }
;
но post-nullable-enable я, кажется, борюсь, так как я не могу сделать TResult обнуляемым (или TResult?
), так как остроумие потребует ограничения либо where TResult: class
, либо where TResult: struct
. Я никак не могу объединить эти два ограничения, чтобы компилятор знал, что TResult может быть классом или типом значения. Что на данный момент меня раздражает - поскольку нужно уметь выражать неважно, класс или структура, она будет обнуляемой (независимо от предыдущего унаследованного дизайна .NET).
Итак, post-nullable-enable у меня есть только один вариант — дублирование кода, примеры ниже:
public static Func<TResult?> ToFuncClass<TResult>(this Action action)
where TResult : class
=> () => { action(); return null; }
;
public static Func<TResult?> ToFuncStruct<TResult>(this Action action)
where TResult : struct
=> () => { action(); return null; }
;
Меня очень беспокоит как дублирование кода, так и связанные с ним схемы именования. Возможно, я неправильно понимаю правильное использование или, может быть, мне не хватает другой функции спецификации, но как бы вы это решили?
ОБНОВЛЕНИЕ: на самом деле, я думаю, что лучше придерживаться собственных реализаций "обработки нулей", чем использовать функцию C# 8.0, допускающую значение null. Как объект "Void" или конкретизированное решение "Option/Maybe/None", кажется, лучше передает информацию. Единственное, что меня беспокоит, это то, что это не очень помогает в продвижении языка вперед, обучении новых программистов и вводит еще один >стороннее/не родное решение для универсальной проблемы, с которой мы все имеем дело с нулевым значением. Потому что собственные реализации обработки с null великолепны и все такое, но возникают по-разному в каждой кодовой базе, должны поддерживаться сообществом, и у вас есть разные варианты. Так что было бы очень полезно и чрезвычайно полезно, если бы язык полностью реализовывал его и если бы повышался стандарт. На что я надеялся, что это будет - ясно, что это не так, и я понимаю. Но я чувствую, что это упущенная возможность.
Спасибо Ив
null
из методов, они возвращают типunit
илиvoid
. Вы можете сделать то же самое.System.Threading.Channels
содержит типVoidResult
по этой причине. - person Panagiotis Kanavos   schedule 10.10.2019Nullable<T>
до этой функции, это можно было бы сделать, но так как это сейчас, нет костей. - person Jeroen Mostert   schedule 10.10.2019null
для чего-то, для чего он не предназначен. - person Panagiotis Kanavos   schedule 10.10.2019