C# 有趣的财产行为
任何人都知道为什么这不起作用(C#或VB.NET或其他.NET语言不重要)。这是我的问题的一个非常简单的例子(对不起VB.NET): 如果您这样做: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
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在setter中code>必须确定:您是否编译了这个简化程序并检查它是否存在问题?@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 SettingCustomTextFormatter=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