There were some issues with the X++ compiler’s enforcement of internal rules, and the Microsoft team has now modified the compiler so that it can correctly diagnose the rules. In the upcoming April 2022 release, the Product team is going to change how we used to access internal method and classes in X++. Before we elaborate the changes that will be included in the next release, let us first discuss what internal is, and why and when it is used.
When a class or method is marked as internal, it can only be accessible from within the model in which it is defined. Internal is a keyword that is used to define a type or a type member’s accessibility to be exclusive to the assembly in which it is defined. An internal modifier is used to restrict the usage of a public modifier, which allows access to other assemblies as needed.
Internal class MyInternalClass
{
internal void myInternalMethod()
{
}
}
The purpose of marking codes as internal in X++ is to allow engineers to write code while also allowing them to change the signatures of their code without damaging any code that extends it.
Below picture will help you to understand how access modifier work in X++.

The changes included in the upcoming release should not present any problems if you make use of the internal access modifier in your own code. For other codes however, the only time you would encounter an issue is if your code is using Inheritance on a Microsoft class and tries to override an internal method or change its access modifier. The issues were mostly fixed because of how inheritance works and what the compiler allows and doesn’t allow you to do.
- Public class shouldn’t be allowed to extend an internal class.
internal class ClassA { }
public class ClassB extends classA
{
// classB is in the same model as classA
}
This scenario was changed from a warning to an error
InconsistentAccessibilityInheritance: Base class ‘ClassA’ is less accessible than class ‘ClassB’).
Customer code that extends Microsoft code will be unaffected because it can’t extend internal classes to begin with.
2. Internal class won’t be used as internal member in any declaration.
internal class ClassA {}
public class ClassB // ClassB is in the same model as ClassA
{
internal ClassA a;
public ClassA b;
protected ClassA c;
private ClassA d;
}
This scenario used to result in the following errors:
Error: InconsistentFieldAccessibility: The type ‘ClassA’ of the member variable ‘a’ is internal to Model ‘MyModel’ and is not accessible from model ‘MyModel’.
Error: InconsistentFieldAccessibility: The type ‘ClassA’ of the member variable ‘b’ is internal to Model ‘MyModel’ and is not accessible from model ‘MyModel’.
Error: InconsistentFieldAccessibility: The type ‘ClassA’ of the member variable ‘c’ is internal to Model ‘MyModel’ and is not accessible from model ‘MyModel’.
With the change, this results in the following errors:
Error: InconsistentAccessibility: field type ‘ClassA’ is less accessible than field ‘b.ClassB’
Error: InconsistentAccessibility: field type ‘ClassA’ is less accessible than field ‘c.ClassB’
With the change, this results in the following errors:
Error: InconsistentAccessibility: field type ‘ClassA’ is less accessible than field ‘b.ClassB’
Error: InconsistentAccessibility: field type ‘ClassA’ is less accessible than field ‘c.ClassB’
3. Internal method overridden in inheritance will result in error.
class Base
{
internal void method()
{
}
}
// in the same model as Base
class LocalA extends Base
{
public void method() {}
}
class LocalB extends Base
{
internal void method() {}
}
class LocalC extends Base
{
protected void method() {}
}
class LocalD extends Base
{
private void method() {}
}
This will now result in the following errors:
LocalA.xpp(3,5): CannotChangeAccess: ‘LocalA.method’ cannot change access modifiers when overriding inherited method ‘Base.method’
LocalC.xpp(3,5): CannotChangeAccess: ‘LocalC.method’ cannot change access modifiers when overriding inherited method ‘Base.method’
LocalD.xpp(3,5): CannotChangeAccess: ‘LocalD.method’ cannot change access modifiers when overriding inherited method ‘Base.method’
Customer code will only be damaged if they have an internal method in their own model that they publicly override.
// in the different model as Base
class LocalA extends Base
{
public void method() {}
}
class LocalB extends Base
{
internal void method() {}
}
class LocalC extends Base
{
protected void method() {}
}
class LocalD extends Base
{
private void method() {}
}
DerivedA.xpp(3,5): CannotChangeAccess: ‘DerivedA.method’ cannot change access modifiers when overriding inherited method ‘Base.method’
DerivedB.xpp(3,5): InvalidOverrideIntenalMethod: Method ‘method’ in class ‘Base’ is internal and is not allowed to be overriden.
DerivedC.xpp(3,5): CannotChangeAccess: ‘DerivedC.method’ cannot change access modifiers when overriding inherited method ‘Base.method’
DerivedD.xpp(3,5): CannotChangeAccess: ‘DerivedD.method’ cannot change access modifiers when overriding inherited method ‘Base.method’
Customer code will only be compromised if it exploits use of an issue in the compiler that allows public overriding of a non-accessible internal method to go unchecked.
Leave a comment