Очистка кода: лучший способ разбить длинную инструкцию на несколько строк
У меня довольно длинное логическое утверждение, и оно должно быть разбито на несколько строк. Где лучшие места, чтобы разбить утверждение? Есть ли соглашение о разделении логических операндов и лямбда-выражений linq? Visual Studio 2013 с ReSharper отформатировал утверждение следующим образом:
var b =
wmsDocument.Document.Types.All(
typePair => validTypes.Any(type => type.DocumentTypeId == typePair.DocumentTypeId &&
(String.IsNullOrWhiteSpace(typePair.DocumentSubTypeId) ||
(type.SubTypes != null &&
type.SubTypes.Any(
subType =>
subType.DocumentSubTypeId == typePair.DocumentSubTypeId)))));
Я знаю, что могу разбить логику с помощью некоторых вызовов методов, но я действительно хочу знать, есть ли у кого-то соглашения о том, как создавать отступы для таких операторов. Мне пока не повезло найти что-нибудь онлайн.
3 ответа
Я использую эти правила:
- Если строка в лямбда-выражении слишком длинная, введите определение
x=>
в одной строке, и это объявление в новой строке. - Разрыв логических операций, чтобы выровнять его таким образом, чтобы показать, какие операнды связаны друг с другом через оператора.
так что ваш код будет примерно таким
var b = wmsDocument.Document.Types.All(typePair =>
validTypes.Any(type =>
type.DocumentTypeId == typePair.DocumentTypeId &&
(string.IsNullOrWhiteSpace(typePair.DocumentSubTypeId) ||
(type.SubTypes != null &&
type.SubTypes.Any(subType =>
subType.DocumentSubTypeId == typePair.DocumentSubTypeId)))));
Есть разные способы сделать это. Это зависит от того, где вы проводите грань между компактным и читабельным. Это было бы на читаемой стороне, и хотя немного многословно позволяет по крайней мере для комментариев во вложенных выражениях linq.
//determine if every document type
var b = wmsDocument.Document.Types.All
(
//contains at least one typePair
typePair => validTypes.Any
(
//where the type's id and the typePair's id are equal
type => type.DocumentTypeId == typePair.DocumentTypeId &&
(
//and the subtype's id has a value
String.IsNullOrWhiteSpace(typePair.DocumentSubTypeId) ||
(
//or the subtype collection is populated and contains a matching subtypeid
type.SubTypes != null && type.SubTypes.Any
(
subType => subType.DocumentSubTypeId == typePair.DocumentSubTypeId
)
)
)
)
);
Трудно сказать, есть хороший ответ на этот вопрос. Это действительно вопрос вкуса. Лично мне нравится разбивать LINQ-запросы на точки.
var result = data
.Where(a => a == someValue)
.Take(5)
.ToList();
Кроме того, я предпочитаю, чтобы каждое условие было в отдельной строке:
if (a == b ||
b == c ||
c == a)
{
}
Применяя эти два предпочтения к вашему запросу, я получил что-то вроде этого:
var b =
wmsDocument.Document.Types
.All(typePair => validTypes
.Any(type => type.DocumentTypeId == typePair.DocumentTypeId &&
(String.IsNullOrWhiteSpace(typePair.DocumentSubTypeId) ||
(type.SubTypes != null &&
type.SubTypes
.Any(subType => subType.DocumentSubTypeId == typePair.DocumentSubTypeId)))));