Thanks to visit codestin.com
Credit goes to github.com

Skip to content

C# compiler reports CS1540 on protected non-function member access even when there is a matching hidden public member in a base class #6201

@colinjneville

Description

@colinjneville

With the following class structure, mcs (tested on Windows 5.4.1.0) fails with error CS1540 "Cannot access protected member `B.Field' via a qualifier of type `B'. The qualifier must be of type `M.C' or derived from it", while VS C# 6.0 compiles and runs successfully. Casting to the base class which declared the public member to access the member avoids the error.

public class A {
	public bool Field;
}

public class B : A {
	protected new bool Field;
}

public class C : B {
	public void Z(B b) {
		// CS1540
		b.Field = true;
	}
}

Complete example at https://gist.github.com/colinjneville/ba7d8ac13c84e135f19df500d1879e20

This doesn't affect methods, which resolve to the public version without error. It's not clear to me whether both should be errors or neither; although VS allows both, from my interpretation of the C# 6.0 draft spec, it does seem like the error is technically correct.

If the declared accessibility of T is public, the accessibility domain of T is the program text of P and any program that references P

The accessibility domain of A, B, C is the entire example.

If the declared accessibility of M is public, the accessibility domain of M is the accessibility domain of T

The accessibility domain of A.Field as also the entire example.

If the declared accessibility of M is protected, let D be the union of the program text of T and the program text of any type derived from T. The accessibility domain of M is the intersection of the accessibility domain of T with D.

The accessibility domain of B.Field is the text of B and C.

The scope of a member declared by a class_member_declaration (Class body) is the class_body in which the declaration occurs. In addition, the scope of a class member extends to the class_body of those derived classes that are included in the accessibility domain (Accessibility domains) of the member.

The scope of A.Field is A, B, and C, and the scope of B.Field is B and C.

A constant, field, property, event, or type introduced in a class or struct hides all base class members with the same name.
A method introduced in a class or struct hides all non-method base class members with the same name, and all base class methods with the same signature (method name and parameter count, modifiers, and types).
A declaration of a new member hides an inherited member only within the scope of the new member.

C is in the scope of B.Field, so B.Field should hide A.Field in C.

When a protected instance member is accessed outside the program text of the class in which it is declared, ... the access must take place within a class declaration that derives from the class in which it is declared. Furthermore, the access is required to take place through an instance of that derived class type or a class type constructed from it. This restriction prevents one derived class from accessing protected members of other derived classes, even when the members are inherited from the same base class.

This clause prevents access to B.Field with a B instance from C, but does not prevent hiding.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions