Avatar billede hrc Mester
23. oktober 2019 - 11:56 Der er 8 kommentarer og
2 løsninger

En boolsk array

I Delphi kan man lave en array med to elementer, som kan tilgås med false og true:

const
  msg: array[boolean] of string = ('no','yes');
begin
  result := msg[false]; // returnerer "no"
  result := msg[EnTaeller = 100]; // et boolsk argument laver direkte opslag i msg
end;

Det vil jeg gerne kunne i C#, men synes Google er lidt tavs på mine spørgsmål.

Har prøvet at lave en array (som fejler):
public static readonly string[] StatusArr = { "NOK", "OK" };
bool IsOK = false;
lStatus.Text = StatusArr[(int) IsOK]; // fejl, cannot cast to int

Jeg vil gerne undgå konstruktioner som disse:
if (IsOK)
{
  return "yes";
}
else
{
  return "no";
}

Hvad er en elegant løsning i C#? Nedenstående er dejlig kompakt men ikke specielt smukt:
lStatus.Text = IsOK ? "yes" : "no";
Avatar billede arne_v Ekspert
23. oktober 2019 - 16:20 #1
Der er ikke en super elegant løsning.

Sprog i Pascal familien (Pascal, Modula-2, Oberon, Ada etc.) har generelle array index.

