VB.Net 为什么这不是一个错误?
我遇到了我认为是一个错误的问题,我只是想知道这是否已经被视为一个问题,或者这是否不是一个问题以及原因。
在 Visual Studio 2008 中使用 VB.Net 编译器进行编译时,该问题与类型的只读属性有关。
以下是类定义和一个无法编译的小型 C# 程序。 (恕我直言,不编译是正确的,因为在委托中设置的属性是只读的)
public interface ITest
{
bool PrivateBool { get; }
}
public class TestClass : ITest
{
bool privateBool = false;
public bool PrivateBool
{
get
{
return privateBool;
}
}
bool publicBool = false;
public bool PublicBool
{
get { return publicBool; }
set { publicBool = value; }
}
}
class Program
{
static void Main(string[] args)
{
TestClass tc = new TestClass();
//Compile Error
//tc.PrivateBool = false;
//Compile Error
//Action act = new Action(delegate()
//{
// tc.PrivateBool = false;
//});
//Action<TestClass> test = new Action<TestClass>(delegate(TestClass tcc)
//{
// tcc.PrivateBool = false;
//});
//Compile Time Error
//Action<TestClass> test = new Action<TestClass>( tz=> tz.PrivateBool = false);
//Compile Time Error
//Action test = new Action(tc.PrivateBool = false);
}
}
在 VB.Net 中,但是这是一个更大的问题......程序将毫无例外地编译和执行。但属性未设置。 这是在运行时调试器中捕获的一场噩梦,我们认为编译器应该捕获我们正在分配给只读属性,就像 CSharp 编译器在编译时提醒您一样。
Module Module1
Sub Main()
Dim tc As New TestClass()
Dim setP = New Action(Of TestClass)(Function(d As TestClass) _
d.PrivateBool = False _
)
setP.Invoke(tc)
End Sub
End Module
谁能解释这是否是正确的逻辑以及为什么?
我假设有人会回应说,编译器的工作是通过检查委托的参数类型来完成的,并且委托的类型是接受该参数,就像解析方法体或函数体时应该接受的那样。
我对此的反驳是,当尝试从方法而不是委托中设置该属性时,编译器确实会抛出错误。委托应该像方法一样被解析。
C# 编译器是否过度扩展自身?我认为不是。我的经验是,这是 vb.net 编译器中的一个错误,应该通过 IDE 的补丁来修复。
最后但同样重要的一点是,当 Invoke 发生时会发生什么?
委托肯定不会使用反射来自动设置属性,因此我假设 CLR 会看到只读限定符并执行 NOOP。这实际上是发生的事情还是行为未定义?
谢谢您的宝贵时间!
I encounter what I believe to be a bug and I was just wondering if this is already known as a issue or if this is not a issue and why.
The problem related to Read Only Properties on a Type when compiling with the VB.Net Compiler in Visual Studio 2008.
Follows are the class definitions and a small C# program which will not compile. (And is correct in not compiling IMHO because the property being set in the Delegate is Read-only)
public interface ITest
{
bool PrivateBool { get; }
}
public class TestClass : ITest
{
bool privateBool = false;
public bool PrivateBool
{
get
{
return privateBool;
}
}
bool publicBool = false;
public bool PublicBool
{
get { return publicBool; }
set { publicBool = value; }
}
}
class Program
{
static void Main(string[] args)
{
TestClass tc = new TestClass();
//Compile Error
//tc.PrivateBool = false;
//Compile Error
//Action act = new Action(delegate()
//{
// tc.PrivateBool = false;
//});
//Action<TestClass> test = new Action<TestClass>(delegate(TestClass tcc)
//{
// tcc.PrivateBool = false;
//});
//Compile Time Error
//Action<TestClass> test = new Action<TestClass>( tz=> tz.PrivateBool = false);
//Compile Time Error
//Action test = new Action(tc.PrivateBool = false);
}
}
In VB.Net However this is a larger issue… the program will compile and execute with no exception. But the property is not set.
This was a nightmare to catch in the debugger at Run time and we feel that the compiler should have caught that we are assigning to a ready only property just as the CSharp compiler alerts you when compiling.
Module Module1
Sub Main()
Dim tc As New TestClass()
Dim setP = New Action(Of TestClass)(Function(d As TestClass) _
d.PrivateBool = False _
)
setP.Invoke(tc)
End Sub
End Module
Can anyone explain if this is correct logic and why?
I assume that someone will respond that the job of the compiler was fulfilled by examining the parameter type to the delegate and that the delegate was typed to accept that parameter just as it should when parsing a Method Body or a Function Body.
My rebuttal to this would be that the compiler DOES throw an error when that property is attempted to be set from within a method but not the delegate. Delegates should be parsed the same as a Method.
Is the C# compiler over extending itself? I think not. My experience is that this is a bug in the vb.net compiler and should be fixed by a patch to the IDE.
Last but surely not least what occurs when the Invoke happens?
The delegate surely does not use reflection to set the property automagically so I assume the CLR sees the read-only qualifier and a NOOP gets executed. Is that actually what occurs or is the behavior undefined?
Thank you for your time!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在 VB.NET 2008 中,没有语句 lambda。所有 lambda 都是函数。它们返回一个值,而不是执行操作。
您的 VB lambda 只是比较
d.PrivateBool
和False
并返回比较结果。这不是一个错误,也是设计使然。因此,建议避免将 VB.NET 2008 的 lambda 分配给
Action
,这对于没有准备的人来说非常令人困惑。语句 lambda 出现在 VB.NET 2010 中。
In VB.NET 2008, there are no statement lambdas. All lambdas are functions. They return a value, not perform an action.
Your VB lambda simply compares
d.PrivateBool
andFalse
and returns the result of the comparison.This is not a bug and by design. It is therefore advisable to avoid assigning VB.NET 2008's lambdas to an
Action
, this is highly confusing for an unprepared person.Statement lambdas appeared in VB.NET 2010.