Schlagwort-Archive: NET Framework

Ready-to-Use C# Enumeration Extension Methods

Bei dem unten stehenden Code handelt es sich um fertige Enum Extension Methods in C#. Damit lassen sich unter anderem

  • die Enum Description
  • der Enum Comment
  • das Enum Value
  • alle Enum Values und
  • gesetzte Enum Flags

auslesen. Der Code ist bereits ein wenig in die Jahre gekommen und einige Methoden habe ich lediglich noch aus Kompatiblitätsgründen drin. Die Tests sind mit Machine.Specifications 0.6.2 geschrieben.

Kopiert euch einfach, was ihr benötigt und passt es nach Belieben an. Über Likes oder Comments, wenn euch der Code Arbeit gespart hat, wäre ich dankbar.

Über gute Alternativen zu Enums könnt ihr hier etwas lesen.

 

Implementierung:

public static class EnumerationExtensions

{

    public static bool ByteIsSet<TEnum>(this Enum bytes, TEnum enumValue)

    {

        if (!Attribute.IsDefined(typeof (TEnum), typeof (FlagsAttribute)) ||

            bytes.GetType() != enumValue.GetType() ||

            bytes.GetType() != typeof (TEnum))

        {

            return false;

        }

 

        return ((Convert.ToInt32(bytes) & Convert.ToInt32(enumValue)) == Convert.ToInt32(enumValue));

    }

 

    public static IList<EnumEntry> GetEnumerationEntries(this Type enumeration)

    {

        var values = Enum.GetValues(enumeration);

 

        var result = new List<EnumEntry>();

 

        foreach (var value in values)

        {

            // ReSharper disable ExpressionIsAlwaysNull

            var desc = (value as Enum).GetEnumDescription();

            var comment = (value as Enum).GetEnumComment();

            // ReSharper restore ExpressionIsAlwaysNull

 

            var name = Enum.GetName(enumeration, value);

            var id = (int)value;

 

            result.Add(new EnumEntry

                       {

                           Name = name,

                           Id = id,

                           DisplayName = desc,

                           Comment = comment

                       });

        }

 

        return result;

    }

 

    public static string GetEnumDescriptionIfExists(this Enum enumeration)

    {

        return GetEnumDescription(enumeration, true);

    }

 

    public static string GetEnumDescription(this Enum enumeration)

    {

        return GetEnumDescription(enumeration, false);

    }

 

    private static string GetEnumDescription(Enum enumeration, bool nullIfNotExists)

    {

        var fi = enumeration.GetType().GetField(enumeration.ToString());

 

        if (fi == null)

        {

            return nullIfNotExists ? null : string.Empty;

        }

 

 

        var attribute = (DescriptionAttribute[])fi.GetCustomAttributes(typeof (DescriptionAttribute), false);

 

        if (attribute.Length > 0)

        {

            return attribute[0].Description;

        }

 

 

        return nullIfNotExists ? null : enumeration.ToString();

    }

 

    public static string GetEnumCommentIfExists(this Enum enumeration)

    {

        return GetEnumComment(enumeration, true);

    }

 

    public static string GetEnumComment(this Enum enumeration)

    {

        return GetEnumComment(enumeration, false);

    }

 

    private static string GetEnumComment(Enum enumeration, bool nullIfNotExists)

    {

        var fi = enumeration.GetType().GetField(enumeration.ToString());

 

        if (fi == null)

        {

            return nullIfNotExists ? null : string.Empty;

        }

 

        var attr = (EnumCommentAttribute[])(fi.GetCustomAttributes(typeof (EnumCommentAttribute), false));

 

        if (attr.Length > 0)

        {

            return attr[0].ResourceComment;

        }

 

        var result = GetEnumDescription(enumeration);

        return nullIfNotExists ? null : result;

    }

 

    public static bool HasValue(this Enum enumeration)

    {

        if (enumeration == null)

        {

            return false;

        }

 

        var type = enumeration.GetType();

        // ReSharper disable once CheckForReferenceEqualityInstead.1

        if (type.Equals(null))

        {

            return false;

        }

 

        var fi = enumeration.GetType().GetField(enumeration.ToString());

        if (fi.Equals(null))

        {

            return false;

        }

 

        return true;

    }

}

 

