Cannot access non-static field [fieldname] in static contex - c#

The Base Class:
public class DatabaseBase
{
private readonly string connectionString;
private bool useCounters;
public DatabaseBase(string connectionString)
{
this.connectionString = connectionString;
}
public DatabaseBase(...)
{
connectionString = ...;
}
public DatabaseBase(..)
{
connectionString = string.Format(...);
}
public string ConnectionString
{
get { return this.connectionString; }
}
...
The derived class:
public class ProjectDB : DatabaseBase
{
private bool useServiceConnection;
private static string ConnectionString
{
get
{
string connectionString = useServiceConnection == true ? ConfigurationManager.AppSettings["SomeConnection1"] : ConfigurationManager.AppSettings["SomeConnection2"];
return connectionString;
}
}
public ProjectDB() : this(false)
{
}
private bool isServiceCall;
public ProjectDB(bool useServiceConnection)
: base(ConnectionString)
{
this.useServiceConnection = useServiceConnection;
}
private SqlConnection CreateConnection()
{
return new SqlConnection(ConnectionString);
}
I'm getting the error "Cannot access non-static field useServiceConnection in static context" for this line:
string connectionString = useServiceConnection == true ? ConfigurationManager.AppSettings["SomeConnection1"] : ConfigurationManager.AppSettings["SomeConnection2"];
However if I make useServiceConnection a static var to satisfy the quirement, then I get that same error here in the constructor:
public ProjectDB(bool useServiceConnection)
: base(ConnectionString)
{
this.useServiceConnection = useServiceConnection;
}
Now if I make useServiceConnection and ConnectionSting property non-static, then I get that error for the constructor here:
public LitleDB(bool useWebServiceConnection)
: base(ConnectionString)
{
this.useWebServiceConnection = useWebServiceConnection;
}
I think the first 2 I understand.
But now with the example updated below, why would the constructor in this case give me an error still? Those are no longer static so where's the static context being expected from? So here's what I have now:
public class ProjectDB : DatabaseBase
{
private bool useServiceConnection; <-- NO LONGER STATIC
private new string ConnectionString <-- NO LONGER STATIC
{
get
{
string connectionString = useServiceConnection == true ? ConfigurationManager.AppSettings["SomeConnection1"] : ConfigurationManager.AppSettings["SomeConnection2"];
return connectionString;
}
}
public ProjectDB() : this(false)
{
}
private bool isServiceCall;
public ProjectDB(bool useServiceConnection)
: base(ConnectionString) <--- IT'S COMPLAINING HERE NOW, SO WHERE IS IT TRYING TO ACCESS STATICALLY? I DON'T GET WHY
{
this.useServiceConnection = useServiceConnection;
}
I have other static properties in this class, does that have anything to do with it? I'm not using them though.

The variable useServiceConnection is not static so it only exists within the context of an instance of the class. Since the property ConnectionString is static, it does not exist in the context of an instance, and so it cannot "see" instance members. You will need to either make ConnectionString not being static, or make useServiceConnection static.

A static member belongs to a type rather than a specific instance of a type. It doesn't matter whether you have no instances of a class or you create a million instances when it comes to static members. Only one will exist. This is not the case for instance variables. Basically, each instance you create has its own specific instance variables. This is why you can't access instance members in static contexts without an object instance. It's not clear the instance member you want to access belongs to which object. You can, however, reference instance members in static contexts by specifying an object reference explicitly:
obj.instanceMember // valid in static context as `obj` specifies the object

Static members are a property of the class itself. You don't even have to have any instances of Database created anywhere to access Database.ConnectionString when ConnectionString is a static property.
So, inside your property declaration, when you try to access "useServiceConnection", it doesn't know what you're talking about. useServiceConnection is an instance variable - it only exists for a given instance of the Database class. What if there were no database classes instantiated? What if there were 5? It doesn't make sense to access instance members of a class from a static scope.
I would make your ConnectionString property non-static, as it doesn't really seem like something that should be static anyway.

Make the ConnectionString and useWebServiceConnection in the LitleDb class instance members also.
However, I don't think that your constructors will work properly once they compile. You are calling the base constructor with the value from ConnectionString as parameter, but at that time you haven't set the useServiceConnection variable, so it will always be false and the ConnectionString property will always return the second connection string.

Related

i want to know how the static properties work in c# and i don't get the meaning of 'Instance._input;

I don't get the meaning of 'Instance._input;
1.What is the relationship between the properties 'Instance' and the instance '_input"? is it related to static?
2.I don't understand that why 'Instance" comes earlier then _input (Instance._input;)
I am sorry asking for easy question
public class managers : MonoBehaviour
{
static managers s_instance; // 유일한 매니저를 갖고온다
public static managers Instance
{
get { return s_instance; }
}
InputManager _input = new InputManager();
public static InputManager Input
{
get { return Instance._input; }
}
The Instance is a static property of class managers, it returns s_instance static variable of class managers.
Therefore Instance._input will return the instance variable _input of type InputManager of static variable Instance of type managers.
The naming conventions of your provided code could cause confusions. Consider this code:
public class Manager : MonoBehavior {
static Manager staticManager;
public InputManager inputManager = new InputManager();
public static Manager GetStaticManager() { return staticManager;}
public static InputManager GetInputManagerOfStaticManager() { return GetStaticManager().inputManager; }
}
When you declare something static, its on class scope. All objects created from the same class shared the same static copy. You access them as Manager.GetStaticManager(). Calling Manager.inputManager will fail.
On the other hand, non-static member is on object/instance scope. You need to create that object first:
var manager = new Manager();
var myInputManager = manager.inputManager;

How can I access a property that belongs to an instance of a class that I passed into another class?

I have this class
public partial class PhrasesFrame : Frame
{
public CancellationTokenSource tokenSource1;
public PhrasesFrameViewModel vm;
public PhrasesFrame()
{
InitializeComponent();
vm = new PhrasesFrameViewModel(this);
}
and this view model
public class PhrasesFrameViewModel : ObservableProperty
{
private readonly PhrasesFrame phrasesFrame;
public PhrasesFrameViewModel(PhrasesFrame phrasesFrame) {
this.phrasesFrame = phrasesFrame;
}
private void ResetTimer1()
{
if (phrasesFrame.tokenSource1 != null)
}
on the if line where I use the value of tokenSource2 I get a message saying:
Error CS0120: An object reference is required for the non-static field, method, or property 'PhrasesFrameViewModel.phrasesFrame'
Can someone explain what I am doing wrong to me.
You want to use the phrasesFrame’s variable in a static function. A static function can’t use a class’s non-static variable. Just remove the static
keyword and it will work.

Is it possible to write from a static method to a non-static label [duplicate]

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?
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.
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"])
{
}
}

Object reference not set to an instance of an object On singleton class

I have a class named DAL with the methods to connect to my database.
When I create a new project, I always go on Add Existing Item and Add this class. Always worked ! But now that I imported to my new project, I got that error on the title... I hope some of you guys could explain to me.
I Know that this exception happens when the method returns a NULL value.(Maybe not).
Here is my code:
#region Singleton
public sealed class Singleton
{
static readonly DAL instance = new DAL(); //HERE IS WHERE THE EXCEPTION OCCURS
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
public static DAL Instance
{
get
{
return instance;
}
}
}
#endregion
And here is where I call this class.
namespace BD
{
public class BDAssociado
{
private DAL _dal;
public BDAssociado()
{
_dal = DAL.Singleton.Instance;
}
}
}
Dal Constructor:
public DAL()
{
_Conexao = new MySqlConnection(ConfigurationManager.ConnectionStrings["NameOfConnectionString"].ConnectionString);
}
Check your connection string key exist in the config file.
Check if it is null before returning:
public static DAL Instance
{
get
{
if (instance == null)
{
instance = new DAL();
}
return instance;
}
}

Assign value to variable

I have this variable, it's an instance of a Interface of a class in business layer.
I need to send messages since data access layer, to business layer and finally to presentation layer. I my class "LogBinaryWriter" in data access I have this:
public class LogBinaryWriter : ILogBinaryWriter
{
private readonly IImageLogBuilder _imageLogBuilder;
public void WriteFrameCodes(string filePath, int logSelected)
{
var fileExists = FileExists(binaryFilePath);
if (fileExists == true)
{
_imageLogBuilder.displayMessage("The file " + binaryFileName + " exist. Dou you want overwrite it? (Y/N)");
}
}
}
I have a message: "the value _imageLogBuilder is never assigned and will always be null"
How can I fix this?
Instantiate an instance of IImageLogBuilder in your constructor for LogBinaryWriter and assign it to _imageLogBuilder. You would have to do it in the constructor since you have _imageLogBuilder marked as readonly.
For example, assuming you have a class called MyImageLogBuilder that implements IImageLogBuilder:
public LogBinaryWriter()
{
_imageLogBuilder = new MyImageLogBuilder();
}
You could also overload the constructor so you can pass in the IImageLogBuilder you want to use (lookup constructor injection for more info on this pattern):
public LogBinaryWriter(IImageLogBuilder imageLogBuilder)
{
_imageLogBuilder = imageLogBuilder;
}
Remember, you will need a class that implements the IImageLogBuilder interface to be able to create a new instance and assign it to the _imageLogBuilder variable. For example:
public interface IImageLogBuilder
{
void Log(string message);
}
//The class below IMPLEMENTS the IImageLogBuilder interface
public class MyImageLogBuilder : IImageLogBuilder
{
//Implement IImageLogBuilder methods here
public void Log(string message)
{
//Log message
}
}
If you had something like the classes defined above then you could the following in the LogBinaryWriter constructor and you would no longer get the null reference error.
public LogBinaryWriter()
{
_imageLogBuilder = new MyImageLogBuilder();
}
You need to assign an instance of a class that implements IImageLogBuilder interface to _imageLogBuilder field.
Right now your field will always have a value of null.
For example:
private readonly IImageLogBuilder _imageLogBuilder = new ImageLogBuilder();
perhaps initialize _imageLogBuilder in constructor ?
public class LogBinaryWriter : ILogBinaryWriter
{
private readonly IImageLogBuilder _imageLogBuilder;
public LogBinaryWriter(IImageLogBuilder imageLogBuilder)
{
_imageLogBuilder = imageLogBuilder;
}
....
}
You never set the value of the _imageLogBuilder variable. And since you marked it as readonly, the only place it can be set is in a field initializer, or in a constructor.
Did you mean to do something like this, perhaps?
private readonly IImageLogBuilder _imageLogBuilder = // get the value from somewhere else, or make a new one

Categories

Resources