Provides methodof
, propertyof
and fieldof
equivalents of typeof
.
See Milestones for release notes.
This is an add-in for Fody
It is expected that all developers using Fody become a Patron on OpenCollective. See Licensing/Patron FAQ for more information.
See also Fody usage.
Install the InfoOf.Fody NuGet package and update the Fody NuGet package:
PM> Install-Package Fody
PM> Install-Package InfoOf.Fody
The Install-Package Fody
is required since NuGet always defaults to the oldest, and most buggy, version of any dependency.
Add <InfoOf/>
to FodyWeavers.xml
<Weavers>
<InfoOf/>
</Weavers>
var type = Info.OfType("AssemblyName", "MyClass");
var method = Info.OfMethod("AssemblyName", "MyClass", "MyMethod");
var methodTyped = Info.OfMethod<MyClass>("MyMethod");
var constructor = Info.OfConstructor("AssemblyName", "MyClass");
var constructorTyped = Info.OfConstructor<MyClass>();
var getProperty = Info.OfPropertyGet("AssemblyName", "MyClass", "MyProperty");
var getPropertyTyped = Info.OfPropertyGet<MyClass>("MyProperty");
var setProperty = Info.OfPropertySet("AssemblyName", "MyClass", "MyProperty");
var setPropertyTyped = Info.OfPropertySet<MyClass>("MyProperty");
var field = Info.OfField("AssemblyName", "MyClass", "myField");
var fieldTyped = Info.OfField<MyClass>("myField");
var getIndexer = Info.OfIndexerGet("AssemblyName", "MyClass", "Int32");
var getIndexerTyped = Info.OfIndexerGet<MyClass>("Int32");
var setIndexer = Info.OfIndexerSet("AssemblyName", "MyClass", "Int32");
var setIndexerTyped = Info.OfIndexerSet<MyClass>("Int32");
var type = typeof(MyClass);
var method = methodof(MyClass.MyMethod);
var methodTyped = methodof(MyClass.MyMethod);
var constructor = methodof(MyClass..ctor);
var constructorTyped = methodof(MyClass..ctor);
var getProperty = methodof(MyClass.get_MyProperty);
var getPropertyTyped = methodof(MyClass.get_MyProperty);
var setProperty = methodof(MyClass.set_MyProperty);
var setPropertyTyped = methodof(MyClass.set_MyProperty);
var field = fieldof(MyClass.myField);
var fieldTyped = fieldof(MyClass.myField);
var getIndexer = methodof(MyClass.get_Item);
var getIndexerTyped = methodof(MyClass.get_Item);
var setIndexer = methodof(MyClass.set_Item);
var setIndexerTyped = methodof(MyClass.set_Item);
- Parameters are specified with their full type name
- For methods, when no parameters are specified, the method with the least number of parameters will be returned.
- Parameters are specified as comma separated list, e.g.
"System.String, System.Int32"
. - For every parameter, the first namespace part can be omitted, so
"String, Int32"
works, too. - Nested namespaces are not handled, only
"Regex"
won't work, but"System.Text.RegularExpressions.Regex"
or"Text.RegularExpressions.Regex"
.
Actually there is no specific support for generic methods. Both "Method()"
and "Method<T>()"
will be found by the name Method
.
If there is a non-generic method and a generic overload with the same parameter signature, only the first of both will be returned.
The typeName
parameter of the Info.Of* methods use the following BNF grammar:
<fullTypeSpec> ::= <typeName> [<genericSpec>]
<genericSpec> ::= "<" <genericTypes> ">"
<genericTypes> ::= <genericType> ["," <genericTypes>]
<genericType> ::= <fullTypeSpec>
<name> ::= <identifier> [<name>]
<typeName> ::= <name>
<assemblyName> ::= <name>
<identifier> ::= <letter> | <digit> | <specialChar>
<letter> ::= "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" |
"N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" |
"a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" |
"n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z"
<digit> ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
<specialChar> ::= "." | "`"
To specify a Dictionary<int, string>
, the typeName would be System.Collections.Generic.Dictionary`2<System.Int32,System.String>
.
To find a method with the following signature
MyMethod<T>(T param)
use
Info.OfMethod<MyClass>("MyMethod", "T")
If the following chars are part of the typeName, they will need to be escaped with a "\": "\", "<", ">", "|", ","
.
Also, whitespace is ignored by default, so they also need to be escaped with "\" if part of the typeName.
It would also be possible to define members and types using a combination of generics and expressions. This would allow for intellisense at code time. The problem with expressions are as follows
- The conversion of expression to "infoof"s is significantly more complex. Making the solution more complex and having a negative impact on compile performance.
- Expressions cannot represent non public types or members.
- It is difficult to represent all combinations of members using expressions.
Actually it is strong typed, it does not have intellisense. If any of the strings passed into Info
do not map to a type or member it will log a build error and stop the build.
Information designed by Phil Goodwin from The Noun Project.