无法在C#中访问类的非共享成员,但可以在VB中访问吗?

时间:2010-06-23 19:08:58

标签: c#

我刚开始学习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#?

3 个答案:

答案 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中共享)。