Associated Properties: How to Avoid an Infinite Loop - c#

I have a Cube class. The cube can be constrained so that the width=height=length. I've coded this functionality but as you can see, my code results in a circular/infinite loop - the width sets the height which sets the width which sets the height and so on.
How can I make my Cube class constrained and avoid this infinite loop? Is my only solution to use a boolean variable propagate (see below)?
public class Cube {
public bool isConstrained {get; set;} // if constrained then width=height=length
// Causes a circular problem. How can I avoid this? Maybe create a variable private bool propagate = false; ??
public double width
{
get { return width; }
set
{
width = value;
if (isConstrained)
{
height = value;
length = value;
}
}
}
public double height
{
get { return height; }
set
{
height = value;
if (isConstrained)
{
width = value;
length = value;
}
}
}
public double length
{
get { return length; }
set
{
length = value;
if (isConstrained)
{
height = value;
width = value;
}
}
}
}
My only solution is this:
private bool propagate = true;
public double length
{
get { return length; }
set
{
length = value;
if (isConstrained && propagate)
{
propagate = false;
height = value;
width = value;
propagate = true;
}
}
}

Currently even just your getters will give a stack overflow - you don't have any fields backing your data, because you're not using automatically-implemented properties. Additionally, your properties don't have conventional names, which is definitely worth fixing.
You should just use private fields to back the properties, and set those accordingly within your property setters. That way no property will call another, and all will be well... except for the design being a bit troublesome to start with. (When changing one property changes another, that can be surprising.)
So something like:
private int width;
private int height;
private int length;
private bool constrained;
...
public int Width
{
get { return width; }
set
{
width = value;
if (constrained)
{
height = value;
length = value;
}
}
}

Shouldn't a cube always have the length, width, and height be the same? You could use a single private variable to hold the length, width, and height, and then when setting any of those Properties, assign that value to the private variable. Return the value of that same variable in the get Properties for width/height/length.

Related

C# Inheritance and Methods

I'm learning inheritance and I understand the code below.
namespace InheritanceApplication {
class Shape {
public void setWidth(int w) {
width = w;
}
public void setHeight(int h) {
height = h;
}
protected int width;
protected int height;
}
// Base class PaintCost
public interface PaintCost {
int getCost(int area);
}
// Derived class
class Rectangle : Shape, PaintCost {
public int getArea() {
return (width * height);
}
public int getCost(int area) {
return area * 70;
}
}
class RectangleTester {
static void Main(string[] args) {
Rectangle Rect = new Rectangle();
int area;
Rect.setWidth(5);
Rect.setHeight(7);
area = Rect.getArea();
// Print the area of the object.
Console.WriteLine("Total area: {0}", Rect.getArea());
Console.WriteLine("Total paint cost: ${0}" , Rect.getCost(area));
Console.ReadKey();
}
}
}
However, why have they created the set height and set width functions. Would it not be better practice to simply just do this:
public int width {get;set;}
public int height {get;set;}
and then in the main class just do something like below:
rect.width = 5;
rect.height = 7;
Many thanks,
Amir
I'm sure others will provide different points, but here are my main 2 reasons for using gets/sets. If these don't apply for a given property, chances are I won't use getters/setters.
1 - Debugging
It makes it significantly easier to debug data propagation (how data gets passed around) if you can debug a setter that you're concerned about. You can easily throw in a Debug.Print call and debug the value being set if you're concerned it's being passed the wrong value. Or you could place break points and actually debug through the stack trace. For example:
class Shape {
public void setWidth(int w) {
if(w < 0)
Debug.Print("width is less than 0!");
width = w;
}
public void setHeight(int h) {
height = h;
}
protected int width;
protected int height;
}
2 - Value Change Actions
There may be better ways to achieve this, but I like being able to add simple logic to setters to ensure that any logic that needs to run when a value changes does so. For instance I may use the following:
public void SetWindowHeight(int newHeight)
{
if(WindowHeight == newHeight)
return;
WindowHeight = newHeight;
UpdateWindowDisplay();
}
public int GetWindowHeight()
{
return WindowHeight;
}
private int WindowHeight;
public void UpdateWindowDisplay()
{
Window.UpdateHeight(WindowHeight);
// Other window display logic
}
Although personally I prefer to use property gets/sets, but that's just my preference.
public int WindowHeight
{
get
{
return windowHeight;
}
set
{
if(windowHeight == value)
return;
windowHeight = value;
UpdateWindowDisplay();
}
}
private int windowHeight;
public void UpdateWindowDisplay()
{
Window.UpdateHeight(WindowHeight);
// Other window display logic
}

