28

我今天在看 Infragistics 控件库的在线帮助,看到一些使用With关键字在选项卡控件上设置多个属性的 VB 代码。自从我进行任何 VB 编程以来,已经快 10 年了,我几乎忘记了这个关键字甚至存在。由于我对 C# 还比较陌生,所以我很快就去看看它是否有类似的构造。可悲的是,我什么也没找到。

C# 是否有关键字或类似结构来模仿VB中的With关键字提供的功能?如果没有,是否有 C# 没有这个的技术原因?

编辑: 在问我的问题之前,我搜索了一个现有的条目,但没有找到 Ray 提到的那个(这里)。那么,为了细化这个问题,C# 没有这个有技术原因吗?Gulzar 做到了——不,C# 没有With关键字没有技术原因。这是语言设计者的设计决定。

4

7 回答 7

26

这就是 C# 程序经理不得不说的: 为什么 C# 没有'with'语句?

  • 小的或不存在的可读性好处。我们认为可读性的好处很小或根本不存在。我不会说 with 语句会降低代码的可读性,但有些人可能会。

  • 语言复杂度增加。添加 with 语句会使语言更加复杂。例如,VB 必须添加新的语言语法来解决局部变量 (Text) 和“with”目标 (.Text) 上的属性之间的潜在歧义。解决这个问题的其他方法也引入了语言复杂性。另一种方法是推送一个作用域并使属性隐藏局部变量,但是如果不添加一些转义语法就无法引用局部变量。

  • C++ 遗产。C++ 从来没有 with 语句,而且 C++ 开发人员通常不认为缺少这样的语句是一个问题。此外,我们并不认为其他变化——人们正在编写的代码类型的变化、平台的变化、语言的其他变化等——使语句变得更加必要。

于 2009-03-02T03:12:50.307 回答
16

在 C# 3.0 中,您可以在创建对象时使用对象初始化器来实现类似的效果。

var control = new MyControl
{
    Title = "title",
    SomeEvent += handler,
    SomeProperty = foo,
    Another = bar
};

而不是:

var control = new MyControl();
control.Title = "title";
control.SomeEvent += handler;
control.SomeProperty = foo;
control.Another = bar;

请注意,虽然这种语法是在 C# 3.0 中引入的,但您仍然可以在 2.0 框架中使用它,它只是编译器引入的语法糖。

于 2009-03-02T03:17:31.997 回答
11

这不是惯用的 c#,但如果你真的想要一个with等价的,你可以这样做:

Person MyPersonWithALongName = new Person();
MyUtils.With(MyPersonWithALongName, p => {

    p.Name = "George";
    p.Address = "123 Main St";
    ...

});

class MyUtils {

    public static void With<T>(T x, Action<T> do) {
        do(x);
    }
}

更新:
在我看来,您可以通过将其转换为扩展方法来简单地使其更简洁,也许将其重命名为“Alias”或“As”以实现可重复性:

MyPersonWithALongName.Alias(p => {
    p.Name = "George";
    p.Address = "123 Main St";
    ...
});
于 2009-03-02T04:04:10.120 回答
9

不,“with”关键字被故意排除在语言之外。

如果您有一个冗长的引用名称,您可以使用变量轻松地对其进行较短的引用,甚至给它一个有限的范围:

{
   SomeClass r = Some.Lengthy.Path.To.Get.To.A.Referece;
   r.Some = 42;
   r.Properites = "none";
   r.To = 1;
   r.Set = null;
}
于 2009-03-02T03:21:57.773 回答
1

对于这些解决方案:

// ....
// (class Common)

public static void With<T>(T property, Action<T> action) {
    action(property);
}

// ...
// usage somewhere ...    
Person person = GetPerson();
Common.With(person, p => { p.Name = "test", p.Age = "123" });

似乎我们用“p”为变量起别名。随着解决方案的发展,我发现保持变量名称简短很容易,这种带有“With”泛型的解决方案不会带来任何优雅。

理想情况下,我们都希望看到对语法进行一些修改,以便其用法类似于今天的多个属性的初始化工作方式:

Person person = new Person() { Name = "test", Age = "123" };
于 2011-11-29T18:01:46.210 回答
0

不,这是 C# 开发团队有意识的决定。人们对 'with' 关键字有复杂的感觉,因为如果被滥用(嵌套 with's)会降低代码的可读性。

于 2009-03-02T03:11:59.153 回答
-1

我不认为它不存在有技术原因。不过,我要说的是,它不存在的原因是它是一种编程构造,其存在的目的仅仅是为了减少打字。有了智能感知和复制粘贴之类的东西,世界对此类功能的需求就不再太多了。我使用 VB.Net,不记得它是否仍然受支持。从来没有真正觉得需要使用它。

于 2009-03-02T03:12:21.820 回答