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.
Related
I've read a few threads related to the question by I'm still not sure what's better for the current situation. I have two simple classes:
File:
string name;
long size;
Folder:
string name;
IList<File> files;
IList<Folder> folders;
If I want to implement a method which calculates the contents size of a folder, should I implement it as an instance or as a static member. The implementation needs a Folder object as a sole parameter and it does not change any state of the variable so I'm thinking of making it static but I'm not sure if this is the right step.
You can make a comparison with something that describe your problem.
Calculate something when i give you a parameter.
The first thing that comes up in my mind and do a similar thing is Math.Pow which is a static method.
If you want to do Folder.Size(folder); than you can make it static.
If the method is inside Folder the problem is different.
Calculate something when i have something
The first thing that i think is Count (although this is a property), this is not static because this calculate something that is unique for every class.
If you want to do Folder.Size or Folder.Size() than, non static is your way to go.
Conclusion: Use static when a method don't belong to a class.
in this case no, since the size needs a Folder object and you must instantiate one, then add a method like CalculateSize() or GetSize() inside the class itself.
The most typical, OOP-ish, way to go here is an instance method. You shouldn't pass any parameters in but use this instead.
Using a static method within the Folder class itself would be counter-intuitive and possibly break encapsulation principles. The reason is, your method primarily operates on a specific Folder instance, and no decoupling of the funcionality away from the Folder class seems to be necessary in such a trivial case. The only valid case would be to support returning a fallback value, such as 0, in case a null reference would be passed in. However, in most cases being tolerant to such inputs causes problems later in the program's control flow.
You don't have to go full OOP and just do it with static.
Say I have a method that requires more that two output values.
My options would be the following (maybe there are more options I haven't considered)
return value along with multiple out/ref parameters
create a class that would hold each output value I want and my method will return that
construct an XML string that contains all the output values I want and return that
I'm asking because i remember reading somewhere that it not good to use out and ref parameters. But I'm not sure how else to do it.
Which way adheres best to design principles and also makes it better for unit testing?
Also are there other options I didn't list that would be acceptable?
EDIT: the extra output values I'm considering to return in addition to the main value, have to do with success failure condition of the process as well as the name of the condition that failed etc. So mostly for tracking and testing of the process.
I would rank your options this way:
create a class that would hold each output value I want and my method will return that
return value along with multiple out/ref parameters
construct an XML string that contains all the output values I want
However, all of these represent a "code smell" that your method is doing too much. At least returning a class indicates that the method is providing several known, related values. Using out/ref is more of a workaround (sometimes they're valid, sometimes they're not) to avoid creating a class, and XML is not a good choice since you force the consumer to know the schema in order to extract the values.
In general, the accepted solution for doing this would be your second bullet point, create an object with all the return data.
out/ref has a very specific semantic associated with it, that you are going to give it some pre-made "things" that the function is expected to modify/set. This isn't the same thing as a return value.
Using an XML string is no better than returning a dictionary or custom object, and is far more confusing.
Another neat option (almost tailor made for this) would be to use a Tuple. Say you want to return an int and string, you could return a Tuple<int, string>. This is a quick way to get an "anonymous" return object. If you are going to reuse it at all though, a named object is better.
Instead of using ref keyword, Custom class and XML go for Tuple.
return new Tuple<int, string>();
You can use the Tuple family of types for ad hoc multiple values, but if the returned values are actually related, you should consider encapsulating them into a separate type, and returning a value of that type.
Jon Skeet mentioned that here. Also, as David Crowell mentioned, struct is also a good choice. Being a value type it has some (Albeit very minor) advantages over a class.
For just a few values, what about a struct?
struct ReturnType
{
int id;
string name;
}
This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
Properties vs Methods
When is it best to use a property or a method?
I have a class which is a logger. When I create this class I pass in a file name.
My file name for the log is fairly simple, basically it just gets the application path and then combines it with myapp.log.
Now instead of having the log file name lines in my method I want to create a new method to get this.
So my question is, since it's fairly simple, is creating a property a good idea instead of creating a method since there are no parameters.
Duplicate Properties vs Methods
Properties are typically used to store a state for an object. Method are typically used to perform an action on the object or return a result. Properties offer both getters and setters and can have different scope (at least in .NET 2.0). There is also some advantages to using a property vs methods for serialization or cloning and UI controls look for properties via reflection to display values.
Properties can be used to return simple values. Methods should always been used when fetching the value might incur any kind of performance hit. Simple linear operations can be fine in properties, though.
Ask yourself whether it's an aspect of your class (something it has) versus a behaviour of your class (something it does).
In your case, I'd suggest a property is the way to go.
I'd definitely go with the property. If you were doing something complex or computationally or time intensive, then you would go the method route. Properties can hide the fact that a complex operation is taking place, so I like to reserve properties for fast operations and ones that actually describe a property on the object. Simply: Methods "do" something, properties describe.
When you want to use it like a variable, you should go for a property. When you want it to be clear that this is a method, you should use a method.
As a property is a method, it depends on the semantic/design you want to communicate here.
Properties should be used to wrap instance variables or provide simple calculated fields. The rule of thumb that I use is if there is anything more that very light processing make it a method.
If you are not doing anything significant, use proerties.
In your case, a readonly property (get only) should be good.
Methods make sense when you are doing something other than returning reference to an internal member.
Properties are a design smell.
They are sometimes appropriate in library classes, where the author cannot know how the data will be used but must simply output the same value that was put in (e.g. the Key and Value properties of the KeyValuePair class.)
IMHO some uses of properties in library classes are bad. e.g. assigning to the InnerHTML property of a DOM element triggers parsing. This should probably be a method instead.
But in most application classes, you do know exactly how the value will be used, and it is not the class's responsibility to remind you what value you put in, only to use the data to do its job. Messages should exercise capabilities, not request information
And if the value you want is computed by the class (or if the class is a factory and the value is a newly-created object), using a method makes it more clear that there is computation involved.
If you are setting the log filename, then there is also the side effect of opening the file (which presumably may throw an exception?) That should probably be a method.
And if the filename is just part of the log message, you do not need a getter for the property, only a setter. But then you would have a write-only property. Some people find these confusing, so I avoid them.
So I would definitely go for the method.
The answer in the dupicate question is correct. MSDN has a very good article on the differences and when one should be used over an other. http://msdn.microsoft.com/en-us/library/ms229054.aspx
In my case I believe using the Property would be correct because it just returns the path of the exe + a file name combined.
If however I decided to pass a file name to get it to combine with the exe path, then I would use a method.
Well, the title says it all. When passing a file name to a method, should I use a FileInfo object or a plain file name (string)? Why would I prefer one to the other?
Some of my colleagues like to write method like this:
void Export(FileInfo fileInfo)
Is it better than:
void Export(string fileName)
Thanks!
I'd usually just use a string - it's simpler in most cases. Otherwise you're likely to just create a new FileInfo from the string in the first place.
If you're creating the method, you could always provide overloads to allow both.
Of course, if you know that where you're intending to call it, you usually have a FileInfo rather than a string, that's a different matter.
I can see your colleagues' point of view - in some ways a FileInfo is a "cleaner" way of expressing the parameter. I think string is the more pragmatic approach though :)
Typically I would pass the string. However, you could overload the method to make everyone happy.
The difference is primarily that there is a little bit of checking going on; the FileInfo constructor does some checking for a null or clearly invalid parameter. There are a few other things it does; taking a FileInfo basically just puts the onus of handling the exceptions from the FileInfo constructor on the calling code, as opposed to your code.
Here's the MSDN reference for the FileInfo constructor that shows what the constructor can throw:
http://msdn.microsoft.com/en-us/library/system.io.fileinfo.fileinfo.aspx
I would say it depends :) Many static file operations on the class File allow a number of things with the filename. The abstraction of a File is not that often useful in the .NET Framework, so I am biased towards using a string and denoting in the argument name what it is.
A FileInfo does do more to show the intent of the data type than a string. And that's almost always a good thing. However, there's certainly plenty of precedent for passing a file name as a string, including most of the .NET framework itself. A file name IS a string. Presumably, you'd have the caller use the FileInfo object to force the calling code to validate the file name (i.e. handle the exception) rather than burdening yourself with passing back the exception.
Certainly, including a method overload would remove all doubt, so long as you're validating the file name being passed in.
If you're working on code involving these colleagues, I would use FileInfo. It really doesn't matter much but writing code the way others expect it reduces maintainence, raises consistency, and generally makes people happy.
I will point out that I dislike the idea of using FileInfo for the sake of putting the onus of checks for validity on the calling function, as pointed out by McWafflestix. If something breaks between the calling function and the function that was called, it won't be caught. It won't necessarily be caught if you use a string...but at least it makes it clear where the problem can happen. And you'll want to catch such exceptions in the called method anyways. Surely you aren't going to open the file and start reading/writing until you're in the actual function (if you are, FileInfo and string are probably both the wrong choice, but Stream makes sense, as TheSean suggests).
I think file name will suffice if it is doing the same thing.
String is not PATH. So string is not the best way to represent path.
FileInfo is also not a PATH, semantically it represents FILE.
So this will be better if MS will provide Path object :) or you can make it yourself, especially if this is your internal code. In this way you will not need to check your PATH arguments every time you will work with them. I often has many structs that represent different stings, NonNullString, IdString(case insensitive), I believe that this makes code simply.
I would follow the convention of using Steams. This is how I see most I/O performed. It makes sense to me:
void Export(string s)
{
Stream fs = new FileStream(s); //think this is correct
Export(fs);
}
void Export(Stream s)
{
s.Write ( ... );
...
}
I agree, FileInfo has never been that useful to me. stick with string or use stream which can be FileStream, MemoryStream, etc.
As usual, it depends. In all but the most basic of cases, I'd say using FileInfo gives you a lot of benefits with almost no negatives. Strict OO dogma would say that information about a file (path, creation date, modified date, etc) should be encapsulated within a class like FileInfo. This will allow you more flexibility if down the road you need more complex behavior. If you write your code against FileInfo, it will almost always be cleaner and less bug-prone if you need to make changes.
If you absolutely can't think of a scenario where you'd need more complex behavior, and it's going to really throw you off, go ahead and just use a string.
Let us say for a moment that C# allowed multiple return values in the most pure sense, where we would expect to see something like:
string sender = message.GetSender();
string receiver = message.GetReceiver();
compacted to:
string sender, receiver = message.GetParticipants();
In that case, I do not have to understand the return values of the method until I actually make the method call. Perhaps I rely on Intellisense to tell me what return value(s) I'm dealing with, or perhaps I'm searching for a method that returns what I want from a class I am unfamiliar with.
Similarly, we have something like this, currently, in C#:
string receiver;
string sender = message.GetParticipants(out receiver);
where the argument to GetParticipants is an out string parameter. However, this is a bit different than the above because it means I have to preempt with, or at least go back and write, code that creates a variable to hold the result of the out parameter. This is a little counterintuitive.
My question is, is there any syntactic sugar in current C#, that allows a developer to make this declaration in the same line as the method call? I think it would make development a (tiny) bit more fluid, and also make the code more readable if I were doing something like:
string sender = message.GetParicipants(out string receiver);
to show that receiver was being declared and assigned on the spot.
No, there isn't currently any syntactic sugar around this. I haven't heard of any intention to introduce any either.
I can't say I use out parameters often enough for it really to be a significant concern for me (there are other features I'd rather the C# team spent their time on) but I agree it's a bit annoying.
.NET 4 will be adding a Tuple concept, which deals with this. Unfortunately, the C# language isn't going to provide any language support for "destructuring bind".
Personally, I like the inconvience introduced when using out parameters. It helps me to think about whether my method is really doing what it should be or if I've crammed too much functionality into it. That said, perhaps dynamic typing in C#4.0/.Net 4 will address some of your concerns.
dynamic participant = message.GetParticipants();
var sender = participant.Sender;
var recipient = participant.Recipient;
where
public object GetParticipants()
{
return new { Sender = ..., Recipient = ... };
}
You can also return a Tuple<T,U> or something similar. However, since you want to return two string, it might get confusing.
I use the Tuples structs of the BclExtras library which is very handy (found it on SO, thank you JaredPar!).
I don't think such functionality exists, but if it were implemented in a way similar to arrays in perl that could be useful actually.
In perl You can assign an array to a list of variables in parentheses. So you can for example do this
($user, $password) = split(/:/,$data);
Where this bugs me the most: since there's no overload of (say) DateTime.TryParse that doesn't take an out parameter, you can't write
if (DateTime.TryParse(s, out d))
{
return new ValidationError("{0} isn't a valid date", s);
}
without declaring d. I don't know if this is a problem with out parameters or just with how the TryParse method is implemented, but it's annoying.
This syntactic sugar is now is now available in the roslyn preview as seen here (called Declaration expressions).
int.TryParse(s, out var x);
At best you would have to use var rather than an explicit type, unless you want to restrict all multiple return values to be of the same type (not likely practical). You would also be limiting the scope of the variable; currently you can declare a variable at a higher scope and initialize it in an out parameter. With this approach, the variable would go out of scope in the same block as its assignment. Obviously this is usable in some cases, but I wouldn't want to enforce this as the general rule. Obviously you could leave the 'out' option in place, but chances are people are going to code for one approach or the other.
I think this is not what you want.
You may have come across a piece of code where you would have
liked that. But variables popping out of nowhere because
they have been introduced in the parameter list would be
a personal nightmare ( to me :) )
Multiple return values have grave downsides from the point
of portability/maintainability. If you make a function that returns two strings
and you now want it to return three, you will have to change all the code
that uses this function.
A returned record type however usually plays nice in such common scenarios.
you may be opening pandora's box ;-)
For line compacting:
string s1, s2; s1 = foo.bar(s2);
Lines can be any length, so you could pack some common stuff into one.
Just try to live with the semicolons.
Try the following code
Participants p = message.GetParticipants();
log(p.sender,p.receiver);