c# - How to use reflection to get extension method on generic type -
from various sources on teh interwebs i've gleaned following function:
public static nullable<t> tryparsenullable<t>(this nullable<t> t, string input) t : struct { if (string.isnullorempty(input)) return default(t); nullable<t> result = new nullable<t>(); try { iconvertible convertiblestring = (iconvertible)input; result = new nullable<t>((t)convertiblestring.totype(typeof(t), cultureinfo.currentculture)); } catch (invalidcastexception) { } catch (formatexception) { } return result; }
i've made extension method, , works fine if call directly:
int? input = new int?().tryparsenullable("12345");
my problem occurs when try call using reflection within context of generic function. full of answers describing how methodinfo of generic methods , static methods, can't seem put these in right way.
i've correctly determined passed generic type generic type (nullable<>
), want use reflection call tryparsenullable
extension method on nullable<>
:
public static t getvalue<t>(string name, t defaultvalue) { string result = getsomestringvalue(name); if (string.isnullorempty(result)) return defaultvalue; try { if (typeof(t).isgenerictype && typeof(t).getgenerictypedefinition() == typeof(nullable<>)) { methodinfo methodinfo; //using tryparse() of underlying type works isn't way want //------------------------------------------------------------------------------------------- nullableconverter nc = new nullableconverter(typeof(t)); type t = nc.underlyingtype; methodinfo = t.getmethod("tryparse", bindingflags.public | bindingflags.static, type.defaultbinder, new[] { typeof(string), t.makebyreftype() }, null); if (methodinfo != null) { var inputparameters = new object[] { result, null }; methodinfo.invoke(null, inputparameters); return (t) inputparameters[1]; } //start of problem area //------------------------- type ttype = typeof(t); //this works undesirable (due reference class containing static method): methodinfo = typeof(parentextensionsclass).getmethod("tryparsenullable", bindingflags.public | bindingflags.static); if (methodinfo != null) console.writeline(methodinfo); //standard way of getting static method, doesn't work (getmethod() returns null): methodinfo = ttype.getmethod("tryparsenullable", bindingflags.public | bindingflags.static); if (methodinfo != null) console.writeline(methodinfo); //jon skeet's advised method, doesn't work in case (again getmethod() returns null): //(see footnote link answer) methodinfo = ttype.getmethod("tryparsenullable"); methodinfo = methodinfo.makegenericmethod(ttype); if (methodinfo != null) console.writeline(methodinfo); //another random attempt (also doesn't work): methodinfo = ttype.getmethod("tryparsenullable", bindingflags.public | bindingflags.static, type.defaultbinder, new[] { typeof(string) }, null); if (methodinfo != null) console.writeline(methodinfo); } // if far, not handling type yet throw new argumentexception("the type " + defaultvalue.gettype() + " not yet supported getvalue<t>.", "t"); } catch (exception e) { [snip] } }
can put me out of misery?
typeof(t)
returns correct type info, figure maybe i'm using little incorrectly getmethod()
call, or haven't specified right parameters call getmethod()
.
the problem extension methods don't modify type 'extending'. happens behind scenes compiler transparently translates calls seem made on object in question calls static method.
ie.
int? input = new int?().tryparsenullable("12345"); // becomes... int? input = yourclass.tryparsenullable(new int?(), "12345");
from there becomes obvious why it's not showing via reflection. explains why have have using
directive namespace yourclass
defined extension methods visible compiler. how can @ information, i'm not sure there way, short of running on declared types (perhaps filtered list of interesting classes, if know sort of information @ compile time) looking static methods extensionmethodattribute
([extensionmethod]
) defined on them, trying parse methodinfo
parameter list work out if work on nullable<>
.
Comments
Post a Comment