Autor Beitrag
Frühlingsrolle
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1679
Erhaltene Danke: 306

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: Fr 16.06.17 15:24 
Hallo Forum

Problemstellung:
In einer enum Eigenschaft sollen die ihm zugewiesenen Attribute/Werte summiert und im Anschluss die nicht gesetzten Attribute daraus ermittelt und an ein byte[] oder ähnliches übergeben werden:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
enum Beispiel
{
    A = 1, B = 2, C = 4, D = 8
}

Beispiel bsp = Beispiel.C | Beispiel.B; // 4 + 2 = 6
// 15 - 6 = 9 

bArray[0] = 1; bArray[1] = 8;

Ich tu mir etwas schwer die korrekten Werte daraus zu ermitteln. Gibt es diesbezüglich etwas, das mir die Arbeit erleichtert oder einen anderen Ansatz?

_________________
„Wo andere blind der Wahrheit folgen, denk daran ... Nichts ist wahr!" (Assassin's Creed I-II)
C#
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 561
Erhaltene Danke: 65

Windows 10, Kubuntu, Android
Visual Studio 2017, C#, C++/CLI, C++/CX, C++, F#, R, Python
BeitragVerfasst: Fr 16.06.17 15:34 
Hey,

das sollte dein Problem lösen:

ausblenden C#-Quelltext
1:
2:
var bsp = Beispiel.C | Beispiel.B;
var notIncluded = Enum.GetValues(typeof(Beispiel)).Cast<Beispiel>().Where(b => (b & bsp) == 0)

_________________
Der längste Typ-Name im .NET-Framework ist: ListViewVirtualItemsSelectionRangeChangedEventHandler

Für diesen Beitrag haben gedankt: Frühlingsrolle
Frühlingsrolle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1679
Erhaltene Danke: 306

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: Fr 16.06.17 15:48 
Spitze, dankschön C# !

Das Thema hat sich erledigt !!!

_________________
„Wo andere blind der Wahrheit folgen, denk daran ... Nichts ist wahr!" (Assassin's Creed I-II)
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1056
Erhaltene Danke: 125

Windows 10 x64 Home Premium
C# (VS 2015 Enterprise)
BeitragVerfasst: Fr 16.06.17 22:05 
Darf ich fragen, was das bringt?

Das sieht für mich sehr nach einem Anwendungsbeispiel vom FlagsAttribute aus
Frühlingsrolle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1679
Erhaltene Danke: 306

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: Fr 16.06.17 22:54 
Meinen Beitrag betreffend habe ich dieses Attribut nicht gebraucht, da ich mir die Zahlenwerte anschauen wollte. Ich versuchte ohne Linq auszukommen, schaffte es aber nicht.
C#*s Lösung gibt als Rückgabewert "A, D" statt "1, 8" zurück. Spielt aber keinen nennenswerte Rolle, wie es dargestellt wird. :nixweiss:

_________________
„Wo andere blind der Wahrheit folgen, denk daran ... Nichts ist wahr!" (Assassin's Creed I-II)
C#
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 561
Erhaltene Danke: 65

Windows 10, Kubuntu, Android
Visual Studio 2017, C#, C++/CLI, C++/CX, C++, F#, R, Python
BeitragVerfasst: Fr 16.06.17 23:39 
Naja zu kannst ja zwischen enum und int casten:
ausblenden C#-Quelltext
1:
Enum.GetValues(typeof(Beispiel)).Cast<int>().Where(b => (b & (int)bsp) == 0)					


Du kannst das Ganze natürlich auch ohne Linq machen. Ich wüsste nur nicht warum. Zumal du dann nicht um eine Schleife herum kommst. Irgendwie musst du ja alle Elemente des Enums abfragen.

_________________
Der längste Typ-Name im .NET-Framework ist: ListViewVirtualItemsSelectionRangeChangedEventHandler
Frühlingsrolle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1679
Erhaltene Danke: 306

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: Sa 17.06.17 00:13 
Richtig, ohne Linq würde ich vieles mit Schleifen durchgehen müssen, nicht nur das enum im angeführten Beispiel.
Ling setzt mindestens das .NET Framework 3.5 voraus. Die meisten Anwender werden sowieso die Version 4 und höher auf ihrem System haben, denn heutigen Spiele installieren es oft genug mit, inkl. dem VC++ Framework.

Das Thema an sich war notwendig, um das Delphi-interne set of TBeispiel in C# nachzustellen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
type
  TBeispielEnum = ( A = 1, B = 2, C = 4, D = 8 );  // Wertzuweisungen könnten ausgelassen werden
  TBeispiel = set of TBeispielEnum;
  // ...
  end;

var
  bsp: TBeispiel;
begin
  bsp := [C, B];
  // ...
end;

Wurde bereits erwähnt:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
enum Beispiel : byte  // mit dem Typ byte ist die Größe auch ident 
{
    A = 1, B = 2, C = 4, D = 8
}

Beispiel bsp = Beispiel.C | Beispiel.B;

... wobei ich konkret die Werte brauch', die nicht zugewiesen sind. Dazu hat user profile iconC# eine schöne Lösung präsentiert.

_________________
„Wo andere blind der Wahrheit folgen, denk daran ... Nichts ist wahr!" (Assassin's Creed I-II)
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4153
Erhaltene Danke: 822


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Sa 17.06.17 13:13 
C# Enums sind maximal ein ähnliches Konzept zu Delphi Sets da sollte man vorsichtig sein das eine mit dem anderen nachzustellen.

