“空安全” VB.NET 中的点表示法...或者它是否存在于任何语言中? “安全解引用运算符”或使用 LINQ 的等效项?

发布于 2024-10-25 07:04:58 字数 775 浏览 1 评论 0原文

我正在 VB.net 中寻找“安全”点符号。在 VB.NET 或任何语言中是否存在这样的东西?我想要做的是,当使用不可为空遗留对象时,解决这样的问题:

“如果有计划,如果有案例,如果有一个人,那个人的配偶,否则什么都没有(VBSpeak for Null)。”

并避免这样做:

Dim Spouse as Person = Nothing
if Case.Plan isnot nothing then
    if Case.Plan.Person isnot Nothing
        Spouse = Case.Plan.Person.Spouse
    end if
end if

并这样做:

Dim Spouse as Person = Case~Plan~Person~Spouse

其中 '~' 是我寻求的“安全”点符号,当遇到第一个 null 对象时立即返回 null 而不是抛出异常?

当然,这个问题更常见:

dim MyVar as string = XMLDoc.DocumentElement.SelectSingleNode("Name").InnerText

当 Name 不存在时,想要 Nothing 而不是异常。

编辑:

有没有办法使用 LINQ for object 或 LINQ for XML 来解决此问题?

I'm looking for a 'safe' dot notation in VB.net. Does such a thing exist - in VB.NET or any language? What I want to be able to do is, when using non-nullable legacy objects, to solve a problem like:

"if there as a plan, if there is a case, if it has a person, that person's spouse, else, nothing (VBSpeak for Null)."

and avoid doing this:

Dim Spouse as Person = Nothing
if Case.Plan isnot nothing then
    if Case.Plan.Person isnot Nothing
        Spouse = Case.Plan.Person.Spouse
    end if
end if

and do this:

Dim Spouse as Person = Case~Plan~Person~Spouse

Where '~' is my sought 'safe' dot notation, which immeditely returns a null upon encountering the first null object instead of throwing an exception?

More common for this problem of course:

dim MyVar as string = XMLDoc.DocumentElement.SelectSingleNode("Name").InnerText

and wanting Nothing instead of an exception when Name doesn't exist.

Edit:

Is there a way to solve this problem using LINQ for objects or LINQ for XML?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

留蓝 2024-11-01 07:04:58

VB.NET 14 引入了 null-conditional 运算符来解决此问题。该运算符也是短路的。

Dim Spouse as Person = Case?.Plan?.Person?.Spouse

