如何创建一个扩展方法,使我能够执行以下操作(警告:exteme伪代码)......
class FooBar
{
Int32 Foo { get; set; }
String Bar { get; set; }
}
new FooBar().With(fb => new Func<FooBar, Object>(instance =>
{
// VB With magic
// NOTE: The instance parameter HAS to be by reference
instance.Foo = 10;
instance.Bar;
return new Object();
}));
如果您可以指定没有返回类型(void)的匿名函数,则上面看起来会更清晰......
new FooBar().With(fb => new Func<FooBar, void>(instance =>
{
instance.Foo = 10;
instance.Bar;
}));
这是最糟糕的伪代码。但我希望你明白这一点。
答案 0 :(得分:4)
要指定不带返回类型的匿名方法,请使用Action<T>
而不是Func<T, TResult>
:
new FooBar().With(new Action<FooBar>(instance =>
{
instance.Foo = 10;
instance.Bar;
}));
(在这个特殊情况下,我不太明白这一点,但我会在伪代码部分接受你的意见......)
<强>更新强>
完整的完整示例:
扩展方法:
public static void With<T>(this T input, Action<T> action)
{
action(input);
}
样本用法
new FooBar().With(fb =>
{
fb.Foo = 10;
fb.Bar = "some string";
});
请注意,您不需要显式声明Action<FooBar>
,编译器会将其显示出来。如果您愿意,为清楚起见,电话会是这样的:
new FooBar().With<FooBar>(new Action<FooBar>(fb =>
{
fb.Foo = 10;
fb.Bar = "some string";
}));
答案 1 :(得分:2)
也许这会有所帮助:
new FooBar().With( fb=> {
fb.Foo = 10;
fb.Bar = fb.Foo.ToString();
} );
// ... somewhere else ...
public static void With<T>( this T target, Action<T> action ) {
action( target );
}
答案 2 :(得分:2)
当您询问如何编写扩展时,请转到
public static void With<T>(this T target, Action<T> action) where T : class
{
action(target);
}
个人看不出这有什么好处,但填补你的靴子!
答案 3 :(得分:1)
如何
return new FooBar{ Foo=10; };
答案 4 :(得分:1)
你希望如何:
FooBar instance = new FooBar();
instance.With(new
{
Foo = 1,
Bar = "B"
});
这可以使用以下扩展方法:
using System.Reflection;
public static class WithExtension
{
public static T With<T>(this T target, object values)
{
Type targetType = typeof(T);
foreach (PropertyInfo prop in values.GetType().GetProperties())
{
PropertyInfo targetProp = targetType.GetProperty(prop.Name);
if (targetProp != null && targetProp.PropertyType==prop.PropertyType)
{
targetProp.SetValue(target, prop.GetValue(values, null), null );
}
else
{
throw new InvalidOperationException();
}
}
return target;
}
}
这基本上是将属性的值从匿名对象复制到目标对象。 (上面的代码只适用于属性,不适用于字段,但可以很容易地扩展到能够处理这两个属性。)
请注意,这比使用lambda更简洁。缺点是静态类型检查不起作用。