Скрывает предупреждение о наследуемом члене

В следующем коде Unity / C# переменная collider выдает следующее предупреждение:

Warning CS0108 'Controller2D.collider' hides inherited member 'Component.collider'. Use the new keyword if hiding was intended.

Что это значит и как это исправить?


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// require that our object has a box-collider-2d component
[RequireComponent(typeof(BoxCollider2D))]

// controller-2D script
public class Controller2D : MonoBehaviour {

    // stores a reference to our object's box-collider-2d component
    BoxCollider2D collider; // the warning occurs here

    // ...
}

Обратите внимание, что повторяющийся вопрос касается предупреждения, выданного «Resharper», но по сути это одно и то же ...

user2819245 03.12.2018 23:12

Кстати, вероятный ответ на ваш вопрос «как мне это исправить?»: не пытайтесь скрыть участников. Возможно, вы сможете добиться успеха, не определяя собственное свойство collider, поскольку ваш Controller2D уже имеет свойство collider, унаследованное от его базового класса.

user2819245 03.12.2018 23:19
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
6 593
2

Ответы 2

Это предупреждение означает, что базовый класс Controller2D с именем Component уже имеет свойство с тем же именем collider. Предупреждение предназначено для того, чтобы сообщить вам, что любая реализация Controller2D будет использовать ваше определение и «скрывать» базовое определение. Чтобы предотвратить предупреждение, просто измените определение коллайдера на

новый коллайдер BoxCollider2D;

Тогда он узнает, что вы хотите скрыть эту примету, и предупреждение исчезнет.

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

Не пытайтесь волей-неволей предлагать «исправление», просто сделав скрытие элементов явным, используя new. Есть причина, по которой компилятор предупреждает о сокрытии члена, если вы действительно явно не намерены скрывать член. Если вы предложите спрятать член наугад, могут возникнуть серьезные побочные эффекты. Скрытие участников следует использовать только в определенных ситуациях и только в том случае, если кто-то действительно знает, что подразумевает скрытие участников, чтобы можно было избежать возможных нежелательных побочных эффектов. (См. Повторяющийся вопрос в первом комментарии к этому вопросу здесь).

user2819245 04.12.2018 00:08

@ elgonzo Он спросил, почему это происходит и как это исправить. Что вы еще хотите? Вы хотите, чтобы я сказал ему не делать этого, если он не уверен, что хочет? Это правильный ответ. Я не обязан знать его намерения. Плюс я сказал ему назвать это как-нибудь по-другому. Боже

JSON 04.12.2018 00:11

Он спросил, что это значит, а это значит, что он действительно не знает. Во всяком случае, все сказано ...

user2819245 04.12.2018 00:12

@egonzo Нет, никто не сказал ему, что это значит и почему это происходит. Я сказал ему

JSON 04.12.2018 00:14

Нет, вы действительно не ... Вы просто сказали примерно в том же духе, что и «Вперед. Поместите туда ключевое слово new. Тогда будет использоваться ваше определение поля, а не определение базового класса». Нет. Будет ли он использоваться или нет, зависит не от помещения ключевого слова new, а от ссылочного типа переменных, ссылающихся на экземпляр Controller2D. Но, учитывая ваше отношение к этому, я думаю, вам действительно все равно, что на самом деле делает прячущийся член ...

user2819245 04.12.2018 00:17

@egonzo, вы только что опубликовали возможный дубликат вопроса, который не имеет отношения к делу. И ты прав. Его не волнует новое определение, и он будет использовать его независимо, но он отключает компилятор от выдачи предупреждений. Он спросил почему, я сказал ему почему. Чего я не сделал, так это отправил случайный ответ, не связанный с вопросом. Хорошего дня, сэр

JSON 04.12.2018 00:20

На самом деле, если OP явно не разъясняет в письмах, что он не знает, что скрывается или делает член, даже если это очевидно из вопроса, ваша точка зрения заключается в том, что OP должен знать то, о чем он не знает. . Ладно, нет смысла развивать этот аргумент ...

user2819245 04.12.2018 00:22

Да, оператор должен знать, намерен ли он спрятать участника после того, как я сказал ему, что это означает. Он не знал, что это значит. Я сказал ему в первом предложении. Я сказал ему, как это исправить. Это лучше, чем размещать совершенно не связанный с ним возможный дубликат, объясняя вещи, которые явно выше его головы. Вы еще не ныли?

JSON 04.12.2018 00:29

