NGWS SDK Documentation  

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Visibility, Accessibility, and Security

To refer to a named entity in a scope, both the scope and the name in the scope must be visible. Visibility is determined by the entity that contains the reference (the referent) and the entity that contains the name being referenced. Consider the following pseudo-code:

class A
{ int32 IntInsideA;
}
class B inherits from A
{ method X(int32, int32) returning Boolean
  { IntInsideA := 15;
  }
}

If we consider the reference to the field IntInsideA in class A:

There are two fundamental questions that need to be answered in order to decide whether the referent is allowed to access the referenced entity. The first is whether the name of the referenced entity is visible to the referent. If it is visible, then there is a separate question of whether the referent is accessible.

Access to a member of a type is permitted only if all three of the following conditions are met:

  1. The type is visible.
  2. The member is accessible.
  3. All relevant security demands have been granted.

Visibility of Types

Only type names, not member names, have controlled visibility. Type names fall into one of the following three categories

Note: In V1, all exportable types are in fact exported from the assembly in which they are defined.

Accessibility of Members

A type scopes all of its members, and it also specifies the accessibility rules for its members. Except where noted, accessibility is decided based only on the statically visible type of the member being referenced and the type and assembly that is making the reference. The VOS supports six different rules for accessibility:

In general, a member of a type can have any one of these accessibility rules assigned to it. There are two exceptions, however:

  1. Members defined by an interface must be public.
  2. When a type defines a virtual method that overrides an inherited definition, the accessibility must either identical in the two definitions or the overriding definition must permit more access than the original definition. For example, it is possible to override an assembly virtual method with a new implementation that is public virtual, but not with one that is family virtual. In the case of overriding a definition derived from another assembly, it is not considered restricting access if the base definition has family or assembly access and the override has only family access.
Rationale: Languages including C++ allow this “widening” of access. Restricting access would provide an incorrect illusion of security since simply casting an object to the base class (which occurs implicitly on method call) would allow the method to be called despite the restricted accessibility.

CLS Rule 9: Accessibility must not be changed when overriding inherited methods, except when overriding a method inherited from a different assembly with accessibility family or assembly. In this case the override must have accessibility family.

CLS (consumer): need not accept types that widen access to inherited virtual methods.

CLS (extender): need not provide syntax to widen access to inherited virtual methods.

CLS (frameworks): must not rely on the ability to widen access to a virtual method, either in the exposed portion of the framework or by users of the framework.

Security Permissions

Access to members is also controlled by security demands that can be attached to an assembly, type, method, property, or event. Security demands are not part of a type contract (see Contracts), and hence are not inherited. There are two kinds of demands:

Only one demand of each kind can be attached to any item. Attaching a security demand to an assembly implies that it is attached to all types in the assembly unless another demand of the same kind is attached to the type. Similarly, a demand attached to a type implies the same demand for all members of the type unless another demand of the same kind is attached to the member.

Nested Types

A type (called a nested type) can be a member of an enclosing type. A nested type has the same visibility as the enclosing type and has an accessibility as would any other member of the enclosing type. This accessibility determines which other types can make references to the nested type. That is, for a class to define a field or array element of a nested type, have a method that takes a nested type as a parameter or returns one as value, etc., the nested type must be both visible and accessible to the referencing type. A nested type is part of the enclosing type so its methods have access to all members of its enclosing type, as well as family access to members of the type from which it inherits (see Type Inheritance). The names of nested types are scoped by their enclosing type, not their assembly (only top-level types are scoped by their assembly). There is no requirement that the names of nested types be unique within an assembly.