Question

I'm new to Java but working on C# for years. So I'm going to translate a code which has been written in Java, to C#. Everything was OK but I come to a code that seems to be strange. Here is the code:

//Java Version
public class ParentClass{

    ArrayList<SomeType> values;
    void MyFunction(){ /*some codes*/ }
    //other codes    

    public class NestedClass {

        public void handleMessage(SomeType val) {           
            values.add(val);                 //This cannot be done in C#
            MyFunction();                    //This cannot be done in C#
        }
    }
}

Not surprisingly, in C# I cannot access to values (which is a List<SomeType>) and MyFunction. Why this is possible in Java and How can I get the equivalent code in C#?

Was it helpful?

Solution

There are several kinds of inner (nested) classes in Java:

  1. Static inner classes
  2. Non-static inner classes
  3. Function-local inner classes
  4. Anonymous inner classes

These classes differ in what members they can access in their outer class.

C# has only one kind of class, corresponding to the #1 from Java's list. What your code has is the #2, a non-static inner class. Instances of these classes have an implicit reference to their outer class, explaining the way they can access the members of their outer class. In exchange for having this implicit reference, non-static inner classes can be instantiated only in the context of an object of the outer class.

To model non-static inner classes in C# one would add a constructor that takes an instance of the outer class, and replace all direct references to members of the outer class with references qualified by the variable referencing the outer class that you set in the constructor.

OTHER TIPS

To access the members of the outer class from the inner class in C# you need to pass the outer class to the inner in the constructor

public class ParentClass{
    public class NestedClass {

        private ParentClass parent;

        public NestedClass(ParentClass parent){
            this.parent = parent;
        }
    }
}

In Java this is no needed because an inner class (non-static nested class) can exist only within an instance of the outer class, having this way access to the members of the outer class. This means in Java you need first to instantiate the outer class and then create the inner object associated to it

ParentClass outer = new ParentClass();
outer.NestedClass = outer.new NestedClass();

The work-around in C# is a little awkward:

public class ParentClass
{
    internal List<SomeType> values;
    internal virtual void MyFunction()
    {
    }

    public class NestedClass
    {
        private readonly ParentClass outerInstance;

        public NestedClass(ParentClass outerInstance)
        {
            this.outerInstance = outerInstance;
        }

        public virtual void handleMessage(SomeType val)
        {
            outerInstance.values.Add(val);
            outerInstance.MyFunction(); 
        }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top