c# - How to access anonymous method from generic list? -
i've been working on library generate fake data using faker.net. problem i'm having don't know how access anonymous method i'm passing constructor of datagenerator child classes.
the issue in order create list of generics had create base class datagenerator cannot pull func<t> member because base class not generic no tavailable. however, datagenerator<t> class expose generator property anonymous method haven't found way access while iterating list of data generators.
any advice highly appreciated.
this have far:
public class employee { public string firstname { get; set; } public string lastname { get; set; } public guid empuid { get; set; } } // define other methods , classes here public abstract class datagenerator { public abstract int getweight(string matchingproperty); public abstract type type { get;} } public abstract class datagenerator<t> : datagenerator { public readonly string[] tags; public readonly func<t> generator; protected datagenerator(func<t> generator, params string[] tags) { tags = tags; //how access this? generator = generator; } public override int getweight(string matchingproperty) { int sum = (from tag in tags matchingproperty.tolowerinvariant().contains(tag.tolowerinvariant()) select 1).sum(); return sum; } public override type type { { return typeof(t); } } } public class stringdatagenerator : datagenerator<string> { public stringdatagenerator(func<string> generator, params string[] tags) : base(generator, tags) { } } public class guiddatagenerator : datagenerator<guid> { public guiddatagenerator(func<guid> generator, params string[] tags) : base(generator, tags) { } } and i'm testing here:
private static void main(string[] args) { var datageneratorlist = new list<datagenerator> { new stringdatagenerator(name.first, "first", "name"), new stringdatagenerator(name.last, "last", "name"), new guiddatagenerator(guid.newguid, "uid", "id") }; var writeproperties = typeof (employee).getproperties().where(p => p.canwrite); foreach (var property in writeproperties) { foreach (var datagenerator in datageneratorlist) { if (property.propertytype == datagenerator.type) { var weigth = datagenerator.getweight(property.name); //how access generator here??? var testvalue = datagenerator.generator.invoke(); } } } }
as tagged, given current setup, reflection option.
var func = datagenerator.gettype().getfield("generator").getvalue(datagenerator); var testvalue = func.gettype().getmethod("invoke").invoke(func, null); i'm not sure call super nice, , won't super fast, it's sufficient need fake data in, suppose.
for measure, here's in action.
your question bit more complicated may seem @ face-value. nice way of handling if ever use in object form add abstract generate method base, non-generic class:
public abstract object generate(); then override in generic one:
public override object generate() { return this.generator(); } of course, return object, isn't nice in generic class. @ least avoids reflection.
another solution avoid reflection nonsense might use of covariance, although will, unfortunately, break value types, guid.
public interface idatagenerator<out t> { int getweight(string matchingproperty); type type { get;} t generate(); } public abstract class datagenerator<t> : idatagenerator<t> { public readonly string[] tags; public readonly func<t> generator; protected datagenerator(func<t> generator, params string[] tags) { tags = tags; //how access this? generator = generator; } public t generate(){ return this.generator(); } . . . } that turns preferable,
private static void main(string[] args) { var datageneratorlist = new list<idatagenerator<object>> { new stringdatagenerator(name.first, "first", "name"), new stringdatagenerator(name.last, "last", "name") // line doesn't work // new guiddatagenerator(guid.newguid, "uid", "id") }; var writeproperties = typeof (employee).getproperties().where(p => p.canwrite); foreach (var property in writeproperties) { foreach (var datagenerator in datageneratorlist) { if (property.propertytype == datagenerator.type) { var weigth = datagenerator.getweight(property.name); var testvalue = datagenerator.generate(); } } } }
Comments
Post a Comment