我刚开始学习C#,曾经是VB程序员。
在VB.NET中,即使此方法未声明为共享,也可以访问表单类方法。 在下面的代码中,我没有遇到编译器错误,并且在 ClassFoo 中调用 Foo 方法可以正常工作。
Public Class Form1
Public Sub Foo()
MsgBox("Test")
End Sub
End Class
Public Class ClassFoo
Sub Foo()
Form1.Foo()
End Sub
End Class
然后,我尝试将相同的代码移植到C#,但是我收到一个错误:
“非静态字段和bla bla bla需要对象引用”。
为什么我可以访问一个没有在VB中共享的方法而且不能用C#?
答案 0 :(得分:6)
这是从VB6继承的一个相当可怕的功能,VB6是一种允许这种结构的语言。在纯OOP语言中不允许使用它,引用对象的成员需要对象名称而不是类型名称。
VB.NET团队在使用VB.NET语言时遇到了一些麻烦。此语句中的“Form1”实际上是一个对象引用,它由编译器自动生成。在线程btw中使用该名称时出现可怕的错误。
但是这不会在C#语言中出现,你有来提供对象引用。您将不得不重新分解代码,以便ClassFoo对象具有该引用。像这样:
public class Form1 {
ClassFoo fooObj;
public Form1() {
fooObj = new ClassFoo(this);
}
public void Foo() {
MessageBox.Show("un-fooed");
}
}
public class ClassFoo {
Form1 mainForm;
public ClassFoo(Form1 main) {
mainForm = main;
}
public void Foo() {
mainForm.Foo();
}
}
在学习C#时,这可能会导致一些痛苦。 Q& D解决方法是使用Application.OpenForms。如果您喜欢使用子弹,请避免使用它。
答案 1 :(得分:3)
在C#Shared
实际上是Static
您的端口应该是:
public class Form1
{
public static void Foo()
{
MessageBox.Show("Test");
}
}
public class ClassFoo
{
public void Foo()
{
Form1.Foo();
}
}
静态方法/字段/属性/等不需要使用实例,它们是类本身的成员。另一个例子:
public class MyClass
{
protected MyClass() { /* Do Something */ }
public static MyClass Create(string someParam)
{
/* Do something with someParam */
return new MyClass();
}
}
然后:
MyClass a = new MyClass(); // Error, Constructor is protected
MyClass b = MyClass.Create("Foobar"); // Works, calls the `static` method
更新:回复您的评论:
<snarky-answer>
因为vb太可怕了?</snarky-answer>
不,真的,这看起来像是一场等待发生的灾难。
如果你没有声明你的sub是共享的,并且你试图访问实例变量,它会爆炸。在C#中,如果您尝试从静态方法访问非静态成员,它将给您一个编译时错误,因此这样的错误代码不会使其投入生产。
至于为什么你可以做到这一点,这是微软团队的一个问题。真实的是你不应该做到这一点!
为了记录,我尝试编译你的代码:
http://i47.tinypic.com/2qco61k.png http://i47.tinypic.com/2qco61k.png
答案 2 :(得分:3)
你不应该在VB中。我复制并粘贴了您的示例vb代码,它给出了相同的编译错误。
VB中的共享是C中的静态#除了关键字,行为是相同的。如果要在不创建该类实例的情况下访问成员,则需要是静态的(在vb中共享)。