I am new to both Godot and C#, so I will try to be as clear as possible in my question.
I am trying to recreate Pong by following a tutorial that uses GDScript (not otpimal, but it forces me to "translate" stuff from one language to the other). The problem I'm currently facing is that I want to verify if the ball is hitting the racket or the walls by using groups. For this, the MoveAndCollide() method is both moving the ball and returning the colliding KinematicBody2D object in this "collision" variable.
Godot.KinematicCollision2D collision = MoveAndCollide(direction * delta);
if (collision != null)
{
direction = direction.Bounce(collision.Normal);
if (collision.Collider.IsInGroup("rackets") //the script doesn't recognize the method IsInGroup, so this line does not work
{
//change the ball's speed
}
}
In the tutorial, the author uses the method is_in_group, but it seems to not exist in the mono version.
The issue is that IsInGroup is declared on the Node class, but collider is defined as Object. So you need to cast it to Node (PhysicsBody2D is probably as close to the actual type that you can get).
This happens on a technicality: The physics server only knows that the physics body is represented by an Object, and it does not care if it is a Node or not (which can be useful if you work with the API at a lower level). Yet, presumably you are not doing anything of the sort, so go ahead and cast it:
if (((PhysicsBody2D)collision.Collider).IsInGroup("rackets"))
{
//change the ball's speed
}
With that said, just in case, you could use a safe pattern, since the above code will throw if the type does not match. I'm going to encourage to check only once by introducing a variable:
var body = collision.Collider as PhysicsBody2D;
if (body != null && body.IsInGroup("rackets"))
{
//change the ball's speed
}
C# offers more compact syntax for null checks, however… Godot does not null references to Nodes when they are freed, instead they mark the instance as invalid. And as far as I can tell, Godot does not overload equality. You can check for null and invalid instances at once with IsInstanceValid:
var body = collision.Collider as PhysicsBody2D;
if (Object.IsInstanceValid(body) && body.IsInGroup("rackets"))
{
//change the ball's speed
}
By the way, you could directly check and cast to KinematicBody2D, RigidBody2D or StaticBody2D instead of PhysicsBody2D if you know what you expect.
while analyzing my code using sonarqube i came across 'variableProducerAgreements' is null on at least one execution path in the following code (the foreach loop):
however, upon looking at it and trying various things, variableProducerAgreements seems to never be null in this foreach loop. during a code review, i'm being told that it can "totally" be null and should add conditional logic to handle it. but i'm not understanding how it can be null and thus not sure how to add a conditional. any ideas?
I can't see a way in which variableProducerAgreements could be null since you have the null guard in place at the top (and assuming you don't have any crazy code in your property getters).
if (userProfile?.ProducerProfile == null)
return result;
The Where and FindAll methods in .NET doesn't return null.
However, it is possible the use of a null-conditional every time you access ProducerProfile is confusing some tools and people. Since you're returning early if it is null, you should remove them:
if (IsActingAsDelegate && userProfile.ProducerProfile.IsInactiveProducer)
{
variableProducerAgreements = userProfile.ProducerProfile.ProducerAgreements.FindAll(ag => ag.IsActive && ag.IsVariableBranchContract);
}
else
{
variableProducerAgreements = userProfile.ProducerProfile.ActiveAgreements.Where(a => a.IsVariableContract);
}
If there was a way for it to be null before the if statement, you would also risk a NullReferenceException when you access the IsInactiveProducer property.
Also, the reviewer should be able to explain his/her reasoning.
I am working in a C# based program. I am attempting to create a short circuit conditional statement:
if(safety() == 'Yes' && reason() == 'Yes')
{
allowed = true;
}
The way the software is set up, however, the software perpetually views the "reason" variable as the first condition in the if statement, no matter what order I record the variables in. This is causing the 2nd variable to always run, when really, I only need it to run when "safety" == 'Yes'.
This is a long-winded way to ask: Is there any way to override the default sequence of the variables for this one instance in the script?
Which out of the following two equivalent ways would be best for the null conditional operator in terms of primarily performance and then ease of use or clarity etc.?
This:
idString = child?.Id;
fatherName = child?.Father?.Name;
motherName = child?.Mother?.Name;
or (assuming that all local vars are null already) this:
if (child != null)
{
idString = child.Id;
fatherName = child.Father?.Name;
motherName = child.Mother?.Name;
}
Is performance even an issue?
Is performance even an issue?
Short answer: Performance about null-checks will never be an issue in a normal application. It's only a matter of readability and maintainability.
Performance:
Yes, you have 3 "explicit" checks against 1. But you must keep in mind that:
The system performs an "implicit" null-check every time you reference an object instance, as explained here, and afaik the JIT doesn't optimize null-checks at all. So in your case the rate is not just 3 against 1.
A null-check is a very (really, very) cheap operation, compared with most operations you do in a normal software flow (instance heap allocation, mathematic calculations, a linq query, graphic object rendering, string parsing, ...).
I see only a remote possibility of significant performance differences: if child or Mother or Father are not local variables or simple plain properties, but methods and properties with very long execution time. For example, a GetChild() method that takes 2 sec to execute. Can you see a realistic scenario for that? I can't. Even if that's the case, you can call GetChild() one single time and assign it to a local variable, then call child? 3 times.
Readability:
A single initial if allows to mentally separate different chunks of code. Pretend to be the reader of the code, without knowing anything else: ask yourself if is it simpler to read "if child is not null do all this operations and stuffs, otherwise just move on", or "if child is not null check the Name. If again child is not null check the Mother. If the Mother is not null get the Mother's Name. Then if again child is not null check the Father. If Father is not null... ... ... ".
Maintainability:
Aka, in this case, the DRY principle. For example, why would you repeat the null-check 3 times? Pretend that at a certain point in the future your boss asks to you a code change: it is required not only to check the nullity of a child, but also if its Id is 0 (things like that happen very frequently in any software development process). In your first code section you should correct 3 lines.
In your second code section you should correct only 1 line: the initial if.
EDIT:
For a discussion about thread-safety on the null conditional operator, see this question.
In second code example for variables will not set new values, but in first example they set as null or value from specified properties.
The ?. operator names like null-conditional operator. This operator works like:
With using ?.:
var result = someProperty?.someField;
Without using ?.:
if (someProperty != null)
result = someProperty.someField;
else
result = null;
About this operator you can read here: https://msdn.microsoft.com/en-us/library/dn986595.aspx.
It is better to use it in fluent of methods invoking. In your sample better to use second variant, because if child is null, then other actions are not perform.
I recenly encountered this problem in a project: There's a chain of nested objects, e.g.: class A contains an instance variable of class B, which in turns has an instance variable of class C, ..., until we have a node in the tree of class Z.
----- ----- ----- ----- -----
| A | ---> | B | ---> | C | ---> | D | ---> ... ---> | Z |
----- ----- ----- ----- -----
Each class provides getters and setters for its members. The parent A instance is created by an XML parser, and it is legal for any object in the chain to be null.
Now imagine that at a certain point in the application, we have a reference to an A instance, and only if it contains a Z object, we must invoke a method on it. Using regular checks, we get this code:
A parentObject;
if(parentObject.getB() != null &&
parentObject.getB().getC() != null &&
parentObject.getB().getC().getD() != null &&
parentObject.getB().getC().getD().getE() != null &&
...
parentObject.getB().getC().getD().getE().get...getZ() != null){
parentObject.getB().getC().getD().getE().get...getZ().doSomething();
}
I know that exceptions should not be used for ordinary control flow, but instead of the previous code, I have seen some programmers doing this:
try {
parentObject.getB().getC().getD().getE().get...getZ().doSomething();
} catch (NullPointerException e){}
The problem with this code is that it may be confuse when maintaining it, since it doesn't show clearly which objects are allowed to be null. But on the other hand is much more concise and less "telescopic".
Is it an acceptable to do this to save development time?
How could the API be redesigned to avoid this problem?
The only thing I can think of to avoid the long null checking is to provide void instances of the nested objects and providing isValid methods for each one of them, but wouldn't this create a lot of innecesary objects in memory?
(I've used Java code, but the same question can apply to C# properties)
Thanks.
It is bad design if parentObject needs to know that A contains a B which contains a C wich contains.... That way, everything is coupled to everything. You should have a look at the law of demeter: http://en.wikipedia.org/wiki/Law_Of_Demeter
parentObject should only call methods on its instance variable B. So, B should provide a method that allows for the decision, e.g.
public class A {
private B myB;
//...
public boolean isItValidToDoSomething(){
if(myB!=null){
return myB.isItValidToDoSomething();
}else{
return false;
}
}
}
Eventually, at the level of Z, the method has to return true.
Imho, saving development time is never a reason for tolerating problems in the design. Sooner or later these problems will steal you more time than it would have taken to fix the problems in the first place
It's bad practice to use Exceptions here.
There's a hint in the name: Exceptions are for exceptional circumstances (i.e. unexpected) . If nulls are expected values, then encountering them is not exceptional.
Instead, I'd have a look at the class hierarchy and try to understand why such deep access chaining needs to happen. This seems like a big design issue, you shouldn't normally expect the caller to construct calls using deep knowledge of the structure of objects hidden within class A.
Questions you could ask:
Why does the caller need to doSomething() with the Z object anyway? Why not put the doSomething() on class A? This could propagate doSomething() down the chain if needed and if the relevant field was not null....
What does a null mean if it exists in this chain? The meaning of a null will suggest what business logic should be employed to handle it.... which could be different at each level.
Overall, I suspect the right answer is to put doSomething() on each level of the heirarchy and have the implementation something like:
class A {
...
public void doSomething() {
B b=getB();
if (b!=null) {
b.doSomething();
} else {
// do default action in case of null B value
}
}
}
If you do this, then the API user only has to call a.doSomething(), and you have the added bonus that you can specify different default actions for a null value at each level.
Personally I like to avoid this problem altogether by using an option type. By adjusting the value returned from these methods/properties to be Option<T> rather than T the caller can choose how they wish to handle the case of no value.
An option type can either have a contained value or not (but the option itself can never be null), but the caller cannot simply pass it on without unwrapping the value so it forces the caller to deal with the fact there may be no value.
E.g. in C#:
class A {
Option<B> B { get { return this.optB; } }
}
class B {
Option<C> C { get { return this.optC; } }
}
// and so on
If the caller wants to throw, they merely retrieve the value without explicitly checking to see if there is one:
A a = GetOne();
D d = a.Value.B.Value.C.Value.D.Value; // Value() will throw if there is no value
If the caller wants to just default if any step doesn't have a value, they can perform mapping/binding/projection:
A a = GetOne();
D d = a.Convert(a => a.B) // gives the value or empty Option<B>
.Convert(b => b.C) // gives value or empty Option<C>
.Convert(c => c.D) // gives value or empty Option<D>
.ValueOrDefault(new D("No value")); // get a default if anything was empty
If the caller wants to default at each stage, they can:
A a = GetOne();
D d = a.ValueOrDefault(defaultA)
.B.ValueOrDefault(defaultB)
.C.ValueOrDefault(defaultC)
.D.ValueOrDefault(defaultD);
Option is not currently part of C# but I imagine one day will be. You can get an implementation by referencing the F# libraries or you may be able to find an implementation on the web. If you'd like mine, let me know and I'll send it to you.
Well, it depends on exactly what you're doing in the catch. In the above case, it appears that you want to call doSomething() if it's available, but if it isn't you don't care. In this case I would say that trapping the specific exception you're after is just as acceptable as a verbose check to ensure you won't throw one to begin with. There are many "null-safe" methods and extensions that use try-catch in a very similar manner to what you propose; "ValueOrDefault"-type methods are very powerful wrappers for exactly what's been done with the try-catch, for exactly the reason try-catch was used.
Try/catch is, by definition, a program flow control statement. Therefore, it is expected to be used to "control ordinary program flow"; I think the distinction you are trying to make is that it should not be used to control the "happy path" of normal error-free logic flow. Even then I might disagree; there are methods in the .NET Framework and in third-party libraries that either return the desired result or throw an exception. An "exception" is not an "error" until you cannot continue because of it; if there's something else you can try or some default case the situation can boil down to, it can be considered "normal" to receive an exception. So, catch-handle-continue is a perfectly valid use of try-catch, and many uses of exception throwing in the Framework expect you to handle them robustly.
What you want to avoid is using try/catch as a "goto", by throwing exceptions that aren't really exceptions in order to "jump" to the catch statement once some condition is satisfied. This is definitely a hack, and thus bad programming.
The problem with the "catch an exception" approach is that it seems a bit heavy-handed. The exception stack trace should show you where it failed since your method names make it quite clear where you are in the hierarchy but it is not a good way of going about it. Plus how would you recover from the exception and carry on to a good state of your code?
If you must keep this very deep hierarchy then you could use static instances of each object which defines an "empty" state. The best example I can think of which does this is the C# string class which has a static string.Empty field. Then each call of getB(), getC() ... getZ() would return either a real value or the "empty" state, allowing you to chain the method calls.
By making the "empty" state instances static there would only be one of each type in your system. But you would need to consider what an "empty" state looks like for each type in your hierarchy and make sure it doesn't affect any other part of your application inadvertently.
In Python, they encourage the style of "easier to ask forgiveness than permission", which could be applied here to say that it's better to just optimistically try to get to Z without safety checking, and let the exception handler fix a miss. That's easier to code, and it's more performant if the call of Z not being in the call chain is less likely than the case that it will be.
Aside from violating a bunch of OOP good design principles and exposing deeply nested private members, this code also seems vaguely dynamic in nature. That is, you want to call method X but only if X exists on the object, and you want that logic to apply to all objects in a hierarchy of unknown length. And you can't change the design because this is what your XML translation gives you.
Can you change languages then? Statically-typed C# may not be the best choice for what you're doing here. Maybe using Iron Python or some other language that's a little looser on typing will let you more easily manipulate your DOM. Once you've got the data in a stable state, you can pass that off to C# for the rest.
Using exceptions seem a poor fit here. What if one of the getters contained non-trivial logic, and threw a NullPointerException? Your code would swallow that exception without intending to. On a related note, your code samples exhibit different behaviour if parentObject is null.
Also, there really is no need to "telescope":
public Z findZ(A a) {
if (a == null) return null;
B b = a.getB();
if (b == null) return null;
C c = b.getC();
if (c == null) return null;
D d = c.getD();
if (d == null) return null;
return d.getZ();
}
I think you could provide static isValid methods on each class, for example for class A that would be:
public class A {
...
public static boolean isValid (A obj) {
return obj != null && B.isValid(obj.getB());
}
...
}
And so on. Then you would have:
A parentObject;
if (A.isValid(parentObject)) {
// whatever
}
However, although I won't get into you business I must say that such a method chaining does not say anything good about the design; maybe it's a sign of need for refactoring.
I agree with the other answers that this should not need to be done, but if you must here is an option:
You could create an enumerator method once such as:
public IEnumerable<type> GetSubProperties(ClassA A)
{
yield return A;
yield return A.B;
yield return A.B.C;
...
yield return A.B.C...Z;
}
And then use it like:
var subProperties = GetSubProperties(parentObject);
if(SubProperties.All(p => p != null))
{
SubProperties.Last().DoSomething();
}
The enumerator will be lazily evaluated leading to no exceptions.