.net 我可以访问静态方法,但不能访问示例化方法

esyap4oy  于 2023-06-25  发布在  .NET
关注(0)|答案(4)|浏览(142)

简单明了我可以访问静态方法,但不能访问示例化方法。
起初我以为这是一个扩展到所有类的问题,但这让我更加困惑。让我用一个例子来说明。
我有一个公共SQLQueries类,它有两个测试方法。Banana()是静态的,橙子()不是。两者都是公有的,类本身也是公有的。
Declaration

public class SQLQueries
    {
        public static string Banana()
        {
            return "Banana";
        }
       
       public string Orange()
        {
            return "Orange";
        }
    }

我转到同一名称空间中的另一个类库(SQLProcedures)文件(DatabaseBehaviour)。我创建了这个类的一个示例,并且我永远都得到了,事实上SQLQueries类名是可以识别的,我甚至可以看到定义。
Errors
正如我所料,如果我直接从类调用,静态方法Banana()工作,如果我试图通过我创建的“ey”示例执行,我会得到一个错误。
然而,这也是让我困惑的地方,橙子()在这两种情况下都不起作用,并在应该起作用的代码处给了我这个消息。
Message error

public class SQLProcedures
    {

        SQLQueries ey = new SQLQueries();

        string a = SQLQueries.Banana();
        string b = ey.Banana();

        string c= SQLQueries.Orange();
        string d= ey.Orange();

    }

为了确保这不是我的类的问题,我试图创建最终将在SQLQueries中的Dictionary,并再次做同样的事情:我可以创建示例,但不能访问它的方法,如.Add()

public class SQLProcedures
    {
        Dictionary<string, string> queriesAdd = new Dictionary<string, string>();
        Dictionary<string, string> queriesRemove = new Dictionary<string, string>();
        Dictionary<string, string> queriesUpdate = new Dictionary<string, string>();

    }

Dictionary test
现在我唯一的假设是,包含这两个文件的项目类型(一个.NET Framework 4类型类库)以某种方式影响了它们,这完全让我无法理解。但我认识到,这是一种非常冒险的东西,不是基于任何东西。
这是怎么回事0.0''
非常感谢所有给予我一点时间的人。

yfjy0ee7

yfjy0ee71#

你的问题是你需要在一个方法。
错误显示“字段初始化器...”。这是因为d(和abc)是字段。
创建一个方法,它会很好地工作:

public class SQLProcedures
{
    public void M()
    {

        SQLQueries ey = new SQLQueries();

        string a = SQLQueries.Banana();
        string b = ey.Banana();

        string c= SQLQueries.Orange();
        string d= ey.Orange();
    }
}

字段初始化器的功能是有限制的,如果你想初始化一些复杂的东西作为类的一部分,请使用构造函数。
问题的一部分是代码运行的顺序以及.NET初始化器字段的方式。

1sbrub3j

1sbrub3j2#

若要访问非静态类的非静态方法,必须示例化该对象。在可执行代码中创建对象的示例

var query = new SQLQueries();
query.Orange();
vbkedwbf

vbkedwbf3#

在C#中,字段初始化器不能引用其他示例变量。
字段初始化器是直接在类内部声明的变量,如abcd。变量c永远不会工作,即使在方法内部也不行,因为访问非静态Orange方法需要对象引用。b变量也永远不会工作,因为您无法从示例访问静态方法。
d变量不起作用的原因很有趣。在阅读了一段时间后,我偶然发现了一些答案,说C#编译器可能会重新安排字段示例化的顺序,因此无法保证SQLQueries会在d之前示例化,这可能会抛出NullReferenceException。这是绝对不正确的。
Microsoft文档中Compiler Error CS0236的示例如下所示

public class MyClass
{
    public int i = 5;

    // To fix the error, remove "= i", and uncomment the line in constructor.
    public int j = i;  // CS0236

    public MyClass()
    {
        // Uncomment the following.
        //j = i;
    }
}

就像其他的答案一样,他们建议将示例化移动到类构造函数中,但它并没有解释为什么会发生这个错误。
类在构造函数结束执行时开始存在,在C#中构造函数逻辑最后执行,因此当字段j引用另一个字段i时,它引用的是类本身的i,并且由于类不存在,编译器错误CS0236发生。引用C#语言规范部分10.5.5.2 A variable initializer for an instance field cannot reference the instance being created
但出现这个错误的真实的原因是C#的设计者想要这样做。这个错误在Java中不会发生,例如,你甚至可以从Java中的示例访问静态方法,但它会给予警告。

snz8szmq

snz8szmq4#

对于static方法(Banana()),只能使用类名,而不能使用示例名。
对于示例方法(Orange()),您需要将它们移动到构造函数或代码中稍后的某个位置,如方法:

public class SQLProcedures
{

    SQLQueries ey = new SQLQueries();

    string a = SQLQueries.Banana();
    string b = null;

    public SQLProcedures()
    {
        b = ey.Orange();
    }

}

相关问题