简体   繁体   English

vb.net vs c#对象初始化程序:c#中的限制?

[英]vb.net vs c# object initializer: limitation in c#?

In VB.NET you can use an object initializer and reference the same members on the right hand side, like this: 在VB.NET中,您可以使用对象初始化程序并在右侧引用相同的成员,如下所示:

  GetValue.Add(New ArrayIndexInfo() With {
               .Type = CType(NvpInfo(Index), Type),
               .Name = NvpInfo(Index + 2).ToString,
               .NvpValues = CType(.Type.GetField(NvpInfo(Index + 1).ToString).GetValue(Instances.First(Function(o) o IsNot Nothing AndAlso o.GetType = CType(NvpInfo(Index), Type))), NameValuePair())
               })

Notice how in the line that sets .NvpValues you can reference .Type and that it's no problem. 请注意,在设置.NvpValues的行中,您可以如何引用.Type ,这没问题。

But if you try to do that in c# (or like I did, try to convert a project from vb.net to c#), you get an error. 但是,如果您尝试在c#中执行此操作(或像我一样,尝试将项目从vb.net转换为c#),则会出现错误。

<variable> is not declared <variable>未声明

I worked around it like this, which is not DRY because ((Type)NvpInfo[Index]) is repeated: 我像这样解决它,它不是DRY,因为((Type)NvpInfo[Index])被重复了:

        functionReturnValue.Add(new ArrayIndexInfo {
            Type = (Type)NvpInfo[Index],
            Name = NvpInfo[Index + 2].ToString(),
            NvpValues = (NameValuePair[])((Type)NvpInfo[Index]).GetField(NvpInfo[Index + 1].ToString()).GetValue(Instances.First(o => o != null && o.GetType() == (Type)NvpInfo[Index]))
        });
  1. Why doesn't c# allow this? 为什么C#不允许这样做? I think it should. 我认为应该。 I think converting legacy code to c# should be as painless as possible. 我认为将遗留代码转换为C#应该尽可能轻松。
  2. Is there a better way that I get around this and still use the object initializer? 有没有更好的方法可以解决此问题,并且仍然使用对象初始化程序?

To answer the question, I'll base myself on a simplified version of your example 为了回答这个问题,我将基于您的示例的简化版本

VB.NET : VB.NET

Dim c = New SomeClass With {
    .Prop1 = "abc",
    .Prop2 = .Prop1
}

Console.WriteLine(c.Prop1) 'prints "abc"
Console.WriteLine(c.Prop2) 'prints "abc"

C# C#

var c = new SomeClass
{
    Prop1 = "abc",
    Prop2 = Prop1 // won't compile. Can't reference Prop1 here.
};

Console.WriteLine(c.Prop1);
Console.WriteLine(c.Prop2);

Addressing your last question: 解决您的最后一个问题:

Is there a better way that I get around this and still use the object initializer? 有没有更好的方法可以解决此问题,并且仍然使用对象初始化程序?

So one of your concerns is that because C# doesn't allow referencing other properties in an object initialization statement, that it causes you to violate the DRY principle. 因此,您担心的一个问题是,由于C#不允许在对象初始化语句中引用其他属性,因此它会导致您违反DRY原理。 But really, all you need to do is use variables: 但实际上,您需要做的就是使用变量:

Working C# example that doesn't violate DRY principle: 不违反DRY原理的工作C#示例:

string temp = "abc";
var c = new SomeClass
{
    Prop1 = temp,
    Prop2 = temp
};

Console.WriteLine(c.Prop1); // prints "abc"
Console.WriteLine(c.Prop2); // prints "abc"

Why doesn't c# allow this? 为什么C#不允许这样做? I think it should. 我认为应该。

Obviously, only the designers of the language can truly answer that one. 显然,只有语言的设计师才能真正回答这一问题。 But I can at least share why I like C#'s design decision better. 但是我至少可以分享为什么我更喜欢C#的设计决策。 For instance, in the VB.NET version, if I mistakenly initialize the properties in a different order: 例如,在VB.NET版本中,如果我错误地以不同的顺序初始化属性:

Dim c = New SomeClass With {
    .Prop2 = .Prop1,
    .Prop1 = "abc"
}

Console.WriteLine(c.Prop1) 'prints "abc"
Console.WriteLine(c.Prop2) 'prints nothing

... the code is still "legal" but I've now inadvertently introduced a bug, and Prop2 is now initialized incorrectly. ...代码仍然是“合法的”,但是我现在无意中引入了一个错误,并且Prop2现在被错误地初始化。

Because C# disallows this, it prevents most bugs related to the order of property initialization. 因为C#不允许这样做,所以它可以防止大多数与属性初始化顺序有关的错误。 I agree that in this very simplified example it's hard to imagine anyone falling for that mistake. 我同意在这个非常简化的示例中,很难想象有人会犯该错误。 But with more properties and more complicated initialization statements, it may not be so obvious, and mistakes can more easily be made. 但是,随着更多的属性和更复杂的初始化语句,它可能不会那么明显,并且更容易出错。 C# helps you avoid these subtle bugs. C#可帮助您避免这些细微的错误。

I think converting legacy code to c# should be as painless as possible. 我认为将遗留代码转换为C#应该尽可能轻松。

I guess you're implying that VB.NET is a legacy language? 我猜您是在暗示VB.NET是一种传统语言吗? Some may take offense :) 有些人可能会冒犯:)

But more seriously, are you implying that language design decisions should be made to facilitate migration from other languages? 但更严重的是,您是否暗示应该制定语言设计决策以促进从其他语言的移植? C# and VB.NET are two full featured languages in their own right. C#VB.NET本身就是两种功能齐全的语言。 They are not meant to have matching and symmetrical language designs. 它们并不具有匹配和对称的语言设计。 If they did, what would be the point of having 2 separate languages? 如果他们这样做了,那么拥有2种独立语言的意义何在?

No. They are 2 different languages with 2 different philosophies. 不。它们是2种不同的语言,具有2种不同的哲学。 We should consider ourselves lucky that the migration path is as easy as it is currently. 我们应该认为自己很幸运,迁移路径是如此简单。 There is no reason why it needs to be. 没有理由这样做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM