mam następujące klasy hierarchia:Jak mogę przekonwertować metody C# na kompilowane wyrażenia?
public class Parent
{
[DebuggerStepThrough]
public void SayParent()
{
Console.WriteLine("Parent");
}
}
public sealed class Child : Parent
{
private static int _number = 0;
public Child() // May contain parameter i.e. not always parameterless consctructor
{
_number++;
}
[DebuggerStepThrough]
public void SayInstance()
{
Console.WriteLine("{0}-Say", _number);
}
[DebuggerStepThrough]
public void SayInstanceWithArg(string input)
{
Console.WriteLine("{0}-Say: {1}", _number, input);
}
[DebuggerStepThrough]
public static void SayStatic()
{
Console.WriteLine("{0}-Say", _number);
}
[DebuggerStepThrough]
public static void SayStaticWithArg(string input)
{
Console.WriteLine("{0}-Say: {1}", _number, input);
}
[DebuggerStepThrough]
public static Task SayStaticWithArgAndReturn(string input)
{
Console.WriteLine("{0}-Say: {1}", _number, input);
return null;
}
}
muszę być w stanie wywołać żadnej z tych metod nowej instancji Child
w danym momencie przy użyciu odbicia jednak w celu zwiększenia wydajności muszę uciekać się do Delegate
i/lub Compiled Expressions
.
Tak na przykład może mam:
var instanceOne = new Child();
var instanceTwo = new Child();
za które muszę w czasie wykonywania wywołania tych metod przekazując argumenty dla tych, którzy jej potrzebują. Zauważ, że obejmują one metody static
i instance
z niektórymi akceptującymi parametr.
ja do tej pory próbowałem następujące dla "SayInstance" metody:
var sayInstanceMethod = typeof(Child)
.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)
.Where(m => m.GetCustomAttributes(typeof(DebuggerStepThroughAttribute), true).Length > 0)
.Where(t => t.Name == "SayInstance")
.First()
, a następnie:
var instance = Expression.Constant(new Child()); // This should NOT be Constant, but then what should it be?!
var mCallInstance = Expression.Call(instance, sayInstanceMethod);
Action action = Expression.Lambda<Action>(mCallInstance).Compile();
action();
action(); // I need to pass in a new instance of Child to this method somehow
Jednak ja dostaję:
1-Say
1-Say
zamiast:
1-Say
2-Say
Podejrzeń, że jest to spowodowane Expression.Constant
, ale nie mogę dowiedzieć się, jak mogę pozwolić mu przyjąć wystąpienie Child
jako cel w czasie wykonywania.
Jestem beznadziejny, jeśli chodzi o Expressions
:-(
jestem zasadniczo próbuje wdrożyć co Jon Skeet wspomina HERE albo za pomocą Delegates
lub Compiled Expressions
.
Każda pomoc jest bardzo mile widziane.
Przyrostowy numer na konstruktorze. I to jest pole statyczne. Tak więc nigdy nie uzyskasz rezultatu, którego się spodziewałeś. Przechowuj pole _number w polu prywatnym –
To tylko metoda zapewniająca efekt końcowy. Głównym problemem jest to, że nie mogę utworzyć wyrażenia, które akceptuje nową instancję 'Child' w czasie wykonywania. – MaYaN
Czy wiersze 'var instanceOne = new Child();' i 'var instanceTwo = new Child();' uruchomiono w tym samym teście, który dwukrotnie wywołuje funkcję 'action();'? – Mat