C# get class and method summary
程序员文章站
2023-02-20 14:43:29
/// ///Class Summary, Xml Comments Summary /// public class XmlCommentsSummary { /// /// Print DateTime Now ///
/// <summary>
///class summary, xml comments summary
/// </summary>
public class xmlcommentssummary
{
/// <summary>
/// print datetime now
/// </summary>
public void printtime()
{
console.writeline($"now is {datetime.now.tostring("yyyymmddhhmmssffff")}");
}
/// <summary>
/// print random guid
/// </summary>
public void printguid()
{
console.writeline($"guid is {guid.newguid().tostring()}");
}
}
1.via oos namotion.reflection
using namotion.reflection; static void summarydemo() { type type = typeof(xmlcommentssummary); string summary = type.getxmldocssummary(); console.writeline(summary); methodinfo[] mis = type.getmethods(); if(mis!=null && mis.any()) { foreach(var mi in mis) { string sum = mi.getxmldocssummary(); if(!string.isnullorwhitespace(sum)) { console.writeline($"method name:{mi.name},summary:{sum}"); } } } }
2.copy * solution from
/// <summary> /// utility class to provide documentation for various types where available with the assembly /// </summary> public static class documenationextensions { /// <summary> /// provides the documentation comments for a specific method /// </summary> /// <param name="methodinfo">the methodinfo (reflection data ) of the member to find documentation for</param> /// <returns>the xml fragment describing the method</returns> public static xmlelement getdocumentation(this methodinfo methodinfo) { // calculate the parameter string as this is in the member name in the xml var parametersstring = ""; foreach (var parameterinfo in methodinfo.getparameters()) { if (parametersstring.length > 0) { parametersstring += ","; } parametersstring += parameterinfo.parametertype.fullname; } //al: 15.04.2008 ==> bug-fix remove “()” if parametersstring is empty if (parametersstring.length > 0) { return xmlfromname(methodinfo.declaringtype, 'm', methodinfo.name + "(" + parametersstring + ")"); } else { return xmlfromname(methodinfo.declaringtype, 'm', methodinfo.name); } } /// <summary> /// provides the documentation comments for a specific member /// </summary> /// <param name="memberinfo">the memberinfo (reflection data) or the member to find documentation for</param> /// <returns>the xml fragment describing the member</returns> public static xmlelement getdocumentation(this memberinfo memberinfo) { if (memberinfo != null) { // first character [0] of member type is prefix character in the name in the xml return xmlfromname(memberinfo.declaringtype, memberinfo.membertype.tostring()[0], memberinfo.name); } return null; } /// <summary> /// returns the xml documenation summary comment for this member /// </summary> /// <param name="memberinfo"></param> /// <returns></returns> public static string getsummary(this memberinfo memberinfo) { if (memberinfo != null) { var element = memberinfo.getdocumentation(); var summaryelm = element?.selectsinglenode("summary"); if (summaryelm == null) { return ""; } return summaryelm.innertext.trim(); } return null; } /// <summary> /// provides the documentation comments for a specific type /// </summary> /// <param name="type">type to find the documentation for</param> /// <returns>the xml fragment that describes the type</returns> public static xmlelement getdocumentation(this type type) { // prefix in type names is t return xmlfromname(type, 't', ""); } /// <summary> /// gets the summary portion of a type's documenation or returns an empty string if not available /// </summary> /// <param name="type"></param> /// <returns></returns> public static string getsummary(this type type) { var element = type.getdocumentation(); var summaryelm = element?.selectsinglenode("summary"); if (summaryelm == null) { return ""; } return summaryelm.innertext.trim(); } /// <summary> /// obtains the xml element that describes a reflection element by searching the /// members for a member that has a name that describes the element. /// </summary> /// <param name="type">the type or parent type, used to fetch the assembly</param> /// <param name="prefix">the prefix as seen in the name attribute in the documentation xml</param> /// <param name="name">where relevant, the full name qualifier for the element</param> /// <returns>the member that has a name that describes the specified reflection element</returns> private static xmlelement xmlfromname(this type type, char prefix, string name) { string fullname; if (string.isnullorempty(name)) { fullname = prefix + ":" + type.fullname; } else { fullname = prefix + ":" + type.fullname + "." + name; } var xmldoc = xmlfromassembly(type.assembly); if (xmldoc != null) { var matchedelement = xmldoc["doc"]["members"].selectsinglenode("member[@name='" + fullname + "']") as xmlelement; return matchedelement; } return null; } /// <summary> /// a cache used to remember xml documentation for assemblies /// </summary> private static readonly dictionary<assembly, xmldocument> cache = new dictionary<assembly, xmldocument>(); /// <summary> /// a cache used to store failure exceptions for assembly lookups /// </summary> private static readonly dictionary<assembly, exception> failcache = new dictionary<assembly, exception>(); /// <summary> /// obtains the documentation file for the specified assembly /// </summary> /// <param name="assembly">the assembly to find the xml document for</param> /// <returns>the xml document</returns> /// <remarks>this version uses a cache to preserve the assemblies, so that /// the xml file is not loaded and parsed on every single lookup</remarks> public static xmldocument xmlfromassembly(this assembly assembly) { if (failcache.containskey(assembly)) { return null; } try { if (!cache.containskey(assembly)) { // load the docuemnt into the cache cache[assembly] = xmlfromassemblynoncached(assembly); } return cache[assembly]; } catch (exception exception) { failcache[assembly] = exception; return null; } } /// <summary> /// loads and parses the documentation file for the specified assembly /// </summary> /// <param name="assembly">the assembly to find the xml document for</param> /// <returns>the xml document</returns> private static xmldocument xmlfromassemblynoncached(assembly assembly) { var assemblyfilename = assembly.codebase; const string prefix = "file:///"; if (assemblyfilename.startswith(prefix)) { streamreader streamreader; try { streamreader = new streamreader(path.changeextension(assemblyfilename.substring(prefix.length), ".xml")); } catch (filenotfoundexception exception) { throw new exception("xml documentation not present (make sure it is turned on in project properties when building)", exception); } var xmldocument = new xmldocument(); xmldocument.load(streamreader); return xmldocument; } else { throw new exception("could not ascertain assembly filename", null); } } } static void getxmlsummarycomments() { type type = typeof(xmlcommentssummary); string typesummary = type.getsummary(); console.writeline($"{typesummary}"); methodinfo[] mis = type.getmethods(); if (mis != null && mis.any()) { foreach (var mi in mis) { string methodsummary = type.getmethod(mi.name).getsummary(); if(!string.isnullorwhitespace(methodsummary)) { console.writeline($"method name:{mi.name},summary:{methodsummary}"); } } } }