2010-12-05 39 views
1

我发现自己(太)经常使用像下面这样的结构:有没有什么办法可以推断一个Action类型,或者一个完整的Action?

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; 
    } 
} 

有没有什么办法让二传手类来推断行动的类型和特点是只透过会员在创建标准(T obj) => Member = obj行动某种方式?我想的是这样的:

new Setter(ObjectA) 

这当然是无效的语法,但应该给你一个想法是什么,我想要的目的。我在我的代码中使用这个构造的字面意思是数百个时间,所以通过这个小改变保存的代码 将是巨大的。


编辑:增加了输入的例子。部分

new Setter<TypeD>(d => ListOfObjectD.Add(d)) 

可以简化为

new Setter<TypeD>(ListOfObjectD.Add) 

这是真棒,因为它从冗余代码切割。如果只有<TypeD>也可以被推断,那将是完美的。我正在为其他人寻找这样的东西。

@Lazarus - 基本目的是返回制定者,所以其它的目的可以设置类的某些成员(或它可以做在操作定义的其它东西),而无需访问类本身,仅设置器对象。完整的原因列表是漫长而复杂的,但是程序的结构就像一种魅力,我怀疑需要改变(当然这个例子是简化的,并没有真正意义)。


编辑2:我发现把事情简单化了名单的一个好办法:该作品完美

ListOfObjectD.GetSetter() 

static class SetterHelper 
{ 
    public static Setter<T> GetSetter<T>(this List<T> list) 
    { 
     return new Setter<T>(list.Add); 
    } 
} 

现在就可以用这个!为什么我不能直接为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 
    } 
} 

当然如预期,因为它会设置项目,但不是通过成员就不会工作。我尝试添加ref(ref this T item)但它不会编译:(......这本来是完美的

+0

对不起,我不能测试这个,因为我的Windows分区上没有安装Visual Studio,但是可以在公共时使用public DoSmth(Object ObjectType),然后键入typeof(ObjectType)以获取对象类型创建它? – 2010-12-05 19:11:24

+1

我在这里错过了什么,是什么这个构造的目标?我的经验是,当事情变得太复杂时,我通常会误解问题空间和/或语言结构。如果有人能够解释这种结构的作用和原因,我会非常感激。 – Lazarus 2010-12-05 19:17:35

回答

2

尽我所能为您提供的是语法如下:

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); 
    } 
} 
相关问题