I have a button click event in class1test where I want to set the value of d_testNumber to 3. Then in class 2test I want to be able to do an if test and if d_testNumber show a message box. My problem is that d_testNumber is always 0 in class 2test. Can someone tell me how to get the value from class 1test d_testNumber to class 2test?
This is in class 1test:
public int d_testNumber = 0;
Method in class 1test :
void miEditCopay_Click(object sender, Telerik.Windows.RadRoutedEventArgs e)
{
d_testNumber = 3;
}
This is in class 2test:
public int d_testNumber;
Method in class 2test:
public void HelloMessage();
if (d_testNumber == 3)
{
messagebox.show('test worked');
}
If it's a public instance property on the class, like this:
public Class Alpha
{
public int DTestNumber ;
}
Then the other class needs a reference to the appropriate instance of the other class in order to examine it. How that reference is obtained is up to you and the design of your program. Here's an example:
public class Bravo
{
public void SomeMethod()
{
Alpha instance = GetAnInstanceOfAlpha() ; // might be passed as a parameter
if ( instance.DTestNumber == 3 )
{
messagebox.Show('test worked') ;
}
return ;
}
If it's a public static property on the class, like this:
public Class Alpha
{
public static int DTestNumber ;
}
Then in the other class you can do something like this:
public class Bravo
{
public void SomeMethod()
{
if ( Alpha.DTestNumber == 3 )
{
messagebox.Show('test worked') ;
}
return ;
}
Note that static members are singletons with respect to the application domain and the class (Note: statics are per-class properties, not per-intance). Further, if your application is multi-threaded (like a windows program almost certainly is), any changes made to static members are a guaranteed race condition unless you take pains to serialize access via the many synchronization primitives available to you (e.g., the lock statement).
Head First Labs produces some excellent books for self-learning. If you're new to programming, cruise over to Head First Labs and get their Head First Programming: A learner's guide to programming using the Python language (and yes, it does use Python, but for most languages, the skill of programming is not related to the language used.
If you already know something about programming, but are new to C#, then get get a copy of, Head First C#: A Learner's Guide to Real-World Programming with C#, XAML, and .NET. Highly recommended.
if you want to use the same value as defined in class 1 then you have 3 options
Make the variable static in first
if you don't want to make it static you need to pass the value to the other class
Example of 1:
public static int d_testNumber = 0;
if (Class1test.d_testNumber == 3)
{
//your code
}
Use static in declaration.
public static int d_testNumber = 0;
You would have to specify further. You have a d_testnumber field in both classes, and the 2test class will use the variable of its own.
If you have an 2test object called 2testObject somewhere, you can do:
void miEditCopay_Click(object sender, Telerik.Windows.RadRoutedEventArgs e)
{
2testObject.d_testNumber = 3;
}
And pass 2testObject to the HelloMessage() method
Maybe you want d_testNumber to be static so both classes can easily access it?
in 1test:
public static int d_testNumber;
//rest of code the same
in 2test:
if (1test.d_testNumber == 3)
{
//code
}
(Assuming both classes are in the same project / namespace, if not you may need a reference / using statement at the top)
Related
In Python, I can have the equivalent of C# static members:
class MyClass:
i = 0 # This is like a C# static member
print(MyClass.i)
gives output
0
But maybe my static member needs to be calculated somehow. I can do:
class MyClass:
i = 0
i += 10
print(MyClass.i)
gives output
10
In practice, I'm writing a config class which needs to read a json file from disk, validate it, and then populate some static members. The closest thing to what I want to do in Python would look like:
class GlobalConfig:
with open('config.json', 'r') as f:
config_dict = json.read(f)
# Maybe do some validation here.
i = config_dict["i"]
a = config_dict["hello_world"]
Truth be told, I wouldn't really do this in Python, but I'm borrowing from C# in that everything needs to go in classes.
In practice in my C# code, I would have a GlobalConfig class in a Config.cs file and all my other files would have access to this.
But it seems I can't do anything other than declare/define members in the class body. How can I do the work of loading up and parsing my config file and have the result of that be accessible as static members to the rest of my program?
PS: I don't really want this to influence the answers I get in unless it has to, but FYI I am working with Unity.
Are you looking for static constructor?
public class MyClass {
private static int i = 0;
private static int j;
private static int loadJ(int value) {...}
// Static constructor will be called before the first MyClass call
static MyClass() {
// If you want to compute anything with static you can do it here
i += 10;
// you can call static methods here, address static fields and properties
j = loadJ(i);
}
}
An alternative to static constrcutors is some lazy-loading approach. In essence you just initialize your class when it is used in any way calling the loading-function internally:
public class MyClass
{
static int i;
private static int loadJ()
{
i = ReadValueFromJson();
}
public static DoSomething()
{
// load if not yet done
if(!loaded)
loadj();
// do the actual work
}
}
The advantage here is that you get more fine-grained controll about if or if not initialization should happen. Imagine some constant within your config-class that allways has the exact same value regardless of any initialization. The downsie is that you need to add this boilerplate to all the members that need loading.
I realize this sounds like a question the answer to which can be found in the first google link, but to my surprise it wasn't. I'm learning C# recently and for the first time I'm writing a fairly large project, which at the moment contains more than 200 lines of code and, according to my estimates, should contain more than 1000 in the end.
I understand that this is not a problem for experienced programmers, but I'm starting to get confused.I have found some answers on pulling classes from neighboring files, but my code consists almost entirely of methods and I have not been able to interpret these answers to my advantage. Again, this is most likely due to my inexperience.
i want my files to look something like this:
program1.cs
int x = 25;
program2.cs
Console.Write(x);
As you can see, this does not happen. I have tried adding the CS file either manually or through the solution explorer. Nothing helps, so I really hope to get an answer here. How can I get all methods and variables from one file to work in another in VS? Additional question: If there is no such possibility at all, can I somehow visually hide a piece of my code from myself, just so that it does not bother me until I need to change something in it?
P.S. Yes, I understand that if it is easy to get confused in the code, then the code is poorly composed. I'm also working in this direction, but I would still like to know the answer.
If your class is so big you want to split it into multiple files it’s likely that you should also be splitting it into multiple classes that each perform a simpler job. To access public methods and variables of one class from another class, either they need to be static (meaning there’s only ever one of that thing basically) in which case you can activate them using the name of the class, e.g.:
Class1.cs
public static int x = 25;
Class2.cs
Console.Write( Class1.x );
Or you need a reference to a specific instance of that class, e.g.
Class1.cs
public int x = 25;
Class2.cs
Class1 instance = new Class1();
Console.Write( instance.x );
Ok, so here is the code I promised.
Here are the two files I created
Program.cs
using System;
namespace splitClass
{
// You can either write a class here and use it on the other file
public class HelloThere
{
public HelloThere()
{
Console.WriteLine("Hello, there");
}
public static int add(int a, int b)
{
return a + b;
}
public int subtractFromTen(int c)
{
return 10 - c;
}
static void Main(string[] args)
{
// You can also use the class in the other file
UseHelloThere useHelloThere = new UseHelloThere();
Console.WriteLine(useHelloThere.add(8, 9));
}
}
// or split a class into two using partial keyword
public partial class SomeOtherClass
{
public int abc;
public SomeOtherClass()
{
abc = 87;
}
public int getAbc()
{
return abc;
}
public int add(int b)
{
return b + abc;
}
}
}
Other file.cs
using System;
namespace splitClass
{
// since namespaces are same, you can use the other class from the same file
public class UseHelloThere
{
HelloThere hello;
public UseHelloThere()
{
hello = new HelloThere();
}
public int add(int a, int b)
{
return HelloThere.add(a, b);
}
}
// or you can write the continuation of the other class
public partial class SomeOtherClass
{
public int subtract(int a)
{
return abc - a;
}
}
}
If you want to get all methods and variables from one file to work in another in VS, you can refer to the following steps:
First, define variables and methods in Program1.cs such as:
namespace ConsoleApp7
{
namespace ConsoleApp
{
public static class Program1
{
static void Main(string[] args)
{
}
public static int x = 25;
public static void add()
{
x++;
}
}
}
}
Second, add project reference in Program2.cs.
Finally add using in Program2.cs and then you can use the variables and methods defined in Program1.cs.
using ConsoleApp7.ConsoleApp;
class Program2
{
static void Main(string[] args)
{
Console.WriteLine(Program1.x);
Program1.add();
Console.WriteLine(Program1.x);
}
}
Is there a .net method that determines whether or not a given method has been previously called for a given object instance?
Sometimes a property getter method has side effects. For instance, a property getter if not called previously may need to create additional objects and perform other work in order to return the value of a backing field. I can't have that happen. If the getter method hasn't been called previously, I don't need the value.
For example...
object item = something;
foreach (PropertyInfo propertyInfoForItem in item.GetProperties(Reflection.BindingFlags.Public)) {
//Need something to avoid calling this if the property getter method has not been previously been called for this item
object itemPropertyValue = nothing;
itemPropertyValue = propertyInfoForItem.GetValue(item, null);
}
I've looked through the MethodInfo class returned from PropertyInfo.GetGetMethod() and didn't spot anything there that would help.
Any ideas?
As an additional note based on feedback (and thanks for chiming in!), I wouldn't be able to modify the existing objects I'm inspecting.
I think your way of achieving this goal is overly complicated. You can simply use a bool or numeric class-level variable for this purpose.
public class C
{
private int _counter = 0;
// private bool _methodCalled = false;
public void M()
{
// check the state of _counter or _methodCalled
_counter++;
// _methodCalled = true;
}
}
You can make the private variable static if you want to take all calls into account, regardless of the instance of the class that was used to invoke it.
Note that locking may be necessary if there is some multi-threading going on and you have conditional branching depending on the counter.
EDIT
Since the class cannot be modified (as stated in the comment), you'll need to create a wrapper class that will aggregate your class and hold the counter.
public class CWrapper
{
private int _counter = 0;
private C _c = new C();
public M()
{
if (_counter == 0)
{
_c.M();
}
counter++;
}
}
Since you've stated a few times that you do not have the ability to modify the objects in question, your only option is going to be to implement wrapper classes for those object types. In your wrapper class you can expose all of the properties and methods on the objects in question, but you can implement in your wrapper Getters the reference counting suggested in the other answers.
If you need to determine if a Getter has been called before you have access to the object, I'm afraid you are out of luck.
You could make a static count within the class and then within the method for the first time increment to 1 if 0 and subsequent times if 1 then you know it has been called already and you can return -1 or whatever.
You can use the decorator design pattern in order to do it.
class Program
{
static void Main(string[] args) {
var hasDoMethodInstance = new HasDoMethodImpl();
var hasDoMethodDecoratorInstance = new HasDoMethodDecorator(hasDoMethodInstance);
hasDoMethodDecoratorInstance.Do();
}
}
public interface IHasDoMethod
{
void Do();
}
public class HasDoMethodDecorator : IHasDoMethod
{
private int counter = 0;
private readonly IHasDoMethod hasDoMethod;
public HasDoMethodDecorator(IHasDoMethod hasDoMethod) {
this.hasDoMethod = hasDoMethod;
}
public void Do() {
hasDoMethod.Do();
counter++;
}
}
public class HasDoMethodImpl : IHasDoMethod
{
public void Do() {
//Your logic
}
}
i know i lack a base knowlage of the realtions between classes and inheritance
i find it hard to understand a simple thing :
a given DDl or TextBox could be accessed from code behind
int selected = DDLID.SelectedIndex ;
string userInput = TBXID.Text;
Now from a class that is placed in code behind :
public static class ControlsValue
{
public static int UserSel = DDLID.Selected.index;
public static string UserText = TBXID.Text;
}
i was trying to "Arange" my code so i will be able to reuse it in some other projects
...so i have moved all global variables related to the code in that class into the class
and what i can't do is assign variables with webControls Values
what is the way to do it ?
update
a way i could think of is via parameter
public static class ControlsValue
{
public static void getValues(DropDownList DDLID)
{
public static int UserSel = DDLID.Selected.index;
}
public static string UserText(TextBox TBXID)
{
return TBXID.Text;
}
}
Create a different class like this
public class ControlValues{
private int_dropDownIndex;
public int DropDownIndex{
get { return _dropDownIndex; }
set { _dropDownIndex= value; }
}
private string _textBoxValue;
public string TextBoxValue{
get { return _textBoxValue; }
set { _textBoxValue= value; }
}
public ControlValues(int dropDownIndex, string textBoxValue){
this._dropDownIndex = dropDownIndex;
this._textBoxValue = textBoxValue;
}
}
You can create an instance from your code behind like below
ControlValues cv= new ControlValues(DDLID.Selected.index, TBXID.Text);
Now you can access the DropDown index and text as
cv.DropDownIndex;
cv.TextBoxValue;
Although I provided an answer for this, Please note:
Remember the stateless nature of web application and the way you are going to use this.
In ASP.NET, it will be inefficient to create an Instance of class to hold values of server control because those controls and their values are directly accessible from the code behind. Using this approach will be an extra overhead.
If you are serious about learning re-usability, I would strongly recommend you to learn basics of object oriented programming. Once you have a good grip of OOP, you will see clearly when to apply OOP principles.
I am reading Josh Bloch's book Effective Java and he suggests using a builder design pattern when building objects that have large amounts of members. From what I can see it isn't the vanilla design pattern but looks like his variation. I rather like the look of it and was trying to use it in a C# web application that I am writting. This is the code written in Java and works perfectly
public class Property {
private String title;
private String area;
private int sleeps = 0;
public static void main(String[] args) {
Property newProperty = new Property.Builder("Test Property").Area("Test Area").Sleeps(7).build();
}
private Property(Builder builder) {
this.title = builder.title;
this.area = builder.area;
this.sleeps =builder.sleeps;
}
public static class Builder{
private String title;
private String area;
private int sleeps = 0;
public Builder (String title){
this.title = title;
}
public Builder Area(String area){
this.area = area;
return this;
}
public Builder Sleeps(int sleeps){
this.sleeps = sleeps;
return this;
}
public Property build() {
return new Property(this);
}
}
}
When I put this into what I think is the C# equivalent
public class Property
{
private String title;
private String area;
private Property(Builder Builder)
{
title = Builder.title;
area = Builder.area;
}
public static class Builder
{
// Required parameters
private String title;
private String area;
// Optional parameters
private int sleeps = 0;
public Builder(String val)
{
this.title = val;
}
public Builder Area(String val)
{
this.area = val;
return this;
}
public Builder Sleeps(int val)
{
this.sleeps = val;
return this;
}
public Property build()
{
return new Property(this);
}
}
}
Then I get compiler warnings. Most of them "cannot declare instance members in a static class".
So my question is firstly what have I missed? If I have missed something, can I do it in the manner Josh Bloch recommends but in C#, and lastly, and this one important too, is this thread-safe?
public static class in Java means that you define a static nested class. That means that it is logically contained in another class but instances of it can exist without a reference to it's outer class. A non-static nested class is called an "inner class" and instances of it can only ever exist in relation to an instance of the outer class.
In C# a static class is one that can't be instantiated and thus can't have any non-static members. There is no direct language-level equivalent to this construct in Java, but you can easily prevent instantiation of a Java class by providing only a private constructor.
Short Java recap:
All Classes defined inside another Class are "nested Classes"
nested Classes that are not static are called inner Classes
instances of inner Classes can only exist in relation to an instance of the outer Class
static nested Classes have no separate name
static nested Classes are largely independent from their outer class (except for some privileged access).
I'd be happy if some C# guru told us how inner/nested classes are handled in C#/.NET.
I think you can achieve pretty much the same effect if you create Builder as a top level class ( for that's exactly what it is in Java ) and create a factory method to receive the builder in order to keep the constructor private ( which in turn would let you return subclasses instances if needed).
The point is to let the builder perform the steps needed to create the object.
So ( without knowing much about C# you could try something like this )
// My naive C# attempt:P
public class Property
{
public static void main( String []args )
{
Property p = Property.buildFrom( new Builder("title").Area("area").Etc() )
}
public static Property buildFrom( Builder builder )
{
return new Propert( builder );
}
private Property ( Builder builder )
{
this.area = builder.area;
this.title = builder.title;
// etc.
}
}
public class Builder
{
public Builder ( String t )
{
this.title = t;
}
public Builder Area( String area )
{
this.area = area;
return this;
}
// etc.
}
The whole point of having Builder as an static inner class of property is to create a high coupling among the two ( as if they where one ). That's why build method in Builder calls the private "Property" constructor.
Probably in C# you could use an alternate artifact to create the same coupling.
saua has the right answer, but I would like to be clear about your example in particular:
In the C# version, you should remove the static keyword from the inner class. It doesn't mean the same thing as the Java version, and indeed the effect it has in the Java version is the normal behaviour for inner classes in C#.
In Java a nested class is by default associated with a particular instance of its containing class. An instance of the nested class can access variables and methods of the containing instance. If the nested class has the "static" keyword then it is not associated with an instance of the outer class. It is in this sense that Bloch uses the "static" keyword on the Builder class.
"Static" means something different when applied to a nested class in C#. I don't know what keyword you would use in C#, or even if it is necessary. Did you try leaving the static keyword out of the class definitions?
Use of "static" in Java class definitions is discussed in Item 18 of Effective Java.
I'm not sure what Java is doing with the static class declaration, but in C#, a static class is one that only has class-level members and, by definition, can not be implemented into an instance. It's like the old VB difference between Class and Module.
I don't know why C# is complaining, but I can say that the code is thread-safe. If you were creating two or more instances of Property at the same time, each in their own threads, you wouldn't run into any problems.
I will try removing the static keyword. My other thought was, as others have already suggested, was to create the builder class as a top level class.
To answer several comments about how to get Java's inner class behavior in C#, it would seem that the reference to the enclosing class needs to be passed in the constructor of the inner class (from a quick Google - C# may have since added the capability).
public class Outer
{
...
void SomeMethod() {
Inner workerBee=new Inner(this);
}
...
class Inner
private Outer outer;
{
Inner(Outer out) {
outer=out;
}
}
}
So C# just makes explicit what Java did implicitly, including explicitly needing the reference to access members of the outer class.
Personally, I have never liked the Java implicit accesses to the outer classes members, since it seems too easy to trip up and accidently break encapsulation - I nearly always create my inner classes as static and pass them a reference to the outer class.
Assuming that your class has publicly settable properties corresponding to the builder members, you don't need Bloch's builder pattern in C#. You can use Object Initializers:
public class Property
{
public String Title {get; set};
public String Area {get; set};
public int Sleeps {get; set};
public static void main(String[] args)
{
Property newProperty = new Property {Title="Test Property", Area="Test Area", Sleeps=7};
}
}
This won't be possible if you need more encapsulation.