С lamba выражениями и инициализаторами класса можно получить то же поведение с небольшим количеством усилия.
public class Example {
public Action DoStuff;
public Action<int> DoStuffWithParameter;
public Func<int> DoStuffWithReturnValue;
}
class Program {
static void Main(string[] args) {
var x = new Example() {
DoStuff = () => {
Console.WriteLine("Did Stuff");
},
DoStuffWithParameter = (p) => {
Console.WriteLine("Did Stuff with parameter " + p);
},
DoStuffWithReturnValue = () => { return 99; }
};
x.DoStuff();
x.DoStuffWithParameter(10);
int value = x.DoStuffWithReturnValue();
Console.WriteLine("Return value " + value);
Console.ReadLine();
}
}
Одна проблема с этим решением, которое я просто осознал, состоит в том, что, если бы необходимо было создать поля в классе В качестве примера, лямбда-выражения не смогли бы получить доступ к тем полям.
Однако нет никакой причины, что Вы не могли передать экземпляр Примера к лямбда-выражениям, которые предоставят им доступ к любому общедоступному состоянию, которое мог бы содержать пример. AFAIK, который был бы функционально эквивалентен Java Анонимный Внутренний Класс.
P.S., Если Вы собираетесь провалить ответ, сделайте нас всех польза и добавьте комментарий относительно того, почему Вы не соглашаетесь :-)
Невозможно объединить дерево выражений, представленное как объект Expression
, в середину «литерал дерева», представленный лямбда-выражением. Вам нужно будет построить дерево выражений для перехода к GroupBy
вручную:
// Need an explicitly named type to reference in typeof()
private class ResultType
{
public string SubcategoryName { get; set; }
public int ProductNumber { get; set; }|
}
private static void DoSomethingWithExpression(
Expression<Func<Product,
string>> myExpression)
{
var productParam = Expression.Parameter(typeof(Product), "product");
var groupExpr = (Expression<Func<Product, ResultType>>)Expression.Lambda(
Expression.MemberInit(
Expression.New(typeof(ResultType)),
Expression.Bind(
typeof(ResultType).GetProperty("SubcategoryName"),
Expression.Invoke(myExpression, productParam)),
Expression.Bind(
typeof(ResultType).GetProperty("ProductNumber"),
Expression.Property(productParam, "ProductNumber"))),
productParam);
using (AdventureWorksDataContext db = new AdventureWorksDataContext())
{
var result = db.Products.GroupBy(groupExpr);
}
}
Если подумать, компиляция выражения не сработает.
Вам нужно будет собрать свой Выражение GroupBy вручную, что означает, что вы не можете использовать анонимный тип. Я бы предложил построить остальную часть вашего выражения, а затем декомпилировать, чтобы увидеть сгенерированное дерево выражений. Конечный результат будет выглядеть примерно так, если использовать соответствующие части myExpression
:
private static void DoSomethingWithExpression(Expression<Func<Product, string>> myExpression)
{
var productParam = myExpression.Parameters[0];
ConstructorInfo constructor = ...; // Get c'tor for return type
var keySelector = Expression.Lambda(
Expression.New(constructor,
new Expression[] {
productParam.Body,
... // Expressions to init other members
},
new MethodInfo[] { ... }), // Setters for your members
new [] { productParam });
using (AdventureWorksDataContext db = new AdventureWorksDataContext())
{
var result = db.Products.GroupBy(keySelector);
// ...
}
}