Ein Enum ist keine Aufzählung aller gültigen Werte dieses Enums. Eine Enum ist eine Aufzählung aller benannten Werte des Basistypen. Es sind aber alle Werte des Basistypen erlaubt auch die nicht benannten. Insofern würde ich wenn ich eine solche Fragestellung hätte wie deine am Enum erstmal explizit definieren was denn erlaubt sein soll (ein All Eintrag im enum). Das gibt dann, denke ich einen halbwegs lesbaren Syntax auch wenn man mit einem Mengen-Mindset an die Sache geht ;)

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
[Flags]
enum Beispiel
{
    None = 0,
    A = 1
    B = 2
    C = 4
    D = 8,
    All = A | B | C | D
}

var bsp = Beispiel.C | Beispiel.B;
var notIncluded = Beispiel.All & ~bsp;


Richtig lesbar wird es dann wenn man passende Extension Methods einsetzt auch wenn enums nur ein mäßig gutes Ziel dafür sind.

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
var bsp = Beispiel.C | Beispiel.B;
var notIncluded2 = Beispiel.All.Without(bsp);

public static class EnumExtensions
{
    public static T Without<T>(this Enum value, T without) where T : struct, IComparable, IFormattable, IConvertible  // genauest mögliche Enum Einschränkung
    {
        if (!typeof(T).IsEnum)
            throw new ArgumentException($"{nameof(T)} is not an enum type.");
        if (!(value is T))
            throw new ArgumentException($"{nameof(value)} is not of type {nameof(T)}");

        return (T)ConvertToUnderlyingType(typeof(T), Convert.ToInt64(value) & ~Convert.ToInt64(without));
    }

    private static object ConvertToUnderlyingType(Type enumType, long value)
    {
        // Drecks Typesystem!!
        switch (Type.GetTypeCode(enumType.GetEnumUnderlyingType()))
        {
            case TypeCode.Byte:
                return Convert.ToByte(value);
            case TypeCode.SByte:
                return Convert.ToSByte(value);
            case TypeCode.UInt16:
                return Convert.ToUInt16(value);
            case TypeCode.Int16:
                return Convert.ToInt16(value);
            case TypeCode.UInt32:
                return Convert.ToUInt32(value);
            case TypeCode.Int32:
                return Convert.ToInt32(value);
            case TypeCode.UInt64:
                return Convert.ToUInt64(value);
            case TypeCode.Int64:
                return Convert.ToInt64(value);
            case TypeCode.Object:
            default:
                throw new InvalidOperationException($"Unknown underlying type of enum {enumType.FullName}");
        }
    }
}



PS. Da gerade das Highlighting im Forum ein Thema war. Der cs Highlighter kennt Interpolated Strings noch nicht.


Zuletzt bearbeitet von Ralf Jansen am Mo 19.06.17 11:04, insgesamt 1-mal bearbeitet

Für diesen Beitrag haben gedankt: Frühlingsrolle
Frühlingsrolle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1679
Erhaltene Danke: 306

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: Sa 17.06.17 14:47 
Vielen Dank Ralf Jansen. Deine Without<T>() Methode gefällt mir gut. Ich könnte mir vorstellen, so oder so ähnlich, eine Klasse zu entwerfen, die als Eigenschaft (im Eigenschaft-Fenster), ein C#-enum entsprechend darstellt, wie Delphi sein set (im Objektinspektor):

csharp_enum

Das ist zwar nicht Anforderung an das Thema, aber ein schönes "Nebenprodukt".
Einloggen, um Attachments anzusehen!
_________________
„Wo andere blind der Wahrheit folgen, denk daran ... Nichts ist wahr!" (Assassin's Creed I-II)
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Chefentwickler
Beiträge: 20052
Erhaltene Danke: 1877

Win 10
C# (VS 2015)
BeitragVerfasst: Sa 17.06.17 14:58 
== Off-Topic Start ==

user profile iconRalf Jansen hat folgendes geschrieben Zum zitierten Posting springen:
PS. Da gerade das Highlighting im Forum ein Thema war. Der cs Highlighter kennt Interpolated Strings noch nicht.

Das ist auch ziemlich fies. Aber lokal scheint es zu gehen, wenn ich C# als Inline-Sprache von C# einbinde :nut:

== Off-Topic Ende ==

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4153
Erhaltene Danke: 822


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mo 19.06.17 11:03 
Kleine Anmerkung. Jetzt wo ich das nochmal gesehen habe ist die Verwendung des (^) XOR Operators eher falsch. Es sollte besser das klassische &~ sein. Ich zieh mal den Code nach.
Frühlingsrolle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1679
Erhaltene Danke: 306

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: Mo 19.06.17 11:57 
& (bitweise AND) ~ (bitweise NOT) ... im Vergleich zu
&& (logisch AND) ! (logisch NOT)

_________________
„Wo andere blind der Wahrheit folgen, denk daran ... Nichts ist wahr!" (Assassin's Creed I-II)
C#
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 561
Erhaltene Danke: 65

Windows 10, Kubuntu, Android
Visual Studio 2017, C#, C++/CLI, C++/CX, C++, F#, R, Python
BeitragVerfasst: Mo 19.06.17 14:33 
Gibts da ne konkrete Frage dazu?

_________________
Der längste Typ-Name im .NET-Framework ist: ListViewVirtualItemsSelectionRangeChangedEventHandler

Für diesen Beitrag haben gedankt: Frühlingsrolle
Frühlingsrolle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1679
Erhaltene Danke: 306

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: Mo 19.06.17 19:31 
Nö, keine Frage. Jemand wird Ralf Jansen's Beitrag lesen und vielleicht nicht verstehen, was er mit den Zeichen meinte. Danke aber für die Bereitschaft. :zustimm:

_________________
„Wo andere blind der Wahrheit folgen, denk daran ... Nichts ist wahr!" (Assassin's Creed I-II)