Undirected graph data structure in C#
Naming
Renaming your instance variable _V and _E to nbVertices and nbEdges respectively allows you get rid of two unnecessary comments and also makes the rest of the code much clearer, especially to someone who's not too familiar with graph notation.
I'm also not a big fan of prefixing private instance variables with underscores, but that's just my personal opinion.
Similarly, you could give most of your methods' arguments much clearer names.
The standard naming convention for C# is to use PascalCase for methods &amp; properties, and camelCase for fields, so I would rename getAdjacency() and addEdge() to GetAdjacency() and AddEdge().
Properties
    // number of vertices
    public int V
    {
        get { return this._V; }
    }

    // number of edges
    public int E
    {
       get { return this._E; }
    }

can be changed to
    // number of vertices
    public int V
    {
        get =&gt; this._V;
    }

    // number of edges
    public int E
    {
       get =&gt; this._E;
    }

which can further be simplified to
    // number of vertices
    public int V =&gt; this._V;

    // number of edges
    public int E =&gt; this._E;

You could go one step further and merge V and _V into a single property, like this :
public int V { get; private set; }

public int E { get; private set; }

and since V doesn't change after being set in the constructor, you can go even further beyond and make V into a read-only property :
public int V { get; }

This makes it so that V can only be set once in the constructor.
Comments
Personal opinion again, but I don't like comments, especially when they can be made useless by simply changing a variable or a method's name, as was the case with your declarations of _V or _E.
I also really don't like comments that just say what the code is doing, like in your addEdge() method :
public void addEdge(int v, int w)
{
    // validate given node numbers
    if ((v &gt; this._adj.Length) || (w &gt; this._adj.Length))
        throw new ArgumentException(&quot;Invalid node number specified.&quot;);

    // add to adjacency lists
    this._adj[v].Add(w);
    this._adj[w].Add(v);
    // increment edge count
    this._E++;
}

These comments add nothing more than redundant, distracting text that makes the code harder to read. If you see a line of code that says NbEdges++;, do you really need a comment to say // increment edge count ?
Exceptions
I'd recommend always throwing the exception that most closely fits the issue, which in this case would be an ArgumentOutOfRangeException (which is derived from ArgumentException).
Additionally, I would make the exception message more clear and give more information about what actually went wrong. Imagine being a user and seeing &quot;Invalid node number specified.&quot;; which argument was wrong? Was it v or w? Why was the value wrong?
You could go even further and create your own exception class that inherits said exception, in order to reduce code repetition and give your exceptions meaningful names which would help your users.
if (v &lt; 0 || v &gt; this._adj.Length)
{
    throw new ArgumentOutOfRangeException($&quot;Error, the value provided for 'v' should be&quot; + 
        &quot;between 0 and {this._adj.Length - 1}\n&quot; + 
        &quot;\tv = {v}\n&quot;);
}

if (w &lt; 0 || w &gt; this._adj.Length)
{
    throw new ArgumentOutOfRangeException($&quot;Error, the value provided for 'v' should be&quot; + 
        &quot;between 0 and {this._adj.Length - 1}\n&quot; + 
        &quot;\tv = {v}\n&quot;);
}