AL icon indicating copy to clipboard operation
AL copied to clipboard

AL0603: Implicit Conversion

Open f4n0 opened this issue 5 years ago • 10 comments

Description Hi, I've just downloaded the latest AL Language from docker and I've found out this warning. I have a simple question: How can it be handled? is there some c# cast or something like that?

if MyEnum in [0, 1, 2, 5, 6] then

this will throw this warning but the enums aren't they an integer-based? Can I do something like that (or like C#)? if MyEnum in (Enum)[0, 1, 2, 5, 6] then

f4n0 avatar Feb 26 '20 10:02 f4n0

You could achieve this by doing MyEnum.AsInteger() in [0, 1, 2, 5, 6]

But this rule generates another problem. If you do that:

table 50000 "MyTable"
{
    
    fields
    {
        field(1; DocType; Enum "Sales Document Type")
        {
            
        }
    }
    
    local procedure MyProcedure()
    begin
        TestField(DocType, DocType::Order);
    end;
}

Then the TestField emits the warning on the second argument. There should be either an overload of TestField that supports Enums, or the rule should test the datatype between the field and the value in the specific case of a TestField.

nicolassaleron avatar Feb 27 '20 15:02 nicolassaleron

@nicolassaleron I can understand the design issue with this - there are a few things that aren't as slick as I'd like, such as the fact that TestField on enum fields require you to now explicitly cast the Enum value to int.

SomeTable.TestField(SomeEnumField, SomeEnumField::SomeValue) raises the above error.

SomeTable.TestField(SomeEnumField, SomeEnumField::SomeValue.AsInteger()) fixes that, but it doesn't feel very slick. Admittedly it's a small price to pay for this feature.

I suppose since AL doesn't support generics/inheritance/interfaces, there's no real way to overload TestField to make it compatible with enum types, but I'm sure some compiler magic could be put in place, after all, it's .NET in the background which can support these features.

charlespockert avatar Apr 17 '20 13:04 charlespockert

@charlespockert I completely agree with you and AsInteger is just a workaround to get rid of this problem without deactivating the rule for other interesting cases.

nicolassaleron avatar Apr 17 '20 14:04 nicolassaleron

bcv16 After downloading symbols" version 16.xx there were about 400 + similar error , how to resolve it ? manually replace by appending **.AsInteger()** at the end. or any other way to replace at one-go ? or any other option ? pls advise . thanks.

sami3187 avatar Apr 24 '20 03:04 sami3187

bcv16

After downloading symbols" version 16.xx there were about 400 + similar error , how to resolve it ? manually replace by appending .AsInteger() at the end. or any other way to replace at one-go ? or any other option ? pls advise . thanks.

Depends, you can use AsInteger in cases where your option doesn't always match the enumeration (assuming that it's the intended behaviour).

Otherwise the best option is to replace references to option with the enum type in your table fields/code.

Enum is compatible with option at the schema level so there are no issues with moving from option->enum when deploying to production as far as I understand.

charlespockert avatar Apr 24 '20 21:04 charlespockert

Noted. Thank you very much.

sami3187 avatar Apr 24 '20 23:04 sami3187

Charles , sorry, what is "AsInteger" ? How to write it ?

weiyin02 avatar Sep 10 '20 21:09 weiyin02

How do I fix this in 2020 w 1? AsInteger is not available.

Here's my line of code:

SLO.SetQtyToShip(rec."Document No.", rec."Document Type", true);

MarkCWEV avatar Nov 25 '20 11:11 MarkCWEV

It looks like this can be closed, as the original question was answered.

For those wondering about how to use AsInteger(), it is just RecordVar."Enum Field Name".AsInteger() or EnumVar.AsInteger(). If you can't do that, you must not have an Enum, maybe an Option instead. Then you have a different problem.

dzzzb avatar Aug 19 '21 11:08 dzzzb

For those wondering how to assign from an integer this is how it is done: Level := Enum::Level.FromInteger(OrdinalValue); (Example from Kaufmanns page)