this is probably very simple, but I have always just made one big class and never tried make clean code. Now I am trying and experiencing errors..
So, this is the idea:
class1
{
method1 { value 1; value 2 }
method2 { value 3; value 4 }
method3 { uses method4 from class2 }
}
class2
{
method4 { uses values 1-4 from class1 }
}
I am doing it by calling: class1 c1 = new class1() in method4 and class2 c2 = new class2 in method3.
So this is what happens:
method1, method2 produce values 1-4
method3 calls class2 c2 = new class2
I get into class2, then into method4 and get null/0 values instead of what I made in first step.
Instead of creating a new instance of class1 in method4 you should pass the current class1 instance (accessible through this inside method3) as a parameter to this method to get the same result.
You need to be more specific...
class Class1
{
Class2 _class2;
public Class1(Class2 class2)
{
_class2 = class2;
}
public void method3()
{
//call _class2.method4()
}
}
class Class2
{
Class1 _class1;
public Class2(Class1 class1)
{
_class1 = class1;
}
public void Method4()
{
//call _class1.MethodWhatever()
}
}
So when you need to access variables within a class you can obviously do this simply via the 'public' modifier, however the below example is not best practice but we will get onto that shortly...
public class MyTestClass
{
public int MyAge;
}
This is a field - fields should really be private, and we should use a property to expose the field. However if you did do this, then you can access that like so:
var foo = new MyTestClass();
var hisAge = foo.MyAge;
Of course based on your requirements maybe you don't want the user to access the variable directly, but rather get a value after some computation has been done on other variables.
You can do this like so:
public class MyTestClass
{
private int _gamesPlayed;
private int _gamesLost;
public int NumberOfWins { get { return _gamesPlayed - _gamesLost; } }
}
NumberOfWins is a Property. It computes the values of two of our fields and reutrns it. See how we have the private modifier, these can't been seen outside of the scope of that class. NumberOfWins can be accessed the same way as MyAge in the previous example.
To be honest, it sounds like you are rather using pseudo-code or are a beginner.
I recommend checking out the following articles for a bit more information on what I have stated.
Modifiers - C# Reference
Properties C# Programming Guide
Difference between a Field and a Property in C#
it is really unclear what you want to achieve and how class1 is linked to class2. If your class2 is ONLY useful for the first class then (and only then) you could use nested classes...
class OuterClass {
string value1;
string value2;
string value3;
// ...
class InnerClass
{
OuterClass o_;
public InnerClass(OuterClass o)
{
o_ = o;
}
public string GetOuterString()
{
return o_.value1 + o.value2 + o.value3; //...
}
}
void SomeFunction()
{
InnerClass i = new InnerClass(this);
i.GetOuterString();
}
}
This would create a clear binding from the inner class (class 2) to the outer one. It is not easier though.
Edit: OK, after your edit I see a whole different story..
Well, here is some code for you. I'm not sure it it's what you require. It might help you get started, though. You can try running it here: https://dotnetfiddle.net/#
This is Class1. It exposes some of its data via properties.
public class Class1
{
// these are properties
public int Value1 { get; set; }
public int Value2 { get; set; }
public int Value3 { get; set; }
public int Value4 { get; set; }
public void Method1()
{
Value1 = 1;
Value2 = 2;
}
public void Method2()
{
Value3 = 3;
Value4 = 4;
}
public void Method3()
{
// uses method4 from class2
var c = new Class2();
c.Method4();
}
}
This is Class2. It calls methods from Class1 and accesses its properties.
public class Class2
{
public void Method4()
{
//uses values 1-4 from class1
var c = new Class1();
c.Method1();
c.Method2();
Console.WriteLine(c.Value1);
Console.WriteLine(c.Value2);
Console.WriteLine(c.Value3);
Console.WriteLine(c.Value4);
}
}
This uses both closes and shows the result:
using System;
public class Program
{
public static void Main()
{
var c1 = new Class1();
c1.Method3();
}
}
Related
So lets say I have two classes. Class A and Class B like this:
Class A
{
B classB;
public A
{
classB = new B();
}
public void funcIHaveToUseInClassB()
{
}
}
Class B
{
A classA;
public B
{
classA = new A();
}
public void funcIHaveToUseInClassA()
{
}
}
As you can see both classes contain functions that need to be used in the other class. Class A has a function that class B has to use and the other way around. No I can't just put the functions in the other class because they heavily rely on the class they are currently in. So how would I go about doing this? With my method I create an infinite loop and get a stack overflow exception. I hope someone can help me out, thanks in advance.
EDIT:
People are asking me why I need these 2 classes to rely on each other so here it is: Class A manages everything that has to do with a WebBrowser control and class B Manages everything that has to do with a certain page in my program. Class A is being used by multiple pages, which is the reason it needs to be a seperate class. Class A sometimes needs to push info to class B. Class B sometimes needs info from the WebBrowser control class A is managing and that is why it calls a function.
Make classB and classA into public properties and initialize them from another class instead of constructor.
class A
{
public B classB { get; set; }
public void funcIHaveToUseInClassB()
{
}
public void anotherF()
{
classB.funcIHaveToUseInClassA();
}
}
class B
{
public A classA { get; set; }
public void funcIHaveToUseInClassA()
{
}
public void anotherF()
{
classA.funcIHaveToUseInClassB();
}
}
static void main()
{
// entry point
var a = new A();
var b = new B();
a.classB = b;
b.classA = a;
// do what ever you want with a and b
}
You need to pass an instance of one of your classes to the constructor of the other class.
Try this:
Class A
{
B classB;
public A()
{
classB = new B(this);
}
public void funcIHaveToUseInClassB()
{
}
}
Class B
{
A classA;
public B(A arg)
{
classA = arg;
}
public void funcIHaveToUseInClassA()
{
}
}
Update
Or just pass in the instance as a parameter to the methods like in Matt Jacobsen's answer.
Create a private and public accessor, and instantiate the property only when the private object is null, like so:
class A
{
private B _b;
public B b {
get {
if (_b == null) _b = new B();
return _b;
}
}
// Constructor can now be empty
public A()
{
}
}
Pass your reference from B/A in to A/B each time you need to use it. You don't need the constructors.
Class A
{
public void funcIHaveToUseFromClassB(B classB)
{
}
}
Class B
{
public void funcIHaveToUseFromClassA(A classA)
{
}
}
Is it possible to to define a string from a variable where the string does NOT have quotations. Example:
public class aclass
{
public string athing;
}
public void example(string thing)
{
aclass thing = new aclass();
}
The string thing can't be put into aclass thing = new aclass(); normaly.
Is there anyway to do it?
You need a constructor
void Main()
{
CreateExampleObject("testing");
}
public class Example
{
// This is a constructor that requires a string as an argument
public Example(string text)
{
this.Text = text;
}
public string Text { get; set; }
}
public void CreateExampleObject(string text)
{
Example example = new Example(text);
Console.WriteLine(example.Text);
}
You can do it this using many way but generally standard way is using constructor
please refer this link for better understanding.
C# : assign data to properties via constructor vs. instantiating
You have to ways of setting fields/property value of an object.
First is to do it through the constructor, as mentioned in other answer.
Second can be implmeneted in various ways:
Expose public property making field privte:
public class aclass
{
private string _athing;
public string Athing
{
get { return _athing; }
set { _athing = value; }
}
}
public void example(string thing)
{
aclass aclass = new aclass();
aclass.Athing = thing;
}
Or even shorter, you could use property:
public class aclass
{
public string Athing {get; set; }
}
Using your implementation, you make your field public, so you can set it easily:
public void example(string thing)
{
aclass aclass = new aclass();
aclass.athing = thing;
}
But it doesn't comply with OOP encapsulation principle.
a simple question :
public class class1
{
public string string1;
public class class2
{
public string string2
{
get{ string tmp = class1.string1; }
}
}
}
I want to be able to reach class1.string1 from class2.string2.get, but I cant. What would you recommend me to change, so that I can do that?
Thanx
Passing class1 reference to class2 in constructor:
public class class1 {
public string string1;
public class class2 {
private class1 _Reference;
public class2(class1 reference) {
if (reference == null) {
throw new ArgumentNullException("reference");
}
_Reference = reference;
}
public string string2 {
get { return _Reference.string1; }
}
}
}
Passing class1 reference to class2 after both classes have been created:
public class class1 {
public string string1;
public class class2 {
private class1 _Reference;
public class1 Reference {
set { _Reference = value; }
}
public string string2 {
get { return _Reference.string1; }
}
}
}
static void usage() {
var foo = new class1();
var bar = new class1.class2();
bar.Reference = foo;
string value = bar.string2;
}
There is no means of accessing a class from within a nested class that I know of. Class nesting doesn't lead to automatic instantiation of the surrounding class, it's just a (usually rather smelly) means of structuring your code.
You would either need a reference to an actual instance of Class1 inside Class2 or you'd need a static method on Class1.
Another way to accomplish this would be to use inheritance, but that's a whole different beast to tame:
public class Class1 {
protected String String1 { get; set; }
}
public class Class2 : Class1 {
public String String2 {
get {
String PropertyFromClass1 = base.String1;
// ...
}
}
}
That said: Your code wouldn't compile, string2's getter doesn't return anything. And please make yourself familiar with C#'s naming conventions.
Thanx for the suggestions. Due to the specific nature of the code, I had to solve this situation with a global public static class in another namespace.
Coming from Java I faced this "problem" when I started developing in C#.
As clearly explained by Dennis Traub and in this article in C# you can't access outer class members or methods. So you have to implement what in Java happens automatically:
class OuterClass {
string s;
// ...
class InnerClass {
OuterClass o_;
public InnerClass(OuterClass o) { o_ = o; }
public string GetOuterString() { return o_.s; }
}
void SomeFunction() {
InnerClass i = new InnerClass(this);
i.GetOuterString();
}
}
This is a pretty beginner question but I'm stumped and I can't figure out how to get what I want from this. I have my first class that obtains information (database/textfile/whatever) but I want it to relay that information into Class2.
For instance, the first:
public class Class1
{
private int first;
private string firstString;
private bool isTrue;
public void SomeMethod()
{
first = 1;
firstString = "FirstString";
isTrue = true;
}
}
Here SomeMethod sets all the attributes that I need to pass into Class2.
ClassTwo looks like
public class Class2
{
private int first;
private string FirstString;
private bool isTrue;
private int second;
private string SecondString;
private bool isFalse;
public void SomeOtherMethod()
{
}
}
Here what I want is for SomeOtherMethod() to set the first set of attributes with the values that were set in Class1's SomeMethod(). So that I can create an object of type Class2 and add what I want to it.
As some other commentators stated, you really should reuse your data definitions. Something like this can get you started:
public class Class1
{
private int _myInt;
private string _myString;
private bool _myBool;
public void SomeMethod()
{
_myInt = 1;
_myString = "FirstString";
_myBool = true;
}
}
public Class2
{
private Class1 _first = new Class1();
private Class1 _second = new Class1();
public void SetFirst(Class1 obj)
{
_first = obj;
}
}
and then use the classes like this:
Class1 c1 = new Class1();
Class2 c2 = new Class2();
c1.SomeMethod();
c2.SetFirst(c1);
You have to define get accessors for the properties of Class1 because they are all unreachable from outside the class and Class2 needs to use their values. Defining public properties with get accessors can be useful:
private int first;
public int First
{
get
{
return first;
}
}
Having every property in Class1 defined like this, you can access the values. After calling SomeMethod, two objects' properties can be equalized in two simple ways (See also: Signatures and overloading):
public void SomeOtherMethod()
{
Class1 tempClass = new Class1();
tempClass.SomeMethod();
this.first = tempClass.first;
this.FirstString = tempClass.firstString;
this.isTrue = tempClass.isTrue;
}
public void SomeOtherMethod(Class1 myClass) // Overloaded method
{
this.first = myClass.first;
this.FirstString = myClass.firstString;
this.isTrue = myClass.isTrue;
}
Even though the techniques above seem like to be what you asked for, the best is to initialize a class's properties using constructors. This way, you don't have to call SomeMethod each time you create a Class1 object, and you can also set its default values whenever a new one is created. Also, giving more general names to the properties will save you from duplicates. I write some code to provide you an understandable syntax that will prevent future problems of non-accessibility and repetition.
public class Class1
{
private int number;
public int Number
{
get { return number; }
}
private string name;
public string Name
{
get { return name; }
}
private bool isTrue;
public bool IsTrue
{
get { return isTrue; }
}
public Class1()
{
number = 1;
name = "FirstString";
isTrue = true;
}
public Class1(int value1, string value2, bool value3)
{
number = value1;
name = value2;
isTrue = value3;
}
}
public class Class2
{
private Class1 firstClass;
private Class1 secondClass;
public Class2()
{
firstClass = new Class1();
secondClass = new Class1(2, "SecondString", false);
}
}
If you're going to define many Class1 objects in Class2, then a solution such as an array or a list becomes must. I'll give a short example, see MSDN List page.
private List<Class1> class1List = new List<Class1>();
class1List.Add(new Class1());
class1List.Add(new Class1(2, "SecondString", false));
I basically don't want to allow compilation if someone makes a specific property of an object bigger than another property of that same object. can I do that? Kind of like:
class Class1 {
public int property1 { set; get; }
public int property2 { set; get; }
public void method (Class1 obj) {
if (obj.property1 < obj.property2) {
//won't compile!
}
}
}
class Class2 {
static void Main() {
Class1 obj = new Class1();
obj.property1 = 10;
obj.property2 = 11;
obj.method(obj);
}
}
What you are trying to check is a runtime operation, which cannot be done by a compiler.
The closest you can get to what you need to do is by using the C# sizeof operator which checks the size of the property in bytes.