What is the difference between the Namespace Index (ns) and the Namespace URI (nsu) access

This article is relevant for all .Net products

In OPC UA the server's address space is described using the name-spaces concept. All addressable entities in the server must belong to one single namespace.
The namespace must contain unique identifiers and using different name-spaces, the server's designer, can ensure a name collision free addressing even in case the same identifiers are used.
A namespace in the server is uniquely represented by an URI (string). The server exposes the list of it's namespace URIs in an array. The index () location of an namespace URI is this array very important because on the regular read/write/subscribe operations only the namespace index will be used for performance reasons. (It is faster to transport an integer value than a full blown string.)
In a server the namespace URIs may not change, but the position of a certain namespace URI in the namespace array may change. That's the reason of existence of a so called ExpandedNodeID structure that besides the namespaceID and Identifier contains the URI of the namespace as well. This ExpandedNodeID should only be used for persisting the identifiers at the client side and for validating that the namespace indexes did not change on the server after a server restart. Nn order to read / write / monitor, the API requires the application to provide a NodeID. This structure is supposed to uniquely identify a certain resource in the address space of a server.
The NodeID consists of a NamespaceIndex (ns) and an Identifier (which is a union and can be a string or an integer or a GUID or a byteArray - opaque). For the NodeID no Namespace URI (nsu) is required. The nsu is only required for an ExpandedNodeID definition.
The namespace URI string is never used in the actual interaction with the server, just the namespace index is used.
The namespace index is always mandatory, the namespace URI is optional and actually not required when NodeID class is used.