|
Okay, thank you for helping me !
|
|
|
|
|
FilipJ wrote: This is the first time im trying to learn to code I have good news and bad news for you.
First the good news: you're embarking on a path that is likely to prove interesting, satisfying and rewarding, and will hopefully open the door to a great new career.
Next, the bad news: you seem to have bitten off more than you can chew. I suggest you take small steps first - learn programming (and C#) by building small, very focused console applications. A console app runs in a command window and has no GUI. The purpose of this multi-month long exercise is to become familiar with programming in general, as well as the rich .NET framework.
- Start by building trivial applications that perform simple math calculations (e.g. addition, multiplication, identifying unique numbers in a collection, etc.)
- Next, get to know how to process character strings.
- Along the way, introduce yourself to the different types of collections (lists, arrays, dictionaries, sets) and see how and where they're used.
- Then, take a step into LINQ (Language Integrate Query Language) and see how LINQ makes it easy to do the things you did manually when you started working with collections.
- Get to know to read and write files (text files, binary files and compressed files).
- Then, introduce yourself to XML serialization and learn how to store and retrieved structured data from an XML file.
- Next, discover simple data access from a database and introduce yourself to the basics of SQL.
- Dip your toes into the wonderful world of fetching data from the internet and learn how to use the
HttpClient class.
By this time, you'll have enough under your belt to move from a command line app to building one with a GUI. I recommend starting out with Windows Forms - although an older technology, it offers an easy way to learn event driven programming, which is different from sequential user-directed programming.
I guarantee you hours of frustration, punctuated with moments of sheer joy. Feel free to ask questions of the CP community. We're a helpful bunch of guys and gals and will try our best to assist whenever we can.
/ravi
|
|
|
|
|
My first project (Not too long ago) was a utility to organize files on my disk. it was a console application. all it did was create a folder for each Document file type pdf doc txt in my documents folder and then search my hard drive and move the files to the respective folders.
It doesn't have to be a hard project to see if you like doing this kind of stuff.
Hope this gives you a few Idea's.
David
|
|
|
|
|
As a self taught ameture in c#, I have never found a reason to implement a struct instead of a class.
Since I am self taught (No formal education) I would like to know what advantage would be gained by using a struct in lieu of a class? More importantly why when and where would it benefit my programs?
To this point I have created applications for my own use or for my family. simple utilities and a few web applications.
Thanks in advance for any input.
David
|
|
|
|
|
|
That's a lot bigger question that you probably thought - it involves a lot of background before you can make a decision to use one or the other. So, let's have a little (hah - it was quite a lot) background...
Struct and Class have one huge difference: struct is a value type, class is a reference type. What that means is simple to describe, but harder to grasp the significance of.
So let's start by defining one of each:
public class MyClass
{
public int I;
public int J;
}
public struct MyStruct
{
public int I;
public int J;
} The two objects are identical, except that one is a class and one is a struct. Which means that if you declare an instance of each in your code then you get a reference and a value, but the code can look the same:
public void UseClassAndStruct()
{
MyClass mc = new MyClass();
mc.I = 1;
mc.J = 2;
MyStruct ms = new MyStruct();
ms.I = 1;
ms.J = 2;
} Or slightly different:
public void UseClassAndStruct()
{
MyClass mc = new MyClass();
mc.I = 1;
mc.J = 2;
MyStruct ms;
ms.I = 1;
ms.J = 2;
} Because you don't have to use the new keyword with structs. If you do, then the struct constructor is called, if you don't it isn't - simple as that. Unlike a class, the name of the struct is the struct itself, it is not a "pointer" to a instance.
And that's important, because that is the whole point: a struct is the object, and class is a reference to the object.
When you create a class variable:
MyClass mc; That allocates memory on the stack to hold a reference to a MyClass instance in future, it does not create an instance of MyClass, and you will have seen that before when you try to use any property or method of a class and you get a "Object reference not set to an instance of an object" exception and your program crashes. You have to explicitly create an instance of the class by using the new keyword:
mc = new MyClass(); What this does is create a new instance of MyClass on the heap, and assign the reference to it to the variable mc . This is important, because the stack and the heap are different "types" of memory: the heap is a big "lump" or memory which is sorted out by the Garbage collector and all classes, methods and threads share it. The stack on the other hand is specific to a thread, and everything on the stack is discarded when you exit the method - which means that the mc variable is lost, but the data it references is not - if you have copied the reference to a variable outside the method, then you can still access it from the rest of your program.
What happens when you create a struct variable is different: the actual struct is immediately created on the stack and is available directly for the lifetime of the method. But it will be thrown away when the method exits. So you don't need the new unless you want to use a struct constructor to initialise your fields. You've used this a lot - probably without noticing:
int i;
double j;
Point p; All create value types.
So that's it? Not quite. Remember I said that "the name of the struct is the struct itself, it is not a 'pointer' to a instance"? That has a big effect, which again you probably have used a lot, and not really noticed. Think about this:
int i = 3;
int j = i;
i = 4;
Console.WriteLine("{0}:{1}", i, j); What does that produce?
Obviously, it produces a string "4:3" - anything else would make coding very, very difficult!
But...what if we do that with reference types?
MyClass i = new MyClass();
i.I = 3;
MyClass j = i;
i.I = 4;
Console.WriteLine("{0},{1}", i.I, j.I);
This time, it prints "4:4" because i and j are references to the same instance in memory, instead of being separate, self contained value types.
The same thing happens if we use our structs:
MyStruct i = new MyStruct();
i.I = 3;
MyStruct j = i;
i.I = 4;
Console.WriteLine("{0},{1}", i.I, j.I); This time, we get "4:3" again.
When you assign a reference type variable to another reference type variable, it copies the reference, not the object. When you assign a value type variable to another value type, it copies the content of the object, not the reference to the object.
So when you call a method with a reference type, a copy of the reference is passed, and any changes you make affect the one and only object.
If you call it with a value type such as a struct, a copy of the value is passed, and any changes you make will not be reflected back:
public void ClassMod(MyClass mc)
{
mc.I += 100;
Console.WriteLine(mc.I);
}
public void StructMod(MyStruct ms)
{
ms.I += 100;
Console.WriteLine(ms.I);
}
MyClass mc = new MyClass();
mc.I = 3;
ClassMod(mc);
MyStruct ms = new MyStruct();
ms.I = 3;
StructMod(ms);
Console.WriteLine("{0},{1}", mc.I, ms.I); What do we get?
103
103
103,3 Within the method, everything works the same.
But outside...the changes we made to the struct inside the method affect the copy, not the original.
So what does this do for us in practice? What are the advantages of a struct over a class?
Speed, under certain conditions. they can be a lot slower to use if you aren't careful: if you have a large struct, just calling a method and passing it as a parameter means it must be copied which takes time. But...if they are small (16 bytes or less) and you use a lot of them then they can be a lot faster than a reference type, because the Heap is not involved. Every time you create a reference type instance, the heap must be looked at, a suitable size bit of memory found and allocated and a reference to that returned. This takes time - quite a lot of it! A value type in contrast takes almost no work to allocate: copy the stack pointer, add the size of the struct to it for next time is pretty much all you have to do (and you have to do that for reference types as well so you have somewhere to store the reference to the heap memory!)
There is one bit I missed out here: boxing. This was deliberate, because it's a bit difficult to explain...
What happens when you have a value type and you want to store it with other types in a mixed List (for example)?
List<object> mixedList = new List<object>();
You can add any object perfectly happily:
mixedList.Add("Hello there");
mixedList.Add(Form1); because object is a class that all reference types derive from. But...what happens here:
mixedList.Add(12); Um...12 is an int which is a value type, and so isn't derived from object ...is it?
Yes, it is: all value types derive from a special class called System.ValueType, which derives from object and what happens is that the value is "boxed" - a reference is created on the heap to hold the value type and it is copied there, and the reference to the boxed value is added to the list. When you cast it back to the original struct it is "unboxed" and you have a value type again. This is not a fast process and is one of the reasons you don't use structs for everything!
So, to copy from MSDN[^]:
"CONSIDER defining a struct instead of a class if instances of the type are small and commonly short-lived or are commonly embedded in other objects.
AVOID defining a struct unless the type has all of the following characteristics:
It logically represents a single value, similar to primitive types (int, double, etc.).
It has an instance size under 16 bytes.
It is immutable.
It will not have to be boxed frequently."
The immutable bit is not enforced - it is just a recommendation, otherwise integers, doubles, and so forth wouldn't work!
But...it's a very good idea to make structs immutable: it causes a lot less confusion.
The Point struct does it by making the X and Y Setters private, so that it is obvious that all Points are different instances and that you don't move the original when you change a copy.
Phew! I need a coffee!
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952)
Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
|
|
|
|
|
+5! You could easily copy & paste that into a new Tip/Trick (or even article)
|
|
|
|
|
Pretty good, but Griff, you know ints etc are immutable, right? You can't exactly change the value of 3..
|
|
|
|
|
I've worked with dialects of FORTRAN where you can...
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952)
Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
|
|
|
|
|
They are and they aren't, but that's kinda the advanced school: who needs to know that
i = i + 1; creates a new integer instance and loads a copy into the original location?
Particularly when it doesn't - If you have a look at the IL it fetches the value, increments it, and stores the new value back - no new instance is explicitly created except in the sense that the load removes the early version instance from the stack and then iteh new value is put back in the same place:
.line 14,14 : 13,25 'int i = 777;'
IL_0001: ldc.i4 0x309
IL_0006: stloc.0
.line 15,15 : 13,23 'i = 1 + 1;'
IL_0007: ldloc.0
IL_0008: ldc.i4.1
IL_0009: add
IL_000a: stloc.0
But it does indeed behave as if they were, specifically to prevent constant values being modified by our code!
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952)
Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
|
|
|
|
|
I disagree with this analysis on many levels.
Firstly, immutability is about semantics, not implementation, so showing some IL or even assembly doesn't show anything.
Secondly, the semantics of the "add" IL instruction are "pop two values, add them, push result". So if you want to treat stack slots as instances (and I disagree with that as well), the old ones are gone and you have a new one.
Thirdly, extending this sort of analysis to assembly gives absurd conclusions. For example, what happens in "add eax, 1"? Obviously one is added to "eax", but that doesn't mean that if "eax" had the value 0 first that you've just "changed the value of the 0-instance".
|
|
|
|
|
I know what you mean, but...
That's not the way I see immutable: I see it as "can't be changed" which is applicable to the constant values 1, 2, 3, etc., but not to the variables which are initialised to the constant value and operated on from there. I would agree that 1 is immutable - to do otherwise induces madness - but I'm not convinced that variables containing what can also be considered as a constant are immutable. If the physical location is the same, but the content has changed and nothing else, then my feeling is that it has changed and is thus not immutable.
Certainly in the case of string the immutability is obvious (if hidden behind the scenes): once a string is created, it can never be changed again, just copied or deleted - even if the scene changers disguise this and appear to allow it!
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952)
Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
|
|
|
|
|
I completely agree that a variable of type int is not immutable, but that doesn't really matter since immutability is a property of a type, not of a variable of that type (obviously a variable is, well, variable).
Funny that you should mention strings, they're less immutable than integers, but most people agree that they should be called immutable anyway because the only way to mutate an instance is by cheating (reflection or unsafe). You can't even mutate an instance of an int by cheating.
modified 17-Feb-14 6:30am.
|
|
|
|
|
OriginalGriff wrote: That's not the way I see immutable:
Similar problem exists with 'const' in C++.
In terms of semantics for that I differentiate between 'binary constant' and 'logical constant'.
The first means that the structure of the memory for the data will not change.
The second means that for a user of the entity that it will not change. And example of this is a class that represents application properties that cannot be changed by the application itself but which use a memory cache which might be refreshed for various reasons.
|
|
|
|
|
+5 very useful response !
I find it hard to conceptualize structs as "immutable" when I can do stuff like that shown in the code for 'TestStruct below; and, so do other people:
public struct MyStruct
{
public string Name;
public int X;
public int Y;
public int Z { set; get; }
public MyStruct(int z) : this() { Z = z; }
}
public void increment(ref MyStruct aStruct, int inc )
{
aStruct.X += inc;
}
private void WriteSValues(params MyStruct[] theStructs)
{
foreach (var theStruct in theStructs)
{
Console.WriteLine("Name: {0} X: {1} Y: {2} X: {3}",
theStruct.Name,
theStruct.X,
theStruct.Y,
theStruct.Z);
}
Console.WriteLine();
}
private void TestStruct()
{
MyStruct ms1 = new MyStruct(300) {Name = "ms1", X = 100, Y = 200};
ms1.X += -300;
MyStruct ms2 = ms1;
ms2.Name = "ms2";
WriteSValues(ms1, ms2);
increment(ref ms1, 200);
WriteSValues(ms1, ms2);
ms1.X += 500;
WriteSValues(ms1, ms2);
MyStruct ms3 = ms2;
ms3.Name = "ms3";
WriteSValues(ms1, ms2, ms3);
increment(ref ms3, 1000);
WriteSValues(ms1, ms2, ms3);
} The above is a diagnostic quiz I wrote for some supposedly "intermediate" C# students (not students of mine): their task was to describe the values for each struct created, at each line of the code, and explain why the values were what they were. About half understood that assigning an instance of a struct to another instance of a struct of the same Type created a copy, but they all were quite confused by the other bits in the code. The quiz was administered by their regular teacher, so I don't think the results exhibit bias due to shyness in the presence of someone from outside their social process.
“But I don't want to go among mad people,” Alice remarked.
“Oh, you can't help that,” said the Cat: “we're all mad here. I'm mad. You're mad.”
“How do you know I'm mad?” said Alice.
“You must be," said the Cat, or you wouldn't have come here.” Lewis Carroll
|
|
|
|
|
Hi David,
I'm writing up my response to your question as a simple article, and with your permission, I'd like to include an extract from your question in that:
David C# Hobbyist. wrote: As a self taught ameture in c#, I have never found a reason to implement a struct instead of a class.
Since I am self taught (No formal education) I would like to know what advantage would be gained by using a struct in lieu of a class? More importantly why when and where would it benefit my programs?
If you agree, I can tidy up the spelling, and either credit you or leave it anonymous - whichever you prefer - but I think it would help the "flow" of the article to explain why it exists.
If you don't agree for whatever reason (or none!), that's no problem either, I just won't reference you and will come up with a different introduction!
Please do reply whichever way you decide - but if you don't I will of course assume you are refusing permission and not reference you in any way.
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952)
Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
|
|
|
|
|
Absolutely and thanks for the long winded reply. I am just now reading it as well as the info in the links posted by @Peter-Leow.
I have some studying to do.
Thank You for the help in understanding the difference.
[Edit] Please inform me when it is posted I would like to read it.[/Edit]
David
modified 17-Feb-14 17:20pm.
|
|
|
|
|
Thank you -and you're welcome!
I certainly will.
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952)
Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
|
|
|
|
|
It's published: Using struct and class - what's that all about?[^]
It's much the same as the answer, but with some added material to cover embedded structs, and arrays.
Thank you again!
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952)
Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
|
|
|
|
|
Thanks, I read it this morning. I found a couple of times in my code where a struct would have been a better choice. But "If it aint broke".
David
|
|
|
|
|
..."don't fix it"
Wise decision!
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952)
Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
|
|
|
|
|
I have the following task to design an interface not the classes for an authorization class it should account for the following conditions can people recommend changes to the class or how could i better it according to the following rules
Administrative users of the application manage users and permissions. Managers can view and edit information about employees reporting to them. Employees can view their information but do not have access to other employees' information. Employees in the Human Resources department have access to information about all employees, but don't have access to the information of others in HR.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NaviNetHrContext.Context
{
public interface IAuthorisation
{
IEnumerable<Sallary> GetSallaryRecordById(int employeeId);
IEnumerable<Vacation> GetVacationRecordsById(int employeeId);
IEnumerable<Employee> GetEmployeesByManagerId(int employeeId);
IEnumerable<Employee> GetEmployees(int employeeId);
Boolean IsInRole(string employeeId, int groupRole);
Boolean DeleteRole(string employeeId);
Boolean EditRole(string employeeId, Boolean deleteRights, Boolean editRights, Boolean viewRights, int groupRole);
string CreateUserInRole(string employeeId, Boolean deleteRights, Boolean editRights, Boolean viewRights, int groupRole);
string CreateRole(Boolean deleteRights, Boolean editRights, Boolean viewRights, int groupRole);
}
}
|
|
|
|
|
Authorization has nothing to do with one's salary. I agree that one has to check whether on is authorized before giving out that info, but I wouldn't expect it to be part of the authorization interface; one would simply check if someone is in the role of HR. Same goes for vacation
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Hello all. I recently finished a homework assignment which involves creating a fully functioning calculator in c# which can also take the integers which are being displayed and convert them to binary, and then vice versa via radio controls.
My convert2decimal function isn't working correctly though. Say I input 999 into the window, it will output the correct binary value of
1111100111 But then when i click the radio button to convert that value from the text box back to decimal, instead if 999 i get 927.
Also yes i am aware that i could simply declare a variable to hold the original decimal value, but i doubt my instructor would look upon that fondly.
Here is the offending code snippet
private void convert2Decimal(string value)
{
String binaryDigits = value;
char [] Binary = binaryDigits.ToCharArray();
long dValue = 0;
int superscript = display.Text.Length - 1;
int bValue = 1;
if (superscript > 0)
{
foreach (char element in Binary )
{
Console.WriteLine((long)char.GetNumericValue(element));
if ((long)char.GetNumericValue(element) == 1)
{
Console.WriteLine( dValue += ((long)char.GetNumericValue(element)) * bValue);
}bValue *= 2;
}
display.Text =""+ dValue;
}
Even more strange behavior is that, when converting the wrong value of 927 back to binary via the binary conversion, i get the correct binary value of 927, but when i finally click the decimal conversion, it shows a value of 999...!
|
|
|
|
|
This is a guess because I haven't tried your code, but I think the problem is that when you convert binaryDigits to a char array, the resulting array is in the wrong order.
In other words, the array is left to right, but when you're increasing bValue by saying bValue *= 2 , you're going from right to left.
To fix it, you either need to reverse the char array, OR loop through the char array in reverse order.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|