Basic Question - Array in Struct
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.
Code:
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
Re: Basic Question - Array in Struct
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 :)
Code:
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];
}
Re: Basic Question - Array in Struct
Why not just have strings ? You can't do much with char [] arrays - if somethings a string it should be a System.String
Code:
public struct TInputQuery
{
string szZipCode;
string szZip4 Code;
string szDpCode;
string szRoute;
};
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.
Code:
public class TInputQuery
{
private string _zipCode;
private string _zip4Code;
private string _dpCode;
private string _route;
TInputQuery(string zipCode, string zip4Code, string dpCode, string route)
{
_zipCode = zipCode;
_zip4Code = zip4Code;
_dpCode = dpCode;
_route = 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.
Re: Basic Question - Array in Struct
Quote:
Originally Posted by darwen
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.
Re: Basic Question - Array in Struct
Sorry RaleTheBlade...
However
Quote:
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.
Re: Basic Question - Array in Struct
There are other differences as well.
Properties allow validation and data binding whereas public fields do not.
Re: Basic Question - Array in Struct
Quote:
Originally Posted by Arjay
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:
Re: Basic Question - Array in Struct
I don't view them as a nice to have, I view them as a necessity (at least in WPF anyway).
Re: Basic Question - Array in Struct
Quote:
Originally Posted by darwen
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.
Quote:
Originally Posted by darwen
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.
Quote:
Originally Posted by darwen
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
Re: Basic Question - Array in Struct
Quote:
Originally Posted by kenrus
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.
Quote:
Originally Posted by kenrus
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.
Re: Basic Question - Array in Struct
Quote:
Originally Posted by Arjay
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.
Re: Basic Question - Array in Struct
I usually use UpperCamelCase for class, struct, and enum definitions:
Code:
public class MyClass
internal struct Person
public struct Employee
public enum EmployeeType
Camel casing for variable identifiers
Code:
string name;
string firstName;
string lastName;
string phoneNumberForManager;
char initial;
And for methods and properties, UpperCamelCase
Code:
public override void ToString();
protected string GetName();
Re: Basic Question - Array in Struct
Microsoft's coding guidelines are here.
Darwen.
Re: Basic Question - Array in Struct
About the only deviation from the Microsoft styles is that I prefer to prefix private fields with an underscore '_' character.
e.g.
Code:
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
Code:
public void Method( int count )
{
this.count = count;
}
Not annoying
Code:
public void Method( int count )
{
_count = count;
}
Re: Basic Question - Array in Struct
Quote:
Originally Posted by kenrus
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'.
Re: Basic Question - Array in Struct
Quote:
Originally Posted by Mutant_Fruit
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.
Re: Basic Question - Array in Struct
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.
Re: Basic Question - Array in Struct
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.
Re: Basic Question - Array in Struct
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.
Code:
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.
Code:
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.