How do I create nested properties? C# - c#

As far as I read, creating nested properties don't seem to be possible in c#.
What I want to do is:
Callout callout = new Callout();
callout.Font.Size = 200;
This is the code I currently have
class Callout
{
// nested properties
}
I know how to create properties, but how do I create a nested property?

class Callout {
public Font Font {get;} = new Font();
}
class Font {
public int Size {get;set;}
}

public class Callout {
public Font Font {get;}
}
public struct Font {
public Font(int size) {
Size = size;
}
public int Size {get;}
}

If you really don't want to implement a separate class or struct, here's a tricky way to do what you are asking.
Note: Tricky != Recommended
class Callout : Callout.IFont
{
public interface IFont
{
int Size { get; set; }
}
protected int _fontSize = 0;
int IFont.Size
{
get
{
return _fontSize;
}
set
{
_fontSize = value;
}
}
public IFont Font => this;
}
var callout = new Callout();
callout.Font.Size = 100;

Related

break Liskov principle with the famous Square/Rectangle example gives a logical error

I was trying to illustrate the Liskov principle with a case where it breaks it and was expecting in the below example that when you set breadth for the sqaure, the length is automatically set to the same length, and vice versa.
However, the area is returned as 0. I was expecting 4x4=16, and 5x5=25, in the second case. What am I doing wrong? I suspect it's in the way I'm overriding the properties of the base class.
using System;
public class Rectangle
{
public int length { get; set; }
public int breadth { get; set; }
public int area()
{
return length * breadth;
}
}
public class Square : Rectangle {
public new int length;
public new int breadth;
public new int Length
{
get
{
return this.length;
}
set
{
this.breadth = this.length = value;
}
}
public new int Breadth
{
get
{
return this.breadth;
}
set
{
this.breadth = this.length = value;
}
}
}
public class Program
{
public static void Main()
{
Square s = new Square();
s.length = 4;
s.breadth = 5;
int xx = s.area();
Console.Write(xx);
s.length = 5;
s.breadth = 4;
xx = s.area();
Console.Write(xx);
}
}
When you inherit from a base class, you will inherit all of its Public and Protected members. When you declare a new member in the derived class with the same name. The compiler will gives you a warning asking you are you intended to hide that member? When you used the new keyword you told the compiler: Yes I want to hide this member please. The implementation of the area Method uses the base class properties, so it will not see your public Fields That's why you get the 0.
So your code will become:
public class Rectangle
{
protected int _length;
protected int _breadth;
public virtual int Length
{
get { return _length; }
set { _length = value; }
}
public virtual int Breadth {
get { return _breadth; }
set { _breadth = value; }
}
public int Area()
{
return Length * Breadth;
}
}
public class Square : Rectangle
{
public override int Breadth
{
get { return _breadth; }
set { _breadth = value;
_length = _breadth;
}
}
public override int Length {
get { return _length; }
set { _length = value;
_breadth = _length;
}
}
}
If you want to override something, you should add the virtual keyword in the base class definition of that thing.
In your example, you will cause a StackOverFlow exception. Because each property setters will call the other. That's why I used a protected member to prevent this thing from happening.
This is a good reference for you to read about inheritance

C# constructor that accepts parameter of the same class