Итак, теперь вы говорите, что «если ОП намеревается сделать то, о чем он ничего не знает, он должен сделать это и так». И вообще все это "над головой ОП". "Кого волнует, что будет с кодом OP, OP все равно ничего не поймет, для него это слишком много." Амирит? Пожалуйста, продолжайте, становится все интереснее ...

user2819245 04.12.2018 00:34

Нет. Я никогда не говорил ничего подобного. Он спросил, что это значит, и я ответил ему. Он спросил, как это исправить, и я сказал ему ответ. Буквально вы можете сделать только две вещи. Чего я не сделал, так это не опубликовал дубликат, который не отвечает на вопрос, объясняющий, когда и если вам следует скрывать свойства, когда вы сами сказали, он даже не знает, что означает скрытие свойства. Теперь я могу добавить больше описания, если хотите, но все, что вам нужно было сделать, это спросить. Или не стесняйтесь редактировать ответ, если хотите.

JSON 04.12.2018 06:48
берет попкорн
Antoine Thiry 04.12.2018 12:32

@JSON Есть два ответов на проблему (возможно, три), один из них более правильный, чем другой. Вы рассказали ему об одном из них, а тот, о котором вы ему рассказали, является очень конкретным вариантом использования-только-делай-если-знаешь-что-делаешь. Остальные (два) гораздо более простые и общие. Кроме того, цель дублирования верна, помните, не имеет значения, отличается ли вопрос, но имеет ли значение ответ применим.. И в этом случае это так.

Draco18s no longer trusts SE 04.12.2018 15:20

@ Draco18s Я четко сказал ему два: либо используйте ключевое слово 'new', либо переименуйте его. Почему вам так трудно это видеть? Это прямо здесь. лол, о человек. Кстати, какой третий я не вижу?

JSON 07.12.2018 16:33

В вашем ответе есть переименование, но в качестве небольшого комментария в самом конце. В любом случае третий вариант - удалить поле и использовать объявление из базового класса.

Draco18s no longer trusts SE 07.12.2018 18:19

Вы, люди, слишком разборчивы для моих ссылок. И да, я тоже об этом упоминаю ...

JSON 07.12.2018 21:19

Это поздний ответ, но он может оказаться полезным. Прежде чем углубиться в вашу проблему, сделаем введение:

  • В C# вы можете определить метод, свойство, индексатор или событие как виртуальные (используя ключевое слово virtual). Тем самым вы заявляете, что виртуальный член может быть переопределен в производном классе.
    • Частные члены не могут быть виртуальными, потому что они не будут унаследованы дочерними классами, поэтому их нельзя переопределить.
  • Если вы не объявляете неприкосновенный член родительского класса с «виртуальным», но добавляете член в дочерний класс с тем же именем, это означает, что вы скрываете родительский член.
  • В то время как ключевые слова «виртуальный» и «переопределить» не применяются к элементам поля, применимы концепция скрытия элемента поля и ключевое слово «новое». Это означает, что если вы определяете неперсональный элемент поля в родительском классе, а затем определяете поле с тем же именем в производном классе, вы скрываете родительский член. В вашем случае предупреждение означает, что MonoBehaviour (или один из его родительских классов) определил общедоступное или защищенное поле под названием «коллайдер» типа «BoxCollider2D».
  • Я бы сказал, что в тех случаях, когда вы являетесь автором родительского класса и видите последствия сокрытия родительского члена, вы можете захотеть это сделать (хотя и не рекомендуется).
  • Но в вашем случае, когда у вас нет исходного кода «MonoBehaviour», хотя добавление ключевого слова «new» подавит предупреждающее сообщение, но всей ситуации следует избегать, иначе вы столкнетесь со странными проблемами полиморфизма.
  • Под избеганием я имею в виду просто переименовать ваше поле «коллайдер» во что-то другое, например, «boxCollider2D».

p.s.1 Под «странными проблемами полиморфизма» я подразумеваю, что в зависимости от указателя на объект будет использоваться член родительского класса или член дочернего класса. Подробнее читайте здесь: https://stackoverflow.com/a/22809757/1854557 p.s.2 В моем тестовом коде, когда я добавляю и удаляю новую клавиатуру, результат тот же. Таким образом, кажется, что не добавление нового ключевого слова просто генерирует предупреждение, но не меняет поведение наследования / полиморфизма.

Вы знаете, как это работает, когда вместо этого применяется к двум интерфейсам? Я получаю то же предупреждение, но, на мой взгляд, я должен получить значение свойства того интерфейса, в который я передаю объект.

ryanwebjackson 30.12.2019 16:32

Другие вопросы по теме