-
Notifications
You must be signed in to change notification settings - Fork 241
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pass by Value becomes, Pass by Reference when using Variant or RecordRef as Parameter and make assignments to other Records #7312
Comments
It is a record reference. So, even if passing by value, you are passing a reference by value. If you want to update an instance within the function only, then first N.B. I don't particularly like this, nor how it is a 'gotcha' that types like |
You are missing the point here. Input parameter is Variant, and problem originated using DataType Management. |
I don't think I'm missing any point, but it'd be easy to miss in the convoluted original post. As far as I can see, you are passing a Variant containing a reference to a record, which is a copy of that reference put into the variant, so just like any normal record ref copy (assignment or passing directly to a function), updates to the copy are reflected in its source. |
Reference should be changed only in the same scope. |
Point is: The You will find the same 'problem' or 'design decision' with things like |
I agree with @SarkeSrb - a function the parameters of which are not defined as reference, must not be able to change the original variable! |
That's nice, but that's not how AL works. Some types 'are' references, and thus have reference semantics even when they're not passed by |
Can you please let Microsoft make a decision here thx. |
I'm not trying to make decisions for Microsoft, but I'm pointing out a very obvious issue they must consider before considering changing this behaviour. If you can come here and say 'just change this entire behaviour of the language!', I can say 'no, do not' because I do not have time to have mine or previous developers' existing code broken suddenly; there is enough else to fix. I don't need any help with my code because I know what I'm doing, and use this as a documented behaviour and not a bug, but thanks for the rather patronising offer :-D |
RecordRef in AL behaves like a reference type in c#. If you are familiar with c# have a look at this example: using System;
var recordRef = new RecordRef()
{
MyInt = 1,
MyString = "bar"
};
Test(recordRef);
Console.WriteLine(recordRef.MyInt); // 4
Console.WriteLine(recordRef.MyString); // foo
TestWithoutRef(recordRef);
Console.WriteLine(recordRef.MyInt); // 4
Console.WriteLine(recordRef.MyString); // foo
TestWithRef(ref recordRef);
Console.WriteLine(recordRef.MyInt); // 99
Console.WriteLine(recordRef.MyString); // foobar
void Test(RecordRef recordRef)
{
recordRef.MyInt = 4;
recordRef.MyString = "foo";
}
void TestWithoutRef(RecordRef recordRef)
{
recordRef = new RecordRef(); // assign new RecordRef
recordRef.MyInt = 99;
recordRef.MyString = "foobar";
}
void TestWithRef(ref RecordRef recordRef)
{
recordRef = new RecordRef(); // assign new RecordRef
recordRef.MyInt = 99;
recordRef.MyString = "foobar";
}
public class RecordRef // class: reference type
{
public int MyInt { get; set; }
public string MyString { get; set; }
}
This is true for value types but not for reference types. see https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/reference-types dnbp is correct on this point. |
Yes, I know many programing languages and they all have, references book or guide or documentation or help. And every single one has its specific behavior documented. Here it is stated:
Yes, it is CAL and here is a difference page. AL is successor of CAL since it is not differently documented it should behave the same. |
C/AL behaved exactly the same way with This is long-established behaviour, has not changed, and therefore cannot be changed. What we probably want here is someone to file a bug at https://github.com/MicrosoftDocs/dynamics365smb-devitpro-pb/issues and request that this warning be far clearer (e.g. ' |
And where exactly do you see here in your screenshots that it is referring to a function parameter??? And once again point here is the Function parameter passed as value and passed as reference not variable scope of reference variables. |
Non- Anyway, I give up. |
A few things to consider here:
The best solution here is to update documentation to call out this behaviour so we have it in writing that it's expected to behave like this. This can be done at: https://github.com/MicrosoftDocs/dynamics365smb-devitpro-pb/issues |
When passing RecordRef as Variant by Value and change assignments to a local RecordRef to a different table it acts like a Pass by Reference and changes the value of the passed parameter like it is passed by Reference even if it is not.
*NOTE: This is isolated example problem originated using Data Type Management Codeunit
Steps to reproduce the behavior:
And in documentation it is stated that “If one RecordRef variable is assigned to another RecordRef variable, then they both refer to the same table instance.” But why it is changing pass as value to pass as reference?
3. Expected behavior
4. Versions:
The text was updated successfully, but these errors were encountered: