- Home /
Change calling object with extension method
Hello, I've tried creating a very simple function:
public static void AssignIfNull(this UnityEngine.Object o, UnityEngine.Object obj)
{
if (o == null)
{
Debug.Log(obj);
o = obj;
Debug.Log(o);
}
}
However, while Debug.Log(o) outputs the correct object, the real object doesn't change. Is it possible to set the calling object to something else with an extension method?
Answer by Namey5 · Mar 29, 2020 at 03:38 AM
As much as it probably looks like this should work, both parameters are still being passed by copy, meaning although you are changing the object reference, you're only changing it in the local context of the function. Luckily enough, according to the C# docs;
Beginning with C# 7.2, you can add the ref modifier to the first argument of an extension method.
Meaning in theory you should be able to change the function to something like this;
public static void AssignIfNull (ref this UnityEngine.Object o, UnityEngine.Object obj)
{
if (o == null)
{
Debug.Log(obj);
o = obj;
Debug.Log(o);
}
}
Haven't tried this personally, so there may be some logical thing I'm overlooking here, but this is how I would think of going about it.
Thanks for the help!
Sadly, it appears that combining this
with ref
doesn't work, in fact it seems that this entire idea of an extension method that modifies the caller is impossible to create that simply. Here I found out why it doesn't work.
That was posted in 2011, long before C# supported the ref modifier with extension methods. If you wish to see the official documentation that says you can do the above, see here;
https://docs.microsoft.com/en-us/dotnet/csharp/program$$anonymous$$g-guide/classes-and-structs/extension-methods
Whether this functionality is supported by the version of C# Unity uses is up for debate, as this would appear to have been implemented in the last year or two. The only way to find out would be to test it.
Ok so I've just done some tests, and it would appear that passing 'this' by reference only works for struct types. However, the principle still applies, and even though you may not be able to do it directly through an extension method, there's nothing stopping you from just writing something like this;
public static void AssignIfNull (ref UnityEngine.Object a, ref UnityEngine.Object b)
{
if (a == null)
a = b;
}
This is what I was getting at. I can do that, but Extension methods with ref are impossible at the moment, and I'm still not entirely convinced that they should be.
Yeah. $$anonymous$$y best guess would be that assigning to an object with the modifier of 'this' (or even assigning to 'this' directly) for class types would end up with unhandled memory, as reassigning the class pointer from within the instance would probably bypass the destructor. Although, in the original case that you are trying to do this, are you trying to point the current instance to the location of the second, or are you simply trying to copy its values?