What is right to do to maintain the principle of inheritance polymorphism?

What is the to do?
to save a specific edge property to square use the rectangle property?
public Square(double edge) : base(edge, edge)
{
}
OR
public Square(double edge) : base(edge, edge)
{
Edge = edge;
}
public Rectangle(double width, double height)
{
Width = width;
Height = height;
}
It does not really matter whether you add a new Edge property in Square, but there is something more important than this. And that is consistency.
If your classes are immutable, then good. But if your classes are mutable, you need to be consistent with the three (or two if you decided not to add Edge) properties in Square. When width changes, height should also change. When you change Edge, both Width and Height should change.
class Square : Rectangle {
public override double Width {
get { return base.Width; }
set {
base.Width = value;
base.Height = value;
}
}
public override double Height {
get { return base.Height; }
set {
base.Width = value;
base.Height = value;
}
}
public double Edge {
get { return Width; }
set {
base.Width = value;
base.Height = value;
}
}
public Square(double edge) : base(edge, edge) {
}
}
Note that the constructor is now empty, because Edge isn't really "stored". When you access it, it just returns the width.
P.S. I don't think Edge is a good name. I would call it SideLength.

Accessing and setting the instance variable of one class from another class

I currently have a class called:
public class HeatmapComponent : GH_Component
I also have another class called:
public class HeatMap
Inside the Heatmap class I have two instance variables declared as:
public int _width;
public int _height;
I would like to be able to access and set the _width and _height variables from the HeatmapComponent class. I know this is a scope issue, but, I am a bit confused as to what needs to be done.
In my HeatmapComponent class, this was what I had in mind:
this._width = width; // width is declared somewhere in this class
this._height = height; // height is same as above
I apologize beforehand if this is a stupid question. Please let me know if I am missing code snippets. I'll be happy to provide.
You want to set the values of those two fields? They are readonly. You can do that only in the constructor.
public class HeatMap
{
private readonly int _width;
private readonly int _height;
public HeatMap(int wid, int hei)
{
_width = wid;
_height = hei;
}
}
And, as it is with passing things through constructor's params, you can use/provide them only when building a new instance. That's why they are called constructor and readonly fields:
public class HeatmapComponent
{
private int widthOfMap;
private int heightOfMap;
void createMapAndDoSomething()
{
var hmap = new HeatMap(widthOfMap, heightOfMap);
hmap.thing();
}
}
If you don't want to create a new HeatMap, and if you want to be able to set the width/height from some 'external' place at any point in time, then:
they cannot be readonly
some public way of changing them must exist
For example:
public class HeatMap
{
private int _width;
private int _height;
public void SetSize(int wid, int hei)
{
_width = wid;
_height = hei;
}
}
public class HeatmapComponent
{
private int widthOfMap;
private int heightOfMap;
private HeatMap oldMap;
void changeTheSizes()
{
oldMap.SetSize(widthOfMap, heightOfMap);
}
}
Or sometimes even better, use properties:
public class HeatMap
{
private int _width;
private int _height;
public int Width { set { _width = value; } }
public int Height { set { _height = value; } }
}
public class HeatmapComponent
{
private int widthOfMap;
private int heightOfMap;
private HeatMap oldMap;
void changeTheSizes()
{
oldMap.Width = widthOfMap;
oldMap.Height = heightOfMap;
}
}
Before I answer your question, you have one major, major issue: readonly. That means that the value of the variable cannot be changed once the object is created. By anyone. Period.
Now, you have a couple ways to do this. The first is to use properties like Snorre said. In effect, you'd get this:
public class HeatMap
{
public int Width { get; set; }
public int Height { get; set; }
}
public class HeatMapComponent
{
private HeatMap myHeatMap; // Must have a reference to the object you want to change!
public void SomeMethod()
{
myHeatMap.Width = 10;
}
}
Now, the obvious downside here is that ANYONE can change the properties of HeatMap. If for some reason you really, really want to make HeatMap's width and height editable only by the HeatMapComponent, you can make HeatMapComponent an inner class, like this:
public class HeatMap
{
private int width;
private int height;
public class HeatMapComponent
{
public HeatMap myHeatMap;
public void SomeMethod()
{
myHeatMap.width = 10;
}
}
}
however, I would strongly advise you to rethink what you're trying to do. Public inner classes are actually quite rare, in my experience, as they can violate OOP principles easily. A different application design may suit you better.
Couple of things:
readonly keyword makes anything settable only in the constructor. Example:
class XYZ
{
private readonly int x;
public XYZ()
{
x = 10; //works
}
public void SomeMethod()
{
x = 100; //does not work since it is readonly
}
}
Then there's the various access modifiers: private is only accessible in the class itself, protected is accessible in inherited classes and public is accessible anywhere. Internal is accessible within the same assembly.
public class HeatMapComponent
{
HeatMap _map;
public HeatMapComponent()
{
_map = new HeatMap();
}
public void SomeMethod()
{
_map.Width = 10; //should work if Width is public and not readonly and if _map was initialized already, ie not null
}
}
This sounds like a homework question, and the problem is you are not understanding the lesson.
Here's a way to create your HeatMap class. It contains an overload so you can either set the Width and Height in the constructor or via a Set method:
public class HeatMap {
public HeatMap() {
Width = 0;
Height = 0;
}
public HeatMap(int width, int height) {
Width = width;
Height = height;
}
public void Set(int width, int height) {
Width = width;
Height = height;
}
public int Width { get; private set; }
public int Height { get; private set; }
}
To use this in your HeatmapComponent class, you only need to create an instance of your HeatMap. Here are two ways of doing that:
public HeatmapComponent() {
}
public void Test1(int width, int height) {
var hm = new HeatMap(width, height);
Console.WriteLine("Width: {0}, Height: {1}", hm.Width, hm.Height);
}
public static void Test2(int width, int height) {
var hm = new HeatMap();
hm.Set(width, height);
Console.WriteLine("Width: {0}, Height: {1}", hm.Width, hm.Height);
}
Be sure you understand what is going on, though.

