Correctly create a class with subclasses (C#) - c#

I am creating a program in C# and I don't know how to create my classes.
Here's what my class looks like:
public class MyClass
{
public class Parameters
{
string Value { get; set;}
}
public class Methods
{
public void MyMethod()
{
Window.Title = Parameters.Value;
}
}
}
And this is how I want to be able to use it from another class:
public class MainClass
{
MyClass myclass = new MyClass();
myclass.Parameters.Value = "Hello World !";
myclass.Methods.MyMethod();
System.Threading.Thread.Sleep(Timespan.FromSeconds(10));
MyClass myclass2 = new MyClass();
myclass2.Parameters.Value = "Hello World Again !";
myclass2.Methods.MyMethod();
//I know this code is stupid, it's just to simplify my example.
}
But it doesn't work, there are accessibility problems that I don't know how to solve.
Thanks in advance, I don't think that the solution is very complicated but I can't find it.

You need to make the Value property public to get or set it from outside the class:
public string Value { get; set; }
The classes are not static, so you need to instantiate them to set their properties or use their methods:
var parameters = new MyClass.Parameters();
parameters.Value = "Hello World !";
var methods = new MyClass.Methods();
methods.MyMethod();
The same applies here:
public void MyMethod()
{
var parameters = new MyClass.Parameters();
Window.Title = parameters.Value;
}
But I suspect you actually want MyClass to have its own instances of these classes. So you can add properties for them:
public Properties Properties { get; set; }
public Methods Methods { get; set; }
Then instantiate them somehow (like in the constructor):
public MyClass()
{
Parameters = new Parameters();
Methods = new Methods();
}
If you do steps 1, 4 and 5, the code you have in MainClass should work.

Create a constructor that force the user to add a Value when initiating the class
public class MyClass
{
public string Value { get; set; }
public MyClass(string value)
{
Value = value;
}
public class Methods
{
public void MyMethod()
{
Window.Title = Value;
}
}
}
and call it like this
MyClass myclass = new MyClass("Hello World !");
myclass.Methods.MyMethod();
System.Threading.Thread.Sleep(Timespan.FromSeconds(10));
MyClass myclass2 = new MyClass("Hello World Again !");
myclass2.Methods.MyMethod();

You can declare the properties and methods all within the class:
public class MyClass
{
public MyClass()
{
// Set any initial values
}
public string Value { get; set;}
public void MyMethod()
{
Window.Title = Value;
}
}
And then to use it:
public class MainClass
{
MyClass myclass = new MyClass();
myclass.Value = "Hello World !";
myclass.MyMethod();
System.Threading.Thread.Sleep(Timespan.FromSeconds(10));
MyClass myclass2 = new MyClass();
myclass2.Value = "Hello World Again !";
myclass2.MyMethod();
}
Or to be more succinct:
public class MainClass
{
MyClass myclass = new MyClass {
Value = "Hello World !"
};
myclass.MyMethod();
System.Threading.Thread.Sleep(Timespan.FromSeconds(10));
MyClass myclass2 = new MyClass {
Value = "Hello World Again !"
};
myclass2.MyMethod();
}
UPDATE
If you absolutely need the classes split (although I wouldn't recommend it), then you need to pass your value into the method class to use it. There are a couple of approaches. Either you have to pass the value down into you methods class (not a very elegant approach):
public class MyClass
{
public string Value { get; set;}
public Methods methods {get; set;)
public MyClass(string value)
{
methods = new Methods(value);
Value = value;
}
public class Methods
{
public string Value { get; set;}
public Methods(string value)
{
Value=value;
}
public void MyMethod()
{
Window.Title = Value;
}
}
}
Or make MyMethod() a static method and pass in the value to use:
public class MyClass
{
public string Value { get; set;}
public MyClass(string value)
{
methods = new Methods(value);
Value = value;
}
}
public static class Methods
{
public static void MyMethod(string Value)
{
Window.Title = Value;
}
}
public class MainClass
{
MyClass myclass = new MyClass {
Value = "Hello World !"
};
Methods.MyMethod(myclass.Value);
System.Threading.Thread.Sleep(Timespan.FromSeconds(10));
MyClass myclass2 = new MyClass {
Value = "Hello World Again !"
};
Methods.MyMethod(myclass2.Value);
}
Both ways are not best practice though as, when you start building more complex classes, having the properties and methods in different places will cause a load of headaches.

Related

C# Accessing properties of a parent class from derived classes

I have a class named PINPAD, a base class named Devices, and two derived classes named DevA and Dev B
The issue is that the main class property PINPAD.Status needs to be updated from classes DevA and DevB
Here is the code:
public class CALLER()
{
CALLER()
{
PINPAD PINPD = new PINPAD("A");
//....
MessageBox.Show(PINPD.Status);
}
}
public class PINPAD()
{
public Devices MyDev = null;
public string Status = "";
public PINPAD(string Model)
{
if (Model = "A")
{
DevA MyDev = new DevA()
}
else
{
DevB MyDev = new DevB()
}
MyDev.DoWork();
}
}
public class Devices
{
public virtual void DoWork() {}
}
public class DevA : Devices
{
public override void DoWork() { }
DevA()
{
PINPAD.Status = "Broken";
//Status not avialable!
}
}
public class DevB : Devices
{
public override void DoWork() { }
DevB()
{
PINPAD.Status = "Working!";
//Status not avialable!
}
}
You've declared PINPAD.Status as an instance field - meaning you have to have an object of the type PINPAD in order to access it.
var myPinpad = new PINPAD();
myPinpad.Status = "Whatever";
If you want there to just be one field that is available everywhere, declare the field static:
public static string Status = "";

How to check if an object has default values in C#

I have an object that I want to check whether it contains default values or not, in the below code but that doesn't cut it.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Rextester
{
public class Program
{
public static void Main(string[] args)
{
MyClass obj1 = new MyClass();
MyClass obj2 = null;
if(obj1 == new MyClass())
Console.WriteLine("Initialized");
if(Object.ReferenceEquals(obj1, new MyClass()))
Console.WriteLine("Initialized");
}
}
}
public class MyClass
{
public int Value {get; set; }
public MyClass()
{
this.Value = 10;
}
}
I have also used Object.ReferenceEquals() but that doesn't cut it as well.
This is the fiddle I am working on.
Is there a way to check whether an object contains default values, or if the object is empty?
Edit: In case of an newly initialized object with many nested properties, how to check whether they contain a default value or not?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Rextester
{
public class Program
{
public static void Main(string[] args)
{
MyClass obj1 = new MyClass();
MyClass obj2 = null;
if(obj1 == new MyClass())
Console.WriteLine("Initialized");
if(Object.ReferenceEquals(obj1, new MyClass()))
Console.WriteLine("Initialized");
}
}
}
public class MyClass
{
public int Value {get; set; }
public MyNestedClass MyProperty { get; set; }
public MyClass()
{
this.Value = 10;
this.MyProperty = new MyNestedClass();
}
}
public class MyNestedClass
{
public string SomeStringProperty { get; set; }
public MyNestedClass()
{
this.SomeStringProperty = "Some string";
}
}
Here is the fiddle in the case of nested objects.
You can achieve your goal by overriding Equals and GetHashCode, creating and saving an immutable "default" instance, and comparing the value to it:
public class MyClass {
public static readonly MyClass DefaultInstance = new MyClass();
public int Value { get; set; }
public MyClass() {
this.Value = 10;
}
public override int GetHashCode() {
return Value.GetHashCode();
}
public override bool Equals(Object obj) {
if (obj == this) return true;
var other = obj as MyClass;
return other?.Value == this.Value;
}
}
Now you can check if the instance is equal to a newly created one by calling
if (MyClass.DefaultInstance.Equals(instanceToCheck)) {
... // All defaults
}
You can change what it means for an instance to be "default" by altering DefaultInstance object.
Note: this trick works well only with immutable MyClass. Otherwise some code could perform MyClass.DefaultInstance.Value = 20 and change the "default" object.
Here is one method using JSON serialization that allows you to check if the objects are equal or not:
DotNetFiddle:
using System;
using Newtonsoft.Json;
public class Program
{
public static void Main()
{
var defaultObj = new MasterObject();
var notDefaultObject = new MasterObject();
var defaultJson = JsonConvert.SerializeObject(defaultObj);
var notDefaultJson = JsonConvert.SerializeObject(notDefaultObject);
Console.WriteLine("First Test");
if (defaultJson == notDefaultJson)
Console.WriteLine("Same thing");
else
Console.WriteLine("Not same thing");
notDefaultObject.Sub1.SomeObject.SomeOtherValue = "Not a default Value";
notDefaultJson = JsonConvert.SerializeObject(notDefaultObject);
Console.WriteLine("Second Test");
if (defaultJson == notDefaultJson)
Console.WriteLine("Same thing");
else
Console.WriteLine("Not same thing");
}
}
public class MasterObject
{
public SubObject1 Sub1 { get; set; }
public SubObject2 Sub2 { get; set; }
public string SomeString { get; set; }
public MasterObject()
{
Sub1 = new SubObject1();
Sub2 = new SubObject2();
SomeString = "Some Default String";
}
}
public class SubObject1
{
public string SomeValue { get; set; }
public SubObject2 SomeObject { get; set; }
public SubObject1()
{
SomeObject = new SubObject2();
SomeValue = "Some other Default String";
}
}
public class SubObject2
{
public string SomeOtherValue { get; set; }
public SubObject2()
{
SomeOtherValue = "Some default";
}
}
Output:
First Test
Same thing
Second Test
Not same thing
What is happening is that you serialize the default object and then you make changes to the "not default object", re-serialize and compare again. This can be slow because you are generating strings, but as long as all the sub-objects can be serialized this will be the simplest way to compare if an object is "default" (what you get from new) or has been modified.

Using single method to return possible different instance types

So I have got these 2 instance types "FirstType" and "SecondType" which inherit from the mother class "ContaBancaria". They both return text from different textboxes. Basically, they do the same thing, but I need 2 instances for 2 different list types (I probably don't think the list has anything to do with my question, so I'll proceed not to go in detail)
Here are the instances:
private FirstType AddTypeFirst()
{
return new FirstType(textBoxNumber.Text,
textBoxBalance.Text,
textBoxName.Text,
textBoxAddress.Text,
textBoxBirth.Text);
}
private SecondType AddTypeSecond()
{
return new SecondType(textBoxNumber.Text,
textBoxBalance.Text,
textBoxName.Text,
textBoxAddress.Text,
textBoxBirth.Text);
}
Is there a way to return these 2 instances with the same method type?
EDIT:
What I meant was to return these 2 different types of instances with 1 single method, for example:
private [type?] AddInstance()
{
return new [type*] textBoxNumber.Text, //* the type could be FirstType or SecondType
textBoxBalance.Text,
textBoxName.Text,
textBoxAddress.Text,
textBoxBirth.Text);
}
EDIT 2:
ContaBancaria looks like this:
abstract class ContaBancaria
{
public string number { get; set; }
public string balance { get; set; }
public Client data { get; set; }
}
And, since there's Client...
class Client
{
public string name;
public string address;
public string birth;
}
Hope you get me.
You can use generic method and derrived classes I think.
For example, you have two classes and you want to receive one of them. Those classes are named "FirstSon" and "SecondSon" and both of them are derrived from class "Father".
class Father
{
string myName;
public string MyName
{
get { return myName; }
set { myName = value; }
}
public Father()
{
myName = "John";
}
}
class FirstSon : Father
{
string mySecondName;
public string MySecondName
{
get { return mySecondName; }
set { mySecondName = value; }
}
public FirstSon()
{
mySecondName = "Bill";
}
}
class SecondSon : Father
{
int age;
public int Age
{
get { return age; }
set { age = value; }
}
string mySecondName;
public string MySecondName
{
get { return mySecondName; }
set { mySecondName = value; }
}
public SecondSon()
{
mySecondName = "Drake";
age = 21;
}
}
And you have method GetObject(). This method is generic. It receives type of class, then checks what type it has received and returnes the new object with the same type.
public static T GetObject<T>() where T: Father
{
var firstSon = new FirstSon();
var secondSon = new SecondSon();
if (firstSon.GetType() == typeof(T))
return (T)Convert.ChangeType(firstSon, typeof(T));
return (T)Convert.ChangeType(secondSon, typeof(T));
}
It uses method Convert.ChangeType(object value, Type conversonType) and allows you to convert your object to your type.
But I am not convinced that this is a good idea according to How do I make the return type of a method generic?
Assuming you want to return the proper type based on the list being added to, you will need to write your own generic Add function, and use Reflection to figure out the type:
public static class Ext {
public static void AddInstancia<T>(this List<T> aList) where T : class {
if (typeof(T) == typeof(FirstType))
aList.Add(AddTypeFirst() as T);
else
aList.Add(AddTypeSecond() as T);
}
}
I see no good reason to do this - after all, you know the type of the list, just call the correct function for that list...
Instead of using Reflection, you could also use dynamic if you add some functions to each sub-type:
public class FirstType : Parent {
public FirstType MakeChild() {
return new FirstType();
}
}
public class SecondType : Parent {
public SecondType MakeChild() {
return new SecondType();
}
}
public static class Static<T> where T : new() {
public static dynamic Value = new T();
}
public static class Ext {
public static void AddInstance<T>(this List<T> aList) where T : new() {
aList.Add(Static<T>.Value.MakeChild());
}
}
Which you can call like
var list1 = new List<FirstType>();
list1.AddInstance();

How to access public Property MyProperty of class A in class C

I have following code:
public class A
{
public int MyProperty {get; set;}
}
public class B
{
A myInstance = new A();
myInstance.MyProperty = 10;
}
public class C
{
public void InvokeA()
{
//How to access MyPropery here?
BInstance = new B();
Console.WriteLine(B.myInstance.MyProperty.ToString());
}
}
I'm looking for a way to access MyProperty as written above. Inheritance is not an option since my class C is already inherited from some base class. A way without declaring any of the given classes as static would be nice!
Thanks,
Orz
Consider following classes:
public class A
{
public int MyProperty { get; set; }
}
public class B
{
public A GetAInstance()
{
A myInstance = new A();
myInstance.MyProperty = 10;
return myInstance;
}
}
public class C
{
private B BInstance;
public void InvokeA()
{
BInstance = new B();
Console.WriteLine(BInstance.GetAInstance());
}
}
and then you will create your C instance in Main:
static void Main(string[] args)
{
C cInstance = new C();
cInstance.InvokeA();
}
In order to accomplish your goal, you need to expose B.MyInstance as a property of the B class, just like you exposed A.MyProperty as a property of the A class.
Edit: Per the comments of others regarding use of the static keyword, here's what you might want your code to look like:
public class A
{
public int MyProperty { get; set; }
}
public static class B
{
static B()
{
MyInstance = new A();
MyInstance.MyProperty = 10;
}
public static A MyInstance { get; set; }
}
public class C
{
// not sure what your intention is here
public C()
{
System.Console.WriteLine(B.MyInstance.MyProperty.ToString()); // "10\n"
}
}
Yes. You can inherits classes from A to B something like this:
public class A
{
public int MyProperty {get; set;}
}
public class B : A
{
public B()
: A()
{
MyProperty = 1;
}
}
Now you can do:
(new B()).MyProperty
Or use Singleton approach to resolve:
public class B
{
private static _a;
public class A
{
public int MyProperty {get; set;}
}
public static A AA {
if (_a == null) {
_a = new A();
}
return _a;
}
}
This implmentation will return
B.A.MyProperty.ToString();

C# Avoid Multiple SWITCH Statements .net

Please excuse bursts of stupidity as I learn the intricacies of C# / .NET
Say I have three classes with multiple static properties (more than three but for arguments sake..)
CLASS FOO
public static A
{
get / set A;
}
public static B
{
get / set B;
}
public static C
{
get / set C;
}
CLASS BAR
{
get / set A;
}
public static B
{
get / set B;
}
public static C
{
get / set C;
}
CLASS YOO
{
get / set A;
}
public static B
{
get / set B;
}
public static C
{
get / set C;
}
And from another class I need to update one or several static properties in each class multiple times... How do I keep from writing multiple SWITCH statments like this...
public void updateVarx(string class, string varx)
{
string y = 'class'
SWITCH (y)
{
case FOO:
FOO.A = Varx;
break;
case BAR:
BAR.A = Varx;
break;
case YOO:
YOO.A = Varx;
break;
}
}
And then another one when I want to update B varY:
public void updateVary(string class, string vary)
{
string y = 'class'
SWITCH (y)
{
case FOO:
FOO.B = Vary;
break;
case BAR:
BAR.B = Vary;
break;
case YOO:
YOO.B = Vary;
break;
}
}
Since you are learning .net/c#, I guess i should warn you, using static properties is probably not the way to go in object oriented programming.
Static is global state and is dangerous. If you end up using multi-threaded code, you have to be super careful. If you need only one instance, just instantiate one, but don't go creating static properties on a class, unless you have a pretty good reason to add them (And I can't think of any right now).
In fact, in well designed, object oriented code you sould probably not have many if, switch, getters or setters either.
Let's say you need different behaviors on your classes, you can do it this way.
Interface ISecurity {
void UpdateVarX(int value);
void UpdateVarY(int value);
int GetValueX();
int GetValueX();
}
class Foo:ISecurity {
// Implement methods of the interface
}
class Bar:ISecurity {
// Implement methods of the interface
}
class Yoo:ISecurity {
// Implement methods of the interface
}
// This class is the class that uses your other classes
class Consumer
{
private ISecurity sec;
public Consumer(ISecurity sec) {
sec.UpdateVarX(25);
}
}
Or if as in your example, all your static classes have the same properties:
public class Settings {
public int A {get; set;}
public int B {get; set;}
public int C {get; set;}
}
public class NeedsToUseOtherClass {
public NeedsToUseOtherClass() {
Settings foo = new Settings();
Settings bar = new Settings();
Settings yoo = new Settings();
foo.setA(25);
}
}
Maybe I am not understanding the problem but if all your classes have the same exact properties then you can just pass the object (FOO, BAR, or YOO) into UpdateVarx or UpdateVary methods and just implement an interface? Something along these lines:
public class FOO : IHasStatus
{
public A
{
get / set A;
}
public B
{
get / set B;
}
public C
{
get / set C;
}
}
public void updateVarx(IHasStatus someObject, string varx)
{
someObject.A = varx;
}
public void updateVary(IHasStatus someObject, string vary)
{
someObject.B = vary;
}
If you don't need the concrete classes, you can abstract out the logic like so:
public class Status {
public string A {
get; set;
}
public string B {
get; set;
}
public string C {
get; set;
}
}
public static class StatusManager {
private static Dictionary<string, Status> statusMap = new Dictionary<string,Status>();
public static Status GetStatus(string name) {
Status status;
if (!statusMap.TryGetValue(name, out status))
statusMap[name] = status = new Status();
return status;
}
public static void SetStatus(string name, Status status) {
statusMap[name] = status;
}
public static void UpdateVarx(string name, string varx) {
GetStatus(name).A = varx;
}
// ...
}
If you are a fan of the javascript way of solving multiple switch cases like this
you can always wrap up the switch handlers as Actions and toss them in a Dictionary.
For example : (Source obtained from here)
public class SwitchCase : Dictionary<string,Action>
{
public void Eval(string key)
{
if (this.ContainsKey(key))
this[key]();
else
this["default"]();
}
}
//Now, somewhere else
var mySwitch = new SwitchCase
{
{ "case1", ()=>Console.WriteLine("Case1 is executed") },
{ "case2", ()=>Console.WriteLine("Case2 is executed") },
{ "case3", ()=>Console.WriteLine("Case3 is executed") },
{ "case4", ()=>Console.WriteLine("Case4 is executed") },
{ "default",()=>Console.WriteLine("Default is executed") },
};
mySwitch.Eval(c);
Below code uses all kinds of hacks, not really recommended in production code unless you have a very good reason.
using System;
using System.Linq;
namespace ConsoleApplication1
{
static class Program
{
private static void SetStaticProperty(string className, string propName, string varx)
{
//This sucks, I couldnt find the namespace with easily through reflection :(
string NAMESPACE = "ConsoleApplication1";
Type t = Type.GetType(NAMESPACE + "." + className);
t.GetProperties().Where(p => p.Name == propName).First().SetValue(null, varx, null);
}
public static void updateVarx(string className, string varx)
{
SetStaticProperty(className, "A", varx);
}
public static void updateVary(string className, string vary)
{
SetStaticProperty(className, "B", vary);
}
static void Main(string[] args)
{
updateVarx("Foo", "FooAstring");
updateVarx("Bar", "BarAstring");
updateVarx("Yod", "YodAstring");
updateVary("Foo", "FooBstring");
updateVary("Bar", "BarBstring");
updateVary("Yod", "YodBstring");
Console.WriteLine(Foo.A);
Console.WriteLine(Foo.B);
Console.WriteLine(Bar.A);
Console.WriteLine(Bar.B);
Console.WriteLine(Yod.A);
Console.WriteLine(Yod.B);
Console.ReadLine();
}
}
class Foo
{
public static string A { get; set; }
public static string B { get; set; }
public static string C { get; set; }
}
class Bar
{
public static string A { get; set; }
public static string B { get; set; }
public static string C { get; set; }
}
class Yod
{
public static string A { get; set; }
public static string B { get; set; }
public static string C { get; set; }
}
}
You can use dictionary as configuration and remove the switch statement
Create a dictionary and add append data as below for mapping
//Have dictionary setted up
Dictionary<string, dynamic> m_Dictionary = new Dictionary<string, dynamic>();
m_xmlDictionary.Add("classA",FOO);
m_xmlDictionary.Add("classB",BAR);
m_xmlDictionary.Add("classC",BAR);
//Have dictionary setted up
//change the function as below
public void updatevarx(string class, string varx)
{
m_Dictionary[class].A=varx // Replaced switch statement
}
//while calling use
updatevarx("classC","abc!");// This will assign BAR.A with abc!

Categories

Resources