36

I'm trying to understand the internal access modifier in C#. I can't seem to understand what an assembly is exactly, and what part of my program is held inside that assembly. I was trying to make it so that a variable is accessibly only by objects within the following namespace:

namespace Engine.Entity

The variable in question is defined in a class inside of that namespace, so I assumed if I made it internal, only objects inside of that namespace have access to it. I am seeing assemblies and namespaces as one, and I don't think that's right.

Michael Currie
  • 13,721
  • 9
  • 42
  • 58
Prodigga
  • 1,457
  • 1
  • 22
  • 37
  • 2
    Take a look at the ".Net Reflector" program. It will let you open an assembly and see what is in it. You'll see that a single assembly can contain multiple namespaces. – David Dec 15 '10 at 05:50

5 Answers5

37

Namespaces affect name resolution only. Namespaces do not imply any sort of storage, nor do namespaces determine which DLLs contain your code. Namespaces allow you to group related things together under a logical name even though they may physically reside in different DLLs.

An assembly is basically just a DLL or EXE file. It contains IL code and type information that describes the code in that DLL or EXE. It can contain a lot of other stuff too, but for starters just think of it as a DLL.

You put your code into a particular assembly by compiling your code into a project (csproj) that produces the DLL or EXE.

A namespace can span multiple assemblies. That is, classes that are members of that logical namespace may reside in multiple DLLs. You can access a particular class in your source code only if your project references the correct assembly (DLL) that contains that class.

The Internal modifier means that the symbol can only be accessed from within the same assembly. Only code that is compiled into the same DLL as your code can access your properties or methods that are tagged with internal.

dthorpe
  • 35,318
  • 5
  • 75
  • 119
  • 2
    "An assembly is basically a DLL or EXE." True, but sometimes it can be any kind of file (jpegs, text files, etc) or several at the same time. It is the edge case though (see my answer on this post). – Brent Arias Dec 15 '10 at 14:40
  • Yes, an assembly can be/contain a whole mess of things. Not relevant to the level of this question. – dthorpe Dec 15 '10 at 16:53
  • 1
    So an assembly is grouped by the project right? So if I have project within a solution, that project will produce an assembly dll or exe – Kellen Stuart Jun 11 '19 at 16:59
  • If I understood you correctly, assembly is a product of one particular project (.csproj) which means that official definition of "Internal members are accessible only within files in the same assembly " can be rephrased to " (...) in the same project". – bombek Jul 18 '19 at 08:24
13

People are easily confused by the namespace/assembly thing, as it decouples the concept of where your code is physically located (the assembly) and how you reference it (logically reference is by using the namespace and physical reference is by referencing the assembly).

I usually explain this using the word contribute:

  1. An assembly can contribute to multiple namespaces.
    For instance, the System.Data.dll assembly contributes to namespaces like System.Data (e.g. the class System.Data.DataTable) and Microsoft.SqlServer.Server (e.g. the class Microsoft.SqlServer.Server.SqlContext).

  2. Multiple assemblies can contribute to a single namespace.
    For instance both the System.Data.dll assembly and the System.Xml.dll assembly contribute to the System.Xml namespace.
    Which means that if you use the System.Xml.XmlDataDocument class from your project, you need to reference the System.Data.dll assembly.
    And if you use the System.Xml.XmlDocument class, you need to reference the System.Xml.dll from your project.

(the above examples are .NET 4.0, but likely hold for previous .NET versions as well).

Danny Thorpe explained the concept of namespace and internal really well, so I won't go into detail about those.

--jeroen

Community
  • 1
  • 1
Jeroen Wiert Pluimers
  • 23,965
  • 9
  • 74
  • 154
3

From internal (C# Reference)

The internal keyword is an access modifier for types and type members. Internal types or members are accessible only within files in the same assembly

So this means from within the same assembly/dll, not namespace.

David
  • 34,223
  • 3
  • 62
  • 80
Adriaan Stander
  • 162,879
  • 31
  • 289
  • 284
2

Namespaces and assemblies are not synonymous. Often a namespace spans several assemblies. Any managed code built from Visual studio has a one for one corresponce of projects to assemblies to DLL/EXE binaries.

However, if you link your managed code with the command line, you can make an assembly where multiple project files all belong to one assembly (which means multiple files on your disk are together representing one assembly). But never mind this case, it is an esoteric thing that never occurs in practice.

The 'internal' access modifer simply means that the target can only be accessed from within that assembly. It has no bearing on namespaces.

Brent Arias
  • 29,277
  • 40
  • 133
  • 234
1

Basically, you cannot make a variable visible only from within a given namespace. As anybody can define any namespace, this would make the idea of internal void: you would just have to write

namespace System
{
    public static MySystemInternalSpy
    {
        public static void SpyInternals()
        {
            ...
        }
    }
}

to gain access to any variable, class or method defined as internal in the System namespace, for instance.

Pierre Arnaud
  • 10,212
  • 11
  • 77
  • 108