Contract:

public class EnumEntry

{

    public int Id { get; set; }

    public string Name { get; set; }

    public string DisplayName { get; set; }

    public string Comment { get; set; }

}

Tests:

internal class EnumerationExtensionsSpecs{

    internal class EnumBase

    {

        protected enum DummyEnum

        {

            [Description("Desc1")]

            WithDescription = 1,

 

            WithoutDescription = 2

        }

 

        protected enum DummyEnum2

        {

            [EnumComment("Comment1")]

            WithComment = 1,

 

            WithoutComment = 2

        }

 

        protected enum DummyEnum3

        {

            WithValue = 1,

 

            WithoutValue

        }

 

        protected enum DummyEnum4

        {

            [Description("DisplayName1")]

            [EnumComment("Comment1")]

            Value1 = 1,

 

            [Description("DisplayName2")]

            [EnumComment("Comment2")]

            Value2 = 2

        }

    }

 

    [Subject(typeof (EnumerationExtensions))]

    internal class Wenn_eine_Enum_2_Werte_besitzt_und_diese_aufgelistet_werden_sollen : EnumBase

    {

        private static IList<EnumEntry> _result;

 

        private Establish context = () => { };

 

        private Because of = () => { _result = (typeof (DummyEnum4)).GetEnumerationEntries(); };

 

        private It dann_ergeben_sich_daraus_2_Listenwerte = () => _result.Count.ShouldEqual(2);

 

        private It dann_werden_alle_Daten_von_Wert1_auf_den_Listeneintrag1_gemappt = () => (

                                                                                               _result.First().Id == 1

                                                                                               && _result.First().Name == "Value1"

                                                                                               && _result.First().DisplayName == "DisplayName1"

                                                                                               && _result.First().Comment == "Comment1"

                                                                                           )

                                                                                               .ShouldBeTrue();

 

        private It dann_werden_alle_Daten_von_Wert2_auf_den_Listeneintrag2_gemappt = () => (

                                                                                               _result.Last().Id == 2

                                                                                               && _result.Last().Name == "Value2"

                                                                                               && _result.Last().DisplayName == "DisplayName2"

                                                                                               && _result.Last().Comment == "Comment2"

                                                                                           )

                                                                                               .ShouldBeTrue();

    }

 

    [Subject(typeof (EnumerationExtensions))]

    internal class When_an_Enum_is_decorated_with_a_description_and_null_if_emtpy_is_requested : EnumBase

    {

        private static string _result;

 

        private Establish context = () => { };

 

        private Because of = () => { _result = DummyEnum.WithDescription.GetEnumDescriptionIfExists(); };

 

        private It should_resolve_the_description_text = () => _result.ShouldEqual("Desc1");

    }

 

    [Subject(typeof (EnumerationExtensions))]

    internal class When_an_Enum_is_not_decorated_with_a_description_and_null_if_emtpy_is_requested : EnumBase

    {

        private static string _result;

 

        private Establish context = () => { };

 

        private Because of = () => { _result = DummyEnum.WithoutDescription.GetEnumDescriptionIfExists(); };

 

        private It should_resolve_null = () => _result.ShouldBeNull();

    }

 

    [Subject(typeof (EnumerationExtensions))]

    internal class When_an_Enum_is_decorated_with_a_description_and_name_if_empty_is_requested : EnumBase

    {

        private static string _result;

 

        private Establish context = () => { };

 

        private Because of = () => { _result = DummyEnum.WithDescription.GetEnumDescription(); };

 

        private It should_resolve_the_description_text = () => _result.ShouldEqual("Desc1");

    }

 

    [Subject(typeof (EnumerationExtensions))]

    internal class When_an_Enum_is_not_decorated_with_a_description_and_name_if_empty_is_requested : EnumBase

    {

        private static string _result;

 

        private Establish context = () => { };

 

        private Because of = () => { _result = DummyEnum.WithoutDescription.GetEnumDescription(); };

 

        private It should_return_the_name_of_the_enum_value = () => _result.ShouldEqual("WithoutDescription");

    }

 

    [Subject(typeof (EnumerationExtensions))]

    internal class When_an_Enum_is_decorated_with_a_comment_and_name_if_empty_is_requested : EnumBase

