I am primarily a C++ programmer. However, I have recently been assigned some programming tasks that require the use of C#.
Currently I am writing code to open and query a proprietary database. There are 4 fields of input data required from the user and I will be returning 2 fields.
In C++ I would provide the user with 2 structures. Here is my C# attempt.
public struct TInputQuery
{
char[] szZipCode = new char[6];
char[] szZip4 Code = new char[5];
char[] szDpCode = new char[3];
char[] szRoute = new char[6];
}
public struct TAnswer
{
char szFlag;
char szSequence = new char[5];
}
Ofcourse, I can not do that in C#. I get plenty of errors about not having initializers in structs.
So, my question is - How do I provide my users with a custom data type for submitting the input and providing the output?
On a side note: Have many C++ programmers found the learning curve for C# to be particularly difficult?
I have had a few programmers insinuate that it was quite easy. However, I find it to be the opposite. The similarities in the syntax make it seem familiar and comfortable, but the way it works and handles data under the covers is quite different and takes a while to really understand and then to reflect that in the way you code.
Kendall
RaleTheBlade
September 18th, 2008, 04:26 PM
Can you use a class instead of a struct? Because in a class in C#, you CAN have field initializers, unlike C++.
Funny how that gets flip-flopped :)
public class TInputQuery
{
char[] szZipCode = new char[6];
char[] szZip4Code = new char[5];
char[] szDpCode = new char[3];
char[] szRoute = new char[6];
}
public class TAnswer
{
char szFlag;
char[] szSequence = new char[5];
}
darwen
September 18th, 2008, 05:06 PM
Why not just have strings ? You can't do much with char [] arrays - if somethings a string it should be a System.String
But, as it is in C++, this is breaking encapsulation so you should really have properties (and you should get out of the habit of using hungarian notation too) :
Also kenrus is right, it should be a class. Unlike C++ classes and structs are different beasts in .NET. A class is a reference type and so gets passed by reference. A struct is a value type and gets passed by value.
public class TInputQuery
{
private string _zipCode;
private string _zip4Code;
private string _dpCode;
private string _route;
// properties - I've only got 'get' methods here
public string ZipCode
{
get { return _zipCode; }
}
public string Zip4Code
{
get { return _zip4Code; }
}
public string DpCode
{
get { return _dpCode; }
}
public string Route
{
get { return _route; }
}
};
Darwen.
RaleTheBlade
September 18th, 2008, 05:12 PM
Also kenrus is right, it should be a class. Unlike C++ classes and structs are different beasts in .NET. A class is a reference type and so gets passed by reference. A struct is a value type and gets passed by value.
Dont you mean RaleTheBlade is right? hahaha, I think you got confused. But yes, properties allow for more secure code access by allowing you to define readonly properties and protected properties and the like. The get {} set {} clauses are a very nice touch, even if they are syntactical sugar :)
But as Darwin said, strings in C# are MUCH more friendly than they are in C++, so the need for character arrays has been all but eliminated. You would really tax yourself by using char arrays versus a string in C# because strings in C# are so much more useful.
darwen
September 18th, 2008, 05:20 PM
Sorry RaleTheBlade...
However
even if they are syntactical sugar
That's not strictly true. Encapsulation is one of the cornerstones of object orientation and shouldn't be taken lightly. I've been very VERY thankful of not having public member variables when maintaining a piece of software so many times I've lost count.
The above is a classic case. If it was required that the string lengths were enforced then you could easily put code into the constructor and set methods of the properties to do this.
If however public member variables had been used and this constraint needed to be added 6 months after this class had originally been implemented the workload could potentially be huge : you'd have to implement this constraint everywhere the member variables were being accessed.
Darwen.
Arjay
September 18th, 2008, 05:42 PM
There are other differences as well.
Properties allow validation and data binding whereas public fields do not.
RaleTheBlade
September 18th, 2008, 06:07 PM
There are other differences as well.
Properties allow validation and data binding whereas public fields do not.
Oh I know :) However, if I were to list them all I would have a very long post indeed! Lets just say they're very nice to have, and allow much finer grain control over your objects :thumb:
Arjay
September 18th, 2008, 07:15 PM
I don't view them as a nice to have, I view them as a necessity (at least in WPF anyway).
kenrus
September 18th, 2008, 11:35 PM
Why not just have strings ? You can't do much with char [] arrays - if somethings a string it should be a System.String
I have tried to avoid strings in C# as much as possible. It may be due to a misunderstanding on my part, but I believe C# strings are immutable. So, anytime I do anything to modify the string I am actually creating a new string and deleting the old string.
However, in this case I will not be doing anything other than reading the input, so a string is probably the best alternative.
But, as it is in C++, this is breaking encapsulation so you should really have properties (and you should get out of the habit of using hungarian notation too) :
I know hungarian notation is out of style with a lot of people (Microsoft being one), but that doesn't negate it's benefits and it has proven to be very useful over the years.
Also kenrus is right, it should be a class. Unlike C++ classes and structs are different beasts in .NET. A class is a reference type and so gets passed by reference. A struct is a value type and gets passed by value.
The user passing the input by reference is preferred, however I would need to pass the output back to the caller by value. I don't want them having a reference to something I am using and something that I will modify on subsequent calls. Can I pass a class by value?
I appreciate all of the help from everyone. Thanks!
Kendall
Arjay
September 18th, 2008, 11:41 PM
I know hungarian notation is out of style with a lot of people (Microsoft being one), but that doesn't negate it's benefits and it has proven to be very useful over the years.It was useful, but it's dated for C#. To avoid confusion, 'when in Rome...' and follow C# naming conventions. It takes a bit getting used to, but you end up writing consistent C# that follows convention.
Can I pass a class by value?In C#, classes are always passed by reference. Structs are passed by value by default but can be passed by reference using the ref keyword.
kenrus
September 18th, 2008, 11:58 PM
It was useful, but it's dated for C#. To avoid confusion, 'when in Rome...' and follow C# naming conventions. It takes a bit getting used to, but you end up writing consistent C# that follows convention.
In C#, classes are always passed by reference. Structs are passed by value by default but can be passed by reference using the ref keyword.
What is the common naming convention for C#?
I only have 1 co-worker that codes in C# and he readily admits to not using any naming convention. Just whatever pops in to his mind at the time he is coding. So, my C# code is the only C# code that I have seen that actually uses a naming convention. (So, I am in Rome, but among immigrants)
I did google a little, but there did not seem to be a consistent style between the search results that came up.
RaleTheBlade
September 19th, 2008, 12:39 AM
I usually use UpperCamelCase for class, struct, and enum definitions:
public class MyClass
internal struct Person
public struct Employee
public enum EmployeeType
public override void ToString();
protected string GetName();
darwen
September 19th, 2008, 03:32 PM
Microsoft's coding guidelines are here ('http://msdn.microsoft.com/en-us/library/czefa0ke.aspx').
Darwen.
Arjay
September 19th, 2008, 04:47 PM
About the only deviation from the Microsoft styles is that I prefer to prefix private fields with an underscore '_' character.
e.g.
private int _count = 0;
That way I can distinguish between a class scoped field and a local variable.
Plus I don't have to use the annoying 'this.' syntax during field assignments.
Annoying
public void Method( int count )
{
this.count = count;
}
Not annoying
public void Method( int count )
{
_count = count;
}
Mutant_Fruit
September 19th, 2008, 05:15 PM
I have tried to avoid strings in C# as much as possible. It may be due to a misunderstanding on my part, but I believe C# strings are immutable. So, anytime I do anything to modify the string I am actually creating a new string and deleting the old string.
That's a terrible reason to avoid strings ;) C# is a managed language, use strings all you want. Combine them, split them, do whatever you like. Otherwise you'll just end up having to write buggy code which duplicates all the string functions but operates on char[] and has 1/10th of the performance of the built in string class.
Of course, if you're doing a *lot* of string mangling, them a StringBuilder might be what you need, but i definitely would not recommend you use char[] as a 'string'.
kenrus
September 19th, 2008, 07:13 PM
That's a terrible reason to avoid strings ;) C# is a managed language, use strings all you want. Combine them, split them, do whatever you like. Otherwise you'll just end up having to write buggy code which duplicates all the string functions but operates on char[] and has 1/10th of the performance of the built in string class.
Of course, if you're doing a *lot* of string mangling, them a StringBuilder might be what you need, but i definitely would not recommend you use char[] as a 'string'.
I am 100% positive that the designers of C# are much, much, much smarter than I am.
However, having said that, it seems to me that it is the opposite. That is a terrible way to design what is probably the most commonly used C# string class in the first place.
I am not saying there is not a use for an immutable string class. However, I am saying programmers moving to C# (especially C++ programmers) will not expect the "string" class to be immutable. I would imagine that most, like myself, will assume that it is similar to std::string and use it as such. That would be a big mistake and one that I made. (I did have to write code to parse and manipulate free form input - hundreds of time per input and millions of input per hour. string seemed the obvious choice until I learned otherwise)
I did see stringbuilder, but I was disappointed to find that it's functionality was severely limited when compared to the functionality of string.
This is one reason I asked the question if it was a difficult learning curve for C++ programmers to move to C#. I have been led to believe that it would be simple. (Not the fault of C# just the people giving advice). However, it seems to me that the learning curve is going to be very difficult due to the fact that it seems similar given the syntax, but under the covers it is working very differently.
Arjay
September 19th, 2008, 09:29 PM
Kenrus, in practice you'll find the string class works quite well.
There is definitely no reason to use a char array over the string or stringbuilder classes.
Mutant_Fruit
September 20th, 2008, 04:03 AM
That's what the garbage collector is for. It'll clean up those extra strings and free their memory once they are unused. I'd still advocate the use of strings in your case. Of course, if you understand that a string is immutable, you can be smarter about how you use strings. Rather than calling ToLower on two strings then comparing them for equality, you'd just use:
strA.Equals (strB, StringComparison.IgnoreCase);
I still could not recommend that you use char[]. I'd still call that a really bad move when you're processing a lot of input.
darwen
September 20th, 2008, 02:01 PM
There's a very good reason why strings are immutable in C#.
In C++ std::string can be passed by reference or by value.
You know by the syntax whether a string is passed by reference or value.
When you have a std::vector<std::string> the strings are copied into the vector. Changing the source string doesn't change the string in the vector i.e.
std::string example = "hello";
std::vector<std::string> vec;
vec.push_back(example);
example = "there";
// vec[0] = "hello"
You don't have the choice in C# - you either have pass by reference with classes or pass by value with structs.
So since string is a class (if string was a struct and always was passed by value then this would have a terrible impact on performance of any C# application) then it is always passed by reference. If string was not immutable this would cause all sorts of problems in C# applications e.g.
string example = "hello";
List<string> listExample = new List<string>();
listExample.Add(example);
// any changes to string instance example would change the value in the list if string wasn't immutable
In the 5 years I've been coding in C# I've yet to have a performance problem with string. In fact I've had more performance problems with std::string (and people passing that by value, using large numbers of strings in std::vector<std::string> rather than using a std::list<std::string>) than I've had with C# string.
Darwen.
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.