Is this efficient use of the is and as operator in a DrawableGameComponent?

I'm learning to use the as operator, and my goal was to create an option window (non windows form) that can:
Have options added to it (for flexibility, in case I want to use if statements to add menu items)
Be able to display text, textures, or a class (using the classes draw function)
Be controlled through the host GameState
I still haven't added the options for indicating an item is selected, my apologies for not posting a complete work. I also have not sorted the code into regions yet. Sorry again!
Is my code (particularly the draw function) properly using the is and as operators properly, from a performance and readability (non spaghetti code) standpoint?
public class OptionWindow : DrawableGameComponent
{
public Dictionary<int, Option> options;
int selectedOption;
bool windowLoops;
Rectangle drawRectangle;
int spacer;
int totalItemHeight;
SpriteFont sf;
SpriteBatch sb;
public Rectangle DrawRectangle
{
get { return drawRectangle; }
set { drawRectangle = value; }
}
public int SelectedOption
{
get { return selectedOption; }
set
{
if (windowLoops)
{
if (selectedOption >= options.Count())
selectedOption = 0;
if (selectedOption < 0)
selectedOption = options.Count() - 1;
}
else
{
if (selectedOption >= options.Count())
selectedOption = options.Count() - 1;
if (selectedOption < 0)
selectedOption = 0;
}
}
}
public OptionWindow(Game game, bool windowLoops, SpriteFont sf, Rectangle drawRectangle)
: base(game)
{
options = new Dictionary<int, Option>();
this.windowLoops = windowLoops;
this.sf = sf;
DrawRectangle = new Rectangle(drawRectangle.X, drawRectangle.Y, drawRectangle.Width, drawRectangle.Height);
}
public void Add(object option, bool selectable, bool defaultSelection, int height)
{
options.Add(options.Count(), new Option(selectable, option, height));
if (defaultSelection)
SelectedOption = options.Count() - 1;
UpdatePositions();
}
public void UpdatePositions()
{
UpdateTotalItemHeight();
if (options.Count() - 1 != 0)
spacer = (drawRectangle.Height - totalItemHeight) / (options.Count() - 1);
for (int i = 0; i < options.Count(); i++)
{
if (i == 0)
options[i].Position = new Vector2(drawRectangle.X, drawRectangle.Y);
else
{
options[i].Position = new Vector2(
drawRectangle.X,
options[i - 1].Position.Y + options[i - 1].Height + spacer);
}
}
}
public void UpdateTotalItemHeight()
{
totalItemHeight = 0;
for (int i = 0; i < options.Count(); i++)
{
totalItemHeight += options[i].Height;
}
}
protected override void LoadContent()
{
sb = new SpriteBatch(GraphicsDevice);
base.LoadContent();
}
public override void Draw(GameTime gameTime)
{
for (int i = 0; i < options.Count(); i++)
{
if (options[i].OptionObject is string)
sb.DrawString(sf, options[i].OptionObject as string, options[i].Position, Color.White);
if (options[i].OptionObject is Texture2D)
sb.Draw(options[i].OptionObject as Texture2D,
new Rectangle(
(int)options[i].Position.X,
(int)options[i].Position.Y,
options[i].Height,
(options[i].Height / (options[i].OptionObject as Texture2D).Height) * (options[i].OptionObject as Texture2D).Width),
Color.White);
if (options[i].OptionObject is DisplayObject)
(options[i].OptionObject as DisplayObject).Draw(gameTime);
}
base.Draw(gameTime);
}
}
public class Option
{
bool selectable;
object optionObject;
int height;
Vector2 position;
public bool Selectable
{
get { return selectable; }
set { selectable = value; }
}
public object OptionObject
{
get { return optionObject; }
set { optionObject = value; }
}
public int Height
{
get { return height; }
set { height = value; }
}
public Vector2 Position
{
get { return position; }
set { position = value; }
}
public Option(bool selectable, object option, int height)
{
Selectable = selectable;
OptionObject = option;
Height = height;
}
}
It is never adviseable to use is and then as. The usual way to go would be to either of the following:
just use is (if you just want to know the type without subsequent casting)
assign the result of as to a variable and check whether that variable is (not) null
The code analysis tool FxCop helps you find any spots in your code that use is and then as and warns you because of performance concerns.
Note however that a better approach altogether might be to declare your OptionObject property as some abstract class with a Draw method. You could then derive a subclass for strings, one for Texture2D instances and another one for DisplayObject instances and just call Draw in your OptionWindow.Draw method. This would leave the decision which actual drawing operations to execute up to built-in polymorphism features of the framework.

