Reputation: 47743
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?
Upvotes: 8
Views: 8245
Reputation: 660098
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.
Upvotes: 27
Reputation: 2228
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 Just work with it...base( ... )
is in the static context.
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"])
{
}
}
Upvotes: 4