    {

        private static string _result;

 

        private Establish context = () => { };

 

        private Because of = () => { _result = DummyEnum2.WithComment.GetEnumComment(); };

 

        private It should_return_the_name_of_the_enum_value = () => _result.ShouldEqual("Comment1");

    }

 

    [Subject(typeof (EnumerationExtensions))]

    internal class When_an_Enum_is_not_decorated_with_a_comment_and_name_if_empty_is_requested : EnumBase

    {

        private static string _result;

 

        private Establish context = () => { };

 

        private Because of = () => { _result = DummyEnum2.WithoutComment.GetEnumComment(); };

 

        private It should_return_the_name_of_the_enum_value = () => _result.ShouldEqual("WithoutComment");

    }

 

    [Subject(typeof (EnumerationExtensions))]

    internal class When_an_Enum_is_decorated_with_a_comment_and_null_if_empty_is_requested : EnumBase

    {

        private static string _result;

 

        private Establish context = () => { };

 

        private Because of = () => { _result = DummyEnum2.WithComment.GetEnumCommentIfExists(); };

 

        private It should_resolve_the_description_text = () => _result.ShouldEqual("Comment1");

    }

 

    [Subject(typeof (EnumerationExtensions))]

    internal class When_an_Enum_is_not_decorated_with_a_description_and_null_if_empty_is_requested : EnumBase

    {

        private static string _result;

 

        private Establish context = () => { };

 

        private Because of = () => { _result = DummyEnum2.WithoutComment.GetEnumCommentIfExists(); };

 

        private It should_return_the_name_of_the_enum_value = () => _result.ShouldBeNull();

    }

 

    [Subject(typeof (EnumerationExtensions))]

    internal class When_an_Enum_has_a_value : EnumBase

    {

        private static bool _result;

 

        private Establish context = () => { };

 

        private Because of = () => { _result = DummyEnum3.WithValue.HasValue(); };

 

        private It should_return_true = () => _result.ShouldBeTrue();

    }

 

    [Subject(typeof (EnumerationExtensions))]

    internal class When_an_Enum_has_no_value : EnumBase

    {

        private static bool _result;

 

        private Establish context = () => { };

 

        private Because of = () =>

                             {

                                 DummyEnum3? d3 = null;

                                 _result = d3.HasValue();

                             };

 

        private It should_return_false = () => _result.ShouldBeFalse();

    }

 

    internal class When_Enum_is_not_decorated_with_FlagsAttribute

    {

        private static TestEnum_MissingFlagAttribute MyEnum;

 

        private Because of = () => { MyEnum = TestEnum_MissingFlagAttribute.Val2 | TestEnum_MissingFlagAttribute.Val3; };

 

        private It should_return_False1 = () => MyEnum.ByteIsSet(TestEnum_MissingFlagAttribute.Val1).ShouldBeFalse();

 

        private It should_return_False2 = () => MyEnum.ByteIsSet(TestEnum_MissingFlagAttribute.Val2).ShouldBeFalse();

 

        private It should_return_False3 = () => MyEnum.ByteIsSet(TestEnum_MissingFlagAttribute.Val3).ShouldBeFalse();

 

        private enum TestEnum_MissingFlagAttribute

        {

            Val1,

            Val2,

            Val3

        }

    }

 

    internal class When_Enum_is_compared_with_wrong_Enum_type

    {

        private static TestEnum1 MyEnum1;

 

        private Because of = () => { MyEnum1 = TestEnum1.Val2 | TestEnum1.Val3; };

 

        private It should_return_False1 = () => MyEnum1.ByteIsSet(TestEnum2.Val1).ShouldBeFalse();

 

        private It should_return_False2 = () => MyEnum1.ByteIsSet(TestEnum2.Val2).ShouldBeFalse();

 

        private It should_return_False3 = () => MyEnum1.ByteIsSet(TestEnum2.Val3).ShouldBeFalse();

 

        [Flags]

        private enum TestEnum1

        {

            Val1 = 0x01,

            Val2 = 0x02,

            Val3 = 0x04

        }

 

        [Flags]

        private enum TestEnum2

        {

            Val1 = 0x01,

            Val2 = 0x02,

            Val3 = 0x04

        }

    }

 

    internal class When_Enum_contains_enum_value

    {

        private static TestEnum MyEnum;

 

        private Because of = () => { MyEnum = TestEnum.Val2 | TestEnum.Val3; };

 

        private It should_return_False_for_val1 = () => MyEnum.ByteIsSet(TestEnum.Val1).ShouldBeFalse();

 

        private It should_return_True_for_val2 = () => MyEnum.ByteIsSet(TestEnum.Val2).ShouldBeTrue();

 

        private It should_return_True_for_val3 = () => MyEnum.ByteIsSet(TestEnum.Val3).ShouldBeTrue();

 

        [Flags]

        private enum TestEnum

        {

            Val1 = 0x01,

            Val2 = 0x02,

            Val3 = 0x04

        }

    }

}

Advertisements

NET Framework 4.5 für Build Server

Wer seine Software auf .NET 4.5 migriert, sollte darauf achten, dass er sich nicht nur das “normale” Setup von Microsoft herunterlädt, denn sonst kann es auf dem Build Server zu folgendem Fehler kommen (dieser tritt nicht bei einem installierten Visual Studio 2012 auf, was auf einem Build Server aber nichts verloren hat):

 

c:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(983,5): warning MSB3644: The reference assemblies for framework „.NETFramework,Version=v4.5“ were not found. To resolve this, install the SDK or Targeting Pack for this framework version or retarget your application to a version of the framework for which you have the SDK or Targeting Pack installed. Note that assemblies will be resolved from the Global Assembly Cache (GAC) and will be used in place of reference assemblies. Therefore your assembly may not be correctly targeted for the framework you intend.

 

Der Pfad an sich ist nicht falsch, da dieser sich mit der neuen Version nicht ändert. Es handelt sich um ein sogenanntes in-place Update, bei dem vorhandenen Verzeichnisse und Registrierungsschlüssel wiederverwendet werden. Damit werden alle 4.0 Assemblies entfernt. Eine Deinstallation von 4.5 bewirkt somit, dass man ohne .NET Framework endet.

 

Der folgende Screenshot zeigt den Stand nachdem eine bestehendes NET Framework 4 mit 4.5 aktualisiert wurde.

image

 

Ein funktionierender Build Server zeigt sich aber so:

image

 

Dazu muss das Windows SDK for Windows 8 (nicht 8.1!) installiert werden, welches ihr hier findet. Mit der Anwendung könnt ihr das eigentliche Setup herunterladen:

image

 

Nach der Installation am besten nochmal die Windows Updates laufen lassen und danach den grünen Build genießen.

NuGet Packages auf neue NET Version aktualisieren

Aktuell migrieren wir unsere Projekte / Solutions von .NET Framework 4.0 auf 4.5. Die Herausforderung bestand darin alle NuGet Packages, von denen wir viele verwenden, umzustellen. Ein Blick in die packages.config verrät, dass die installierten Pakete immer gegen eine entsprechende .NET Version gebunden sind:

   1: <?xml version="1.0" encoding="utf-8"?>

   2: <packages>

   3:   <package id="EntityFramework" version="5.0.0" targetFramework="net40" />

   4: </packages>

 

Dies lässt sich auch in den zugehörigen Assemblies ablesen:

image

Unter Path wird in diesem .NET 4.0 Projekt beispielsweise auf “packages\EntityFramework.5.0.0\lib\net40” verwiesen. Darüber ist es beim EntityFramework Package so, dass die Installation der aktuellen 5er Version in obigem Projekt lediglich die 4.4er Version referenziert wird. In der packages.config steht allerdings weiterhin 5.0.0.

Nach der Änderung des Target Frameworks auf 4.5, ergibt sich folgende Zeile in der packages.config:

   1: <package id="EntityFramework" version="5.0.0" targetFramework="net40" requireReinstallation="True" />

 

Der requiresReinstallations-Schalter bewirkt Warnungen beim Build. Um nun nicht alle packages von Hand aktualisieren zu müssen, gibt es den Befehl

update-package -reinstall

welcher die komplette Solution samt aller Projekte durchgeht und alle Packages deinstalliert und danach wieder gemäß dem gesetzten Target Framework installiert.

%d Bloggern gefällt das: