Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 有趣的财产行为_C#_.net_Vb.net - Fatal编程技术网

C# 有趣的财产行为

C# 有趣的财产行为,c#,.net,vb.net,C#,.net,Vb.net,任何人都知道为什么这不起作用(C#或VB.NET或其他.NET语言不重要)。这是我的问题的一个非常简单的例子(对不起VB.NET): 如果您这样做: Dim myObj as new MyClass Console.WriteLine(myObj.CustomTextFormatter) 你会对结果感到惊讶。它将打印“无”。有人知道为什么不打印“某物”吗 根据建议,这里有一个单元测试: Imports NUnit.Framework <TestFixture()> _ Publi

任何人都知道为什么这不起作用(C#或VB.NET或其他.NET语言不重要)。这是我的问题的一个非常简单的例子(对不起VB.NET):

如果您这样做:

Dim myObj as new MyClass
Console.WriteLine(myObj.CustomTextFormatter)
你会对结果感到惊讶。它将打印“无”。有人知道为什么不打印“某物”吗

根据建议,这里有一个单元测试:

Imports NUnit.Framework

<TestFixture()> _
Public Class Test
   Private itsCustomTextFormatter As String
    Public Property CustomTextFormatter As String
        Get
            If itsCustomTextFormatter Is Nothing Then CustomTextFormatter = Nothing 'thinking this should go into the setter - strangely it does not' 
            Return itsCustomTextFormatter
        End Get
        Set(ByVal value As String)
            If value Is Nothing Then
                value = "Something"
            End If
            itsCustomTextFormatter = value
        End Set
    End Property

    <Test()>
    Public Sub Test2()
        Assert.AreEqual("Something", CustomTextFormatter)
    End Sub
End Class

因为你从来没有初始化过这个变量。您必须将属性“设置”为nothing才能实际获取“某物”。要修复它,您可能应该在声明内部变量时设置默认值

Private itsCustomTextFormatter As String = "Something"

在单元测试中对我来说很好;尽管是C#(见下文)

(玩了一会儿之后)

啊,明白了!这是因为您正在调用
CustomTextFormatter=Nothing
,在Getter的作用域中,它实际上只是设置封闭访问器方法的返回值——它实际上并没有触发setter(如果您在setter中放置断点,您将看到并调试它,您将看到它的步骤就在它上面)

基本上,你真的不应该做这种模式无论如何;这不是返回默认属性值的方法。这会更好(或者使用与C#
运算符等效的任何运算符):

原始C#测试

您的评论:

'thinking this should go into the setter - strangely it does not'    
说出你的错误是什么。在Visual Basic中,有两种从函数返回内容的方法:

Function GetSomeValue() As String
    Return "Hello"
End Function

将这两种风格混合在一起是完全合法的,但令人困惑,而且是一种糟糕的做法:

Function GetSomeValue() As String
    GetSomeValue = "Hello" ' I should return Hello... '
    Return "GoodBye"       ' ...or perhaps not. '
End Function
正如您所看到的,您在getter中混合了这两种风格设置该变量不调用setter;它通知运行时,当getter返回时,这是它应该返回的值。然后用
return
语句覆盖该值


如果你那样做很痛,那就不要那样做

我很惊讶
value=“Something”
能够编译。Hmm看起来像是VB.net中的
value
不是一个关键字,只是一个普通的参数,它解释了它的编译过程。它是一个字符串,设置时不必“新建”它it@CodeInChaos在C#中,您可以执行
value=null必须确定:您是否编译了这个简化程序并检查它是否存在问题?@CodeInChaos:
value
是一个引用变量的关键字。当然,你可以重新分配变量的值。我不理解你的推理。不知道这是怎么回事relevant@Denis-好的,我们注意到的第一件事是它不是.Net-它要么特定于VB,要么(更可能)特定于您的VB代码。我们只需要从编译器中找出原因:'Set'参数不能声明为'ByRef'@Denis C#与VB不同,因为,呃,C#与VB是不同的语言。如果您想知道为什么VB有
Return
以及
=
技术:它是为了与旧版本的VB向后兼容,旧版本的VB没有用于从函数返回值的
Return
语句。您可能更喜欢新代码中的
Return
语句。@Denis yes Me.CustomTextFormatter可以工作,因为它显式引用类作用域中的属性。而CustomTextFormatter本身使用getter的隐式作用域,其中名称具有作为函数本身返回值的特定含义。粗暴地说,是的,但这是语言的一部分,所以嘿嘿嘿:D@Denis,如果您了解VB6及更早版本,这是有意义的。这些语言没有
Return
关键字。相反,函数有一个隐式变量,使用函数名保存返回值。换句话说,要从
函数SomeFunction()返回
7
作为整数
,必须有一个类似
SomeFunction=7
的语句。令人困惑的是,属性getter也是如此,因此为了避免必须使用
Me.PropertyName=valuewhichtocallsetter
。VB.NET保留了语法,同时还添加了
Return
关键字。@Denis是的,有。设置[function/property name]=[some value]本质上是赋值,只是赋值一个隐式返回值,如果在方法结束之前没有其他
Return
命令,则在方法结束时返回。@Denis Setting
CustomTextFormatter=Nothing
告诉
CustomTextFormatter
如果没有其他返回语句,则默认返回
Nothing
。但是,您没有走那么远,而是到达
返回其CustomTextFormatter
,其中
其CustomTextFormatter
的值仍然为零,因为尚未调用该集。@Denis从getter调用setter是一种拙劣的设计。也就是说,您可以通过明确声明
Me.CustomerTextFormatter=Nothing
@GuthMD:您完全正确!该死的VB.NET-你又抓住我了!!!!就这样-这将是一些可怜的笨蛋的面试问题@CodeInChaos:从getter调用setter确实是一种奇怪的做法,但它确实偶尔发生。特别是如果所讨论的值是延迟计算的;getter可能会检查该值是否已计算,如果已计算,则返回该值。如果不是,则它计算该值,调用setter缓存该值以供下次使用,并返回该值。
    private string _foo;
    private string foo
    {
        get
        {
            if (_foo == null)
                foo = null;
            return _foo;
        }
        set
        {
            if (value == null)
                value = "Something";
            _foo = value;
        }
    }

    [TestMethod]
    public void Test()
    {
        Assert.AreEqual("Something", foo);
    }
'thinking this should go into the setter - strangely it does not'    
Function GetSomeValue() As String
    Return "Hello"
End Function
Function GetSomeValue() As String
    GetSomeValue = "Hello"
End Function
Function GetSomeValue() As String
    GetSomeValue = "Hello" ' I should return Hello... '
    Return "GoodBye"       ' ...or perhaps not. '
End Function