I have a custom class
class MyClassA{
public int Width { get; set; }
}
and another custom class B
class MyClassB {
public MyClassA paramClassA;
public int Height { get; set; }
}
Is there a way to have a constructor inside MyClassB which accepts a parameters of type MyClassB and automatically assigns values to the attribute?
Something like this:
class MyClassB{
public MyClassA paramClassA;
public int Height { get; set; }
public MyClassB(MyClassB param){
}
public MyClassB(MyClassB param){
// automatically assign properties of param to the instance it is created
}
}
So I can do this:
var classB = new MyClassB();
classB.Height = 100;
classB.paramClassA = new MyClassA();
classB.paramClassA.Width = 100;
var classB2 = new MyClassB(classB);
Is there a way to do this?
ThereĀ“s no in-built way to do this. Anyway this is the purpose of a copy-constructor and can be achieved by copying all the properties from your existing instance to the current one. However when you have a deep inheritance-chain copying all those members can be non-trivial task which also includes private members.
class MyClassB{
public MyClassA paramClassA;
public int Height { get; set; }
public MyClassB(MyClassB param){
this.Heigth = param.Height;
this.MyClassA = param.MyClassA;
}
}
You could also implement ICloneable:
class MyClassB : ICloneable {
public MyClassA paramClassA;
public int Height { get; set; }
public object Clone(){
return new MyClassB
{
this.Height;
this.MyClassA;
};
}
}
Yes, you can do it manually. Remember about differences between shallow copy and deep copy in C# language:
class MyClassB{
public MyClassA paramClassA;
public int Height { get; set; }
public MyClassB(MyClassB param){
Height = param.Height;
paramClassA = new MyClassA();
if (param.paramClassA != null)
{
paramClassA.Width = param.paramClassA.Width;
}
}
}
I'll recommend Clone method inside MyClassB class:
class MyClassB{
//....
public MyCLassB Clone()
{
var result = new MyClassB
{
Height = Height
};
result.paramClassA = new MyClassA();
if (paramClassA != null)
{
result.paramClassA.Width = paramClassA.Width;
}
}
}
And use it, like below:
var classB = new MyClassB();
classB.Height = 100;
classB.paramClassA = new MyClassA();
classB.paramClassA.Width = 100;
var classB2 = classB.Clone();
You could always create a copy method that would assign the values and return a MyClassB where you assign the values within. If you must do it in a constructor check out the following.
public MyClassB(MyClassB param)
{
Width = param.Width;
// If you want to keep the same reference classA
paramClassA = param.paramClassA;
// if you want the classA to not be the same reference you could always do.
paramClassA = new MyClassA() { Width = param.Width };
}

C# - declare constant fields, but organize with interface?

I have a bunch of constant values for several types of "buildings", the sizes of which are fixed (due to the 3D model they will hold).
I've looked around and read about base classes, interfaces and abstracts, but couldn't really grasp the concepts completely. However I really liked the idea of using interfaces to "organize" classes with common fields. In this case, sizeX and sizeY is a type of field shared across all building classes.
public static class BuildingProperties {
public class House
{
public const int sizeX = 4;
public const int sizeY = 4;
}
public class House1
{
public const int sizeX = 6;
public const int sizeY = 6;
}
public class Commercial
{
public const int sizeX = 10;
public const int sizeY = 10;
}
}
Is there some way I can implement an interface for this, without the need for constructors in each class? (I would like to simply call for these constants as required, like so:)
public void program()
{
int sizeX = BuildingProperties.House.sizeX;
}
And for future use, if I needed to add another field (for example "height"), I would like the compiler to throw an error and say "hey! you forgot to give House1 a "height" value!
Is there something like this that someone can point me towards?
Seems to me like your code need some re-design. I don't see why you would want to have all these public sub classes. Instead, I would just use one class for all building types (assuming the all always have the same properties) and 3 properties for that class's type:
public class Building
{
public Building(int sizeX, int sizeY)
{
SizeX = sizeX;
SizeY = sizeY;
}
public int SizeX { get; }
public int SizeY { get; }
}
public static class BuildingProperties
{
public static Building House { get; } = new Building(4, 4);
public static Building House1 { get; } = new Building(6, 6);
public static Building Commercial { get; } = new Building(10, 10);
}
Note that all the properties are immutable in this code sample, and also, if you add a property in the future, and would like to get compiler errors when it's missing, all you have to do is change the constructor of the Building class to acccept another parameter for this new readonly property.
You can simply create an interface that will declare 2 getter properties:
public interface IProvideSizes
{
int SizeX { get; }
int SizeY { get; }
}
And in your classes have them return the data from your const:
public class House : IProvideSizes
{
public const int _sizeX = 4;
public const int _sizeY = 4;
public int SizeX { get { return _sizeX; } }
public int SizeY { get { return _sizeY; } }
}
public class House1 : IProvideSizes
{
public const int _sizeX = 6;
public const int _sizeY = 6;
public int SizeX { get { return _sizeX; } }
public int SizeY { get { return _sizeY; } }
}
public class Commercial : IProvideSizes
{
public const int _sizeX = 10;
public const int _sizeY = 10;
public int SizeX { get { return _sizeX; } }
public int SizeY { get { return _sizeY; } }
}
This way you can preserve and maintain the contract of each type, while still being able to access each type's specific size in a static way (without the need to instantiate it).
Have you considered a dictionary?
Dictionary<string, System.Drawing.Point> properties = new Dictionary<string, System.Drawing.Point>() {
{"House", new System.Drawing.Point(4,4)},
{"House1", new System.Drawing.Point(6,6)},
{"Commercial", new System.Drawing.Point(10,10)}
};

