|
I intended to make all of my Number classes immutable, and thought I had done so. If they are in fact immutable, is there any danger left?
|
|
|
|
|
Depends on how immutable you made them!
You know how to do that, I assume:
1) Remove the setters of the class, only have getters.
2) Provide all parameters via constructor.
3) Make all variables readonly .
Do note that doesn't mean that any collections an immutable class contains will themselves be immutable: Add and Remove will still work for example, only the assignment of a new collection will not be possible.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
OK, so I'm creating a simple card game. So far I can move my cards with mouse and this work as it should, but on the other hand I feel that most of my code is wrong because I had to repeat the same method for each object. So I'd like to simplify my code. Tried to use lists, collections and 'foreach' loops, but couldn't make it work. How can I make my code smaller, simpler and more elegant?
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
class MainForm : Form {
class Card {
public int Type;
public Rectangle Position;
public Bitmap Image;
public Card(int Type, Rectangle Position) {
this.Type = Type;
switch (Type) {
case 1:
Image = new Bitmap("1.png");
break;
case 2:
Image = new Bitmap("2.png");
break;
case 3:
Image = new Bitmap("3.png");
break;
case 4:
Image = new Bitmap("4.png");
break; }
this.Position = Position; } }
Card RedCard = new Card(1, new Rectangle(0, 32, 32, 32));
Card BlueCard = new Card(2, new Rectangle(0, 64, 32, 32));
Card GreenCard = new Card(3, new Rectangle(0, 96, 32, 32));
Card YellowCard = new Card(4, new Rectangle(0, 128, 32, 32));
Card RedCard2 = new Card(1, new Rectangle(0, 160, 32, 32));
int IsTaken = 0, OffsetX = 0, OffsetY = 0;
PictureBox Table = new PictureBox();
void DrawTable(object sender, PaintEventArgs e) {
Color FirstColor = Color.FromArgb(46, 135, 46);
e.Graphics.FillRectangle(new SolidBrush(FirstColor), 0, 0, 400, 400); }
void DrawCards(object sender, System.Windows.Forms.PaintEventArgs e) {
e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
e.Graphics.PixelOffsetMode = PixelOffsetMode.Half;
e.Graphics.DrawImage(RedCard.Image, RedCard.Position);
e.Graphics.DrawImage(BlueCard.Image, BlueCard.Position);
e.Graphics.DrawImage(GreenCard.Image, GreenCard.Position);
e.Graphics.DrawImage(YellowCard.Image, YellowCard.Position);
e.Graphics.DrawImage(RedCard2.Image, RedCard2.Position); }
int IsCursorOverCard(int X, int Y) {
if ((X > RedCard.Position.Left) && (X <= RedCard.Position.Right) && (Y > RedCard.Position.Top) && (Y <= RedCard.Position.Bottom))
return 1;
else if ((X > BlueCard.Position.Left) && (X <= BlueCard.Position.Right) && (Y > BlueCard.Position.Top) && (Y <= BlueCard.Position.Bottom))
return 2;
else if ((X > GreenCard.Position.Left) && (X <= GreenCard.Position.Right) && (Y > GreenCard.Position.Top) && (Y <= GreenCard.Position.Bottom))
return 3;
else if ((X > YellowCard.Position.Left) && (X <= YellowCard.Position.Right) && (Y > YellowCard.Position.Top) && (Y <= YellowCard.Position.Bottom))
return 4;
else if ((X > RedCard2.Position.Left) && (X <= RedCard2.Position.Right) && (Y > RedCard2.Position.Top) && (Y <= RedCard2.Position.Bottom))
return 5;
else
return 0; }
void RedrawRedCard(object sender, System.Windows.Forms.PaintEventArgs e) {
e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
e.Graphics.PixelOffsetMode = PixelOffsetMode.Half;
e.Graphics.DrawImage(RedCard.Image, RedCard.Position); }
void RedrawBlueCard(object sender, System.Windows.Forms.PaintEventArgs e) {
e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
e.Graphics.PixelOffsetMode = PixelOffsetMode.Half;
e.Graphics.DrawImage(BlueCard.Image, BlueCard.Position); }
void RedrawGreenCard(object sender, System.Windows.Forms.PaintEventArgs e) {
e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
e.Graphics.PixelOffsetMode = PixelOffsetMode.Half;
e.Graphics.DrawImage(GreenCard.Image, GreenCard.Position); }
void RedrawYellowCard(object sender, System.Windows.Forms.PaintEventArgs e) {
e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
e.Graphics.PixelOffsetMode = PixelOffsetMode.Half;
e.Graphics.DrawImage(YellowCard.Image, YellowCard.Position); }
void RedrawRedCard2(object sender, System.Windows.Forms.PaintEventArgs e) {
e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
e.Graphics.PixelOffsetMode = PixelOffsetMode.Half;
e.Graphics.DrawImage(RedCard2.Image, RedCard2.Position); }
void TakeCard(object sender, MouseEventArgs e) {
switch (IsCursorOverCard(e.X, e.Y)) {
case 1:
this.Table.Paint += new PaintEventHandler(this.RedrawRedCard);
IsTaken = 1;
OffsetX = RedCard.Position.X - e.X;
OffsetY = RedCard.Position.Y - e.Y;
break;
case 2:
this.Table.Paint += new PaintEventHandler(this.RedrawBlueCard);
IsTaken = 2;
OffsetX = BlueCard.Position.X - e.X;
OffsetY = BlueCard.Position.Y - e.Y;
break;
case 3:
this.Table.Paint += new PaintEventHandler(this.RedrawGreenCard);
IsTaken = 3;
OffsetX = GreenCard.Position.X - e.X;
OffsetY = GreenCard.Position.Y - e.Y;
break;
case 4:
this.Table.Paint += new PaintEventHandler(this.RedrawYellowCard);
IsTaken = 4;
OffsetX = YellowCard.Position.X - e.X;
OffsetY = YellowCard.Position.Y - e.Y;
break;
case 5:
this.Table.Paint += new PaintEventHandler(this.RedrawRedCard2);
IsTaken = 5;
OffsetX = RedCard2.Position.X - e.X;
OffsetY = RedCard2.Position.Y - e.Y;
break; } }
void MoveCard(object sender, MouseEventArgs e) {
switch (IsTaken) {
case 0:
if (IsCursorOverCard(e.X, e.Y) == 0)
Table.Cursor = Cursors.Default;
else
Table.Cursor = Cursors.Hand;
break;
case 1:
RedCard.Position.X = e.X + OffsetX;
RedCard.Position.Y = e.Y + OffsetY;
Table.Invalidate();
break;
case 2:
BlueCard.Position.X = e.X + OffsetX;
BlueCard.Position.Y = e.Y + OffsetY;
Table.Invalidate();
break;
case 3:
GreenCard.Position.X = e.X + OffsetX;
GreenCard.Position.Y = e.Y + OffsetY;
Table.Invalidate();
break;
case 4:
YellowCard.Position.X = e.X + OffsetX;
YellowCard.Position.Y = e.Y + OffsetY;
Table.Invalidate();
break;
case 5:
RedCard2.Position.X = e.X + OffsetX;
RedCard2.Position.Y = e.Y + OffsetY;
Table.Invalidate();
break; } }
void PutCard(object sender, MouseEventArgs e) {
IsTaken = 0; }
MainForm() {
this.SuspendLayout();
this.Width = 1024;
this.Height = 768;
this.Controls.Add(this.Table);
this.Table.Location = new Point(0, 0);
this.Table.Size = new Size(400, 400);
this.Table.Paint += new PaintEventHandler(this.DrawTable);
this.Table.Paint += new PaintEventHandler(this.DrawCards);
this.Table.MouseDown += new MouseEventHandler(this.TakeCard);
this.Table.MouseMove += new MouseEventHandler(this.MoveCard);
this.Table.MouseUp += new MouseEventHandler(this.PutCard);
this.ResumeLayout(); }
static void Main() {
Application.Run(new MainForm()); } }
|
|
|
|
|
That does look quite ugly.
You need to start by reading at the builder pattern, to build up the objects (you had a switch statement in the constructor).Understanding and Implementing Builder Pattern in C#.
Then as for the rest of the code, I might just create a separate function to handle the types, because most of the operations are same.
case 1:
RedCard.Position.X = e.X + OffsetX;
RedCard.Position.Y = e.Y + OffsetY;
Table.Invalidate();
break;
case 2:
BlueCard.Position.X = e.X + OffsetX;
BlueCard.Position.Y = e.Y + OffsetY;
Table.Invalidate();
break;
That part of the code can be rewritten to, something like this,
private void updateCardPosition(Card card, int x, int y) {
card.Position.X = x;
card.Position.Y = y;
}
case 1:
updateCardPosition(RedCard);
Lastly, the Table.Invalidate(); gets called in each of the block, so you can bring it out of the switch statement.
So basically you need to rewrite the code a bit functional in nature. Otherwise your code looks fine to me, just the redundancy of the code which you have to remove.
The sh*t I complain about
It's like there ain't a cloud in the sky and it's raining out - Eminem
~! Firewall !~
|
|
|
|
|
I am receiving an unhandled exception of type 'System.ArgumentException' occured in System.Drawing.dll error. The additional information is 'Parameter is not valid.
This error just recently started occurring and it happens in the designer page in the InitializeComponent procedure.
All the forms have started showing this message when trying to create a text box, combo box etc.
The controls are dragged and dropped onto the form without any data binding or any special restrictions etc.
When I create a new project adding the exact same type of layout, the application seems to be working fine.
Google overs no solution to this problem.
|
|
|
|
|
|
i have two or three forms created in c#sharp and in each form i am repeating the steps of attaching the library,the entering the routine code of data adapter,connection and other stuff , is there a easy way to put it inside central class library so that i can refer it instead of typing it everytime.
|
|
|
|
|
Yes, there is. You can make this as fine grained as you like - it would be easier if you move away from using the data adapter. What you are basically looking at is how to make the data access part of a data access layer. This really isn't that difficult, as you're looking at the ability to update data, retrieve data, called stored procs and the likes. If I were you, I would just tackle adding each part just as I needed it. So, start with the easy stuff - getting the connection string, opening a connection, closing it, issuing a command directly (make sure to use parameterised properties, rather than concatenating values in).
This space for rent
|
|
|
|
|
|
|
There are a vast number of Data Access Layer (DAL) samples around CP Search
However Pete's suggestion that you roll your own is absolutely valid, get some ideas from others but every competent developer should have written his own DAL. Start small and build on it as additional requirements arise.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
I want to download same data from a web page. Using Excel webquery it works, while using C# it doesn't.
Here my code:
WebClient webClient = new WebClient();
a = "http://www.borsaitaliana.it/borsa/obbligazioni/mot/obbligazioni-in-euro/dati-completi.html?isin=DE000UB5WF78&lang=it";
string page = webClient.DownloadString(a);
System.Net.WebException: 'The remote server returned an error: (403) Forbidden.'
Have you any ideas?
Thanks for your time
|
|
|
|
|
|
I 'm trying to write audio to USB Modem via COM PORT. But it throwing me the error.
Can someone help. It really very important.
I am getting error in
waveSource_DataAvailable .
WaveIn waveSource;
waveSource = new WaveIn(this.Handle);
waveSource.DataAvailable += new EventHandler<WaveInEventArgs>(waveSource_DataAvailable);
.....
void waveSource_DataAvailable(object sender, WaveInEventArgs e)
{
portReceived.Write(e.Buffer, 0, e.BytesRecorded);
}
|
|
|
|
|
What kind of error? A compile-time error, a runtime exception? What did the error-text say?
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
What error?
Is there a message?
What does the debugger show you?
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Exception thrown: 'System.IO.IOException' in System.dll
An unhandled exception of type 'System.IO.IOException' occurred in System.dll
A device attached to the system is not functioning.
|
|
|
|
|
Any there is only one "device" in your question: the COM port connected USB modem.
So I'd start by using Hyperterminal or similar to find out why it isn't working, and what I needed to do to get it working.
Until you have reliable communications, there is no point writing code at all: it just adds complications and more "points of failure". Only ever start with code when you have baseline communications fully established and reliable.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Thanks for reply.
I am trying to write a application which will communicate through AT Commands with USB Modem. I will make calls using AT Command and speak through mic and listen through Speaker. I have managed all things but I am not able to speak through mic. It gives error as above. Although I can hear what other end is saying very clearly. Please help...
|
|
|
|
|
As I said: start by connecting via Hyperterminal or similar, and use that to send AT commands: until you have established fully working communications, it doesn't matter if you code is right or wrong: it can't be tested until you know the link it relies upon works!
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Yes I have tried. It's working.
|
|
|
|
|
I have figured out something. When the value of
e.BytesRecorded=1600
there is an exception. I need to convert microphone audio to 8Khz, 8 bit 1 channel so that it can be send to Port.
portReceived.Write(e.Buffer, 0, 960);
It works great but there too much echo and noise.
|
|
|
|
|
Assume that I have a pipe that consists of sections of variable radiuses and that I want to make calculations at different frequencies. So I want the calculations done at different threads for each frequency, but the list of pipe sections stays the same.
public class PipeSection
{
public PipeSection(double radius)
{
this.Radius = radius;
}
public double Radius { get; set; }
public double Calculate(double Frequency)
{
return Frequency * this.Radius;
}
}
To run the frequencies in parallel I use Rx:
CancellationTokenSource ctr = new CancellationTokenSource();
List<PipeSection> wn = new List<PipeSection>();
public MainWindow()
{
InitializeComponent();
PipeSection[] input = { new PipeSection(5), new PipeSection(6), new PipeSection(7) };
wn.AddRange(input);
var FreqData = new double[] { 0, 100, 2000, 3000 }.ToObservable<double>();
FreqData
.ObserveOn(Scheduler.Default)
.SelectMany(x => Task.Run<double>(() => DoCalcualtions(x,wn), ctr.Token))
.ObserveOnDispatcher()
.Subscribe(args => {
pgbProgress.Value += 1;
txtText.Text += Environment.NewLine + args.ToString();
},
() => {
txtText.Text += Environment.NewLine + "All done";
}
);
}
private double DoCalcualtions(double Freq, List<PipeSection> input)
{
double result=1;
for (int i = 0; i < input.Count(); i++)
result *= input[i].Calculate(Freq);
return result;
}
This does compile and run, but I have some questions regarding if the multithread calls:
1) Will I have to clone my list of Pipesections for each frequency (i.a. for each thread I want to run) ?
2) Can the DoCalcualtion function now be accessed in parallel or will I have to move it inside the PipeSection class to ensure this?
3) Is there a much better way of doing this?
-Kenneth
|
|
|
|
|
As long as your threads don't modify the data they're reading it's all perfectly thread-safe. No need to clone the data or to move DoCalcualtions . Moving DoCalcualtions into the PipeSection class wouldn't make a lot of sense anyway because it doesn't operate on a single PipeSection instance.
I assume in practice your input data set is a lot larger so threading is actually called for? There are of course alternative ways of doing this but I don't think there's an objectively better way. You're aware that you're ignoring the CancellationToken in DoCalcualtions ?
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
|
|
|
|
|
Thank you for the answer.
I understand that they are thread safe, but what I was worried about was that there was just "one function" in memory, so when it was used no other threads could use the function, thereby making the multithreading single thread instead? (So I tried (and failed) to described a wrapper class that had several instances of the function in memory).
As for the reasoning behind using multithreading, the datasets itself are not so large, but I'm going to do some numerical integration inside DoCalcualtions that is very time-consuming. As for the non-use of
CancellationToken I just stripped the calculations to the bare minimum.
Kenneth
|
|
|
|
|