Sprog i C familien (C, C++, Java, C# etc.) har array index fra 0 til N-1.

Der er visse workarounds som masske vil give paenere kode.

Eksempler:


using System;

namespace Indexing
{
    public static class Extensions
    {
        public static int AsInt(this Boolean b)
        {
            return b ? 1 : 0;   
        }
    }
    public class StatusClass
    {
        public string this[bool b] { get { return b ? "OK" : "NOK"; } }
    }
    public class MyInt
    {
        public int Value { get; set; }
        public static explicit operator MyInt(bool b)
        {
            return b ? new MyInt { Value = 1 } : new MyInt { Value = 0 };
        }
        public static implicit operator int(MyInt mi)
        {
            return mi.Value;
        }
    }
    public class Program
    {
        public static readonly string[] StatusArr = { "NOK", "OK" };
        public static int Int(bool b)
        {
            return b ? 1 : 0;
        }
        private static readonly StatusClass StatusObj = new StatusClass();
        public static void Main(string[] args)
        {
            bool IsOK = false;
            // inline
            Console.WriteLine(StatusArr[IsOK ? 1 : 0]);
            // method
            Console.WriteLine(StatusArr[Int(IsOK)]);
            // extension method
            Console.WriteLine(StatusArr[IsOK.AsInt()]);
            // indexer
            Console.WriteLine(StatusObj[IsOK]);
            // explicit and implicit conversion
            Console.WriteLine(StatusArr[(MyInt)IsOK]);
            //
            Console.ReadKey();
        }
    }
}
Avatar billede hrc Mester
24. oktober 2019 - 09:43 #2
Tak for feedback. Jeg er i processen at lære at leve med C# og .NET og forventer mindst at kunne lave de samme ting som tidligere. Det undrede mig derfor, at Anders Hejlsberg, nu han skulle i gang med .NET (og dermed C#) ikke fik forhandlet sådan en detalje med. Jeg har brugt det meget, men dine eksempler viser fint, at det kan klares pænt med "?".
Avatar billede arne_v Ekspert
24. oktober 2019 - 14:54 #3
C# er et sprog i C familien ikke i Pascal familien. Inspirationen til C# er vel 3/4 Java og 1/4 C++. Han valgte at følge "trended". Og husk at skiftede ikke Delphi -> C#. Han skiftede Delphi -> MS Java -> C#.
Avatar billede arne_v Ekspert
24. oktober 2019 - 14:59 #4
Jeg glemte iøvrigt en løsning: Dictionary.


using System;
using System.Collections.Generic;

namespace Indexing
{
    public static class Extensions
    {
        public static int AsInt(this Boolean b)
        {
            return b ? 1 : 0;   
        }
    }
    public class StatusClass
    {
        public string this[bool b] { get { return b ? "OK" : "NOK"; } }
    }
    public class MyInt
    {
        public int Value { get; set; }
        public static explicit operator MyInt(bool b)
        {
            return b ? new MyInt { Value = 1 } : new MyInt { Value = 0 };
        }
        public static implicit operator int(MyInt mi)
        {
            return mi.Value;
        }
    }
    public class Program
    {
        public static readonly string[] StatusArr = { "NOK", "OK" };
        public static int Int(bool b)
        {
            return b ? 1 : 0;
        }
        private static readonly StatusClass StatusObj = new StatusClass();
        private static readonly Dictionary<bool, string> StatusDict;
        static Program()
        {
            StatusDict = new Dictionary<bool, string>();
            StatusDict[false] = "NOK";
            StatusDict[true] = "OK";
        }
        public static void Main(string[] args)
        {
            bool IsOK = false;
            // inline
            Console.WriteLine(StatusArr[IsOK ? 1 : 0]);
            // method
            Console.WriteLine(StatusArr[Int(IsOK)]);
            // extension method
            Console.WriteLine(StatusArr[IsOK.AsInt()]);
            // indexer
            Console.WriteLine(StatusObj[IsOK]);
            // explicit and implicit conversion
            Console.WriteLine(StatusArr[(MyInt)IsOK]);
            // dictionary
            Console.WriteLine(StatusDict[IsOK]);
            //
            Console.ReadKey();
        }
    }
}
Avatar billede arne_v Ekspert
24. oktober 2019 - 15:07 #5
Den sidste løsning er måske den mest interessante.

Arrays er faktisk sjældent det bedste valg i C#.

Hvis du vil have et array med normale index så er List<> ofte bedre.

Hvis du vil have et array med sjove index så er Dictionary<> ofte bedre.
Avatar billede arne_v Ekspert
24. oktober 2019 - 17:45 #6
Der er iøvrigt et par detaljer i mit eksempel som kan laves bedre i C# 6.0 eller nyere (8.0 er current).

Jeg vil muligvis poste en modificeret version senere.
Avatar billede arne_v Ekspert
25. oktober 2019 - 01:48 #7
C# 6.0+:


using System;

using Support;
using static Support.Globals;

namespace Indexing
{
    public class Program
    {
        public static void Main(string[] args)
        {
            bool IsOK = false;
            // inline
            Console.WriteLine(StatusArr[IsOK ? 1 : 0]);
            // method
            Console.WriteLine(StatusArr[Int(IsOK)]);
            // extension method
            Console.WriteLine(StatusArr[IsOK.AsInt()]);
            // indexer
            Console.WriteLine(StatusObj[IsOK]);
            // explicit and implicit conversion
            Console.WriteLine(StatusArr[(MyInt)IsOK]);
            // dictionary
            Console.WriteLine(StatusDict[IsOK]);
            //
            Console.ReadKey();
        }
    }
}



using System;
using System.Collections.Generic;

namespace Support
{
    public static class Extensions
    {
        public static int AsInt(this Boolean b)
        {
            return b ? 1 : 0;
        }
    }
    public class StatusClass
    {
        public string this[bool b] { get { return b ? "OK" : "NOK"; } }
    }
    public class MyInt
    {
        public int Value { get; set; }
        public static explicit operator MyInt(bool b)
        {
            return b ? new MyInt { Value = 1 } : new MyInt { Value = 0 };
        }
        public static implicit operator int(MyInt mi)
        {
            return mi.Value;
        }
    }
    public static class Globals
    {
        public static readonly string[] StatusArr = { "NOK", "OK" };
        public static int Int(bool b)
        {
            return b ? 1 : 0;
        }
        public static readonly StatusClass StatusObj = new StatusClass();
        public static readonly Dictionary<bool, string> StatusDict = new Dictionary<bool, string>() { [false] = "NOK", [true] = "OK" };
    }
}
Avatar billede hrc Mester
07. april 2020 - 16:34 #8
Hej Arne. Tak for dine input. Jeg sidder i en transformationssituation og den føles nogle gange noget ond. Skal jeg have en chance, for at nå at mestre (hvis det er muligt) C#, inden jeg skal pensioneres om små 30 år, så bliver jeg nødt til at kunne holde tingene op mod noget jeg er vant til. Dine input er altid veldokumenterede og fornuftige.
Avatar billede arne_v Ekspert
07. april 2020 - 16:54 #9
Der er heldigvis en masse på nettet omkring C#.

Jeg har også selv skrevet lidt:
  https://www.vajhoej.dk/arne/articles_dotnet.html
Avatar billede hrc Mester
07. april 2020 - 17:26 #10
På internettet er information sjældent det vanskeligste. Dét er at finde hoved og hale i det. :-) Jeg kigger på dit link.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester