Поделиться через


Ошибки и предупреждения, связанные с объявлениями свойств

Вы можете столкнуться со следующими ошибками, связанными с объявлениями свойств:

  • CS0200: Нельзя присвоить значение свойству или индексатору 'свойство' — он доступен только для чтения.
  • CS0545: «функция»: невозможно переопределить, поскольку у свойства нет доступного для переопределения метода доступа get.
  • CS0571: «function»: не может напрямую вызывать оператор или аксессор.
  • CS0840: "Имя свойства" должно объявлять текст, так как он не помечен абстрактным или экстерном. Автоматически реализованные свойства должны определять как методы доступа get, так и set.
  • CS1014: ожидается аксессор get или set
  • CS1043: { или ; ожидается
  • CS8050: только автоматически реализованные свойства или свойства, использующие ключевое слово field, могут иметь инициализаторы
  • CS8051: автоматически реализованные свойства должны иметь методы доступа
  • CS8053: свойства экземпляра в интерфейсах не могут иметь инициализаторы
  • CS8145: автоматически реализованные свойства не могут возвращаться по ссылке
  • CS8147: свойства, возвращаемые по ссылке, не могут иметь наборы методов доступа
  • CS8341: автоматически реализуемые свойства экземпляра в структурах только для чтения должны быть помечены как readonly
  • CS8657: статический элемент не может быть помечен как readonly
  • CS8658: Автоматически реализуемый аксессор set нельзя пометить как readonly.
  • CS8659: не удается пометить свойство "readonly", так как он имеет метод доступа set
  • CS8660: Нельзя указать модификатор 'readonly' как для свойства, так и для его аксессора.
  • CS8661: не удается указать модификаторы readonly для обоих методов доступа свойства
  • CS8664: "readonly" можно использовать только для аксессоров, если у свойства есть и get, и set
  • CS9029: Типы и псевдонимы не могут называться "обязательными".
  • CS9030: элемент должен быть обязательным, так как он переопределяет обязательный элемент.
  • CS9031: обязательный элемент не может быть скрыт производным элементом.
  • CS9032: обязательный член не может быть менее видимым или иметь сеттер с меньшей видимостью, чем видимость содержащего типа.
  • CS9033: не используйте "System.Runtime.CompilerServices.RequiredMemberAttribute'. Вместо этого используйте ключевое слово "обязательный" для обязательных полей и свойств.
  • CS9034: обязательный элемент должен быть изменяемым.
  • CS9035: обязательный элемент должен быть задан в конструкторе объектов или конструкторе атрибутов.
  • CS9036: обязательный член "memberName" должен быть назначен значением, он не может использовать вложенный элемент или инициализатор коллекции.
  • CS9037: обязательный список элементов неправильно сформирован и не может быть интерпретирован.
  • CS9038: список обязательных элементов для базового типа неправильно сформирован и не может быть интерпретирован. Чтобы использовать этот конструктор, примените атрибут 'SetsRequiredMembers'.
  • CS9039: Этот конструктор должен добавить "SetsRequiredMembers", так как он связан с конструктором с этим атрибутом.
  • CS9040: тип не может удовлетворить ограничение "new()" для параметра в универсальном типе или методе, так как он имеет необходимые элементы.
  • CS9042: Обязательный член не должен быть помечен как "ObsoleteAttribute", если содержащий тип не устарел или все конструкторы не устарели.
  • CS9045: обязательные члены не допускаются на верхнем уровне скрипта или отправки.
  • CS9258: в этой языковой версии ключевое слово "field" привязывается к синтезируемом поле резервного копирования для свойства. Чтобы избежать создания синтезированного поля резервной копии, а также для ссылки на существующий элемент, используйте вместо него "this.field" или "@field".
  • CS9263: частичное свойство не может иметь инициализатор для определения и реализации.

Для свойств, поддерживаемых полем, можно создать следующие предупреждения:

  • CS9264: свойство, не допускающее значение NULL, должно содержать ненулевое значение при выходе конструктора. Попробуйте добавить модификатор "обязательный" или объявить свойство как допускающее значение NULL или добавить атрибуты "[field: MaybeNull, AllowNull]".
  • CS9266: один метод доступа к свойству должен использовать "field", так как другой метод доступа использует его.
  • CS9273: в этой языковой версии "field" является ключевым словом в методе доступа к свойствам. Переименуйте переменную или используйте вместо него идентификатор@field.

В следующих разделах объясняется причина и исправление этих ошибок и предупреждений.

Синтаксис метода доступа к свойствам

  • CS0545: 'function': невозможно переопределить, так как 'property' не имеет переопределяемого аксессора get.
  • CS0571: function: не может явно вызывать оператор или метод доступа.
  • CS1043: { или ; ожидается

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

Переопределите только те методы доступа, которые существуют в объявлении свойств базового класса (CS0545). Невозможно переопределить метод доступа свойства, который отсутствует или недоступен в базовом классе, поскольку в скомпилированном IL отсутствует виртуальный метод для переопределения. Если свойство базового класса имеет только аксессор get, удалите аксессор set из переопределения или добавьте отсутствующий аксессор в базовый класс и отметьте его как virtual. В качестве альтернативы, используйте new ключевое слово вместо override, чтобы замаскировать свойство базового класса с помощью нового определения свойства, включающего разные методы доступа.

Используйте синтаксис свойств для доступа к свойствам, вместо прямого вызова методов аксессоров (CS0571). Методы доступа к свойствам компилируются в специальные методы с такими именами, как get_PropertyName и set_PropertyName, но следует вызывать эти методы с помощью синтаксиса свойств (obj.Property и obj.Property = value). Этот подход поддерживает правильную семантику и позволяет компилятору выполнять необходимые проверки. Тот же принцип применяется к операторам, которые компилируются в такие методы op_Increment , но должны вызываться с помощью синтаксиса оператора (++obj) вместо вызовов методов.

Используйте правильный синтаксис доступа к свойствам с фигурными скобками или телами выражений (CS1043). Методы доступа к свойствам должны соответствовать правилам синтаксиса C#: тела доступа должны быть заключены в фигурные скобки { }, методы доступа с выражением должны использовать => синтаксис, а автоматически реализованные свойства должны заканчиваться точкой с запятой после списка доступа. Компилятор ожидает либо полную реализацию метода доступа, либо точку с запятой, указывающую автоматически реализованный метод доступа.

Дополнительные сведения см. в разделе "Свойства", " Наследование" и "Использование свойств".

Автоматически реализованные свойства

  • CS0840: "Имя свойства" должно объявлять тело, так как оно не помечено как абстрактное или внешнее. Автоматически реализованные свойства должны определять методы доступа как get, так и set.
  • CS1014: ожидается аксессор get или set

Чтобы исправить ошибки автоматически реализованных свойств, примените одно из следующих изменений на основе конкретной диагностики:

Добавьте оба get и set методы доступа в объявление свойства (CS0840). Для автоматической реализации свойств компилятору требуется создать резервное поле, и компилятор может сделать это только в том случае, если оба метода доступа присутствуют, чтобы обеспечить возможность чтения и записи хранилища. Если требуется автоматически реализованное свойство только для чтения, включите аксессор set и используйте private, чтобы ограничить доступ на запись, что позволяет компилятору автоматически создавать резервное поле. Как альтернативный вариант, если свойство объявляется как abstract или extern, удалите тела методов доступа полностью, так как эти модификаторы указывают, что реализация реализована в другом месте. Для свойств partial можно объявление и реализацию разделить по частичным декларациям типа.

Убедитесь, что объявление свойства содержит только допустимые ключевые слова для доступа get и set (CS1014). Синтаксис свойств разрешает только декларации аксессоров, а не произвольные инструкции или объявления членов в теле свойства. Если вам нужна дополнительная логика, реализуйте свойство с явными методами доступа, содержащими код. Если вы пытаетесь объявить поля или методы, переместите эти объявления за пределы свойства в класс или тело структуры, где разрешены объявления членов.

Дополнительные сведения см. в разделе "Свойства " и "Автоматически реализованные свойства".

Свойства, поддерживаемые полем

  • CS9258: в этой языковой версии ключевое слово "field" привязывается к синтезируемом поле резервного копирования для свойства. Чтобы избежать создания синтезированного поля резервной копии, а также для ссылки на существующий элемент, используйте вместо него "this.field" или "@field".
  • CS9263: частичное свойство не может иметь инициализатор для определения и реализации.
  • CS9264: Свойство, не допускающее NULL значение, должно содержать ненулевое значение при выходе из конструктора. Попробуйте добавить модификатор 'обязательный', объявить свойство как допускающее значение NULL или добавить атрибуты "[field: MaybeNull, AllowNull]".
  • CS9266: один метод доступа к свойству должен использовать "field", так как другой метод доступа использует его.
  • CS9273: в этой языковой версии "field" является ключевым словом в методе доступа к свойствам. Переименуйте переменную или используйте вместо него идентификатор@field.

Чтобы исправить ошибки, связанные со свойствами, поддерживающими поля, примените одно из следующих изменений в зависимости от конкретного диагноза:

Переименуйте любую переменную, именуемую field другим идентификатором, или используйте @field escape-синтаксис для ссылки на переменную (CS9258, CS9273). Это исправление необходимо, так как field это контекстное ключевое слово в методах доступа к свойствам в C# 13 и более поздних версиях, где оно ссылается на поле резервной копии, синтезированное компилятором. Если вы хотите получить доступ к существующему элементу field вместо синтезированного поля резервной копии, присвойте ему this.field значение, чтобы отсоединить ссылку.

Удалите инициализатор из определения частичного свойства или реализации, сохраняя только один (CS9263). Это исправление необходимо, так как разрешение инициализаторов в обоих местах приведет к неоднозначности использования значения и может привести к инициализации вспомогательного поля дважды с возможными разными значениями.

[field: MaybeNull, AllowNull] Добавьте атрибуты к объявлению свойства, чтобы указать, что резервное поле должно рассматриваться как допускающее значение NULL (CS9264). Это исправление приводит в соответствие ожидания nullability между типом свойства и вспомогательным полем, созданным компилятором, устраняет несоответствие, при котором свойство объявлено как ненулевое, но использование ключевого слова field предполагает, что оно может иметь значение NULL. В качестве альтернативы измените тип свойства на допускающий значение null, добавьте модификатор required для обеспечения инициализации, или инициализируйте свойство в конструкторе.

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

Дополнительные сведения см. в разделе "Ключевое слово поля " и "Частичные свойства".

Свойства Readonly

  • CS0200: Свойству или индексатору "свойство" нельзя присвоить значение: оно доступно только для чтения.
  • CS8341: автоматически реализуемые свойства экземпляра в структурах только для чтения должны быть только для чтения
  • CS8657: статический элемент не может быть помечен как readonly
  • CS8658: автоматически реализованный метод доступа set нельзя пометить как readonly.
  • CS8659: Автоматически реализуемое свойство нельзя пометить как 'readonly', так как оно имеет метод доступа 'set'
  • CS8660: не удается указать модификаторы readonly как для свойства, так и для его аксессора.
  • CS8661: не удается указать модификаторы readonly для обоих методов доступа свойства
  • CS8664: "readonly" можно использовать только для методов доступа, если свойство имеет как get, так и set

Чтобы исправить ошибки свойств только для чтения, примените одно из следующих изменений на основе конкретной диагностики:

Добавьте аксессор set или init к свойству, чтобы сделать его доступным для записи (CS0200). Это исправление необходимо, так как свойства без заданных методов доступа доступны только для чтения и могут быть назначены только в конструкторе декларативного типа или инициализаторе полей. Если необходимо, чтобы свойство было задано во время инициализации объектов, но неизменяемое после этого, используйте init метод доступа вместо set метода доступа. Если свойство должно оставаться доступным только для чтения, переместите присвоение в конструктор, где разрешена инициализация, или пересмотрите необходимость в присвоении вообще.

Помечайте автоматически реализованные свойства экземпляра, как readonly при объявлении их внутри readonly struct (CS8341). Это исправление применяет контракт на неизменяемость структуры, гарантируя, что все члены экземпляра соблюдают гарантию readonly. Если свойство должно быть изменяемым, удалите readonly модификатор из объявления структуры или реализуйте свойство с явным резервным полем и телами доступа, которые не изменяют состояние экземпляра.

Удалите модификатор readonly из объявлений статических свойств или аксессоров (CS8657). Это исправление необходимо, так как readonly модификатор применяется только к элементам экземпляров структур, чтобы указать, что они не изменяют состояние экземпляра, а статические элементы не имеют состояния экземпляра для защиты. Если требуется статическое свойство только для чтения, просто опустите set аксессор вместо использования readonly модификатора.

readonly Удалите модификатор из автоматически реализованных set аксессоров или примените его только к аксессору get (CS8658). Это исправление необходимо, так как set методы доступа по сути изменяют состояние, которое противоречит назначению readonly модификатора, гарантирующего отсутствие изменения состояния экземпляра. Если вам требуется свойство, которое можно установить во время инициализации, но которое затем становится только для чтения, используйте init акцессор вместо set акцессора.

Удалите модификатор readonly из объявления свойства, когда свойство имеет аксессор set (CS8659). Это исправление необходимо, так как свойства с set аксессорами могут изменять состояние экземпляра, что нарушает гарантию readonly. Если вам нужно задавать свойство только во время инициализации, замените аксессор set на аксессор init или полностью удалите аксессор set, чтобы сделать свойство действительно доступным только для чтения.

readonly Поместите модификатор в объявление свойства или на отдельные методы доступа, но не оба (CS8660, CS8661). Это исправление предотвращает избыточные объявления модификатора, которые могут привести к путанице о том, какой модификатор получает приоритет. Если вы хотите пометить определенные методы доступа как readonly, удалите модификатор из объявления свойства и поместите его только на методы доступа. Кроме того, если все методы доступа должны быть readonly, помечайте само свойство, а не отдельные методы доступа.

Убедитесь, что оба метода доступа get и set присутствуют при определении отдельных методов доступа как readonly (CS8664). Это исправление необходимо, так как модификатор readonly на отдельных методах доступа позволяет различать методы, которые изменяют состояние, и те, которые этого не делают, что имеет смысл только в случае, если существуют оба типа методов доступа. Если свойство имеет только get метод доступа, пометьте все свойство как readonly, а не отдельный метод доступа.

Дополнительные сведения см. в разделе "Элементы экземпляра чтения", ключевое слово init и свойства.

Инициализаторы свойств

  • CS8050: только автоматически реализованные свойства или свойства, использующие ключевое слово field, могут иметь инициализаторы
  • CS8051: автоматически реализованные свойства должны иметь методы доступа
  • CS8053: свойства экземпляра в интерфейсах не могут иметь инициализаторы

Чтобы исправить ошибки инициализатора свойств, примените одно из следующих изменений на основе конкретной диагностики:

Преобразуйте свойство для использования автоматического синтаксиса, удалив модификаторы доступа и позволяя компилятору автоматически создавать поле (CS8050). Это исправление необходимо, так как только свойства, управление которыми осуществляется компилятором, могут иметь инициализаторы, что обеспечивает инициализацию перед выполнением любой логики доступа к этим свойствам. Кроме того, измените реализацию метода доступа, чтобы использовать field ключевое слово для доступа к полю резервной копии, синтезированной компилятором. Этот подход позволяет активировать инициализатор при сохранении логики пользовательского доступа. Если ни один из подходов не подходит, удалите инициализатор и назначьте значение в конструкторе, где у вас есть полный контроль над последовательностью инициализации.

get Добавьте метод доступа к свойству автоматической реализации, чтобы включить чтение инициализированного значения (CS8051). Это исправление необходимо, так как инициализаторы задают значение, которое должно быть извлечено, а свойство только для записи нарушает это базовое ожидание инициализации свойств. Если вам действительно требуется свойство только для записи, реализуйте методы доступа явным образом с резервным полем и назначьте поле непосредственно в конструкторе, а не с помощью инициализатора свойств.

Удалите инициализатор из объявлений свойств интерфейса (CS8053). Это исправление необходимо, так как интерфейсы определяют контракты для реализации типов, а не предоставляют конкретные реализации с начальными значениями. Если необходимо предоставить значения по умолчанию, реализуйте свойство в классе, реализующего интерфейс, или используйте методы интерфейса по умолчанию (доступные в C# 8.0 и более поздних версиях), чтобы предоставить реализацию по умолчанию.

Дополнительные сведения см. в разделе "Свойства", " Автоматически реализованные свойства" и ключевое слово поля.

Обязательные члены

  • CS9029: Типы и псевдонимы не могут называться "обязательными".
  • CS9030: элемент должен быть обязательным, так как он переопределяет обязательный элемент.
  • CS9031: обязательный элемент не может быть скрыт производным элементом.
  • CS9032: Обязательный элемент не может быть менее видимым или иметь метод установки менее видимым, чем содержащий тип.
  • CS9033: не используйте "System.Runtime.CompilerServices.RequiredMemberAttribute'. Вместо этого используйте ключевое слово "обязательный" для обязательных полей и свойств.
  • CS9034: обязательный член должен быть изменяемым.
  • CS9035: обязательный элемент должен быть задан в конструкторе объектов или конструкторе атрибутов.
  • CS9036: обязательный член "memberName" должен быть присвоен значением, он не может использовать вложенный член или инициализатор коллекции.
  • CS9037: обязательный список элементов неправильно сформирован и не может быть интерпретирован.
  • CS9038: список обязательных элементов для базового типа неправильно сформирован и не может быть интерпретирован. Чтобы использовать этот конструктор, примените атрибут 'SetsRequiredMembers'.
  • CS9039: Этот конструктор должен добавить "SetsRequiredMembers", так как он цепляется к конструктору с этим атрибутом.
  • CS9040: тип не может удовлетворить ограничение "new()" для параметра в универсальном типе или методе, так как он имеет необходимые элементы.
  • CS9042: обязательный член не должен быть атрибутирован с "ObsoleteAttribute", если содержащий тип не устарел или все конструкторы не устарели.
  • CS9045: требуемые члены не допускаются на верхнем уровне скрипта или представления.

Чтобы исправить необходимые ошибки члена, примените одно из следующих изменений на основе конкретной диагностики:

Избегайте использования required в качестве имени типа или псевдонима (CS9029). Это исправление необходимо, так как required это контекстное ключевое слово в C# 11 и более поздних версиях, и его использование в качестве имени типа создает неоднозначность в коде, где может появиться ключевое слово.

Убедитесь, что производные члены поддерживают модификатор required при переопределении обязательных членов (CS9030). Это исправление применяет контракт, установленный базовым классом, гарантируя, что все производные типы поддерживают одинаковые требования к инициализации. Избегайте скрытия обязательных элементов с не обязательными элементами в производных классах (CS9031), так как это действие нарушает контракт инициализации, который потребители ожидают от базового типа.

Сделайте обязательные члены как минимум такими же доступными, как содержащий их тип, и убедитесь, что установщики свойств также обладают достаточной видимостью (CS9032). Это исправление предотвращает ситуации, когда тип является общедоступным, но его обязательные элементы не могут быть инициализированы из всех контекстов, в которых создается тип.

Используйте ключевое required слово вместо применения RequiredMemberAttribute вручную (CS9033). Это исправление гарантирует, что компилятор создает правильные метаданные и применяет все необходимые правила члена, которые приложение атрибутов вручную может не правильно выполнять.

Убедитесь, что необходимые члены имеют назначенные аксессоры или иным образом могут быть установлены (CS9034). Это исправление необходимо, так как необходимые элементы должны быть инициализированы во время создания объекта, для которого требуется доступ на запись. При создании экземпляров напрямую инициализируйте необходимые элементы в инициализаторах объектов (CS9035, CS9036). Необходимо назначить значение каждому обязательному элементу, а не использовать вложенные инициализаторы элементов или инициализаторы коллекции, так как перед доступом к его свойствам необходимо задать обязательный элемент.

Примените SetsRequiredMembers атрибут к конструкторам, которые инициализируют все необходимые элементы в своих телах (CS9038, CS9039). Это исправление сообщает компилятору, что конструктор выполняет обязательный контракт члена, позволяя создавать объекты без инициализаторов объектов. Если конструктор объединяется с другим конструктором, используя SetsRequiredMembers, он также должен иметь этот атрибут.

Избегайте использования обязательных элементов в типах, которые должны соответствовать new() ограничению (CS9040), так как конструктор без параметров не может гарантировать обязательное инициализацию элементов без инициализатора объектов. Не помечайте необходимые члены как устаревшие, если содержащий их тип или все конструкторы не устарели (CS9042), чтобы предотвратить ситуации, когда члены необходимы, но их использование не рекомендуется. Обязательные члены не допускаются в инструкциях верхнего уровня или контекстах скриптов (CS9045), так как эти контексты не поддерживают синтаксис инициализации объектов, необходимый для задания обязательных элементов.

Дополнительные сведения см. в справочной статье о необходимых модификаторахи инициализаторах объектов и коллекции .

Свойства, возвращающие ссылки

  • CS8145: автоматически реализованные свойства не могут возвращаться по ссылке
  • CS8147: свойства, возвращаемые по ссылке, не могут иметь наборы методов доступа

Чтобы исправить ошибки возвращаемого свойства ref, примените одно из следующих изменений на основе конкретной диагностики:

Реализуйте свойство явно с помощью резервного поля и используйте ref ключевое слово в get выражении возврата метода доступа (CS8145). Это исправление необходимо, так как автоматически реализованные свойства создают частное резервное поле, которое компилятор управляет внутренне. При возврате ссылки на закрытое поле будут предоставлены внутренние данные, к которым вызывающие не должны обращаться напрямую. Чтобы создать возвращаемое свойство ref, объявите явное поле и верните его с синтаксисом => ref backingField . Кроме того, если вам не нужно возвращать ссылку, чтобы разрешить прямое изменение хранилища, удалите ref модификатор из объявления свойства.

set Удалите метод доступа из возвращаемых свойств ref (CS8147). Это исправление необходимо, поскольку свойство, возвращающее ref, уже предоставляет доступ для чтения и записи через саму возвращаемую ссылку. Вызывающие могут напрямую изменять значение с помощью ссылки без необходимости отдельного метода задания. Добавление метода доступа set создаст два разных механизма модификации одного и того же хранилища, что может быть избыточным и привести к неопределенности о том, какой путь модификации следует использовать.

Дополнительные сведения см. в разделе возврат по ссылке и локальные переменные по ссылке и Свойства.