I have a class with a string property that's actually several strings joined with a separator.
I'm wondering if it is good form to have a proxy property like this:
public string ActualProperty
{
get { return actualProperty; }
set { actualProperty = value; }
}
public string[] IndividualStrings
{
get { return ActualProperty.Split(.....); }
set
{
// join strings from array in propval .... ;
ActualProperty = propval;
}
}
Is there any risks I have overlooked?
Linking two settable properties together is bad juju in my opinion. Switch to using explicit get / set methods instead of a property if this is really what you want. Code which has non-obvious side-effects will almost always bite you later on. Keep things simple and straightforward as much as possible.
Also, if you have a property which is a formatted string containing sub-strings, it looks like what you really want is a separate struct / class for that property rather than misusing a primitive type.
Seems that the array is the real data, and the single-string stuff is a convenience. That's fine, but I'd say look out for things like serialization and memberwise cloning, which will get and set both writeable properties.
I think I would;
keep the array as a property
provide a GetJoinedString(string seperator) method.
provide a SetStrings(string joined, string seperator) or Parse(string joined, string seperator) method.
Realistically, the seperator in the strings isn't really part of the class, but an ephemeral detail. Make references to it explicit, so that, say, a CSV application can pass a comma, where a tab-delimited app could pass a tab. It'll make your app easier to maintain. Also, it removes that nasty problem of having two getters and setters for the same actual data.
Define "good". It shouldn't break (unless you failed to properly guarantee that the delimiter(s) passed to Split() are never allowed in the individual strings themselves), but if IndividualStrings is accessed more frequently than ActualProperty you'll end up parsing actualProperty far more often than you should. Of course, if the reverse is true, then you're doing well... and if both are called so often that any unnecessary parsing or concatenation is unacceptable, then just store both and re-parse when the value changes.
Properties are intended to be very simple members of a class; getting or setting the value of a property should be considered a trivial operation without significant side-effects.
If setting a property causes public values of the class other than the assigned property to change, this is more significant than a basic assignment and is probably no longer a good fit for the property.
A "complex" property is dangerous, because it breaks from the expectations of callers. Properties are interpreted as fields (with side-effects), but as fields you expect to be able to assign a value and then later retrieve that value. In this way, a caller should expect to be able to assign to multiple properties and retrieve their values again later.
In your example, I can't assign a value to both properties and retrieve them; one value will affect the other. This breaks a fundamental expectation of the property. If you create a method to assign values to both properties at the same time and make both properties read-only, it becomes much easier to understand where the values are set.
Additionally, as an aside:
It's generally considered bad practise to return a temporary array from a property. Arrays may be immutable, but their contents are not. This implies you can change a value within the array which will persist with the object.
For example:
YourClass i = new YourClass();
i.IndividualStrings[0] = "Hello temporary array!";
This code looks like it's changing a value in the IndividualStrings property, but actually the array is created by the property and is not assigned anywhere, so the array and the change will fall out of scope immediately.
public string ActualProperty { get; set; }
public string[] GetIndividualStrings()
{
return ActualProperty.Split(.....);
}
public void SetFromIndividualStrings(string[] values)
{
// join strings from array .... ;
}
Well I'd say your "set" is high risk, what if somebody didn't know they had to pass an already joined sequence of values or your example above was maybe missing that. What if the string already contained the separator - you'd break.
I'm sure performance isn't great depending on how often this property is used.
I'm not sure what the benefit of this design would be. I think the split would be better served in an extension method.
At a minimum, I'd remove the setter on the IndividualStrings property, or move it into two methods: string[] SplitActualProperty() and void MergeToActualProperty(string[] parts).
Related
I learned that in C# there is this thing called autoproperty, which ist normally automatically generated by the compiler if i declared a variable like:
public List myList { get; set; }
public class MyClass
{
private List<int> myList;
public List<int> MyList
{
get
{
return this.myList;
}
set
{
this.myList = value;
}
}
}
It lets me access the variable like:
List<int> a = myInstance.MyList;
So it works like a function, but is called like a normal object.
But what is really assigned on a ? Is there assigned a "deep link" on the object myList or is there assigned something like a "functor" on the get function?
What i mean is, if i work with a, will the get function be called again everytime?
The reason why I'm asking: If I'm using this in a multithreaded case with some locking of the object in the get and set function I don't want to bypass the locking. So if I first assign myList on a and then work with it, it won't be locked anymore? Am I right?
But what is really assigned on a?
The type of a is List<int>, and lists are reference types, so the variable contains a reference to a list. C# doesn't lie to you. The type of the variable is the type of the variable.
it works like a function, but is called like a normal object.
This sentence makes no sense and it indicates to me that you have some misunderstanding of how C# works. "Objects" are not things that are "called" unless they are delegates. It sounds like you are confusing properties, variables, objects and delegates. Learn what those things are. It will be difficult to be successful in C# programming if you do not know the correct names of all the parts.
I think what you intended to say is that a property is a member which is accessed like a field, but reads and writes of the property are implemented as calls to member access methods.
What i mean is, if i work with a, will the get function be called again everytime?
You could answer this question for yourself by trying it:
myInstance.MyList = new List<int> { 10, 20, 30 };
List<int> a = myInstance.MyList;
myInstance.MyList = new List<int> { 100, 200, 300 };
Console.WriteLine(a[0]);
If a fetches the property again, it should be 100. If it does not, it should be 10. Make a prediction about what will happen, and then try it and see if you were right.
If I'm using this in a multithreaded case with some locking of the object in the get and set function I don't want to bypass the locking. So if I first assign MyList to a and then work with it, it won't be locked anymore? Am I right?
Yes. I will take this opportunity to point out that it is an extremely poor programming practice to make a public interface that exposes an object that must be locked. Better options are:
Do not write multithreaded programs. It's really hard to get them right.
If you must, do not write multithreaded programs that share memory across threads.
If you must share memory, use threadsafe collections, always.
Properties are just better named List<int> getValue() and setValue(List<int> value) function pair. There are some minor properties:
they appear on reflection
they can be declared in interfaces/abstract classes
they are used like a field, except in rare cases (out and ref parameters)
But overall that is all there is to them.
Autoimplement proeprties are the same as manual ones, except the backing field has no name (you could use in your code), so there is 0 chance to accidentally access the backingfield.
One of the most important rules with Properties is to not write the Backing fields, especially in class code. And just lower casing it does not work. I lost track how often I coded so fast, a Upper case did not stick. For reliable naming, append a underscore to the backing field. _MyList and MyList are pretty hard to mix up. MyList and myList are easy to mix up.
When you assign myInstance.MyList to a, you call the MyList get Property which copies the reference myList into a. If you then work with a you will be working directly with the List referred to by the private myList. You will only go via the get Property if you actually call it.
This is basically losing the private nature of myList. If you want to force the caller to go via functions which do things like locking then you will have to write functions for the operations you want to allow, like adding to the List, without exposing the actual List to the caller.
There's no need to do this in C# for thread safe operations - you should use the Concurrent Collections which implement these operations for free.
int and object have a parameterless constructor. Why not string?
Because there is no point in doing that.
string is immutable. Creating an empty string is just useless.
MSDN:
Strings are immutable--the contents of a string object cannot be changed after the object is created, although the syntax makes it appear as if you can do this.
As Jonathan Lonowski pointed out, we have string.Empty for that.
Update:
To provide more information for you.
You don't have an empty Constructor with a string, however you do have String.Empty. The reason is because a string is an immutable object every instance of a string you modify is actually creating a new string in memory.
For instance: string name = ""; though it is an empty string it will still hold around twenty bytes. Where the string.Empty will only hold around four or eight bytes. So though they mean the same thing, one is more efficient than the other.
However I believe you want an empty Constructor to do manipulation that may be more commonly handled by the StringBuilder. Some really nice usage between the two can be found here (Determine performance hit / usage).
Some additional information on the string can be found here. They are immutable thus the contents cannot be changed afterwards.
Example:
string first = "Greg "; // Creates string "first" in memory.
string last = "Arrigotti "; // Creates string "last" in memory.
string name = first + last; // Creates string "name" in memory.
As you edit one of these, it is simply creating a whole new string in memory. If you are looking at a way to potentially handler user data in a field where no middle name exist for instance, the empty string may contain valid usage.
Hopefully these point you in the proper direction.
Strings are immutable, therefore new String() has no purpose. What would you do with it?
As said before, strings are immutable and therefore if you manipulate a string you actually create a new one every time.
Example:
string s = "str"; // str was created in the memory.
s += "2"; // str2 was created in the memory.
Use StringBuilder when you want to manipulate string(that's why you wanted an empty ctor, right?)
Why indeed?
It would be completely logical and sensical to provide a parameterless constructor for the string type, yet it doesn't have one.
The reason is because the designers of that type thought it would be a much better idea to have string.Empty.
There could be a logical reason for having the ability to construct multiple empty strings that are different instances. I fail to see one off the top of my head, but that doesn't mean someone else can't see one.
There are some technical reasons behind why limiting the usage to string.Empty might be a good idea. First, all empty strings are considered equal, though not necessarily ReferenceEquals, so having multiple empty strings would seemingly make no sense. The second you say that "I have these two seemingly similar things, yet I've attached a different meaning to each" then perhaps you're trying to solve a problem with the wrong tool.
There's also some upshots of having a predefined string.Empty. Whenever you reference it, you're referencing the same object instance as every other place, and thus you don't have lots of empty (and identical) string objects in memory.
But could it be done? Sure.
So while everybody here has tried to justify that there should be no such constructor, I am saying that there could be such a constructor.
However, someone decided to design the type without one.
Also there is already a defined constant for this: String.Empty
int is a value type, and as such it must have a parameterless constructor. There is no consideration that can be made here.
object has no reason to have anything but a parameterless constructor. There is no data to give it. What parameters would you expect it to take? objects constructed with a parameterless constructor also have a purpose; they are used, for example, as objects to lock on. It is however a class, so it doesn't need to have a public parameterless constructor, however since it has no need for parameters, it's a question of whether you want instance of it to be constructed at all; Microsoft chose to make it concrete, rather than abstract.
string is a class, so it isn't required to have a parameterless constructor. The team building it simply never saw a need to have one. One could sensibly use such a constructor to create an empty string, but they choose to expose string.Empty (as well as an empty string literal) as a way of explicitly creating an empty string. Those options have improved clarity over a parameterless constructor.
Another pretty significant advantage of string.Empty and the empty literal string is that they are capable of re-using the same string instance. Since strings are immutable, the only way to observe the difference between two different references to empty strings is through the use of ReferenceEquals (or a lock on the instance). Because there is virtually never a need to go out of your way to have different references to an empty string, removing the parameterless constructor removes the possibility of an equivalent but poorer performing method of constructing an empty string. In the very unlikely event that it is important to construct a new string instance that is an empty string, an empty char array can be passed to the relevant constructor overload, so removing the parameterless constructor doesn't remove any functionality from the end user; it simply forces you to go out of your way to do something really unusual if you want to do something really unusual, which is the sign of good language design.
Provided that you know that string is immuable, your question can be rephrased as the following:
why on earth can't I initiate a null object??
answer:
Because there is no null object :)
When I am looking at my code and I am writing things like..
if (role == "Customer")
{
bCustomer = true;
}
else if (role == "Branch")
{
bIsBranch = true;
}
Or
foreach(DataRow as row in myDataSet.Tables[0].Rows)
{
row["someField"]=somefield.Tostring()
}
Are you guys doing this? When is this ok to do and when shouldn't you be doing this? What if any would be a better approach to write this if any?
Thanks For the Comments: I guess I should add what if (for this example purposes) I am only using this role comparison once? Is it still a better idea to make a whole new class? Also should I have 1 class called "constants" are multiple classes that that hold specific constants, like "roles" class for example?
No. Don't use "magic strings". Instead create a static class with constants, or an enum if you can.
For example:
public static class Roles
{
public const string Customer = "Customer";
public const string Branch = "Branch";
}
Usage:
if (role == Roles.Customer)
{
}
else if (role == Roles.Branch)
{
}
Here's a good discussion on various solutions.
It is always better to declare the hard coded strings separately as constants rather then declaring a new string every time. It keeps code clean and reduce errors which are caused by typing mistakes.
Regarding should or shouldn't be done totally depends on scenario.
I would make a Roles static class:
public sealed class Roles
{
public const string BRANCH = "Branch";
public const string CUSTOMER = "Customer";
public static bool IsCustomer(string role)
{
return role == CUSTOMER;
}
}
Then in your code:
bCustomer = Roles.IsCustomer(role);
Alternatively, this requires a little more setup but the RoleProvder (depending on Web or Not) provides a lot of good methods.
I believe a better approach is to use application settings which means you won't ever need to recompile your code if "Customer" or "Branch" values change. Magic values are obviously bad, and this would be a good first step/option getting away from them. Additionally it keeps your values in one place, and I also believe you can reload the settings at runtime without restarting the application (although I haven't tried this myself).
E.g.:
if (role == Properties.Settings.Default.CustomerRole)
{
bCustomer = true;
}
else if (role == Properties.Settings.Default.BranchRole)
{
bIsBranch = true;
}
Eliminate the use of magic strings in your C# code by using the nameof expression
Using the nameof expression, you can retrieve the literal casing of types, classes, structs, properties, methods, functions, fields, arguments, parameters, locals, and more to the casing they appear in the code at compile time. This will not eliminate or solve all your "magic string" problems, but its a good start and worth discussing.
For example, getting the literal casing of an enum value.
public enum ExportType
{
CSV,
Excel
}
nameof Usage
nameof(ExportType.CSV); // "CSV"
nameof(ExportType.Excel); // "Excel"
nameof(ExportType); // "ExportType"
Returns the literal casing of the expression in the argument.
No more "magic strings"
If you are referring the code names of specific type names, classes, etc., strongly consider replacing those fragile magic strings with nameof. You will not fear changing the name of a internal type, or property without fear of breaking the code. Using renaming features IDEs like Visual Studio has will rename all references anywhere in your code base referring to that expression.
Type Safety
This operation is done at compile time. Ultimately, if you are relying on the names of types, classes, etc. in your code, you can introduce compile time type safety via nameof expression into your code when referring to them.
Performance
You can eliminate a lot of reflection in your code as well that gets the names of these objects or types.
Caveats
Getting the name of generic types
nameof(T); // "T"
nameof(TEntity); // "TEntity"
In these cases, you must continue to use reflection to get the name of the type at runtime. typeof(T).Name.
For example:
var enumValuesNames = typeof(ExportType).GetProperties().Select(p => p.Name).ToArray();
Polimorphism is one thing, but using hardcoded strings along your code is not good at all. It's way better to define a variable holding the string and use this variable along the code. This case if you need to change something (believe me you will), you can just change the value of this variable and it's done (less errors too!)
For the sake of maintainability, you should formalize string comparators when possible, either as named constants or as an enumeration. The benefit for the programmer is that you can localize changes. Even when using a refactoring tool, finding all the places a string is used can be tedious and error prone. You may only have one place where you're doing this comparison today, but you or a future maintainer may extend this to other parts of the code. Also, the class itself may grow and need to be broken apart. These things tend to creep up on a program over time.
I would simply declare these strings as constants close to where they're used, but together. Don't bother with a new abstraction like Roles until you know you need it. If the number of roles you need to compare grows, or is needed outside of this class, then you can create a Roles enum or Roles class, depending on the complexity of the comparison.
Also, by using constants, you signal the intended use to the compiler, so you get some minor memory management benefits, which, given your comparison is in a loop, is generally a good practice.
Well, in my opinion it is up to you and it depends on your application design.
I uaully look at it from the positive side- if application works the way it supposed to work, it is all good. IMHO
Lets say I have the following code
public static string GetXMLValue()
{
XDocument settingsFile = XDocument.Load("Settings.xml");
return settingsFile.Element("Settings").Element("GenericValue").Value;
}
It simply reads an XML Settings file and returns the GenericValue value. It can't be any simpler than that. Now my question is, would it provide any benifit (readability, performace, syntactically, maintainablitiy, etc.) to first place the return value in a string variable then return? Or is it best left the way it is?
To be honest, the simplicity of the methods makes it readable even in "one" line:
public static string GetXMLValue()
{
return XDocument
.Load("Settings.xml")
.Element("Settings")
.Element("GenericValue")
.Value;
}
There are a couple situations in which I see value in creating an auxiliary variable:
I want to assert something about it as a precondition (e.g. not empty string; a minimum/maximum length; etc.)
I am having trouble and I want to debug the value more easily.
Even in the absence of these, for such a nontrivial expression, I would create a local variable, to make the function more readable.
would it provide any benifit [...] to
first place the return value in a
string variable then return? Or is it
best left the way it is?
The function is so simple it just does not matter, so don't lose sleep about it. Once the function becomes more complex, you can always rethink this.
If for example you later need to run checks on the value before returning it, or want to log it for auditing reasons, a separate variable will make sense. Until then, leave it as it is.
As an aside:
What I find much more questionable is that you are reading an external resource (file) in a getter method. Invoking operations that can have side effects (such as reading a file) in a getter is bad style IMHO. That way for example every caller of the getter will have to handle IOExceptions from reading the file.
Consider changing this, for example by passing in the information via the constructor (either read the file from the constructor, or pass in an object that takes care of supplying the information). This will decouple your design, and simplify e.g. reuse and unit testing.
From a readability perspective, assigning the values to a variable and returning it would definitely help.
This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
Properties vs Methods
In method you can type some code and in properties too. For example I have a property Name. When class name changes I would like to get some data from database and change state of my object. I can add this code to set part of my property. Other solution is to change set part to private and add method called SetName and in this method add my code.
So what is the difference? When is the point when it's not good to put some code to getter / setter and when to create own method that is used to change my property and other parts of my class?
Here is a good set of guidelines for when to use properties vs methods from Bill Wagner (fixed link)
Use a Property when all these are true:
The getters should be simple and thus unlikely to throw exceptions. Note that this implies no network (or database) access. Either might fail, and therefore would throw an exception.
They should not have dependencies on each other. Note that this would include setting one property and having it affect another. (For example, setting the FirstName property would affect a read-only FullName property that composed the first name + last name properties implies such a dependency )
They should be settable in any order
The getter does not have an observable side effect Note this guideline doesn't preclude some forms of lazy evaluation in a property.
The method must always return immediately. (Note that this precludes a property that makes a database access call, web service call, or other similar operation).
Use a method if the member returns an array.
Repeated calls to the getter (without intervening code) should return the same value.
Repeated calls to the setter (with the same value) should yield no difference from a single call.
The get should not return a reference to internal data structures (See item 23). A method could return a deep copy, and could avoid this issue.
Given a property like this
private string _name;
public string Name { get { return _name; } set { _name = value; } }
it is possible to write the following two methods:
public string get_Name() { return _name; }
public void set_Name(string value) { _name = value; }
which act identically. And in fact, this is exactly what the compiler does for you when you create a property.
Generally speaking, I steer away from properties when the code within them starts to feel "expensive", if that makes any sense. I want properties to feel like fields (with controlled side effects that happen at specific times), so they should be lightweight.
A property is nothing but some syntactic sugar.
In some cases, it is better to define a property instead of a method because it is clearer / more readable.
Design guidelines state that, when the functionality you're implementing is expensive, a method should be preferred over a property.
in fact, a property is implemented as one or two methods; depending whether your property has a setter or not. The property is translated into a get_xxx and a set_xxx method.
Coming to think of it, Properties are more than just syntactic sugar. They are the public face of your member data to you member code.
Thus, giving you a clean layer for retrieval or input of a single aspect of you member data from you code.
A DTO for example is nothing but a bunch of well written properties, cleaving data and behavior efficiently.
Without a DTO would you imagine tightly coupling your DataGrid or Dropdown to complex business logic method?
Put it simply, Methods are actually doing the work...Properties either instigate action or get the status.
Though, you can use method code inside your properties ...it is not what they are meant for. Even, if you have to you are better of making a clean call to another method inside the property instead of actually writing you code in it. HTH!
Whenever I've come across the need to put code in a getter/setter I put the code in a private method and call that method from within the getter/setter. That way the code is available in a method call should I need it elsewhere. Not sure if this is the answer you were seeking but it is just a methodology I use.
There is basically no difference (except for the reserved identifier "value" in a setter).
Getters and setters get internally translated into standard methods such that the runtime has no idea whether some getter or setter is associated with a certain property. The term syntactic sugar is often used for convenience constructs like these.
However, there is an important software engineering benefit: your code tends to be easier to understand if you restrict yourself to use getters and setters with get and set semantics. I.e. do only the steps necessary to provide the respective property.
A common use case for doing a bit of extra work is for instance the setting or getting of a property which is not directly backed by a member field. For example, you've got a class that contains say a value that represents a distance. Your class could provide two Properties: Kilometers and Miles with respective setters and getters. Then you would do simple conversions in one pair and save yourself to store the value twice.
As a general rule of thumb, you should not put any code in a getter that has side effects. Also, the only side effect that code in a setter should have is the change of state in the object the setter refers to.
Essentially a property is a couple of methods - getProperty and setProperty. It is only the convention / simplification of the thing.
It is assumed that property getter has no side effects (well - they might have certain side effect, like lazy loading).
This probably isn't the most important difference, but one of the differences is that the debugger can be configured to step over properties (assuming their code is trivial).