【问题标题】:Missing the 'with' keyword in C# [duplicate]在 C# 中缺少“with”关键字 [重复]
【发布时间】:2009-03-02 03:08:32
【问题描述】:

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

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

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

【问题讨论】:

  • (离题;您询问了 protobuf-net - 给我发电子邮件至 marc.gravell@gmail.com)
  • 除了 Gulzar Nazim 所说的之外,我还在一次会议上向 Anders Helsburg 提出了这个问题。他的回答更……简洁。 'C# 永远不会支持 With 关键字'

标签: c# .net syntax keyword


【解决方案1】:

这是 C# 程序经理必须说的: Why doesn't C# have a 'with' statement?

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

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

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

【讨论】:

  • @Gulzar - 感谢您的链接。虽然我不同意 Wiltamuth 先生的前两条推理,但它“抓痒了”。对我来说,with 关键字与可读性的关系比它更容易编写代码...
  • ... 而且我发现很难相信 with 关键字与 LINQ、匿名方法等所涉及的复杂性相近,但我离题了。再次感谢您的链接。
  • 你在钱上是对的,但解释很薄弱。 C++ 遗产不包括现代数据 C# 中的一大堆东西。
  • 这些是对C#程序管理器的解释。任何 VB.NET 开发人员都知道 With 关键字在多大程度上提高了代码质量:与 C# 相比,没有临时变量、快速转换、实现相同目标的代码要少得多。
【解决方案2】:

在 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 框架中使用它,它只是编译器引入的语法糖。

【讨论】:

  • 是的,但只有在创建对象时才能这样做。如果对象已经存在,则没有机制。不过还是谢谢你的提醒。
  • 好的,谢谢。我在帖子中进一步澄清了这一点。
【解决方案3】:

这不是惯用的 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";
    ...
});

【讨论】:

  • 您需要确保将 T 限制为引用类型(“where T : class”),以免意外编辑 struct x 的副本
【解决方案4】:

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

如果你有一个很长的引用名称,你可以很容易地使用一个变量对其进行更短的引用,甚至给它一个有限的范围:

{
   SomeClass r = Some.Lengthy.Path.To.Get.To.A.Referece;
   r.Some = 42;
   r.Properites = "none";
   r.To = 1;
   r.Set = null;
}

【讨论】:

    【解决方案5】:

    对于这些解决方案:

    // ....
    // (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" };
    

    【讨论】:

      【解决方案6】:

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

      【讨论】:

      • 我不知道您可以嵌套“with”语句。那会降低可读性。然而,像 GoTo 和许多其他编程结构一样,如果使用得当,真的那么糟糕吗?
      • 我认为如果使用得当会很好。
      【解决方案7】:

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

      【讨论】:

        猜你喜欢
        • 2010-10-08
        • 2012-03-27
        • 1970-01-01
        • 1970-01-01
        • 2018-01-12
        • 2015-02-24
        • 2015-12-03
        • 2019-08-17
        • 1970-01-01
        相关资源
        最近更新 更多