I am trying to develop a clock application with images for each digits from 0-9. Wrote a struct that gives me each digits every now and then. Following is the struct.
public struct TimeStruct
{
public DateTime dt
{
get
{
return DateTime.Now;
}
}
public int s
{
get
{
return dt.Second;
}
}
public int s2
{
get
{
return s % 10;
}
}
public int s1
{
get
{
return s / 10;
}
}
public int m
{
get
{
return dt.Minute;
}
}
public int m2
{
get
{
return m % 10;
}
}
public int m1
{
get
{
return m / 10;
}
}
public int h
{
get
{
return dt.Hour;
}
}
public int h2
{
get
{
return h % 10;
}
}
public int h1
{
get
{
return h / 10;
}
}
public int d
{
get
{
return (int)dt.DayOfWeek;
}
}
}
Please guide me to modify this struct so that the prop s2 should be set only when s1 becomes 0. And the same with minutes.
Technology Used : Silverlight
Platform : Windows Phone 7
Was that a bad idea to use struct?
What do you mean by "prop s2 should be set only when s1 becomes 0" - what do you want it to do when s1 isn't 0? Are you perhaps looking for nullable value types, where s1 would return the null value in some cases?
I have to say, I think this is a pretty confusing type. It has no real state - it's effectively just a bunch of static properties. Any reason for not implementing it as a bunch of static properties, e.g. in a CurrentDateTime class? Or just use DateTime.Now? Note that if you ask your struct for a bunch of values, one at a time, it may very well give you inconsistent results as time will pass. For example, suppose the time is 1:59:59 and you call s, then m, then h - you may end up getting 59, 59, 2 as the current time rolls over from 1:59:59 to 2:00:00 between the last two calls. If you take the value of DateTime.Now just once and ask it for all its properties, you'll get a consistent view.
Why re-invent the wheel ? Use DateTime and TimeSpan.
Related
I got an assignment where I have to come up with a code that continues to create unbelievably long strings and I can't figure out how to get around the issue of simply running out of memory by going beyond the limits of a simple string.
The program asks for the following from the user:
A: string that will be its first "real" input (e.g. "a", "asdf", etc.)
B: "base" string with special characters that can be substituted by A (e.g. "%n%", "%abc%def%, %%asd%tr, etc.)
C: number of times the program should run (up to 1 billion)
D: first index of a character from the final string
E: last index of a char from the final string - these are to return to the user with something.
The catch is, with every iteration, A should be updated to whatever output is produced when substituting it into B, and then it's used as an input again.
An example would be 1) ana (A: a, B: %n%) 2) ananana (A: ana, B: %n%) 3) ananananananana (A: ananana, B: %n%) etcetc, and then with D & E being 3 & 7 respectively, the final output would be anana.
Another would be with A: x, B: %a%b%c%, C: 999999999, D: 33, E: 65 --> xaxbxcxaxaxbxcxbxaxbxcxcxaxbxcxbx
One more: A: abcdef, B: %%, C:500, D: 3, E: 22 --> cdefabcdefabcdefabcdef
And like a simple one, A: hi, B: %hey, C: 10, D: 10, E: 20 --> eyheyheyhey
I've been trying to solve it by creating a separate class and running what I think is a form of recursion (although I'm not 100% sure, I'm very much a beginner) but despite my best efforts, I keep getting the OOM error once the string reaches what I assume must be past a string's limit. Maybe I've been trying to approach the whole problem from the wrong angle? But at this point I can't envision a different path I could've taken towards a solution.
Here's what I have so far - would really appreciate any help from anyone!
class Program
{
static void Main(string[] args)
{
BehindTheScenes trial = new BehindTheScenes(Console.ReadLine(), Console.ReadLine(),
int.Parse(Console.ReadLine()), int.Parse(Console.ReadLine()), int.Parse(Console.ReadLine()));
trial.ReWrite();
Console.WriteLine(trial.Display());
Console.ReadLine();
}
}
class BehindTheScenes
{
public string InAndOut { get; set; }
public string specialchar { get; set; }
public int no_of_times { get; set; }
public int min { get; set; }
public int max { get; set; }
public int counter { get; set; }
public BehindTheScenes(string substitute, string specialchar, int no_of_times, int min, int max)
{
this.InAndOut = substitute;
this.specialchar = specialchar;
this.no_of_times = no_of_times;
this.min = min;
this.max = max;
this.counter = 0;
}
public void ReWrite()
{
if (this.specialchar.Contains("$"))
{
string temp = "";
while (counter < this.no_of_times)
{
temp = this.specialchar.Replace("$", this.InAndOut);
this.InAndOut = temp;
counter++;
}
}
}
public string Display()
{
int total_length = this.max - this.min + 1;
string dash = new string('-', 99);
string final = "";
if (!this.specialchar.Contains("$"))
{
if (this.min > this.specialchar.Length)
{
return dash.Substring(0, total_length);
}
else
{
final = string.Concat(this.specialchar, dash);
return final.Substring(this.min - 1, total_length);
}
}
if (this.max > this.InAndOut.Length)
{
final = string.Concat(this.InAndOut, dash);
return final.Substring(this.min - 1, total_length);
}
else
{
return this.InAndOut.Substring(this.min - 1, total_length);
}
}
}
This question already has answers here:
C# 3.0 Auto-Properties - Is it possible to add custom behaviour?
(6 answers)
Closed 1 year ago.
I have the following class with auto properties:
class Coordinates
{
public Coordinates(int x, int y)
{
X = x * 10;
Y = y * 10;
}
public int X { get; set; }
public int Y { get; set; }
}
As you can see from the constructor I need the value to be multiplied by 10.
Is there anyway to do it without removing autoproperties?
I tried the following not thinking that it causes recursion and then everything goes fubar
public int X { get {return X;} set{ X *= 10;} }
I would like to assign values to X and Y multiplied by 10.
Coordinates coords = new Coordinates(5, 6); // coords.X = 50 coords.Y = 60
coords.X = 7; // this gives 7 to X but I would like it to be 70.
In order to make setter working like that, you'll need to use backing field:
class Coordinates
{
public Coordinates(int x, int y)
{
X = x;
Y = y;
}
private int _x;
public int X
{
get { return _x; }
set { _x = value * 10; }
}
private int _y;
public int Y
{
get { return _y; }
set { _y = value * 10; }
}
}
Given your example:
Coordinates coords = new Coordinates(5, 6); // coords.X = 50 coords.Y = 60
coords.X = 7; // this gives 70
However, I don't recommend you having such setter because it could lead to confusion. It's better to have a dedicated method which will do such multiplication. In the end, your code will be more descriptive and intuitive.
You get a recursion, because you again call the same property, which in turn calls the same property, which in turn calls the same property... you get the point.
public int X { get {return X;} set{ X *= 10;} }
How does auto properties works ?
Behind the scenes Properties are actually methods, which means they don't actually store data. So who saves the data ? AutoProperties generate private backend field to save the data.
So in the simple declaration of auto property
int X { get; set; }
The compiler translate it into something like that
private int <X>k__BackingField;
public int X
{
[CompilerGenerated]
get
{
return <X>k__BackingField;
}
[CompilerGenerated]
set
{
<X>k__BackingField = value;
}
}
So no matter if you use it as Auto Properties or simple property, they are the same.
Now, to answer you question, with paraphrasing, "How do i return the value multiply with 10"
You can solve it with using 2 ways:
1. By saving the data multiply by 10 (setter implementation)
2. By returning the data multiply by 10 (getter implementation)
I won't elavorate, which one you should use, because for this kind of simple scenario, both will be perfectly valid.
I would just say that some of the factors for the choice will be micro(micro micro micro) performence, true state storage.
Here is the setter implementation
private int _x;
public int X
{
get
{
return _x;
}
set
{
return _x*10;
}
}
I am storing a int in schadstoffklasse so when calling the Car object like so (last int in brackets) :
PKW Kaefer = new PKW("VW", "Käfer", "K-GS-01", 1965, 9999, 1000, 30, 1);
I can either say 0, 1, 2.
Now when i write this Console.WriteLine(Kaefer.Schadstoffklasse)
to the console it obiously outputs 1 in this case.
I do want it to not say 1 i want for example....
0 = foo
1 = bar
2 = foobar
So it outputs to the console a string.
Here is what i have tried, which does not work.
private int schadstoffklasse;
public int Schadstoffklasse
{
get
{
return schadstoffklasse;
}
set
{
if (value == 0)
{
string foo = value.ToString();
foo = "BLABLALBA";
}
schadstoffklasse = value;
}
}
Thank you for having patience with a beginner
You can't have a property return mixed types. Your property of Schadstoffklasse is an int, therefore it can only ever return an int never a string.
There are a variety of different ways to accomplish this though, but without knowing more of how you are using this it'd be impossible to say which one you should do. I'd recommend either another property that has no setter and the getter looks at the other property, reads it's value and returns the string that you want or a method that does the same.
To expand on my suggestion:
public enum SchadstofklasseStrings
{
foo = 0,
bar = 1,
foobar = 2
}
public int Schadstoffklasse { get; set; }
public string SchadstoffklasseToString {
{
get
{
var stringValue = (SchadstofklasseStrings) Schadstoffklasse;
return stringValue.ToString();
}
}
Also, sorry for mutilating the German.
You can't change the type of a variable from int to string .
in this case i would create an array
["foo","bar","foobar"]
and use value of schadstoffklasse as an index
Console.WriteLine(Kaefer.myArray[Schadstoffklasse]);
Try this
private int schadstoffklasse;
public object Schadstoffklasse
{
get
{
if(this.schadstoffklasse==0)
return "foo";
if(this.schadstoffklasse==1)
return "bar";
if(this.schadstoffklasse==2)
return "foobar";
return "N/A";
}
set
{
this.schadstoffklasse=(int)value;
}
}
Note: The explain from user #gilliduck is useful. Consider this just
as a situational workaround.
I find enum helpful in situations like this since it is a collection of named integers. This is one example of how I might handle it.
void Main()
{
var Kaefer = new PKW("VW", "Käfer", "K-GS-01", 1965, 9999, 1000, 30, Schadstoffklassen.Bar);
Console.WriteLine(Enum.GetName(typeof(Schadstoffklassen), Kaefer.Schadstoffklasse));
// Output: Bar
}
public class PKW
{
private Schadstoffklassen schadstoffklasse;
public PKW(string v1, string v2, string v3, int v4, int v5, int v6, int v7, Schadstoffklassen _schadstoffklasse) {
schadstoffklasse = _schadstoffklasse;
}
public Schadstoffklassen Schadstoffklasse
{
get { return schadstoffklasse; }
set { schadstoffklasse = value; }
}
}
public enum Schadstoffklassen {
Foo = 0,
Bar = 1,
FooBar = 2
}
I am trying to solve or be pointed in the right direction. I am having difficulty determining where to place my Area formula in the Triangle Class (not the main). Area can only have a 'get' and not a 'set'.
Next issue is identifying the type of triangle based on the inputed side and if it is a 'right' triangle, appending the 'type' with '-right' for example (isosceles-right). I have an enum for the triangle types.
I'm not looking for the direct answer to solve this but rather some help and coaching to help better build my skills
Here is the class structure I have generated so far in C#, please keep in mind it is not complete.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TriangleCheck;
namespace TriangleCheck
{
public class Triangle
{
private StringBuilder _ErrorMsg;
private int[] _Sides;
private const int _nSides = 3;
private int _Area;
public Triangle(int[] Sides)
{
//Track amunt of errors recieved.
int nErrors = 0;
//Make sure ErrorMsg is cleared
_ErrorMsg = new StringBuilder();
//Did I get _nSides? If not, append to ErrorMsg and throw exception
if(Sides.Length != _nSides)
{
_ErrorMsg.Append(string.Format("Expected {0} sides but recieved {1}", _nSides, Sides.Length));
nErrors += 1;
}
//Is each side positive? If not, append to ErrorMsg and throw exception
for (int i = 0; i < Sides.Length; i++)
{
if (Sides[i] <= 0)
{
_ErrorMsg.Append(string.Format("{0} side is not a postive integer", Sides[i]));
nErrors += 1;
}
}
//Set input from user to private property _Sides
_Sides = Sides;
_Area = Area;
}
public int Area
{
get { return _Area; }
private set
{
int parameter =
}
}
public string ErrorMsg
{
get
{ return ErrorMsg.ToString();}
}
public bool IsRight
{
get
{
return ;
}
}
public int Sides
{
get
{ return _Sides; }
set
{
if (value > 0)
{
_Sides = value;
}
else
throw new ArgumentOutOfRangeException("Value must be postive!");
}
}
public TriangleTypes TriangleTypes
{
get
{
throw new System.NotImplementedException();
}
set
{
}
}
public void ScaleUp(int[] ScaleFactor)
{
throw new System.NotImplementedException();
}
public override string ToString()
{
return "A Triangle with sides " + _Sides + " is Type: " + TriangleTypes + " with Area:" + Area;
}
}
}
You mention that you can't set the Area property... it looks like you're trying to enforce that by making a private set, but why not just exclude the set leaving it as a read-only property?
The Area formula could go a couple places; the key is that it is derived from the sides but only matters when someone asks for it. So you could reasonably:
Apply the formula and update internal state every time sides changes
Apply the formula and return the value every time someone does a get operation on Area
Remember the point of getter and setter being functions is that they could contain logic to execute (to fully update internal state in setter, or to calculate the value of a read-only derived property).
More sophisticated patterns exist if performance of the area calculation were very worrisome, but I wouldn't get into that at this point.
As for determining if the triangle is right... if it is, which side must be the hypotenuse? What relationship do you know between the length of the hypotenuse and the lengths of the other sides, if the triangle is right?
using System;
namespace ConsoleApp
{
class Program
{
static void Main()
{
var t = new Triangle(2, 3, 5);
//var Triangle = new Triangle(2); // won't compile as no Triangle constructor can be found that takes 1 integer
//var Triangle = new Triangle(2, 3, 5, 7); // won't compile as no Triangle constructor can be found that takes 4 integers
//var Triangle = new Triangle(2, -3, 5); // won't compile as the 2nd value is negative - and we've asked for unsigned for all 3 values
Console.WriteLine("The triangle ({0}, {1}, {2}) has an area of {3}.", t.A, t.B, t.C, t.area());
Console.ReadKey();
}
}
public class Triangle
{
public uint A { get; set; }
public uint B { get; set; }
public uint C { get; set; }
public Triangle(uint a, uint b, uint c)
{
this.A = a;
this.B = b;
this.C = c;
}
public uint area()
{
return A * B * C; // this needs fixing ...
}
}
}
Isn't this roughly what you are trying to achieve with your Triangle class - a way of stopping it being used incorrectly with too few or incorrect types of arguments. This one only allows 3 positive (uint) integers. Nothing else will comple - which is what you want. Sorry if I have misunderstood.
In my Class i need to set one property value according to another:
public class Quantities
{
private int _quant;
public int Quant
{
get { return _quant; }
set
{
if (Unit == "K")
{
_quant = value / 1000;
}
else
{
_quant = value;
}
}
}
public string Unit { get; set; }
}
according to several tests i made it works fine but i still don't know if it's safe to do this.
is it possible that the Quant Property will be evaluated before the Unit Property or does the compiler (or JIT) knows that it should assign the Unit Property first?
This has nothing to do with the compiler or the JIT. Your code assigns the values. You need to know the order in which they should be assigned.
BTW: Your code exhibits temporal coupling. It would be better to make at least the Unit unchangeable by making the property readonly and by providing a constructor that requires the unit:
public class Quantities
{
private readonly string _unit;
private int _quant;
public Quantities(string unit)
{
if(unit == null) throw new ArgumentNullException("unit");
_unit = unit;
}
public int Quant
{
get { return _quant; }
set
{
if (Unit == "K")
{
_quant = value / 1000;
}
else
{
_quant = value;
}
}
}
public string Unit { get { return _unit; } }
}
This class now can't be used in an incorrect way.
For more points that can be improved with your class, please refer to Lasse's answer.
Code on the outside of this class must know about this dependency or you risk someone changing Unit without re-setting Quant:
var x = new Quantities(); // why no constructor for this?
x.Unit = "K";
x.Quant = 1700; // why int? this will now be 1, not 1.7
x.Unit = "M";
Personally I would make the class a struct, and make it immutable:
public struct Quantity
{
private readonly double _Value;
private readonly string _Unit;
public Quantity(double value, string unit)
{
_Value = value;
_Unit = unit;
}
public double Value
{
{
return _Value;
}
}
public double Unit
{
{
return _Unit;
}
}
}
Also note that I did not change the value at all, hence:
var x = new Quantity(1700, "K");
means 1700K, not 1.7K. I would refrain from doing such "automagical" interpretations of data. If you need to display the value with a different unit, I would instead build in a conversion system:
public Quantity ConvertToUnit(string newUnit)
{
var newValue = ... calculate value with new unit
return new Quantity(newValue, newUnit);
}
The class is not a good design. Do not do this.
Consider the following code:
Quantities q1 = new Quantities { Unit = "K", Quant = 1000};
Console.WriteLine(q1.Quant); // Prints 1
// Make a copy of q1
Quantities q2 = new Quantities{ Unit = q1.Unit, Quant = q1.Quant };
Console.WriteLine(q2.Quant); // Prints 0
You would expect that making a copy of the Quantities would work by doing a basic copy like the above. That it does not shows you how dangerous this kind of design is.
This is still a problem after making the changes in the accepted answer above
If you use the changes that Daniel suggested, you still have the nastyness associated with your property setter and getter not being commutative. Sure, you would be forced to pass the units into the constructor, but the object copy still won't work as the user might expect:
Quantities q1 = new Quantities("K"){ Quant = 1000};
Console.WriteLine(q1.Quant); // Prints 1
// Make a copy of q1
Quantities q2 = new Quantities(q1.Unit){ Quant = q1.Quant };
Console.WriteLine(q2.Quant); // STILL Prints 0