Access 2d array with point in wpf C#

I have a 2d array of a class. The size of array is very large (around 3000*3000) and accessing the array with ordinary row and column method is taking very much time. For this purpose, I want to use pointers to access the array.
Following is my array code:
Class definition:
Class BoxData
{
Size _bound;
bool _isFilled=false;
Color _color=Colors.White;
public Size Bounds
{
get
{
return _bound;
}
set
{
_bound=value;
}
}
public bool IsFilled
{
get
{
return _isFilled;
}
set
{
_isFilled=value;
}
}
public Color FillColor
{
get
{
return _color;
}
set
{
_color=value;
}
}
}
Class used as array in application:
BoxData[,] boxData=new BoxData[3000,3000];
I want to access boxData with pointers.
Thanks
Try a jagged array instead of a multi dimensional one, they are faster in Microsoft's CLR implementation
BoxData[][] boxData=new BoxData[3000][];
for (int i=0; i<3000; i++)
boxData[i] = new BoxData[3000];
Maybe you could use a struct instead of a class for BoxData ?
Struct is a value type: as you declare your array, everything will be populated already.
You will not longer use a loop to create new BoxData() instances.
var x = new BoxData[3000,3000]; // Populated array of BoxData
Because of struct vs class restrictions, you will have to remove initializers this way...
struct BoxData
{
Size _bound;
bool _isFilled; // = false;
Color _color; // = Color.White;
public Size Bounds
{
get
{
return _bound;
}
set
{
_bound = value;
}
}
public bool IsFilled
{
get
{
return _isFilled;
}
set
{
_isFilled = value;
}
}
public Color FillColor
{
get
{
return _color;
}
set
{
_color = value;
}
}
}
...and initialize your default values using a loop will be much more faster.
for (int j = 0; j < 3000; j++)
for (int i = 0; i < 3000; i++)
x[i, j].FillColor = Color.White;

Categories

Resources