@footballer

Почему required проперти не могут иметь более ограничиващий модификатор set\init, чем модиикатор класса, их содержащего?

https://learn.microsoft.com/ru-ru/dotnet/csharp/la...

Объясните логику пункта
"Обязательные элементы должны быть не менее видимыми, чем содержащие их типы. Например, public класс не может содержать required поле , равное protected. Кроме того, обязательные свойства должны иметь методы задания (set или init методы доступа), которые по крайней мере так же видимы, как их содержащие типы. Элементы, которые недоступны, нельзя задать с помощью кода, создающего экземпляр."

а то я в упор не пойму, почему я не могу объявить проперти так:

public class QQQ
{
    private QQQ()
    {
    }

    public required DDD Dddd { get; internal init; }
}


если я хочу, чтобы проперти Dddd было видно для чтения во всех классах, но было доступно для инициализации только в той же сборке и при этом при создании объекта внутри той же сборки это проперти должно быть обязательно задано. При этом, чтобы невозможно было создать экземпляр сз другой сборки, конструктор отмечен как internal.

В общем, мне нужно, чтобы внутри сборки проперти ОБЯЗАТЕЛЬНО было инициализировано при создании объекта, и при этом чтобы вне сборки объект нельзя было создать, но можно было прочитать его поля - как это сделать?

UPDATE:
попробовал такой вариант (заменил public модификатор у класса на internal ), он не показывает ошибок и вроде бы позволяет делать то, что мне надо:

internal class QQQ
{

    public required DDD Dddd { get; internal init; }
}


единственное, что мне не понятно - а разве само по себе наличие у internal класса пропертей с модификаторами public не является ошибкой? я че то думал, что раз класс internal, то объекты этого класса не должны быть видны снаружи сборки (но тогда и смысл public полей отсуствует) . Либо я не прав, и экземпляры internal классов могут быть видны снаружи сборки ?
  • Вопрос задан
  • 108 просмотров
Решения вопроса 1
mindtester
@mindtester Куратор тега C#
http://iczin.su/hexagram_48
у вас отличная ссылка на доку, там все. претензии туда же. ну подумать зачем вам скрытый required?
.. банально же - он обязательный, вы сами так потребовали

ps может internal или protected internal? в смысле для класса..
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
AshBlade
@AshBlade Куратор тега C#
Просто хочу быть счастливым
Представь ситуацию, что кто-то во внешней сборке создает твой класс и ему обязательно нужно будет инициализировать это поле - он не сможет, т.к. internal set. А сделать это просто - рефлексия:
SomeClass obj = (SomeClass) typeof(SomeClass).GetConstructor(
                  BindingFlags.NonPublic | BindingFlags.Instance,
                  null, Type.EmptyTypes, null).Invoke(null);

И все!

Тут несколько решений:
1. Объяви класс как internal
2. Выдели интерфейс с публичным get без set
3. Для хранения используй поле и доступ к нему через свойство (но тут уже и required не особо нужен)
Ответ написан
NikFaraday
@NikFaraday
Student full-stack Developer
Обязательные элементы должны быть не менее видимыми, чем содержащие их типы

Что значит обязательные? У вас в примере есть это:
public required DDD Dddd { get; internal init; }

Что это значит? Допустим, у вас класс public class QQQ, а внутри него есть обязательное поле Dddd. Допустим, вы хотите создать объект этого типа из другого проекта. Как вы это сделаете? Ответ - НИКАК.

Почему? Потому что систему будет требовать инициализировать поле Dddd, но вы его не видете, т.к. оно internal. На этом моменте у вас просто отвалится вся логика программы та и всей платформы .NET. По этому такие вещи просто запрещены

Почему этот кусок будет работать?
internal class QQQ
{

    public required DDD Dddd { get; internal init; }
}


Потому что в любом месте видимости класса QQQ вы сможете инициализировать обязательное поле, которое имеет бо'льшую область видимости

Вот тут отличная документация по модификаторам доступа, а вот тут видео об области видимости
Ответ написан
Чтобы запретить создавать класс в других сборках, но оставить его видимым для них – нужно сделать конструктор класса internal, а сам класс оставить public.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы