Evan Aad
Evan Aad

Reputation: 6035

Why does a class definition in one cell not recognize another class's fields made in another cell?

I used a Visual Studio Code's Polyglot notebook and wrote the following in 3 separate cells, in the order indicated below.

Cell 1:

class Z;

Cell 2:

class A
{
    public static void f()
    {
        Console.WriteLine(Z.x);
    }
}

Cell 3:

class Z: A
{
    public static int x = 42;
}

I then executed the cells in order, and got the following error message.

'Z' does not contain a definition for 'x'

My original question was:

Is it possible, in C#, to write a (possibly abstract) class A that has a (possibly static) function with signature void f(B b), whose parameter's type B is a (possibly abstract) class that derives from A (class B: A {...})? If not, why not?

and it was titled Can a C# class use a derived class?

I accepted the answer below based on this formulation. This formulation was later deleted by another user who edited my question, and changed its title.

Upvotes: -3

Views: 116

Answers (3)

MakePeaceGreatAgain
MakePeaceGreatAgain

Reputation: 37060

The notebook executes the cells one by one. So when you execute cell 2, Z is nothing but a class, without any notion of x. That's why you get the error.

It's not clear what behaviour you actually want. Of course you can just write the entire code into a single cell:

class A
{
    public static void f()
    {
        Console.WriteLine(Z.x);
    }
}    
class Z: A
{
    public static int x = 42;
}

So your problem is not related to inheritance, but to how Polyglot executes the cells. Be aware, though, that your approach is pretty strange. A base-class should never make any assumptions about derived classes, this it it shouldn't even know that there exist any derived classes in the first place. However that's more of a conceptual problem, which is way too broad for this questions scope.

Upvotes: 4

wohlstad
wohlstad

Reputation: 28774

Yes, it is possible.

Here's an example that follows exactly what you requested:

using System;

class A
{
    public void f(B b)
    {
        Console.WriteLine("in A.f.  b.Prop=" + b.Prop.ToString());
    }
}

class B : A
{
    public int Prop { get; set; } = 0;
}

class Program
{
    static void Main(string[] args)
    {
        B b1 = new B();
        b1.Prop = 1;
        B b2 = new B();
        b2.Prop = 2;
        b1.f(b2);
        A a = new A();
        a.f(b1);
    }
}

Output:

in A.f.  b.Prop=2
in A.f.  b.Prop=1

Live demo

Note:
Since you asked, A and/or B can also be abstract.


Update:
The questiom was editted after this answer was given, with additional details about the usage of Polyglot notebook.
Regarding this additional information: the problem is related to the way the notebook executes the cells one by one. It is not an issue related to C# in general or the usage of inheritance in particular.

Upvotes: 2

PMF
PMF

Reputation: 17288

Yes, sure. This is fully valid:

class A
{
   public B GetDerived() => new B();
}

class B : A
{
   // ...
}

Of course, the two classes need to be in the same assembly, because they need to know each other. The other question is for a relevant use case, which I find hard to imagine. Normally, if A is abstract, you would return A's (which then need to be derived types of A), and not B's, since that prevents you from later creating a class C that derives from A and which would replace B.

Upvotes: 2

Related Questions