patterncsharpMinor
Multiple functions to establish a fallback value for a property until not null
Viewed 0 times
untilnullvalueestablishfallbackpropertyformultiplefunctionsnot
Problem
I have a property (called "Head") that can be set externally. When "Head" is not set, it uses Unity3D's
So I developed a loop:
Would this create too much lambda overhead? Do you think the lambdas even increases readability? Is there a more elegant way to handle multiple fallbacks?
Edit:
RobH helped me discover the Null coalescing doesn't work with Unity3D components.
RobH's extension method workaround worked great with some tweaking. I had to enforce that comparison had to be done through UnityEngine.Object.
With that extension method my code is now just
MonoBehaviour functions to try to find the best value for "Head". I started with a nested if, but the nesting was starting to get out of hand.if (Head == null)
{
Head = this.GetComponent();
if (Head == null)
{
Head = this.GetComponentInChildren();
if (Head == null)
{
Head = Camera.main;
}
}
}So I developed a loop:
System.Func[] fallbacks = new System.Func[]
{
() => this.GetComponent(),
() => this.GetComponentInChildren(),
() => Camera.main,
};
foreach (var fallback in fallbacks)
{
if (Head != null)
{
break;
}
Head = fallback();
}Would this create too much lambda overhead? Do you think the lambdas even increases readability? Is there a more elegant way to handle multiple fallbacks?
Edit:
RobH helped me discover the Null coalescing doesn't work with Unity3D components.
RobH's extension method workaround worked great with some tweaking. I had to enforce that comparison had to be done through UnityEngine.Object.
public static T IfNullThen(this T obj, Func factory) where T : UnityEngine.Object
{
return obj != null ? obj : factory();
}With that extension method my code is now just
Head = Head
.IfNullThen(() => this.GetComponent())
.IfNullThen(() => this.GetComponentInChildren())
.IfNullThen(() => Camera.main);Solution
This seems to be a textbook case for the null coalescing operator
You also (probably) don't need to prefix with
Edit:
If the null coalescing operator doesn't work (which is a massive shame) why not create an extension method?
then you can do:
Unfortunately I'm on my mac so I don't have a compiler but I think it should work :)
??Head = GetComponent() ?? GetComponentInChildren() ?? Camera.main;You also (probably) don't need to prefix with
thisEdit:
If the null coalescing operator doesn't work (which is a massive shame) why not create an extension method?
public static T IfNullThen(this T obj, Func factory) where T : class
{
return obj != null ? obj : factory();
// or
// return obj == null ? factory() : obj;
}then you can do:
Head = GetComponent().IfNullThen(GetComponentInChildren).IfNullThen(() => Camera.main);Unfortunately I'm on my mac so I don't have a compiler but I think it should work :)
Code Snippets
Head = GetComponent<Camera>() ?? GetComponentInChildren<Camera>() ?? Camera.main;public static T IfNullThen<T>(this T obj, Func<T> factory) where T : class
{
return obj != null ? obj : factory();
// or
// return obj == null ? factory() : obj;
}Head = GetComponent<Camera>().IfNullThen(GetComponentInChildren<Camera>).IfNullThen(() => Camera.main);Context
StackExchange Code Review Q#85020, answer score: 6
Revisions (0)
No revisions yet.