3

My base class declares:

public double Value;

My derived class declares:

public new decimal Value;

In the tip to use the new keyword, it says: "...Use the new keyword if hiding was intended.".

This explanation doesn't seem correct. When using the new keyword, it is not hiding the base variable. It keeps both variables with the same name, and even with different values.

I understand there is a design issue on my side, but I'd like to know why the new keyword doesn't really hide the base class variable. Also, why the new keyword is even available if it would mean a design issue (changing data type in the derived class). Is using dynamic an option here? The issue is: for most part, double is fine. However in a few derived classes, it must be decimal.

This question is focused on the use of the new keyword for variables in derived classes, not really a discussion of differences between double and decimal.

Thank you.

igorjrr
  • 790
  • 1
  • 11
  • 22
  • 2
    Both variables are there. If you say `var der=new Derived();` then `der.Value` will be `decimal`. However, `((Base)der).Value` will be `double`. An instance of a subclass is *always* an instance of its base class, so the base class member must be there. What the `new` keyword does is say that in the context of the derived class, `Value` has a *new* meaning compared to the meaning in the context of the base class – Flydog57 Jun 20 '20 at 05:26
  • 1
    OP,. one question you could ask yourself is, what exactly is the variable hidden *from*? When you are able to answer that question correctly then I think the answer to your post will be obvious. – John Wu Jun 20 '20 at 06:56

1 Answers1

5

You mixed the concepts about (new, override) and (property, field).

I'll provide some information about them and provide my suggestion. My suggestion is on the 3rd part.

If this post doesn't answer your question, please edit your post with use case.


new is not override

new is to "hide" base class's property/field, which is NOT overriding virtual functions.

To sum up:

  1. override is used when base class' virtual function need to be altered or abstract function need to be defined.

If child class calls a function foo of base class which calls a virtual function bar, the CHILD version of bar would be called, not base version.

  1. For new,

If a child class calls a function foo of base class which calls a function bar, the BASE version of bar would be called, not child version.

I rarely use new, so can't suggest about how to use it.

Ref Difference between new and override


You cannot override a Field.

public class foo
{
    public double field; // This is field
    public int property  // This is property
    {
        get{ return 1  };
    }
}
  1. Property is a wrapper of get/set functions.

  2. Property could be overridden (because of #1), but fields could not be overridden.

Ref What is the difference between a field and a property?


Suggestion

What I come to mind is to implement Value as an object property

public class foo
{
    public virtual object Value
    {
        get; set;
    }
}

Then wrapping it to desired type, but this would cost box and unboxing.

However if your case is not performance critical, it should be okay.

public class bar : foo
{
    public override object Value
    {
        get{ // something different
        }; 
        set{ // something different
        };
    }

    public double DesiredValue
    {
        get{  return (double)Value };
    }
}
Louis Go
  • 2,213
  • 2
  • 16
  • 29
  • Since in this case we are dealing with Double (8 bytes) and Decimal (16 bytes) should we also consider the memory / CPU trade-off of just storing them all as Decimal and truncating it as a Double as needed? I assume this would be faster than boxing and unboxing. – Origin Jul 29 '20 at 11:40
  • @Origin I can't answer your question easily, because it depends on context. If box/unboxing frequently occur, I'd say profile it and see if performance increases. Also memory usage of the machine might be concerned in resource limited case.... – Louis Go Jul 29 '20 at 11:46