【问题标题】:Use the ref principle on the new not null test在新的非空测试中使用 ref 原则
【发布时间】:2020-01-31 12:40:07
【问题描述】:

我不知道它到底叫什么,但现在我将它称为“非空测试”。在 C# 8 中,有一个新行为允许测试对象是否不为空,例如:

Foo foo = new Foo();

if(foo is { })
{
    //foo is not null
}

你也可以从这个对象中提取属性:

public class Foo
{
    public int Bar { get; set; }
}

Foo foo = new Foo();

if(foo is { Bar: var bar })
{
    //Foo is not null and bar contains the value of the property of the foo instance
}

到目前为止一切顺利,但我想它类似于这样:

public bool GetBar(Foo foo, out int bar)
{
    if(foo is null)
    {
        return false;
    }

    bar = foo.Bar;
    return true;
}

这将被用作这样的东西:

Foo foo = new Foo();

if(GetBar(foo, out var bar))
{
    //Foo is not null and bar contains the value of the property of the foo instance
}

现在我的实际问题是:有什么方法可以使用 ref 的行为吗?看起来像这样:

if(foo is { Bar: ref var bar })
{
    //Foo is not null and bar contains the value of the property of the foo instance
}

如果这不存在,我会理解,因为out ref 也不存在。那么有什么方法可以做到这一点,或者有什么反对它的吗?

【问题讨论】:

  • 据我了解,{ } 的符号表示“某个对象”。对象没有引用变量的概念。 ref 关键字用于函数参数。所以答案是否定的
  • 好吧,我只是用 ref 来举例说明我的意思。

标签: c# notnull c#-8.0


【解决方案1】:

您使用的模式是来自 C#8 pattern matching feature属性模式

属性模式使您能够匹配所检查对象的属性。

如果我没有正确回答您的问题,您不仅希望获得属性值,而且还希望能够在匹配的对象中更改该值。

if (foo is { Bar: ref var bar })
{
    bar = 42; // now foo.Bar is 42 too
}

为了使ref 语义起作用,它必须得到语言和编译器的支持。

但是,C# 不允许您将 ref 与属性一起使用 - 对于任何 C# 版本都是如此。原因很明显:您的 get-set 属性 Bar(与任何其他 C# 属性一样)将被编译为两种方法:get_Barset_Bar。所以实际上你有一个方法,而不是一个值 - 因此,你不能 ref 一个方法返回的值(好吧,有 ref returns,但这些不适用于属性获取器)。

【讨论】:

  • 感谢您的解释,我想至少那时它可以与 Fields 一起使用,但我通常会遇到问题。
猜你喜欢
  • 2021-12-16
  • 2020-01-21
  • 2019-03-23
  • 2012-06-30
  • 1970-01-01
  • 2016-05-26
  • 2021-09-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多