2

In the following Unity/C# code, the collider variable produces the following warning:

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

What does this mean and how do I fix it?


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

    // ...
}
Ben
  • 14,557
  • 16
  • 84
  • 127
  • 3
    Possible duplicate of [Why does resharper prefer to not hide a property from an abstract class inside another abstract class?](https://stackoverflow.com/questions/19671421/why-does-resharper-prefer-to-not-hide-a-property-from-an-abstract-class-inside-a) –  Dec 03 '18 at 22:12
  • Note that the duplicate question asks about a warning given by "Resharper", but it is essentially the same thing... –  Dec 03 '18 at 22:12
  • 2
    By the way, the likely answer to your question "_how do i fix it?_" is: Don't attempt hiding members. Possibly, you should be able to succeed without defining your own `collider` property, as your Controller2D already has a `collider` property inherited from its base class. –  Dec 03 '18 at 22:19

2 Answers2

4

It is a late answer, but you may find it useful. Before digging into your problem, here is an introduction:

  • In C#, you can define a method, property, indexer, or event as virtual (using "virtual" the keyword). By doing so, you are declaring that the virtual member can be overridden in a derived class.
    • Private members cannot be virtual, because they won't be inherited by the child classes, so they cannot be overridden.
  • If you don't declare a non-private member of a parent class with "virtual", but you add a member to a child class with the same name, it means you're hiding the parent member.
  • While "virtual" and "override" keywords don't apply to field members, the concept of hiding a field member and the "new" keyword do. This means if you define a non-private field member in a parent class, then define a field with the same name in the derived class, you're hiding the parent member. In your case the warning means MonoBehaviour (or one of its parent classes) has defined a public or protected field called "collider" of type "BoxCollider2D".
  • I would say in the cases that you're the author of the parent class, and you can see the consequences of hiding a parent member, you may want to do it (although not recommended).
  • But, in your case, where you don't own the "MonoBehaviour" source code, although adding the "new" keyword would suppress the warning message, but the whole situation should be avoided or you'll encounter weird polymorphism issues.
  • By avoiding, I mean simply rename your "collider" field to something else like "boxCollider2D"

p.s.1 By "weird polymorphism issues" I mean depending on your object pointer, the parent class member or the child class member will be used. You can read more here: https://stackoverflow.com/a/22809757/1854557 p.s.2 In my test code, when I add and remove the new keyboard, the result is the same. So it seems not adding the new keyword just generates the warning, but doesn't change the behavior of inheritance/polymorphism.

Siavash Mortazavi
  • 917
  • 1
  • 9
  • 15
  • Do you know how this works when applied to two interfaces instead? I'm getting the same warning, but in my mind, I should get the value of the property of whichever interface I'm casting the object as. – ryanwebjackson Dec 30 '19 at 15:32
3

This is a warning that means a base class of Controller2D named Component already has a property with the same name collider. The warning is there to inform you that any implementation of Controller2D will use your definition of it and "hide" the base definition. To prevent the warning simply change the definition of collider to

new BoxCollider2D collider;

Then it will know that you mean to hide this priperty and the warning would go away.

There is not much reason to do it. Public and internal properties are already available. If the your property doesn't match or extend the the property you are hiding it will most likely cause issues, so if you don't know if you want to hide another property you should rename it.

JSON
  • 967
  • 8
  • 24
  • Don't nilly-willy suggest a "fix" by simply making member hiding explicit by using `new`. There is a reason why the compiler warns about member hiding unless you make your intention of really wanting to hide a member really explicit. There can be grave side-effects if you suggest to utilize member hiding haphazardly. Member hiding should only be used in certain situations and only if one really knows what member hiding implies so one can avoid possible unwanted side-effects. (See the duplicate question in the first comment to this question here). –  Dec 03 '18 at 23:08
  • @ elgonzo He asked why it was happening and how to fix it. What more do you want? You want me to tell him not to do that unless he is sure he wants to? This is the correct answer. It is not my responsibility to know his intent. Plus I told him to name it something else. Jeez – JSON Dec 03 '18 at 23:11
  • He asked what it means, which means he doesn't really know. Anyway, everything has been said... –  Dec 03 '18 at 23:12
  • @egonzo No it hasn't, no one told him what it means or why it was happening. So I told him – JSON Dec 03 '18 at 23:14
  • 1
    No, you really didn't... You just said along the lines of "Go ahead. Put the `new` keyword there. Then your field definition will be used and not that of the base class". No. Whether it will be used or not does not depend on putting the `new` keyword there but on the reference type of the variables referencing a Controller2D instance. But considering your attitude here, i think you really don't care about what member hiding really is doing... –  Dec 03 '18 at 23:17
  • @egonzo you just posted a possible duplicate for a question that is completely unrelated. And you are right. It does not care abou the new definition and will use it regardless, but it shuts up the compiler from giving warnings. He asked why, I told him why. What I didn't do is post some random response unrelated to the question. Good Day sir – JSON Dec 03 '18 at 23:20
  • Really, unless OP spells out explicitly in letters that he doesn't know what member hiding is or does, even though it is obvious from the question, your point is that it is the OP's responsibility to know the thing he doesn't know about. Okay, there is no point in furthering this argument... –  Dec 03 '18 at 23:22
  • Yes it is the op's responsibility to know if he intends to hide the member after I told him what it means. He didn't know what it meant. I told him, in the first sentence. I told him how to fix it. It is better than posting a completely unrelated possible duplicate, explaining things that is clearly over his head. Are you done whining yet? – JSON Dec 03 '18 at 23:29
  • So, now you are saying that "_if the OP intends to do the thing he doesn't know anything about he should do so and so_". And the whole thing is "_over the OP's head_" anyhow. "_Who cares what will happen with OPs code, OP will not understand anything anyhow, it's too much for him to understand._" Amirite? Please proceed, it gets more and more interesting... –  Dec 03 '18 at 23:34
  • No. I never said anything like that. He asked what it means, and I told him the answer. He asked how to fix it and I told him the answer. Literaly you the only two things you can do. What I didn't do is post a duplicate that does that doesn not answer the question explaining when and if you should hide properties, when you said yourself, he doesn't even know what hiding a property means. Now, I can add more description if you wish, but all you had to do is ask. Or feel free to edit the answer if you wish. – JSON Dec 04 '18 at 05:48
  • 4
    *grabs popcorn* – Antoine Thiry Dec 04 '18 at 11:32
  • @JSON There are *two* answers to the problem (possibly three), one of them is more right than the other. You told him one of them, and the one you told him about is the very-specific-use-case-only-do-if-you-know-what-you're-doing one. The other (two) are far simpler and more general case. Also, the dupe target is correct, remember, doesn't matter if the *question* is different, but whether or not the *answer applies.* And in this case, it does. – Draco18s no longer trusts SE Dec 04 '18 at 14:20
  • @Draco18s I clearly told him two, Either use the 'new' keyword or rename it. Why is this so hard for you people to see that? It is right there. lol, oh man. BTW what is the third one I am not seeing? – JSON Dec 07 '18 at 15:33
  • Your answer does have renaming, but as a minor comment at the very end. In any case, the third option is to remove the field and u use the declaration from the base class. – Draco18s no longer trusts SE Dec 07 '18 at 17:19
  • 1
    You people are far too picky for my linking. And yes I mention that too... – JSON Dec 07 '18 at 20:19