JS like enumaration in C#

In JavaScript I can have an array of different objects in each cell, and when enumerating it each cell will get treated as the object it is and not as an underlying common object of the collection.
Lets say I have 2 objects:
class car
{
public color;
...
}
class paint
{
public color;
...
}
Is there a syntax for an enumaration like
car beemer;
paint panda;
...
foreach (thing in [beemer, panda])
{
thing.color = "red";
}
in c#?
Well, you can use dynamic typing if you really want:
public class Paint
{
public string Color { get; set; }
}
public class Car
{
public string Color { get; set; }
}
...
var objects = new object[]
{
new Car { Color = "Red" },
new Panda { Color = "Black" }
};
foreach (dynamic value in objects)
{
Console.WriteLine(value.Color);
}
But it would be more conventional to declare an interface with the property you want, and then make all the relevant types implement the interface:
public interface IColored
{
string Color { get; set; }
}
public class Paint : IColored
{
public string Color { get; set; }
}
public class Car : IColored
{
public string Color { get; set; }
}
...
var objects = new IColored[]
{
new Car { Color = "Red" },
new Panda { Color = "Black" }
};
foreach (IColored value in objects)
{
Console.WriteLine(value.Color);
}
This is:
More efficient
Safer, as then you know at compile-time that every value you're iterating over has a Color property.
If you implement an interface with the color property defined on the interface will be able to achieve this.
public interface IHasColor
{
string color { get; set; }
}
public class car : IHasColor
{
public color { get; set; }
...
}
foreach (IHasColor thing in new IHasColor[] { beemer, panda })
{
thing.color = "red";
}

Raise event from Inner class to outer class in c#

I'm using MVVM pattern in my project.
My class design is like this:
Class Model : AbstractModel
{
InnerClass Iclass = new InnerClass();
Public String ModelProp1
{
get
{
return Iclass.prop1;
}
set
{
Iclass.prop1 = value;
}
}
public override void SetLabel(UInt16 value, int Index)
{
byte[] arr = BitConverter.GetBytes(value);
this.Iclass.IclassConfig[Index].Label = arr[0];
}
public override string DateFormat
{
get { return Iclass.intlDate.ToString(); }
set { Iclass.intlDate = Convert.ToByte(value); }
}
}
Class InnerClass
{
public byte intlDate
{
get { return this.intl_date; }
set { this.intl_date = value;
RaiseModelPropertiesChangedEvent(new ValueChangedEventArgs { Parameter_dateformat = this.intlDate });
}
private JClassa []channel_config = new JClass[2];
public JClass[] IclassConfig
{
get { return this.channel_config; }
set { this.channel_config = value; }
}
}
Public JClass
{
private byte channel_label;
public byte Label
{
get { return this.channel_label; }
set { this.channel_label = value;}
}
I'm getting data from other application. updated data is coming in InnerClass property from there I want to push this updated data to Model class.
Problem is coming for JClass property how can I fire event such that It will push updated data to model class.
For this I have created Event in InnerClass like this:
public event EventHandler<ValueChangedEventArgs> ModelPropertiesChanged;
public void RaiseModelPropertiesChangedEvent(ValueChangedEventArgs e)
{
if (ModelPropertiesChanged != null)
ModelPropertiesChanged(this, e);
}
public class ValueChangedEventArgs : EventArgs
{
public int Parameter_dateformat { get; set; }
public int Parameter_channelLabel { get; set; }
}
Tell me how Can I achieve this. Becuase I have 4 property in Jclass and 6 Property is InnerClass.
I would add event triggers in the setter of your inner class properties. Then in the Constructor of your parent class, move the IClass = new InnerClass() into your constructor and attach your event listeners.
Since you're MVVM you could leverage INotifyPropertyChanged, but heat will get messy in the long run.
Better to have a 'PropertyName'Changed event for each property you want to notify to the parent class.

Categories

Resources