我遇到了我认为是一个错误,我只是想知道这是否已经被认为是一个问题,或者这不是问题,为什么。
在Visual Studio 2008中使用VB.Net编译器进行编译时,与“类型”上的“只读属性”相关的问题。
以下是类定义和一个不能编译的小型C#程序。 (并且在不编译IMHO时是正确的,因为在委托中设置的属性是只读的)
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
任何人都可以解释这是否是正确的逻辑以及为什么?
我假设有人会通过检查委托的参数类型来响应编译器的工作,并且在解析方法体或函数体时键入委托以接受该参数。 / p>
我对此的反驳是,当尝试从方法中设置该属性而不是委托时,编译器会抛出错误。代理应该像方法一样进行解析。
C#编译器是否过度扩展?我想不是。我的经验是,这是vb.net编译器中的一个错误,应该通过IDE的补丁修复。
最后但肯定的是,当Invoke发生时会发生什么?
委托肯定不使用反射来自动设置属性,所以我假设CLR看到只读限定符并执行NOOP。这实际上是发生了什么或行为未定义?
感谢您的时间!
答案 0 :(得分:5)
在VB.NET 2008中,没有语句lambdas。所有lambdas都是函数。它们返回一个值,而不是执行操作。
您的VB lambda只是比较d.PrivateBool
和False
并返回比较结果。
这不是错误和设计。因此,建议避免将VB.NET 2008的lambdas分配给Action
,这对于没有准备的人来说非常困惑。
声明lambdas出现在VB.NET 2010中。