Why can’t I access a field but the method can?

Asked

Viewed 61 times

4

I have the following code in C#:

namespace ConsoleApplication4
{
    public class BaseClass
    {
        public BaseClass()
        {
            System.Console.WriteLine("BaseClass::BaseClass();");
        }
    }
    public class DerivedClass : BaseClass
    {
        public int num;
        public DerivedClass(int x)
        {
            num = x;
            System.Console.WriteLine("DerivedClass::DerivedClass(int x);");
        }
    }
    class Program
    {
        static void Main()
        {
            BaseClass A = new DerivedClass(20);
            //B.num = 20; Erro
            //Mas se converter para DerivedClass e mostrar resultado do 'num':
            DerivedClass B = (DerivedClass)A;
            System.Console.WriteLine(B.num); //Ele mostra o resultado que modificou no construtor! Ué? Por que isso pode?
            /* Resultado:
             * BaseClass::BaseClass();
             * DerivedClass::DerivedClass(int x);
             * 20
             */
            System.Console.ReadKey();
        }
    }
}

The comments in the code are already self-explanatory.

1 answer

5


The problem is that your reference A, of the kind BaseClass, may keep a reference for any object of BaseClass, not only of DerivedClass. Thus, there is no way for the compiler to know beforehand what the actual type of the object pointed by A, and so know that he owns the type DerivedClass (and therefore the field num).

(Okay, in that case, it would even be possible if the compiler was "smart," but in others it was not)

For example, what if you had:

static void teste(BaseClass A) 
{
    System.Console.WriteLine(A.num);
}

static void Main()
{
    teste(new DerivedClass(20)); // tem o campo num
    teste(new BaseClass());      // NÃO TEM o campo num! O que acontece agora?
}

To avoid such problems, the compiler only lets you access the fields it are sure that are there, hence the mistake in trying to make A.num.

Formally speaking, the static type of A is BaseClass, and the dynamic type of A at that time of execution is DerivedClass. Since C# is a statically typed language, what counts when accessing an object field is its static type. If it were a dynamically typed language (like Javascript, Python, Ruby, etc.) then this command would work - but in compensation, it would cause an error at runtime if the object contained in A had not the field num.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.