Why method should be converted to a property? - c#

I'm creating a method named Check_Finished() but the visual studio won't allow me to do so. Instead, it prompts me as potential fix to convert it into a property. I can't understand why can't we use a method instead of the property here, provided that both have the same purpose and both are gonna return the same thing.
enter image description here
This(below) is the code I want to use.
public bool Check_Finished()
{
if(started && !running)
{
return true;
}
}
This is the one visual studio prompts me to convert to:
public bool Check_Finished
{
get
{
if (started && !running)
{
return true;
}
}
}
which still isn't working. Here this happens:
enter image description here
I can do the following and it works but I wanted to try a different approach just to understand things more.
public bool Finished
{
get { return started && !running; }
}

Sure, you can use a method, but all code paths need to return a value. What if the condition (if-statement) doesn't pass? What should be returned? You don't specify it, leading to a case where no return value is given, which causes the compiler error.
But in general, for such a case, you should prefer using a property, as it represents data and no special calculations have to be done in order to return the value (this wording is not necessarily the rule, but it is easy to "remember" what to use with this mnemonic, though you will get a feeling for that with more experience). Take a look at the MSDN guideline for using properties or methods:
In general, methods represent actions and properties represent data. Properties are meant to be used like fields, meaning that properties should not be computationally complex or produce side effects. When it does not violate the following guidelines, consider using a property, rather than a method, because less experienced developers find properties easier to use.

Related

redundant 'IEnumerable.OfType<T>' call consider comparing with 'null' instead

I'm getting this message from ReSharper. ReSharper is not proposing the change that I think would be appropriate after examining the code. As a result I am concerned that the problem might might be my not understanding what's going on instead of ReSharper not being as helpful as it could be.
public interface IFrobable { }
public class DataClass
{
public List<IFrobable> Frobables {get; set;}
//...
}
public class WorkerClass
{
//...
void Frobinate(List<IFrobable> frobables)
{
//Frobs the input
}
void DoSomething(List<IFrobable> input>)
{
//Original code with Resharper on OfType<IActivity>
Frobinate(input.OfType<IFrobable>().ToList());
//Suggested change from ReSharper - Is this a generic refactor
//instead of issue specific?
Frobinate(Enumerable.OfType<IFrobable>(input).ToList());
//What I think should be safe to do - compiles and appears to work
Frobinate(input);
}
}
Is there any reason why my proposed change might not be safe.
This is a regular function call:
Enumerable.OfType<IFrobable>(input)
This is the same function but invoked as an extension method:
input.OfType<IFrobable>()
In your case:
Frobinate(input);
Is absolutely fine because:
input.OfType<IFrobable>().ToList()
Equals to:
input.Where(x => x as IFrobable != null).ToList()
And in you method input is already defined as List<IFrobable> so what's the point?
Your last case may or may not introduce a logic error.
Do you really want Frobinate the ability to modify the input list passed into DoSomething or just a copy of those references?
//Suggested change from ReSharper
Actually, invoking OfType as a static method on Enumerable rather than as an extension method on input is not a suggestion from ReSharper - it's a context action. I expound on the difference in this post.
To the actual issue:
The inspection
Redundant 'IEnumerable.OfType<T>' call. Consider comparing with 'null' instead
is not one that ReSharper offers a quick fix solution with, I guess since there isn't a single unambiguously 'correct' change to make. It's just saying
hey, everything in input is definitely going to be of type IFrobable - if you're trying to filter this list you might have meant to be filtering by nullness instead
This probably isn't relevant in your case.
As to your proposed fix - as already noted, this will mean passing the actual List<> reference given to DoSomething to Frobinate, rather than a new List<> containing the same items - if this is OK, then go for it.
in your example you have input which already consists of elements of type IFrobable so ReSharper says that it doesn't make sense to filter them by type IFrobable because the filter condition is always true it proposes you to use just input.ToList() invocation or to filter elements buy nullness: input.Where(element => element != null).ToList()

Is it possible to specify code contracts to ensure that method doesn't change state of object

Lets say I got a boolean IsValid property on my object.
I would like to create a method, and ensure that IsValid isn't changed after calling it, whether it was true or false before the call.
Is there a support for such thing?
For that purpose the [Pure] Attribute has been added to the System.Diagnostic.Contracts Namespace. See here for further explanation. However you cannot prevent a single property from being changed. The method is not allowed to change the object state at all (like the C++ const).
EDIT: Unfortunately the Pure attribute does not work with the current tools. I implemented a test with the following code, no error message either at static nor at runtime type checking:
public class Test
{
private int x = 0;
[Pure]
public void Foo()
{
x++;
}
}
Regarding to the documentation of Pure checks will be supported 'in the future'. Whenever that is ("The Code Contracts team is working heavy on that, thus to come up with a purity checker in a future release.").
I have been using the attribute in the believe it works properly. The documentation says that all methods called within a contract must be declared as pure. It doesn't say whether that's checked or not.
So the answer to your question is: There is no current support for this, but may be in the future.
I haven't tried it myself, but according to the MSDN Contract.OldValue might help to check that a single property value has not changed:
public bool IsValid
{
get
{
...
}
}
public void SomeMethod()
{
Contract.Ensures(this.IsValid == Contract.OldValue(this.IsValid));
...
}
No, unfortunately c# doesn't provide a const logic such c++ does.
The only way to go about doing this is to control your code in such a way that you know it won't change. There is no specific code or syntax to control this otherwise (as in C++).

