在C#中实现VB With语句

时间:2010-09-03 08:46:19

标签: c# vb.net

如何创建一个扩展方法,使我能够执行以下操作(警告: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;
}));

这是最糟糕的伪代码。但我希望你明白这一点。

5 个答案:

答案 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更简洁。缺点是静态类型检查不起作用。