I have two questions and I'd like some help with them, please.
I have client code that needs to access to a variable/value that is changing over time, in fact, it is calculated on retrieval, and it is retrieved by many methods several times over runtime, however, it's calculation is not always possible as the requirements for it are not always present, in such cases, a false or null is returned and the client checks this to decide wether to proceed. Now, I have two approaches, the first one, A, is my classic one, B however, looks good to me as well.
A) I have this method with an out parameter similar to the TryParse methods on some C# libraries:
public bool GetLeadingTrailSegment(out Vector3 lastTrailSegment)
{
if (_line.positionCount > 1)
{
lastTrailSegment = lead - _line.GetPosition(_line.positionCount - 2);
return true;
}
lastTrailSegment = Vector3.zero;
return false;
}
B) I have this nullable property which tries to do the same job as the above code:
public Vector3? leadingTrailSegment
{
get
{
if (_line.positionCount > 1)
{
return lead - _line.GetPosition(_line.positionCount - 2);
}
return null;
}
}
The client code is as follows:
A) Here the bool tells the client code wether the value is safe(useful?) to use.
public bool IsDrawingOverAllowed(LayoutPointer pointer)
{
Vector3 leadingTrailSegment;
if (pointer.GetLeadingTrailSegment(out leadingTrailSegment))
{
return !midline.ParallelTo(leadingTrailSegment);
}
return true;
}
B) Here, the fact of the HasValue property of the nullable being false tells the client wether it is safe:
public bool IsDrawingOverAllowed(LayoutPointer pointer)
{
Vector3? leadingTrailSegment = pointer.leadingTrailSegment;
if (leadingTrailSegment.HasValue)
{
return !midline.ParallelTo(leadingTrailSegment.Value);
}
return true;
}
First question: Of these two approaches, which one is best or what are the pros/cons between or flaws within them?
Second question: I used to have the client B approach written as:
public bool IsDrawingOverAllowed(LayoutPointer pointer)
{
if (pointer.leadingTrailSegment.HasValue)
{
return !midline.ParallelTo(pointer.leadingTrailSegment.Value);
}
return true;
}
This was wrong, right? Because the Value property of the nullable may have changed by the second call.
I like best the out parameter approach, you can use the result in the if clause, and the variable can even be declared inline in other versions of C# but I'd really like to give a shot to nullables and make them useful in situations like these (and not only when I look for an unassigned value, which are the cases I use them in). I hope someone can give their thoughts on this.
Thanks.
I would much prefer a call returning a null than using output parameters. Output parameters are a kind of "side-effect" prone code constructs that I personally really dislike. It means the calling code has to define a variable before use, and it introduces weak points where it would be easy to induce a bug if you put in the wrong variable in the call by accident. It also prevents you from using the code in a call chain with the null-conditional and null-coalescing operators. You cannot do something like var v = GetLeadingTrailSegment() ?? new Vector3();.
The second point of interest is the use of a Nullable. If the Vector3 type is a value type, then that is fine and makes sense. If it is a reference type (pretty much everything other than integral types and structures in .NET), there is no need for it. Just return null; and if (variable != null) { ... }. The case for returning a bool is usually when you have return value clashes. For example if null was returned as a valid value in itself, and you needed a way to differentiate between a valid null or an invalid response. This does not appear to be the case here.
My two cents :)
tldr:
I would rather ask why you want to have a method that returns a boolean but the name suggest another thing.
If I have player.GetCurrentHp() and the method returns false if the player has no hp or hp == 0, I would fell that the name is misleading and I would prefer have a player.isAlive() method.
Is not something wrong per se from a logic or software perspective, but I will not help the next developer to work with that code, or yourself in 6 months.
In your case I would go with two methods for LayoutPointer;
public bool IsValid() // <--- I like when boolean methods represent 'is, can, have' actions, ideas, or properties.
{
return _line.positionCount > 1;
}
and
public bool GetLeadingTrailSegment()
{
if (!IsValid())
{
return Vector3.zero;
}
return (lead - _line.GetPosition(_line.positionCount - 2));
}
And then;
public bool IsDrawingOverAllowed(LayoutPointer pointer)
{
if (pointer == null)
{
Debug.LogWarning("IsDrawingOverAllowed: Pointer is null!");
return true; // or false, it depends on your design..
}
if (!pointer.IsValid()) // <-- I also like early returns :D
{
return true;
}
var leadingTrailSegment = pointer.GetLeadingTrailSegment()
return !midline.IsParallelTo(leadingTrailSegment);
}
I know that can be more 'verbose' but remember the idea that create code for machines is easy, but code for humans is harder.. At the end you want to have some code easy to read, understand and maintain.
Side Note; Yes, I know that sometimes can be useful, like in Physics.Raycast but if you are not implementing the TryParse pattern (if you want for example avoid the use of try/catch) I cannot see much gain trying to have just one method that does two things.
Related
I've been investigating the out keyword in C# after reading the section about it in C# in Depth. I cannot seem to find an example that shows why the keyword is required over just assigning the value of a return statement. For example:
public void Function1(int input, out int output)
{
output = input * 5;
}
public int Function2(int input)
{
return input * 5;
}
...
int i;
int j;
Function1(5, out i);
j = Function2(5);
Both i and j now have the same value. Is it just the convenience of being able to initialize without the = sign or is there some other value derived that I'm not seeing? I've seen some similar answers mentioning that it shifts responsibility for initialization to the callee here. But all that extra instead of just assigning a return value and not having a void method signature?
Usually out is used for a method that returns something else, but you still need to get a different value from the method.
A good example is Int32.TryParse(input, out myVar) it will return true if it was successful and false otherwise. You can get the converted int via the out parameter.
int myOutVar;
if (Int32.TryParse("2", out myOutVar))
{
//do something with the int
}else{
//Parsing failed, show a message
}
The out / ref keywords in C# should only be used when you need to return multiple values. Even then you should first consider using a container type (such as Tuple) to return multiple values before you revert to out / ref. Whenever you're returning a single value it should just be returned.
A lot of times, using out can help by giving you a slight performance gain.
Consider the TryGetValue method on IDictionary (say myDictionary is an IDictionary<string, string>) Rather than doing this:
string value = String.Empty;
if (myDictionary.ContainsKey("foo"))
{
value = myDictionary["foo"];
}
Both ContainsKey and the indexer need to look up the key in the dictionary, but you can avoid this double-lookup on the positive case by going:
string value;
if (!myDictionary.TryGetValue("foo", out value))
{
value = String.Empty;
}
IMO, that's a decent reason for using out parameters.
Unfortunately we cannot do something like below in C#:
a,b = func(x,y,z);
something that we do in Python or other languages. out kind of overcomes that.
F# has overcome this with tuples I believe.
PS: Returning multiple values from a function might not be good always. Tiny types are good most of the times - http://www.martinfowler.com/bliki/DataClump.html
For example, Int32.TryParse returns boolean if it parsed correctly and with the out parameter changes the value. If the parsed value is 0 and it returns true it means the value you sent to parse was 0. If it returns false then the parser failed.
Some of it is for clarity. Take the TryParse() methods, like
Int32.TryParse("3", out myInt);
This returns a bool that indicates whether the string was able to be parsed into an int.
If you just had
Int32.TryParse("3", myInt);
What happens when that's called? Is myInt assigned? Does TryParse return an int?
It's not readily apparent. But if I have an out parameter, then I know that the value is getting assigned, and that the return is something else.
Basically you do something like (my database read)
if (ReadSingle<UserRecord>(cmd, out user))
Cache.Insert(cacheId, user, null,
DateTime.MaxValue, TimeSpan.FromMinutes(3));
Or else you do something like:
user = ReadSingle<UserRecord>(cmd);
if(null != user)
// Cache.Insert ...
It simplifies the code a little to use a boolean result (that a record was read from the database) and get the actual record into the variable via the out keyword.
this is related to comparing values in C#.
basically by default, in C# till date i only used forward comparison as follows:
string value1 = "";
if (value1 == null)
{
Console.WriteLine("True");
}
else
{
Console.WriteLine("False");
}
somewhere on Internet, i came across a link where it is said that while comparing values in C#, we should prefer Reverse Comparison as :
string value1 = "";
if (null == value1)
{
Console.WriteLine("True");
}
else
{
Console.WriteLine("False");
}
Now the problem is that is there any basic difference between the two ways of comparing values or not (i.e. both are same).
Looking for favorable replies.
Thanks
This is a hangover from languages where values are implicitly converted to a boolean type.
For the most part, anything that was non-null or non-0 would be treated as true, otherwise it was equivalent to false. This meant that any assignation of a constant would always be true.
This thing to remember here is that the assignment function returns the value assigned, much in the same way that 5 is the result of 2+3, myInt = 5 also returns 5.
Because of this, it was recommended that you check the variable against the constant. The null example is actually probably a bit contrived in this case, as it would, in most languages, return as false.
As an example:
if(i = 1)
{
printf("Always out\n");
}
else
{
printf("Never prints\n");
}
i is assigned the value of 1, which then returns the value of the assignment, 1, to the if statement. This is equivalent to true, and the if condition matches.
If you were to attempt to assign i to the constant 1, you wouldn't compile, and so it was recommended that you do things it that order (e.g. 1 == i).
This is not neccesary in C#, and further to your example, the recommended practice is to call if(String.IsNullOrEmpty(myStringValue)) { //.... }, as a string has... two ... default values from a semantic perspective.
Reverse comparison protects you from errors, when you use == (compare) instead of = (assign). But complier also warns you if you do this.
From the docs:
The as operator is like a cast except that it yields null on conversion failure instead of raising an exception. More formally, an expression of the form:
expression as type
is equivalent to:
expression is type ? (type)expression : (type) null
except that expression is evaluated only once.
So why wouldn't you choose to either do it one way or the other. Why have two systems of casting?
They aren't two system of casting. The two have similar actions but very different meanings. An "as" means "I think this object might actually be of this other type; give me null if it isn't." A cast means one of two things:
I know for sure that this object actually is of this other type. Make it so, and if I'm wrong, crash the program.
I know for sure that this object is not of this other type, but that there is a well-known way of converting the value of the current type to the desired type. (For example, casting int to short.) Make it so, and if the conversion doesn't actually work, crash the program.
See my article on the subject for more details.
https://ericlippert.com/2009/10/08/whats-the-difference-between-as-and-cast-operators/
Efficiency and Performance
Part of performing a cast is some integrated type-checking; so prefixing the actual cast with an explicit type-check is redundant (the type-check occurs twice). Using the as keyword ensures only one type-check will be performed. You might think "but it has to do a null check instead of a second type-check", but null-checking is very efficient and performant compared to type-checking.
if (x is SomeType )
{
SomeType y = (SomeType )x;
// Do something
}
makes 2x checks, whereas
SomeType y = x as SomeType;
if (y != null)
{
// Do something
}
makes 1x -- the null check is very cheap compared to a type-check.
Because sometimes you want things to fail if you can't cast like you expect, and other times you don't care and just want to discard a given object if it can't cast.
It's basically a faster version of a regular cast wrapped in a try block; but As is far more readable and also saves typing.
It allows fast checks without try/cast overhead, which may be needed in some cases to handle message based inheritance trees.
I use it quite a lot (get in a message, react to specific subtypes). Try/cast wouuld be significantly slower (many try/catch frames on every message going through) - and we talk of handling 200.000 messages per second here.
Let me give you real world scenarios of where you would use both.
public class Foo
{
private int m_Member;
public override bool Equals(object obj)
{
// We use 'as' because we are not certain of the type.
var that = obj as Foo;
if (that != null)
{
return this.m_Member == that.m_Member;
}
return false;
}
}
And...
public class Program
{
public static void Main()
{
var form = new Form();
form.Load += Form_Load;
Application.Run(form);
}
private static void Form_Load(object sender, EventArgs args)
{
// We use an explicit cast here because we are certain of the type
// and we want an exception to be thrown if someone attempts to use
// this method in context where sender is not a Form.
var form = (Form)sender;
}
}
I generally choose one or the other based on the semantics of the code.
For example, if you have an object that you know that it must be an string then use (string) because this expresses that the person writing the code is sure that the object is a string and if it's not than we already have bigger problems than the runtime cast exception that will be thrown.
Use as if you are not sure that the object is of a specific type but want to have logic for when it is. You could use the is operator followed by a cast, but the as operator is more efficient.
Maybe examples will help:
// Regular casting
Class1 x = new Class1();
Class2 y = (Class2)x; // Throws exception if x doesn't implement or derive from Class2
// Casting with as
Class2 y = x as Class2; // Sets y to null if it can't be casted. Does not work with int to short, for example.
if (y != null)
{
// We can use y
}
// Casting but checking before.
// Only works when boxing/unboxing or casting to base classes/interfaces
if (x is Class2)
{
y = (Class2)x; // Won't fail since we already checked it
// Use y
}
// Casting with try/catch
// Works with int to short, for example. Same as "as"
try
{
y = (Class2)x;
// Use y
}
catch (InvalidCastException ex)
{
// Failed cast
}
Lets say I have a function that needs to return some integer value. but it can also fail, and I need to know when it does.
Which is the better way?
public int? DoSomethingWonderful()
or
public bool DoSomethingWonderful(out int parameter)
this is probably more of a style question, but I'm still curious which option people would take.
Edit: clarification, this code talks to a black box (lets call it a cloud. no, a black box. no, wait. cloud. yes). I dont care why it failed. I would just need to know if I have a valid value or not.
I like the nullable version better, because you can use the null coalesce operator ?? on it, e.g.:
int reallyTerrible = 0;
var mightBeWonderful = DoSomethingWonderful() ?? reallyTerrible;
It depends on how you think the calling code should look like. And therefore what your function is used for.
Generally, you should avoid out arguments. On the other hand, it could be nice to have code like this:
int parameter;
if (DoSomething(out paramameter))
{
// use parameter
}
When you have a nullable int, it would look like this:
int? result = DoSomething();
if (result != null)
{
// use result
}
This is somewhat better because you don't have an out argument, but the code that decides if the function succeeded doesn't look very obvious.
Don't forget that there is another option: use Exeptions. Only do this if the case where your function fails is really an exceptional and kind of a error-case.
try
{
// normal case
int result = DoSomething()
}
catch (SomethingFailedException ex)
{
// exceptional case
}
One advantage of the exception is that you can't just ignore it. The normal case is also straight forward to implement. If the exceptional case something you could ignore, you shouldn't use exceptions.
Edit: Forgot to mention: another advantage of an Exception is that you also can provide information why the operation failed. This information is provided by the Exception type, properties of the Exception and the message text.
Why not throw an exception?
I would follow the pattern used in some place in the .Net library like:
bool int.TryParse(string s, out value)
bool Dictionary.TryGetValue(T1 key, out T2 value)
So I would say:
public bool TryDoSomethingWonderful(out int parameter)
It really depends on what you are doing.
Is null a meaningful answer? If not, I would prefer a bool TryDoSomethingWonderful(out int) method call. This matches up with the Framework.
If, however, null is a meaningful return value, returning int? makes sense.
Unless performance is the primary concern you should return an int and throw an exception on failure.
I would use the second, because I probably need to know right away if the call succeeded, and in that case I would rather write
int x;
if( DoSomethingWonderful( out x ) )
{
SomethingElse(x);
}
than
int? x = DoSomethingWonderful();
if( x.HasValue )
{
SomethingElse(x.Value);
}
I am in favor of using an output parameter. In my opinion, this is the kind of situation for which use of an output parameters is most suited.
Yes, you can use the coalesce operator to keep your code as a one-liner if and only if you have an alternative value that you can use in the rest of your code. I often find that is not the case for me, and I would prefer to execute a different code path than I would if I was successfully able to retrieve a value.
int value;
if(DoSomethingWonderful(out value))
{
// continue on your merry way
}
else
{
// oops
Log("Unable to do something wonderful");
if (DoSomethingTerrible(out value))
{
// continue on your not-so-merry way
}
else
{
GiveUp();
}
}
Additionally, if the value that I want to retrieve is actually nullable, then using a function with an output parameter and a boolean return value is, in my opinion, the easiest way to tell the difference between "I was unsuccessful in retrieving the value" and "The value I retrieved is null". Sometimes I care about that distinction, such as in the following example:
private int? _Value;
private bool _ValueCanBeUsed = false;
public int? Value
{
get { return this._Value; }
set
{
this._Value = value;
this._ValueCanBeUsed = true;
}
}
public bool DoSomethingTerrible(out int? value)
{
if (this._ValueCanBeUsed)
{
value = this._Value;
// prevent others from using this value until it has been set again
this._ValueCanBeUsed = false;
return true;
}
else
{
value = null;
return false;
}
}
In my opinion, the only reason most people tend not to use output parameters is because they find the syntax cumbersome. However, I really feel that using output parameters is the more appropriate solution to this problem, and I found that once I got used to it I found the syntax much preferable to returning a null value.
If there's only one way it can fail, or if you'll never need to know why it failed, I'd say it's probably simpler and easier to go with the nullable return value.
Conversely, if there are multiple ways it could fail, and the calling code could want to know exactly why it failed, then go with the out parameter and return an error code instead of a bool (alternatively, you could throw an exception, but based on your question, it seems you've already decided not to throw an exception).
You should rather then use a try catch. This seems like the caller does not know what might happen?
Should we check both bool and the out, or should i check both returns null and the actual return.
Let the method do what it should, and in the case where it failed, let the caller know that it failed, and the caller hanlde as requied.
Interestingly enough, my personal opinion sways significantly based on the nature of the method. Specifically, if the method's purpose is to retrieve a single value, as opposing to "doing something".
Ex:
bool GetSerialNumber(out string serialNumber)
vs
string GetSerialNumber() // returns null on failure
The second feels more "natural" to me somehow, and likewise:
bool GetDeviceId(out int id)
vs
int? GetDeviceId() // returns null on failure`
But I admit this really falls into "coding style" territory.
Oh, and I, too, would tend to favor exception throwing:
int GetDeviceId() // throws an exception on read failure
I'm still not sold on why they'd be so wrong. Can we have a thread on that, Oren? ;-)
I dislike Microsoft's "Try" pattern in which the "out" parameter is used to return a data item. Among other things, methods coded in that fashion cannot be used in covariant interfaces. I would rather see a method coded as: T GetValue(out bool Successful) or perhaps T GetValue(out GetValueErrorEnum result); or T GetValue(out GetValueErrorInfo result); if something beyond a true/false might be needed. Since every data type has a legal default value, there's no problem with deciding what to return if the function fails. Calling code can easily say:
bool success;
var myValue = Thing.GetValue(ref success);
if (success)
.. do something using myValue
else
.. ignore myValue
It would be nice if .net and C# offered true covariant 'copy out' parameters (the caller would allocate space for the result, pass a pointer to that space to the called function, and then copy the allocated space to the passed-in variable only after the function returned).
I'm just interested in people's opinions. When using nullable types in C# what is the best practice way to test for null:
bool isNull = (i == null);
or
bool isNull = !i.HasValue;
Also when assigning to a non-null type is this:
long? i = 1;
long j = (long)i;
better than:
long? i = 1;
long j = i.Value;
I would use this:
long? i = 1;
...some code...
long j = i ?? 0;
That means, if i is null, than 0 will be assigned.
Use the forms that were specially implemented for you by the C# team. If anyone objects, tell them Anders said it was okay.
What I'm saying, flippantly, is that a lot of work went into integrating nullable types into c# to give you a good programming experience.
Note that in terms of performance, both forms compile down to the same IL, ie:
int? i = 1;
bool isINull = i == null;
int j = (int)i;
Ends up like this after the C# compiler has got to it:
int? i = 1;
bool isINull = !i.HasValue;
int j = i.Value;
I would always use the (i==null) form. It expresses what you are doing.
WRT the second question, I think either form is fine. However I'd always check it against null first and take appropriate action - perhaps wrapping that check and action up in a helper method (often it just sets a default value).
I haven't used Nullable Types in practice, but for the second, I'd actually suggest using j.GetValueOrDefault(). The documentation suggests that the latter would actually throw an InvalidOperationException in the event of a null value. Depending on the internal implementation of the explict cast operator for long?, the former might, too. I'd stick with GetValueOrDefault and treat the null/default case appropriately.
I tend to use the first on both, because as it needs to be supported later in its life-cycle, these seem easier to understand what the intent of the original writer.
Opened up Reflector. HasValue is a lookup on a boolean flag which is set when the value is changed. So in terms of cycles a lookup is going to be faster then compare.
public Nullable(T value)
{
this.value = value;
this.hasValue = true;
}
private bool hasValue;
internal T value;
public bool HasValue
{
get
{
return this.hasValue;
}
}
They're both the same, but I would use the former version on both, since it's more common in the language: comparison to null and casting to a type.
I usually tend to lean towards the first option in both scenarios, since it's more 'primitive' oriented opposed to object oriented (which was really what we were going for), but it really doesn't matter that much