C# - Methods for null checking

What's the preferred way of checking if the value is null?
Let's say we have some entity, which has properties, which can be null (some of them or all of them).
And I wish to check this in runtime, if some property is actually null or not.
Would you use simple Entity.Property != null check in this case or would you implement a specific method, let's say like
bool HasProperty() {
return Property != null;
}
What would you choose and why?
For property values which can be null, my preference is to do the following
Have the property containing the value which can possibly be null
Have another property prefixed with Has and the rest containing the original property name which determines if the other property is non-null
Add an assert into the original property if it's accessed when null
In this example it would be
SomeType Property {
get {
Contract.Requires(HasProperty);
return _property; }
}
bool HasProperty {
get { return _property != null; }
}
The reasoning behind this is that C# does not have a standard way of describing whether or not a value can be null. There are many different conventions and techniques avalaible but simply no standard. And not understanding the null semantics around a value leads to missed null checks and eventually NullReferenceExceptions.
I've found the best way to express this is to make the null feature of a property explicit in the type itself by adding the Has property if and only if the property can be null. It's not a perfect solution but I've found it works well in large projects.
Other solutions I've tried
Do Nothing: This just fails over and over again
Using an explicit Maybe<T> or Option<T> type in the flavor of F#. This works but I find I receive a lot of push-back from developers who've never done functional programming and it leads to a rejection of the idea entirely in favor of #1.
Just check if the property itself is null, there is no need to create a method for this. Properties are really just methods that are generated by the compiler.
There is no pattern that covers this. In fact, anything you do to try and make this "easier" could be considered an anti-pattern.
"Hey, don't check if the property is null, use the Is[Property Name]Null property"
Uh, no.
I check only against null, because every nullable type does internally exactly what you described (but the internal method is called HasValue instead of HasProperty):
http://msdn.microsoft.com/de-de/library/b3h38hb0.aspx
If Property is something that isn't public, then you would need a method like HasProperty(). Also, if you implement your "nullness" in another way, it would also be good to have a HasProperty() method.
Null is not necessarily bad. I think it all depends on why you need to check for null to determine how you should check for it.
I would choose to write a separate Has* property only if the property is auto-initializing (i.e. just getting it might cause, say, an empty collection to be allocated) and it makes a performance difference. If getting the property is cheap (as it should be; in some cases you just can't help having it make a difference, though), there's no need for a superfluous Has method.
So no Has for the general case:
public string Foo { get; set; }
But in some cases, it can be a good idea:
private List<string> someStrings = null;
public List<string> SomeStrings {
get {
if (someStrings == null)
someStrings = new List<string>();
return someStrings;
}
}
public bool HasSomeStrings {
get { return (someStrings != null && someStrings.Count > 0); }
}

Method naming depending on returntype

Trying to avoid Tell-don't-ask, I want to combine a bool property that I was asking before calling a method, into a new method returning bool.
I try to follow the pattern, that if a method can't perform the action implied by it's name, it will throw an exception. For example if SendMail can't send the mail, it will throw an exception.
I want this particular method to return a bool to indicate the success. And am considering if I should change the name to something like TrySendMail, perhaps looking at the method signature with the bool return type should be enough?
Naming the method TrySendMail seems like a not too bad approach. However, being consistent with your overall naming sceme is the most important thing.
The whole TryWhatever naming pattern seems to be a fairly recent thing coming from Microsoft, but the behavior (try to do something, throw if it fails, return a meaningful strongly-typed value if it doesn't) has been around for a long time.
In theory, TryWhatever should be used if the method takes a ref parameter that receives the result, and returns a bool. If the method fails, it returns false. If it succeeds, the result is stored in the ref parameter (always the last parameter), and returns true.
You can use the DateTime.TryParse method as an example. If the method doesn't match that pattern, it's not a candidate for this naming convention.
For me, when using this convention, consistency is key. Don't surprise developers. Some of us are very scary people!
The TrySomething pattern is, as you know, used in several .NET BCL methods (various TryParse methods), and people are accustomed to it, so it shouldn't surprise anyone.
If your method's signature is simply bool TrySendMail(Mail mail), then it should be pretty obvious what's going on. And I would prefer to see that signature over something like:
bool WasMailSentSuccessfully(Mail mail);
because it is not so clear from the latter method that the method is actually sending the mail. So you are making the right naming choice if you go with the Try prefix, as far as I am concerned.
On the other hand, when I see the Try prefix, I usually expect to see the out keyword inside the argument list, which would follow these conventions:
bool TrySendMail(Mail mail, out string error);
And be used as:
string error = null;
if (!TrySendMail(mail, out error))
Console.WriteLine(error);
This convention, although pretty common, is actually rather ugly from an OOP point of view. It is basically a method which returns two values, and instead of passing one of the arguments by reference, a proper OOP way would be to wrap all of the return values in a new class.
So I would prefer something like:
SendResult SendMail(Mail mail);
and then you could use it like this:
SendResult sendResult = SendMail(mail);
if (!sendResult.Success)
Console.WriteLine(sendResult.Value);
where SendResult could be something like:
public class SendResult : ActionResult<string>
{ ... }
public class ActionResult<T>
{
public bool Success { get; private set; }
public T Value { get; private set; }
public ActionResult<T>(bool success, T value)
{
Success = success;
Value = value;
}
}
The benefit is that later adding a bunch of additional return values does not change your method's signature.
I remember reading a piece in Code Complete 2 (although I can't remember where abouts exactly) about naming conventions, aside from trying to keep them generic so they can be used for multiple applications they should all have some consistency. In this case calling it "SendMail" keeps it straight to the point and allows you to easily reuse it without the user having to worry about the implementation details, it's obvious what it does.
Setting the return type as a boolean should be a sure sign that the method works on a Success/Fail operation, making the "Try" part redundant.
private bool SendMail()
{
try
{
//Send mail
return true;
}
catch()
{
//Handle exception
}
return false;
}
If you were to add the XML header for the method you can even add an explanation as to what the method does when you try to call it through IntelliSense.
Be careful with the exceptions. For instance, if the address passed into the SendMail is badly formed, I don't think it appropriate to throw an exception. Exceptions are for exceptional behaviour, and to my mind not sending a mail because the address is badly formed is expected behaviour, not exceptional. I would definitely return a false (and maybe a string reason) if the mail isn't sent rather than throwing an exception. Throwing exceptions is not just slow, but means that the stack gets unwound so has to worry about leaving everything in a good state.

Is it necessarily bad style to ignore the return value of a method

Let's say I have a C# method public void CheckXYZ(int xyz) {
// do some operation with side effects
}
Elsewhere in the same class is another method public int GetCheckedXYZ(int xyz) {
int abc;
// functionally equivalent operation to CheckXYZ,
// with additional side effect of assigning a value to abc
return abc; // this value is calculated during the check above
}
Is it necessarily bad style to refactor this by removing the CheckXYZ method, and replacing all existing CheckXYZ() calls with GetCheckedXYZ(), ignoring the return value? The returned type isn't IDisposable in this case. Does it come down to discretion?
EDIT: After all the responses, I've expanded the example a little. (Yes, I realise it's now got out in it, it's especially for #Steven)
public void EnsureXYZ(int xyz) {
if (!cache.ContainsKey(xyz))
cache.Add(xyz, random.Next());
}
public int AlwaysGetXYZ(int xyz) {
int abc;
if (!cache.TryGetValue(xyz, out abc))
{
abc = random.Next();
cache.Add(xyz, abc);
}
return abc;
}
It entirely depends upon what that return value is telling you and if that is important to know or not. If the data returned by the method is not relevant to the code that is calling it then ignoring it is entirely valid. But if it indicates some failure/counter/influential value then ignore it at your peril.
Usually it's bad style, yes. It's allowed and ok where methods return an instance of the class for chaining (foo.bar().baz().xyz().asdf() => asdf returns the instance foo but you don't need it anymore)
In your case the point of bad style wouldn't be the ignored return value but the methods with side effects. A CheckXyz() function should always return a boolean and have no further side effects.
In general, side effects are bad and if you call a method and can ignore the returned value it means that the method/object/library/program might be poorly designed.
A common C convention is to write this:
(void)GetCheckedXYZ();
The cast to void has no effect, but by convention it shows that the developer knows that the return value is being ignored, i.e. it shows it's deliberate.
C# won't let you do that, but I've seen this instead (Also in Java):
/*(void)*/GetCheckedXYZ();
Which some may feel lacks aesthetics, but it does convey the intent of the developer without resorting to alternative versions of methods, which to my eye seems worse.
A lot of these answers have good points. I'd just add that if you choose to ignore a return value, then comment it along the lines of "don't care about the return value because...", so that the next person who comes into the code will see that you have not missed it by accident and that you have thought things through
EDIT: better still, put your comment inside an empty block
if (!something()) {
// Not worried if this fails because blah
}
IMHO it's generally best to have one (and only one) way of doing things to avoid duplicating your codebase. Generally though, if you sometimes use and sometimes don't use the return value, it's probably a sign that your code could be broken down in a better way. In your example, it would probably be fine if both of those functions called a third (common) function to avoid duplicating the core functionality.
Error codes should always be checked for and handled but if the function's just returning information then what you do with that information is up to you.
[Edit] ...and as dbemerlin points out, side effects should be avoided wherever possible.
you could work with out parameters as well.

Categories