In the code example below, if HighValue and LowValue properties are not set by the client, how can I pass default values for these properties to the base class?
If there is a design mistake in this example setup, I'd like to thank you in advance for warning me.
public class Foo
{
public Foo(int scaleHigh, int scaleLow)
{
ScaleHigh = scaleHigh;
ScaleLow = scaleLow;
}
public int ScaleHigh { get; }
public int ScaleLow { get; }
}
public class Bar : Foo
{
public Bar(Bar bar)
: base(bar.ScaleHigh, bar.ScaleLow)
{
HighValue = SomeHelper.ReCalculate(bar.HighValue);
LowValue = SomeHelper.ReCalculate(bar.LowValue);
}
public int HighValue { get; }
public int LowValue { get; }
}
public class SomeHelper
{
public static int ReCalculate(int scale)
{
return scale * 5;
}
}
public class Client : Bar
{
public Client(Bar bar) : base(bar) { }
public int Request(bool condition)
{
return condition ? HighValue : LowValue;
}
}
you have a bug in your bar class, since it doesn't have a default constructor, you will never be able to create the object, since it will be a recursion forever - each new instance would neeed another and so on
public class Bar : Foo
{
public Bar(Bar bar)
: base(bar.ScaleHigh, bar.ScaleLow)
{
HighValue = SomeHelper.ReCalculate(bar.HighValue);
LowValue = SomeHelper.ReCalculate(bar.LowValue);
}
public int HighValue { get; }
public int LowValue { get; }
}
you can fix it by adding another constructor like this
public Bar(int scaleHigh=0, int scaleLow=0, int highValue=0, int lowValue=0)
: base(scaleHigh, scaleLow)
{
HighValue = SomeHelper.ReCalculate(highValue);
LowValue = SomeHelper.ReCalculate(lowValue);
}
Try this:
public int LowValue { get; } = 0; //You can change these values.
public int HighValue { get; } = 10;
Sorry if I misunderstand, but I believe you want to set default values of Bar if they are not set? In what case would the constructor not set the values?
In the case that you didn't set those in your constructor, one thing you can consider is making the types int? and then set the variable like this:
public int? HighValue => HighValue ?? (defaultValue)
Related
This question already has answers here:
What's the correct alternative to static method inheritance?
(8 answers)
How to use polymorphism or inheritance in static classes?
(4 answers)
Closed 2 years ago.
I have a static class containing several subclasses for managing different constants.
Very different classes I want to implement the same properties depending only on the defined constants.
It looks like this:
public static class A
{
public static class Subclass1
{
public const int Constant1 = 0;
public const int Constant2 = 1;
public static List<int> Elements
{ get { return new List<int> { Constant1, Constant2 }} }
public static int Sum { get { return Elements.Sum(); } }
public static int NegSum { get { return -Elements.Sum(); } }
}
public static class Subclass2
{
public const int Constant3 = 3;
public const int Constant4 = 4;
public static List<int> Elements
{ get { return new List<int> { Constant3, Constant4 }} }
public static int Sum { get { return Elements.Sum(); } }
public static int NegSum { get { return -Elements.Sum(); } }
}
}
so that I can easily access them by
int a = A.Subclass1.Constant1;
List<int> b = A.Subclass1.Elements;
int c = A.Subclass1.Sum;
The code of the Properties Sum and NegSum is always the same.
You see the problem: I need to include them for every subclass again. Is there any way to reuse the code of the properties without implementing them for every single class?
What I would like to do is something like:
public abstract class Base
{
public abstract static List<int> Elements { get; }
public static int Sum { get { return Elements.Sum(); } }
public static int NegSum { get { return -Elements.Sum(); } }
}
public static class B
{
public static class Subclass1 : Base
{
const int Constant1 = 0;
const int Constant2 = 1;
public override static List<int> Elements
{ get { return new List<int> { Constant1, Constant2 }} }
}
public class Subclass2 : Base
{
const int Constant3 = 0;
const int Constant4 = 1;
public override static List<int> Elements
{ get { return new List<int> { Constant3, Constant4 }} }
}
}
Well, I know that in C# Inheritance like this doesn't work for static classes.
Is there any other smart way to implement this?
Maybe try implementing Subclass1 and Subclass2 without static keyword. Like this
public abstract class Base
{
public Base(params int[] elements)
{
this.Elements = new List<int>(elements);
}
public List<int> Elements { get; private set; }
public virtual int Sum { get { return Elements.Sum(); } }
public virtual int NegSum { get { return -Elements.Sum(); } }
}
public static class B
{
public static class Subclass1 : Base
{
const int Constant1 = 0;
const int Constant2 = 1;
public Subclass1() : base(Constant1, Constant2){}
}
public class Subclass2 : Base
{
const int Constant3 = 0;
const int Constant4 = 1;
public Subclass2() : base(Constant3, Constant4){}
}
}
Then add two static properties to class B
public static Subclass1 InstanceSubclass1 {get; private set}
public static Subclass2 InstanceSubclass2 {get; private set}
At the end add static constructor to class B
static B()
{
InstanceSubclass1 = new Subclass1 ();
InstanceSubclass2 = new Subclass2 ();
}
You can now access to your classes by using
B.InstanceSubclass1
What you are wanting will not be possible without some code duplication. C# doesn't handle inheritance with static the same way. While you can't override the static member of a super class, you can use new to hide and reimplement it. The downside to this is you lose the subtype contract that abstract provides, but if you really want your types to be "abstract" and have static members, you are pretty much SOL on that front.
public class Base
{
public static List<int> Elements { get; }
public static int Sum(List<int> Elements) => Elements.Sum();
public static int NegSum(List<int> Elements) => -Elements.Sum();
}
public static class B
{
public sealed class Subclass1 : Base
{
const int Constant1 = 1;
const int Constant2 = 2;
public static new List<int> Elements
{ get => new List<int> { Constant1, Constant2 }; }
public static new int Sum { get => Base.Sum(Elements); }
public static new int NegSum { get => Base.NegSum(Elements); }
}
public sealed class Subclass2 : Base
{
const int Constant3 = 3;
const int Constant4 = 4;
public static new List<int> Elements
{ get => new List<int> { Constant3, Constant4 }; }
public static new int Sum { get => Base.Sum(Elements); }
public static new int NegSum { get => Base.NegSum(Elements); }
}
}
An alternative is that you can use the singleton pattern to create the illusion that you are achieving what you want to achieve. As far as intellisense is concerned, this will produce the exact same effect of accessing the members like B.Subclass1.Sum. The downside being that this would also expose the _Subclass1 and _Subclass2 classes and pollute the namespace, but you will just have to decide if that is an acceptable trade-off.
public abstract class Base
{
public abstract List<int> Elements { get; }
public int Sum { get => Elements.Sum(); }
public int NegSum { get => -Elements.Sum(); }
}
public static class B
{
public static _Subclass1 Subclass1 { get; } = new _Subclass1();
public static _Subclass2 Subclass2 { get; } = new _Subclass2();
public sealed class _Subclass1 : Base
{
const int Constant1 = 1;
const int Constant2 = 2;
public override List<int> Elements
{ get => new List<int> { Constant1, Constant2 }; }
}
public sealed class _Subclass2 : Base
{
const int Constant3 = 3;
const int Constant4 = 4;
public override List<int> Elements
{ get => new List<int> { Constant3, Constant4 }; }
}
}
You could use interfaces and an extension method if you didn't want to have a base class:
public interface IElementsHost
{
List<int> Elements { get; }
}
public static class ElementsExtensions
{
public static int Sum(this IElementsHost host) => host.Elements.Sum();
public static int NegSum(this IElementsHost host) => -host.Elements.Sum();
}
public class Host : IElementsHost
{
public const int Constant1 = 2;
public const int Constant2 = 3;
public List<int> Elements { get; }
= new List<int>(new int[]{ Constant1, Constant2 });
}
// client code
var host = new Host();
var sum = host.Sum();
If you wanted related subclasses to have such capabilities, you'd have to do it with composition. It would look like:
public static class OtherStaticClass
{
public static ElementHost { get; } = new Host();
static OtherStaticClass()
{
Host.Elements.Add(/* some constant, etc. */);
}
}
// client code
var sum = OtherStaticClass.ElementHost.Sum();
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)}
};
So at begining I like to set up some variables, which will later used. I am building some graph moving parts, where I must set up Step for every movement (if X change for 1 then Value change 1*Step ... bla bla).
I have MainWindowViewModel (short version):
public class MainWindowViewModel : ViewModelBase
{
public MainWindowViewModel()
{
// Initialization
Step = 3;
}
}
DiagramObject Class:
public abstract class DiagramObject : ViewModelBase
{
public abstract double X { get; set; }
public abstract string Xmeaning { get; set; }
public abstract double Y { get; set; }
public abstract string Ymeaning { get; set; }
}
So there inside I have defined "Steps":
public class DiagramNode : DiagramObject
{
public int xstep = 3;
public int ystep = 1;
public int xstepvalue = 5;
public int ystepvalue = 5;
private double _x;
public override double X
{
get { return _x; }
set
{
//"Grid Snapping"
_x = (Math.Round(value / xstep)) * xstep;
NotifyPropertyChanged("X");
double minutes = (_x / xstep) * xstepvalue;
TimeSpan interval = TimeSpan.FromMinutes(minutes);
_xmeaning = interval.ToString();
NotifyPropertyChanged("Xmeaning");
}
}
private string _xmeaning;
public override string Xmeaning
{
get { return _xmeaning; }
set
{
//"Grid Snapping"
_xmeaning = value;
NotifyPropertyChanged("Xmeaning");
}
}
private double _y;
public override double Y
{
get { return _y; }
set
{
//"Grid Snapping"
_y = (Math.Round(value / ystep)) * ystep;
NotifyPropertyChanged("Y");
double keks = (_y / ystep) * ystepvalue;
_ymeaning = keks.ToString();
NotifyPropertyChanged("Ymeaning");
}
}
private string _ymeaning;
public override string Ymeaning
{
get { return _ymeaning; }
set
{
//"Grid Snapping"
_ymeaning = value;
NotifyPropertyChanged("Ymeaning");
}
}
}
My question is How to update "xstep", "ystep" and others steps inside DiagramNode class from MainWindowViewModel at beginning of the program?
So when I start the program step will be defined and updated into DiagramNode class - now I have defined direct in class.
I hope that I give enough code for understanding the concept (if not say so). If any question please ask.
Your MainWindowViewModel will need to have an instance of the DiagramNode class instantiated so that it can access the properties to modify them.
public class MainWindowViewModel : ViewModelBase
{
DiagramNode myDiagramNode = new DiagramNode();
public MainWindowViewModel()
{
// Initialization
Step = 3;
myDiagramNode.xstep = 3;
}
}
Typically, though, it is a better practice to have variables like xstep and ystep to be set as private, and have accessors which can handle the setting/getting of the values, like so
public class DiagramNode : DiagramObject
{
private int xstep;
public int XStep
{
get { return this.xstep; }
set { this.xstep = value; }
}
...
}
public class MainWindowViewModel : ViewModelBase
{
DiagramNode myDiagramNode = new DiagramNode();
public MainWindowViewModel()
{
myDiagramNode.XStep = 3;
}
}
You could set them via a constructor overload
public class DiagramNode(int xstep, int ystep)
{
// set your values
}
I have many methods that have a parameter called from. If I do some refactoring to such a method, R# decides to change the from to #from. But both the compiler and I are happy with from and we don't want this change. I can't find any way to suppress it.
Example method:
public class ObjectA
{
public int J { get; set; }
public int K { get; set; }
}
public class ObjectB
{
public int Y { get; set; }
public int Z { get; set; }
}
public static ObjectB ConvertAtoB(ObjectA from)
{
return from != null
? new ObjectB
{
Y = from.J,
Z = from.K,
}
: null;
}
After invert condition twice on the if statement, the method looks like this:
public static ObjectB ConvertAtoB(ObjectA from)
{
return #from != null
? new ObjectB
{
Y = #from.J,
Z = #from.K,
}
: null;
}
Is there any R# setting that will prevent this?
Sorry for the title i will put here an example of what i want to accomplish:
namespace mdclass
{
class pClass
{
static void Main()
{
tiles<int> tl = new tiles<int>();
tl[0].X = 0;
}
}
class tiles<T> : List<T>
{
public int X
{
//get/set the X-coordonate
}
public int Y
{
//get/set the Y-coordonate
}
}
}
how can i transfer the [0] from the tl[0] in the public int X and work with it?
Create a class for x and y coordinates:
public sealed class Point {
public int X { get; set; }
public int Y { get; set; }
}
Use the Point class to store the coordinates into the list:
public sealed class Program {
public static void Main() {
var tiles = new List<Point>();
tiles.Add(new Point { X = 5, Y = 10 });
tiles[0].X = 15;
}
}
Could you not just make tl public?
Then myInt = mypClass.tl[0].X
A data heirachy like this might work for you (no time to add actual code, sorry!). Then you could implement appropriate getters and setters.
Public class Grid {
List<Row>
}
Public class Row{
List<Point>
}
Public Class Point{
public int X { get; set; }
public int Y { get; set; }
}