Inspect Mono Classes and Assemblies with monop

monop prints the public shape of a Mono class straight from the compiled assembly, skipping the hunt for matching API documentation.

Allow about ten minutes for a first inspection. The examples assume the mono-devel package is installed and use only ordinary user privileges.

1. Check the installed tool

This guide was tested with Ubuntu's mono-devel package version 6.8.0.105+dfsg-3.6ubuntu2. The binaries report runtime version 4.0.30319.42000. Your output can differ if the package has been updated, so check the command before copying examples into documentation or scripts.

$ command -v monop monop2
/usr/bin/monop
/usr/bin/monop2
$ dpkg-query -W -f='${Package} ${Version}\n' mono-devel
mono-devel 6.8.0.105+dfsg-3.6ubuntu2
$ monop --runtime-version
runtime version: 4.0.30319.42000

The manual describes monop as the viewer for 1.0 assemblies and monop2 for 2.0 assemblies. This Mono release ships both, and the examples below use whichever is available at /usr/bin/monop. Treat the output as a description of the installed assemblies, not a substitute for the API documentation of another Mono release.

2. Inspect a fully qualified class

Pass the class name as the final argument, including its namespace. Start with System.String, which is available from the core library:

$ monop System.String
[Serializable]
public sealed class String : ICloneable, IComparable, IComparable<string>, ... {
	public String (char [] value);
	public static string Compare (string strA, string strB);
	...
}

The output is an outline: type modifiers, base types and interfaces, constructors, methods, properties and other members. The displayed class name is not necessarily the spelling you use in source code: a generic type may appear as List<T> in the output, while the lookup name uses the runtime generic-arity suffix from the next step.

Checkpoint: if you see Could not find CLASS_NAME, check the namespace and spelling first. A non-zero result is a lookup problem, not a reason to run the command with sudo.

3. Quote generic type names

For a generic type, use the backtick followed by the number of generic parameters, and quote the value so the shell passes the backtick literally:

$ monop2 'System.Collections.Generic.List`1'
[Serializable]
public class List<T> : ICollection, ICollection<T>, IEnumerable, ... {
	public List ();
	public void Add (T item);
	public bool Contains (T item);
	...
}

The 1 means one generic parameter; a type with two would use `2. Use single quotes rather than leaving the backtick unquoted: in an interactive shell, an unquoted backtick starts command substitution and changes what actually reaches monop.

4. Reduce noise when reading an API

Large framework types produce long listings. These options make a targeted inspection easier:

Combine options before the class name:

$ monop -d -f System.DateTime | sed -n '1,35p'
public struct DateTime : IComparable, IComparable<DateTime>, IConvertible, ... {
	public DateTime (long ticks);
	public static int Compare (DateTime t1, DateTime t2);
	...
}

monop writes a human-readable report, not a stable machine-readable format, so avoid parsing whitespace-sensitive output in build tooling. Pipe it to a pager or use sed as above for a short terminal view; truncating the display does not change the inspection.

5. Select an assembly explicitly

When several assemblies contain similar types, or the type belongs to a library outside the default search set, provide the assembly with -r:ASSEMBLY. This local installation has the framework System.dll at the following path:

$ test -r /usr/lib/mono/4.5/System.dll && echo readable
readable
$ monop -r:/usr/lib/mono/4.5/System.dll System.Net.WebClient | sed -n '1,28p'
public class WebClient : Component {
	public WebClient ();
	public void DownloadFile (string address, string fileName);
	...
}

Replace the path with the actual assembly you need. Do not infer a path from an example on another host: check it with test -r or find first. Reading an assembly needs no elevated privilege when your account can read the file. If permissions block access, fix package or directory ownership through your normal administration process rather than granting broad permissions just for an inspection.

6. Inspect references and search for unknown types

To see the assemblies named by another assembly, combine --refs with -r:. The reference listing does not accept a class name:

$ monop --refs -r:/usr/lib/mono/4.5/System.dll
mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03bf3856ad364e35
System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
...

Reference names help explain why a type may not load in a particular environment. They do not install missing assemblies or alter the runtime search path.

If you only know part of a type name, use --search, -s or -k:

$ monop --search WebClient
Loading mscorlib, Version=4.0.0.0, Culture=neutral, ...
Loading System, Version=4.0.0.0, Culture=neutral, ...
...

Tip: search scans known assemblies and can load many of them, so its diagnostic output may be far larger than the result you actually want. Use it interactively, then rerun the inspection with the exact namespace and an explicit -r: path. If search finds nothing, check that the relevant assembly is installed and the name fragment is distinctive.

7. Keep broad and platform-specific options deliberate

-a asks for all types in a specified assembly and can produce a very large report, so do not use it casually in a terminal capture or automated job. -xa and -xi select Xamarin.Android and Xamarin.iOS lookup paths: they only matter on systems with those SDK directories, and will not make a missing mobile SDK appear.

Warning: these commands only read metadata and print it; they do not modify assemblies, package state or application configuration, so no rollback is needed. Keep output containing private type names out of public bug reports, and remember that -p can expose implementation details that may be security-sensitive.

Done means