C# 有没有办法推断动作类型或完整动作?

C# 有没有办法推断动作类型或完整动作?,c#,types,action,type-inference,C#,Types,Action,Type Inference,我发现自己(太)经常使用如下构造: class MyClass { public TypeA ObjectA; public TypeB ObjectB; public TypeC ObjectC; public List<TypeD> ListOfObjectD = new List<TypeD>(); public void DoSmth() { return SomeConstruct(

我发现自己(太)经常使用如下构造:

class MyClass
{
    public TypeA ObjectA;
    public TypeB ObjectB;
    public TypeC ObjectC;
    public List<TypeD> ListOfObjectD = new List<TypeD>();

    public void DoSmth()
    {
        return SomeConstruct(
            /*...*/
            new Setter<TypeA>(a => ObjectA = a), // these are the
            new Setter<TypeB>(b => ObjectB = b), // things I'm trying
            new Setter<TypeC>(c => ObjectC = c), // to make shorter
            new Setter<TypeD>(d => ListOfObjectD.Add(d)),
            /*...*/
        );
    }
}
class Setter<T>
{
    public Action<T> Action;

    public Setter(Action<T> action)
    {
        Action = action;
    }
}
这当然不是有效的语法,但应该能让你知道我想要实现什么。我在我的代码中使用了数百个时间,所以代码 这一小小的变化所带来的好处将是巨大的


编辑:添加了键入的示例。角色

new Setter<TypeD>(d => ListOfObjectD.Add(d))
这很好用!为什么我不能直接为t做同样的事情?我试过这个:

static class SetterHelper
{
    public static Setter<T> GetSetter<T>(this T item)
    {
        return new Setter<T>(t => item = t); // THIS DOESN'T SET THE PASSED MEMBER
    }
}
静态类SetterHelper
{
公共静态Setter GetSetter(此T项)
{
returnnewsetter(t=>item=t);//这不会设置传递的成员
}
}

当然,它不会按预期工作,因为它将设置项,但不会设置传递的成员。我尝试将
ref
添加为
(ref this T item)
,但它无法编译:(…它本来是完美的。

我能为您提供的最佳语法是:

Setter.For( () => ObjectA );
使用此帮助器类

static class Setter
{
    public static Setter<T> For<T>(Expression<Func<T>> e)
    {
        ParameterExpression[] args = { Expression.Parameter(((e.Body as MemberExpression).Member as FieldInfo).FieldType) };
        Action<T> s = Expression.Lambda<Action<T>>(Expression.Assign(e.Body, args[0]), args).Compile();

        return new Setter<T>(s);
    }
}
静态类设置器
{
用于(表达式e)的公共静态设置器
{
ParameterExpression[]args={Expression.Parameter((e.Body作为MemberExpression.Member作为FieldInfo.FieldType)};
Action s=Expression.Lambda(Expression.Assign(e.Body,args[0]),args.Compile();
返回新的设定器;
}
}

很抱歉,我无法对此进行测试,因为我的Windows分区上没有安装Visual Studio,但您可以先执行public void DoSmth(对象对象类型)然后执行typeof(对象类型)吗在创建对象时获取对象类型?我这里缺少一些东西,这个构造的目标是什么?我的经验是,当某个对象变得太复杂时,我通常会误解问题空间和/或语言构造。如果有人能解释这个构造的作用和原因,我会非常感激。我的经验当人们发布示例时,他们通常会删除无关的代码,以便将注意力集中在问题上。如果没有上下文,其他程序员可能会对他们为什么要这样做感到困惑。当然,确保尽可能有效地解决问题是很有用的,但我觉得这会进入设计。如果不是关于设计的,那么我只是想帮助他们解决手头的问题。哦,我刚刚读了你的上一篇编辑…也许这可以帮助你?-->你为什么不把
GetSetter
作为一个普通方法(而不是扩展方法)来实现呢,使用
ref T item
作为参数。您可以缩短方法和静态类的名称以避免重复键入。实际上,将
Setter
静态类和
Setter
类都放在同一命名空间中是合法的,因此您可以编写
Setter.Get(ref对象a)
Mmh…听起来和这个答案很相似-->@digEmAll:是的,在很多方面都很相似。但直到我在Visual Studio中把所有内容都散列出来后,才看到你的链接。这并不完全是性能友好的,但还是要感谢你的想法。是的,我可能应该提到……表达式树与反射相比是有效的,但与compa不同当然,一旦创建了委托,它的速度也会一样快,但是初始设置过程不是这样的。
ListOfObjectD.GetSetter()
static class SetterHelper
{
    public static Setter<T> GetSetter<T>(this T item)
    {
        return new Setter<T>(t => item = t); // THIS DOESN'T SET THE PASSED MEMBER
    }
}
Setter.For( () => ObjectA );
static class Setter
{
    public static Setter<T> For<T>(Expression<Func<T>> e)
    {
        ParameterExpression[] args = { Expression.Parameter(((e.Body as MemberExpression).Member as FieldInfo).FieldType) };
        Action<T> s = Expression.Lambda<Action<T>>(Expression.Assign(e.Body, args[0]), args).Compile();

        return new Setter<T>(s);
    }
}