Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot access non-static field

Tags:

c#

I can't figure out why it's looking for something static:

public class DatabaseBase
{
    private readonly string connectionString;

    public DatabaseBase(string connectionString)
    {
        this.connectionString = connectionString;
    }
}

public class MyDB : DatabaseBase
{
    readonly string connectionString = ConfigurationManager.AppSettings["MyConnectionString"];

    public MyDB() : base(connectionString)
    {          
    }
}

I get Cannot access non-static field 'connectionString' in static context. I don't see anything static in the base Database class so why??

here's another example of when we did kinda the same thing:

partial class Database : DatabaseBase
{
    static string DbConnectionString
    {
        get
        {
            if (dbConnectionString == null)
                dbConnectionString = 
                    ConfigurationManager.AppSettings["MyConnectionString"];
            return dbConnectionString;
        }
    }
    public Database() :base(DbConnectionString)
    {
    }

ok so why did it have to be a static string for the connection string to be passed?

like image 699
PositiveGuy Avatar asked Sep 16 '09 03:09

PositiveGuy


People also ask

Can you access a non-static variable in the static context?

“Can a non-static method access a static variable or call a static method” is one of the frequently asked questions on static modifier in Java, the answer is, Yes, a non-static method can access a static variable or call a static method in Java.

What is a non-static field?

Non-static fields are instance fields of an object. They can only be accessed or invoked through an object reference. The value of static variable remains constant throughout the class. The value of Non-static variables changes as the objects has their own copy of these variables.

How do you assign a non-static variable to a static variable?

You cannot assign the result of a non-static method to a static variable. Instead, you would need to convert the getIPZip method to be a static method of your MyProps class, then you could assign its result to yor IPZip variable like this. public static String IPZip = MyProps. getIPZip("IPZip");

Why can't a static method call a non-static method?

Static variables are class variables that belong to the class with only one instance created initially. But, to access instance variables it is a must to create an object, these are not available in the memory, before instantiation. Therefore, you cannot make a static reference to non-static fields(variables) in Java.


2 Answers

We have worked hard to give error messages that are accurate, so read them carefully. The error message is telling you exactly what is going wrong: you are accessing a non-static field in a context where it is only legal to access statics.

So why is a base constructor call argument list a context where it is only legal to access statics?

When you call a base constructor, the arguments you pass must not reference "this". Why? Because neither the derived constructor nor the base constructor for your "this" has run yet, and therefore "this" is almost certainly in an inconsistent, partially-initialized state. That is a recipe for crazy bugs. We therefore restrict you from accessing "this" until we know that at the very least, the base constructor has run.

This feature encourages sensible, well-ordered, understandable, maintainable and bug-free construction logic; I recommend working with, not against, those safeguards.

like image 80
Eric Lippert Avatar answered Oct 12 '22 16:10

Eric Lippert


Your problem is in the MyDB constructor. The instance field (MyDB.connectionString) will not be initialized until the call to the base constructor returns, so everything inside base( ... ) is in the static context. Just work with it...

public class MyDB : DatabaseBase
{
    static readonly string connectionString = 
          ConfigurationManager.AppSettings["MyConnectionString"];
    public MyDB() : base(connectionString)
    {
    }
}

or better yet (as suggested by Simon Fox) ...

public class MyDB : DatabaseBase
{
    public MyDB() : base(ConfigurationManager.AppSettings["MyConnectionString"])
    {
    }
}
like image 40
Av Pinzur Avatar answered Oct 12 '22 15:10

Av Pinzur