用于在执行成员访问 (?.) 或索引 (?[) 操作之前测试 null。这些运算符可帮助您编写更少的代码来处理 null 检查,特别是在深入分析数据结构时。

同样的事情在 C# 中也适用:

Person spouse = Case?.Plan?.Person?.Spouse;

VB.NET 14 introduced the null-conditional operator to address this. This operator is also short-circuiting.

Dim Spouse as Person = Case?.Plan?.Person?.Spouse

Used to test for null before performing a member access (?.) or index (?[) operation. These operators help you write less code to handle null checks, especially for descending into data structures.

The same thing works in C#:

Person spouse = Case?.Plan?.Person?.Spouse;
菩提树下叶撕阳。 2024-11-01 07:04:58

我通常使用扩展方法来处理这类事情,与 AakashM 指向的线程非常相似。一个很好的例子是字符串 LENGTH。由于 LENGTH 函数是一个实例方法,因此如果您在空字符串对象上调用它,则会抛出异常。

但是在字符串类上编写一个扩展方法 LEN 来测试 null,并且可以让它返回 0(我碰巧一直认为 null 字符串长度为 0,但这是另一个线程的主题。)

使用相同的逻辑,您可以实现 IsNotNull,或者 IsValid。主要问题将是“停止”持续的属性解析(例如,从案例到计划),

上述线程上的方法使用 Lambda,如果你问我,这会产生相当笨重的语法。我怀疑,如果 IsNotNull 测试产生 null,则可以返回代表 null 的 Proxy 对象,并且也可以简单地将您对其进行的任何方法调用解析为 null。但这需要一个动态代理,而动态代理本身就很混乱。

I've generally used extension methods for this sort of thing, very similar to what the thread that AakashM pointed to. A good example of this is string LENGTH. Since the LENGTH function is an instance method, if you invoke it on a null string object, you'll throw.

But code up an extension method LEN on the string class that tests for null and you can have it return 0 (I happen to consider null strings 0 length virtually all the time, but that's a topic for another thread.)

Using that same logic, you could implement an IsNotNull, or maybe an IsValid. the main problem will be "stopping" the continued property resolution (from, say, Case to Plan)

the methods on the above mentioned thread use Lambdas, which yields a pretty unwieldy syntax if you ask me. I suspect it'd be possible to, if the IsNotNull test yields a null, to return a Proxy object that stands in for the null, and would simply resolve anything method call you make on it to a null as well. But that would require a dynamic proxy which is messy in and of itself.

听不够的曲调 2024-11-01 07:04:58

VB.NET 语法就是这样,它没有任何类似于 C# 的 ?? 的空合并运算符。操作员。 Iif() 函数可以编写更紧凑的 If 语句,但它们很少适用于空引用,因为两个参数都被评估。

一般来说,尝试使用空引用作为调试辅助。当您没有编写的其他代码正在调用您的代码但搞乱了诸如初始化之类的事情时,它们会抛出一个很好的异常。默默地传播编程错误会导致难以诊断故障。就像 NullReferenceException 一样,它与原因相去甚远。或者更糟糕的是,错误的数据。您也许可以使用 NotAPlan 和 NoSpouse 对象来解决您的场景,这些对象的存在只是为了避免空引用异常,并且逻辑上意味着“未分配计划,未定义配偶”。否则,可以为 null 的引用只不过是引用 + 布尔值。不要跳过布尔。

That's about it for the VB.NET syntax, it doesn't have anything resembling the null coalescing operator like C#'s ?? operator. The Iif() function can write more compact If statements but they rarely work for null references since both arguments are evaluated.

In general, try to favor null references as a debugging aid. They throw a nice exception when some other code you didn't write is calling yours but messed up something like initialization. Silently propagating programming bugs leads to hard to diagnose failure. Like a NullReferenceException that's far removed from the cause. Or worse, bad data. You could perhaps address your scenario with a NotAPlan and a NoSpouse object, objects that solely exists to avoid null reference exceptions and logically mean "no plan assigned, no spouse defined". A reference that can be null is otherwise nothing more than a reference + a boolean. Don't skip the bool.

傾旎 2024-11-01 07:04:58

14 (Visual Studio 2015) 之前的 VB 版本中没有空安全点表示法。

处理可能的 null 值的更好方法是使用 AndAlso(短路 And),而无需使用太多 if:

If Case.Plan IsNot Nothing _
AndAlso Case.Plan.Person IsNot Nothing _
AndAlso Case.Plan.Person.Name = "Something" Then
    'Do something here
End If

另一个选项是使用 空对象模式。但这仅适用于您自己的数据类型,并且需要对代码进行一些更改。

编辑:

要回答您有关 LINQ 的问题,它无法帮助您解决此问题。 LINQ 的目标是帮助您查询数据集(列表、数组等)。如果您尝试使用 LINQ 查询数据,如果您的对象之一为空,您将遇到同样的问题。

There is no null-safe dot notation in VB versions prior to 14 (Visual Studio 2015).

A nicer way of dealing with possible null values, without having too many ifs, is to use AndAlso (short-circuiting And):

If Case.Plan IsNot Nothing _
AndAlso Case.Plan.Person IsNot Nothing _
AndAlso Case.Plan.Person.Name = "Something" Then
    'Do something here
End If

Another options is to use the Null Object Pattern. But that would only be possible with your own data types and would require some changes in your code.

Edit:

To answer your question about LINQ, it can't help you with this. LINQ's goal is to help you query sets of data (lists, arrays, etc.). If you try to query your data with LINQ you'll have the same problem if one of your objects is null.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文