我发现自己(也经常)使用如下构造:
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;
}
}
Setter类是否有任何方法可以通过仅以某种方式传递Member来推断Action的类型并创建标准(T obj) => Member = obj
Action?我想的是:
new Setter(ObjectA)
当然这不是有效的语法,但应该让你知道我想要实现的目标。我在我的代码中使用这个构造字面数百,所以代码 通过这个小小的变化得到了巨大的帮助。
修改:添加了TypeD示例。部分
new Setter<TypeD>(d => ListOfObjectD.Add(d))
可以简化为
new Setter<TypeD>(ListOfObjectD.Add)
这很棒,因为它会从冗余代码中删除。如果只能推断<TypeD>
,那将是完美的。我正在为其他人寻找类似的东西。
@Lazarus - 基本上目的是返回setter,因此其他对象可以设置类的某些成员(或者它可以执行Action中定义的其他内容)而无需访问类本身,仅Setter对象。完整的原因列表很长很复杂,但程序的结构就像一个魅力,我怀疑需要改变(当然,这个例子是简化的,并没有真正有意义。)
编辑2:我找到了简化List的简化方法:
static class SetterHelper
{
public static Setter<T> GetSetter<T>(this List<T> list)
{
return new Setter<T>(list.Add);
}
}
现在我可以使用它:
ListOfObjectD.GetSetter()
完美无缺!为什么我不能直接为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 :(得分: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);
}
}