I'm abit new in C#. I have some code like this:
namespace Example
{
public partial class Example_Setting : Form
{
public Example_Setting(String somethings)
{
}
private myPlace()
{
MessageBox.Show(somethings);
}
}
I don't know how to get value of somethings variable in myPlace().How can I do?
An example would be:
namespace Example
{
public partial class Example_Setting : Form
{
string somethings; // <-- declare a variable in the class
public Example_Setting(String somethings)
{
this.somethings = somethings; // save param to variable
}
private myPlace()
{
MessageBox.Show(somethings); // now data is here for use
}
}
I think you can use below code.Declaring the other variable and assign it into constructore and then you can use it in whole class.
public partial class Example_Setting : Form
{
public string some;
public Example_Setting(String somethings)
{
this.some = something;
}
private myPlace()
{
MessageBox.Show(this.some);
}
}
Others have already demonstrated an example. I just want to point out why you can't access somethings from myPlace.
In the example provided in your question, somethings is scoped locally to the constructor. That is, once the constructor has completed, somethings is no longer available to reference and use. In the examples others have provided, they scope somethings to the class, and then assign a the value provided in the constructor parameter. Since somethings is scoped to the class, your other methods (and properties) can access it. Note that if you use public, others outside of the class can use it as well. Best practice though is to keep it private and if you need public access, to use a property.
Related
EDIT: added follow up question from getting a solution suggested from another question
EDIT2: I just realised that my follow up question was not needed.
Is it possible to have an abstract base class with a type parameter of T have a constructor that takes a parameter of T and assigns it to a property of T? What i want to achieve is that all derived classes has a constructor that does this?
Something like:
public abstract class NotificationBase <T>
{
public string Text { get; set; }
public T Context { get; set; }
public NotificationBase(T context, string text)
{
Context = context;
Text = text;
}
}
public class NumberNotification : NotificationBase<int>{}
public class Program
{
public void Run()
{
var thing = new NumberNotification(10, "Hello!");
}
}
EDIT:
I got a link to another question that explained how to do this which is great. However i have some issues with that. And i dont mean its wrong, if that is the only way to do it then thats how it is. However its not the ideal situation for what im trying to do. I explain. This was the solution:
public class Base
{
public Base(Parameter p)
{
Init(p)
}
void Init(Parameter p)
{
// common initialisation code
}
}
public class Derived : Base
{
public Derived(Parameter p) : base(p)
{
}
}
..which works great. However it does create two small issues that id like to se if they can be addressed.
What i want is to force all classes that derives from the base to pass a T into the constructor so that its mandatory. With this solution, its possible to leave it out.
If all classes should do this then it feels redundant to create a constructor to propagate a mandatory parameter.
EDIT: I just realised that demanding a constructor that propagates the type parameter IS what im looking for. I makes sure that the T property gets a value and also allows for other things to happen in the constructor.
Yes, you can, you just need to propagate the constructor chain using the relevant type, and call the ancestor if needed:
public class NumberNotification : NotificationBase<int>
{
public NumberNotification(int context, string text)
: base(context, text)
{
}
}
Without constructor in child class, the instantiation you wrote can't compile because you don't offer a way for the compiler to know what to do.
You can also offer any other constructor needed.
Therefore now this compiles and works:
var thing = new NumberNotification(10, "Hello!");
Inheritance And Constructors (C# Corner)
base (C# Reference)
Define the parameterized constructor for NumberNotification class which should invoke the required constructor of NotificationBase using base
public class NumberNotification : NotificationBase<int>
{
public NumberNotification(int context, string text)
:base(context, text)
{
}
}
Now for NumberNotification object, context is type of int as here T is marked as int type which Yyou can check using below code:
var thing = new NumberNotification(10, "Hello!");
Console.WriteLine(thing.Context.GetType());
The above prints the output as System.Int32
Check the fiddle - https://dotnetfiddle.net/keufQO
What I would like to do is to have a list that is in an object counts that is defined in the App class as a static when my application starts:
Here's the object:
public class Counts
{
public Counts()
{
public static List<CntQty> CardClicks2m;
}
}
In my application I declare this
am using the following code:
public partial class App : Application
{
public static Counts counts = new Counts();
public App()
{
}
}
Now I try to use load some data into the list but it gives me the error below. Note that this function is in another class.
public void GetClickHistory()
{
App.counts.CardClicks2m = db2.Query<CntQty>(sql);
The last line of the code is giving me an error saying
counts.CardClicks2m cannot be accessed with an instance reference;
qualify it with a type name instead.
I have tried a few different ways to make this work. One by removing the static and creating the object in the app constructor. This also didn't seem to work so I am hoping someone can point me in the right direction or at least suggest something.
i guess scope of variable is not right , you need to do like this
public class Counts
{
public static List<CntQty> CardClicks2m;
public Counts()
{
}
}
The error is pretty self explanatory, you cannot access a static property using an instance variable. all you need to do is use the typename. So this:
App.Counts.CardClicks2m
Becomes this:
Counts.CardClicks2m
You may need to specify the full namespace of the Counts class:
Some.Namespace.Counts.CardClicks2m
The error you are receiving is because you are trying to access to a static member from a instance object
public void GetClickHistory()
{
App.counts.CardClicks2m = db2.Query<CntQty>(sql);
EDITED after comments:
Try this (accessing the static member from the class):
public void GetClickHistory()
{
Counts.CardClicks2m = db2.Query<CntQty>(sql);
As CardClicks2m is declared static, it must be accessed from the class scope. If Counts class doen't have any other code, you can declare
public static class Counts
And there is not neccesary to create an instance of counts
public static Counts counts = new Counts(); //this is not neccesary
As your CardClicks2m-member is static there´s no need to have any instance of your Counts- or aven your App-class. The member exists once per appdomain however. Having said this in order to access CardClicks2m you don´t have to create an instance of your Counts-class within App.
Use this instead:
class MyClass
{
void DoSometjing()
{
Counts.CardClicks2m = db2.Query<CntQty>(sql).ToList();
}
}
Be aware to that Query will surely not return a List<CntQty>, but an IQueryable<CntQty>, that´s why you should call ToList afterwards.
Furthermore you can´t declare a member within a method or constructor. Thus declare it within the class´-body instead of the constructor:
public class Counts
{
public static List<CntQty> CardClicks2m;
public Counts() { /* any further initialzation */ } }
}
In the C# code listed below, I get a "NullReferenceException" with the error:
"Object reference not set to an instance of an object"
I guess the error is related to the inheritance and/or the template definitions. The list gets initialized, and when debugging I can confirm that the list does not point to NULL. I can't figure out how to do this in another way. (Sorry about the confusing class names / structure). The exception happens here: this.localSMT.doSomething(base.list);
public class VTEST<V>
{
public List<V> list;
public LocalSMT<V> localSMT;
public VTEST()
{
list = new List<V>();
}
}
public class VTEST_FSUB<V> : VTEST<V>
{
public VTEST_FSUB()
{
do_virtual();
}
public void do_virtual()
{
this.localSMT.doSomething(base.list);
}
}
public class VTEST_RUN : VTEST_FSUB<int>
{
public VTEST_RUN()
{
localSMT = new VTEST_SUB();
}
}
public class LocalSMT<V>
{
public LocalSMT() { }
public virtual void doSomething(List<V> value) { }
}
public class VTEST_SUB : LocalSMT<int>
{
public VTEST_SUB(){}
public override void doSomething(List<int> value) {
System.Console.WriteLine("VTEST_SUB VIRTUAL");
}
}
class Program
{
Program() {}
static void Main(string[] args)
{
VTEST_RUN run = new VTEST_RUN();
}
}
The problem is that the VTEST_FSUB<V> constructor body is executing before the VTEST_RUN constructor body. So when do_virtual is called, localSMT is still null. Then do_virtual tries to call a method on localSMT, hence the exception.
Basically the initialization order for any class in the hierarchy is:
Initialize variables which have been declared within an initializer at the point of declaration (any other variables just have the variable type's default value)
Chain up to the base class initialization
Execute the constructor body
See my article on constructor chaining for more details.
Lessons to learn:
Avoid public fields. If you use private fields, it's easy to find every piece of code that reads them and writes to them
Ideally, use readonly fields: if you'd passed the value up the constructor chain and set it in the VTEST<V> constructor, you wouldn't have had a problem. (Admittedly readonly fields can still be a pain because of the next point...)
Avoid virtual method calls in constructors. In this case that wasn't the problem, but you could easily have had the same issue if do_virtual had been abstract in VTEST_FSUB<V> and overridden to call localSMT.doSomething in VTEST_RUN. It would still have executed before the constructor body had run, which would be surprising. Anything you call within a constructor is operating on a partially-initialized object, which is a precarious situation.
Avoid large inheritance hierarchies. They're a pain to work with and reason about.
Follow .NET naming conventions! Your code is partly hard to read because it's so unidiomatic. Even when you're just giving sample code, at least follow the capitalization conventions.
try:
public void do_virtual()
{
localSMT=new LocalSMT<V>();
localSMT.doSomething(list);
}
in public class VTEST_FSUB<V> : VTEST<V>
You are not instatianing localSMT before using, so it's not working.
EDIT: OR
public class VTEST<V>
{
public List<V> list;
public LocalSMT<V> localSMT;
public VTEST()
{
list = new List<V>();
localSMT = new LocalSMT<V>();
}
}
initialize it in constructor, preferable.
Second solution is cleaner.
public class VTEST_RUN : VTEST_FSUB<int>
{
public VTEST_RUN()
{
localSMT = new VTEST_SUB(); // BAD! localSMT isn't initialized yet!
}
}
I believe that you have failed to new up one of your objects:
public void do_virtual()
{
localSMT = new LocalSMT<V>();
localSMT.doSomething(list);
}
Make sure that when you are trying to use an object that you initialize them! And don't worry too much, this is a very common problem in coding.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why Would I Ever Need to Use C# Nested Classes
I'm doing it shorty, I have a class which looks like this:
namespace Blub {
public class ClassTest {
public void teest() {
return "test";
}
public class AnotherTest {
public void blub() {
return "test";
}
}
}
}
I can access to the function called "teest" like this, but how can I access to the function "blub" without doing another "new ClassTest.AnotherTest()"?
Accessing to the function teest:
Blub.ClassTest = new Blub.ClassTest();
ClassTest.teest(); //test will be returned
My try (and how I want it to, to access on AnotherTest is this:
Blub.ClassTest = new Blub.ClassTest();
ClassTest.blub(); //test will be returned
Which don't work, I can just access to AnotherTest like this, how I dont want it:
Blub.ClassTest2 = new Blub.ClassTest.AnotherTest();
ClassTest.blub(); //test will be returned
Does someone know a solutions for this?
You're declaring AnotherTest inside ClassTest, that's why you have to browse for it using namespace.class.2ndClass.
However, I suppose that you're not much aware of OO concepts, are you? If you declare a method inside a class, it will only be available for objects of that class, unless you declare it as static, what means that it would be a class method rather than a instance method.
If you want ClassTest to have 2 methods (teest and blub) simply declare both at the body of the class, like:
public class ClassTest
{
public string teest()
{
return "test";
}
public string blub()
{
return "test";
}
}
Also, note that if a method is declared as void it won't return anything (in fact, I think that your original code wouldn't even compile at all).
I'd recommend you to study OO a little deeper before trying to figure things out at your own.
If you need access to another class you have to make it a property in the first class.
namespace Blub {
public class AnotherTest {
public void blub() {
return "test";
}
}
public class ClassTest {
public AnotherTest at = new AnotherTest();
public void teest() {
return "test";
}
}
}
Then access it like this:
ClassTest x = new ClassTest();
x.at.blub();
I am trying to set/read a variable in class bluRemote from another namespace/class like so:
namespace BluMote
{
class bluRemote
{
public string cableOrSat = "CABLE";
........
}
}
and the other cs file (which is the form):
namespace BluMote
{
public partial class SettingsForm : Form
{
if (BluMote.bluRemote.cableOrSat == "CABLE")
{
BluMote.bluRemote.cableOrSat = "SAT";
}
.......
}
}
I know i am doing it wrong but I'm more used to doing stuff like this in VB so its like night and day ha :o)
What you are trying to do is work with static variables so you would need to change your class to this:
namespace BluMote
{
public static class bluRemote
{
public static string cableOrSat = "CABLE";
........
}
}
It is better if you stay away from static classes (for the most part) and instead focus on an object oriented approach where you have an instance (object) of bluRemote.
So instead of making the bluRemote class static you keep it the same and do:
public partial class SettingsForm : Form
{
private bluRemote _remote = new bluRemote(); // possibly created somewhere else
public void SomeFunction()
{
if (_remote.cableOrSat == "CABLE")
{
_remote.cableOrSat = "SAT";
}
}
.......
}
You're trying to access an instance variable - i.e. one which has a potentially different value for each object - just by class name. That only works for static variables.
You need to have an instance of bluRemote, and ask that for its value. However, I would strongly suggest that:
You rename your class to follow .NET naming conventions
You don't make variables public; use properties
Also note that there's only one namespace here - BluMote. Both of your classes are declared in that namespace.
As you've declared the cableOrSat field, you'll need to set it on an instance of the bluRemote class, but you are trying to set it using the name of the class itself.
If you declare the cableOrSat field as:
public static string cableOrSat = "CABLE";
You will be able to access it through the class name itself.