[Proposal] allowing ref (readonly) when declaring casting operators #1973
Replies: 6 comments
-
How would the refness of a ref-returned implicit conversion result be utilized? Can you write a usage example to help clarify what kinds of scenarios this is for? |
Beta Was this translation helpful? Give feedback.
-
Sure! Say that you have a reference type used for definitions (and allow me to borrow here the class "ScriptableObject" of Unity game engine), like: public sealed class AudioDefinition : ScriptableObject
{
[SerializeField, HideInInspector] private AudioClip _clip = null;
[SerializeField, HideInInspector] private float _volume = 1f;
[SerializeField, HideInInspector] private float _pitch = 0;
public ref readonly AudioClip Clip => ref _clip;
public ref readonly float Volume => ref _volume;
public ref readonly float Pitch => ref _pitch;
} ... and that you want to create pool of elements that contain such definitions. A way of achieving it would be for example: public abstract class ScriptableEntry<TScriptable> : ScriptableObject
where TScriptable : ScriptableObject, new()
{
private static TScriptable DefaultScriptable { get; } = default;
[SerializeField] private TScriptable _scriptable = default;
public ref readonly TScriptable Element => ref _scriptable;
public static implicit operator TScriptable(ScriptableEntry<TScriptable> entry)
{
return entry == null ? DefaultScriptable : entry.Element;
}
...
}
public class AudioEntry : ScriptableEntry<AudioDefinition>
{
private static readonly AudioEntry _DefaultEntry = default;
public static ref readonly AudioEntry DefaultEntry => ref _DefaultEntry;
....
} Then, you could define a pool for this case like: public class AudioPool : ScriptableObject
{
[SerializeField] private AudioEntry[] _entries = null;
public int Count => _entries?.Length ?? 0;
public ref readonly AudioEntry this[int position] => ref (position >= 0 && position < Count) ? ref _entries[position] : ref AudioEntry.DefaultEntry;
...
} And finally somewhere else have an instance of an audio pool where you could write the following: private void SomeMethod()
{
...
AudioDefinition definition = _myAudioPool[position];
...
} The code is neither optimized nor validates values in many places, but it reflects the spirit of the proposal. |
Beta Was this translation helpful? Give feedback.
-
@Ultrahead What is the point of using |
Beta Was this translation helpful? Give feedback.
-
@svick: I'm coding by inertia :) |
Beta Was this translation helpful? Give feedback.
-
Why do this in the first place? |
Beta Was this translation helpful? Give feedback.
-
Noted. Now focusing on the proposal it-self ... |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Currently if you do something like ...:
... where IsPlaying returns a ref readonly boolean, the null conditional operator applied on DispatchManager, breaks the "ref-ness" of the IsPlaying getter.
Given that there is not allow to declare an expression like ...:
if (ref DispatchManager?.IsPlaying ?? ref _DefaultValue) { ... }
... a way to bypass that is writing something like the following code:
Now, a similar situation occurs if you declare casting operators this way:
Here you lose the benefit of the ref getter, even if you modify it like this:
Why? Because casting operators do not support ref (readonly) scenarios.
Thus, the proposal here is to allow coding something like:
Beta Was this translation helpful? Give feedback.
All reactions