Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Зайцев Дмитрий #228

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

Emi1337-ops
Copy link

@Emi1337-ops Emi1337-ops commented Dec 11, 2024

@@ -0,0 +1,16 @@
using System;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Привет) давай сначала общие рекомендации:

Содержание коммитов должно быть атомарным. Один коммит - одно логическое изменение. Сейчас у тебя на все решение, правки, тесты - лишь один коммит =(
Зачем это нужно? Чтобы по истории коммитов, понимать, что произошло. Или уметь ревертить только "плохие" части. Или уметь их черри-пикать. И тд

Прямо сейчас что-либо делать с коммитами не надо. Это рекомендации на будущее

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Аналогичные комментарии и про новый коммит Refactor Homewark Solution. В нем и перенеслись тесты в самостоятельный проект, и произошло разделение логики PrintingConfig'а (даже не просто разделение, а еще доработка), и чистка зависимостей и лишних файлов. Каждый из подэтапов вполе уместно смотрелся бы отдельным коммитом

Дальше
Имя коммита Fix mistakes не говорит о том, что произошло внутри. Какие-то ошибки исправлены. Стоит именовать в соответствии с непосредственными изменениями. Например, Remove obsolete files. А, там еще и часть другого - тогда его в отдельный коммит и назвать Update PrintToString_Correct_WhenCallAllMethods logic или как-то так

А вот коммит Add Solution for Nestin Property выглядит вполне хорошо, как раз оптимально соответствует рекомендациям

@@ -0,0 +1,16 @@
using System;

namespace ObjectPrinting.Extensions;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Также не выполнен пункт про меншн наставника
image


namespace ObjectPrinting.Extensions;

public static class ObjectExtensions

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Не нашел использований. Возможно, они должны быть

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Удалил класс

</ItemGroup>

<ItemGroup>
<None Update="Tests\Snapshots\ObjectPrinterTests.PrintToString_Correct_WhenCallAllMethods.verified.txt">

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тесты стоит выносить отдельным проектом, чтобы "боевая" логика и тесты не лежали в одном месте. Это нужно, например, для потребителей, которые будут подключать логику к себе. Предполагаю, им для использования нет необходимости тянуть еще и тесты)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Убрал

namespace ObjectPrinting
namespace ObjectPrinting;

public class PrintingConfig<TOwner>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

В этом классе оказалось много ответственности (нарушается SRP): конфигурация объектов для сериализации, непосредственно алгоритм сериализации, а также работа с рефлексией

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Разделил

}

var collectionOnString = new StringBuilder();
var indentation = new string('\t', nestingLevel + 1);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'\t'` дублируется, полезно вынести в константу

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

вынес в константу


foreach (var property in type.GetProperties())
{
if (excludedTypes.Contains(property.PropertyType) || excludedProperties.Contains(property.Name))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А как в данном случае отработает логика?
Есть объект

public class Person1
{
    public Guid Id { get; set; }
    
    public Person2 Parent { get; set; }
}

public class Person2
{
    public Guid Id { get; set; }
}

И мы исключили из сериализации только Person1.Id

Будет ли продолжать сериализоваться Person2.Id ?
Если не будет, корректное ли это поведение?
Если не будет, есть ли какие-то другие места с похожими потенциальными проблемами?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Здесь я понял проблему, но как узнать какой класс приходит в Expression я не понял, я вообще первый раз работаю с ними. Да и сама задача прямо не говорит, что нужно учитывать такое поведение, так что не смог реализовать такую логику.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Решил проблему, теперь информация по свойствах\полях хранится в PropertyInfo, так же добавил тест PrintToString_NotSkipProperty_WhenNestingClass, проверяющий логику при вложенных полях

return sb.ToString();

var serializedProperty = SerializeProperty(property, obj, nestingLevel + 1);
serializedString.Append(indentation + property.Name + " = " + serializedProperty);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Предлагаю использовать интерполяцию

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Не нашел исправлений

@@ -0,0 +1,9 @@
Person
Id = 00000000-0000-0000-0000-000000000000

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Давай хотя бы один пример, что работает и на не пустом гуиде

Copy link
Author

@Emi1337-ops Emi1337-ops Dec 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Добавил в ObjectPrinterTests.PrintToString_AlternativePropertySerialization.verified
и ObjectPrinterTests.PrintToString_Correct_WhenCallAllMethods.verified

@@ -0,0 +1,23 @@
Dictionary`2:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Что такое Dictionary2? И KeyValuePair2? и List1`?
Выглядит нечитаемым особенно в контексте задачи по сериализации)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

изменил


namespace ObjectPrinting

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Куда-то пропал namespace почти везде
image

{
private readonly PrintingConfigStorage _config;
private readonly HashSet<object> _processedObjects = new();
private const char tab = '\t';

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Для констант есть гайдлайны именования. Райдер их, кстати, подсказывает)
image

public string Serialize(TOwner obj)
{
_processedObjects.Clear();
return SerializeObject(obj, 0);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Потенциальное NRE
image

Решить можно по разному, но хорошим решением было бы использовать MaybeNullWhen
Например так
private bool TrySerializeFinalType(object obj, [MaybeNullWhen(false)] out string serializedFinalType)

Рекомендую ознакомиться, очень полезный атрибут)
https://learn.microsoft.com/ru-ru/dotnet/api/system.diagnostics.codeanalysis.maybenullwhenattribute?view=net-8.0

: obj.ToString() + Environment.NewLine;
}

if (_processedObjects.Contains(obj))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Стоит уделять внимание подсказкам от IDE, они могут помочь писать код чище)
Например здесь
image

Потому что сигнатура на добавление
image


private bool TrySerializeFinalType(object obj, out string? serializedFinalType)
{
var type = obj.GetType();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Получение типа дублируется

Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spectacle", "Samples\Spectacle\Spectacle.csproj", "{EFA9335C-411B-4597-B0B6-5438D1AE04C3}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spectacle", "Samples\Spectacle\Spectacle.csproj", "{EFA9335C-411B-4597-B0B6-5438D1AE04C3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{0A6EEC4E-959A-4378-A8A9-B965F5F7D7FB}"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Скорее не просто Tests, а что-то вроде ObjectPrinter.Tests, по аналогии с проектом тестов в этом же солюшене

person,
new()
{
Id = new Guid("11111122-1234-1234-1234-000000000000"),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Для случайного гуида принято (и действительно проще) использовать Guid.NewGuid()

public Task PrintToString_SerializeDictionary()
{
var persons = new Dictionary<Person, string>
{

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Что-то в этом файле совсем плохо с отступами и форматированием
Попробуй в райдере комбинацию ctrl + alt + l

@@ -0,0 +1,235 @@
using System;
using System.Collections.Generic;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Лишние usings

@@ -0,0 +1,16 @@
using System;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Аналогичные комментарии и про новый коммит Refactor Homewark Solution. В нем и перенеслись тесты в самостоятельный проект, и произошло разделение логики PrintingConfig'а (даже не просто разделение, а еще доработка), и чистка зависимостей и лишних файлов. Каждый из подэтапов вполе уместно смотрелся бы отдельным коммитом

Дальше
Имя коммита Fix mistakes не говорит о том, что произошло внутри. Какие-то ошибки исправлены. Стоит именовать в соответствии с непосредственными изменениями. Например, Remove obsolete files. А, там еще и часть другого - тогда его в отдельный коммит и назвать Update PrintToString_Correct_WhenCallAllMethods logic или как-то так

А вот коммит Add Solution for Nestin Property выглядит вполне хорошо, как раз оптимально соответствует рекомендациям

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants