Pointers of generic type?
Instead of supplying a pointer to the value, supply a setter:
class CommandChangeValue<T> : Command
{
T _previous;
T _new;
Action<T> _set;
public CommandChangeValue(T value, Action<T> setValue, T newValue)
{
_previous = value;
_new = newValue;
_set = setValue;
setValue(_new);
}
public void Undo() { _set(_previous); }
public void Redo() { _set(_new); }
}
// ...
double v = 42;
var c = new CommandChangeValue(v, d => v = d, 99);
Just for the record you can get a pointer to a generic type or any other type using these methods....
/// <summary>
/// Provides the current address of the given element
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="t"></param>
/// <returns></returns>
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public static System.IntPtr AddressOf<T>(T t)
//refember ReferenceTypes are references to the CLRHeader
//where TOriginal : struct
{
System.TypedReference reference = __makeref(t);
return *(System.IntPtr*)(&reference);
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
static System.IntPtr AddressOfRef<T>(ref T t)
//refember ReferenceTypes are references to the CLRHeader
//where TOriginal : struct
{
System.TypedReference reference = __makeref(t);
System.TypedReference* pRef = &reference;
return (System.IntPtr)pRef; //(&pRef)
}
I have used them along with a few others to implement a form of slicing used with Arrays.
C# 7.3 solved that issue with new generic constraint - unmanaged
.
Basically it allows to do something like that:
void Hash<T>(T value) where T : unmanaged
{
// Okay
fixed (T* p = &value)
{
...
}
}
Docs