Skip to content

Commit 9da9914

Browse files
committed
updated to auto-initialize
1 parent 62e4334 commit 9da9914

File tree

8 files changed

+98
-67
lines changed

8 files changed

+98
-67
lines changed

Enum.Ext/Enum.Ext.Tests/ConvertTests.cs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,6 @@ namespace Enum.Ext.Tests
88
{
99
public class ConvertTests
1010
{
11-
[SetUp]
12-
public void InitWeekday()
13-
{
14-
Initialize.InitEnumExt<Weekday>();
15-
}
16-
1711
[Test]
1812
public void Test_ConvertToJson()
1913
{

Enum.Ext/Enum.Ext.Tests/WeekdayTests.cs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,6 @@ namespace Enum.Ext.Tests
77
[TestFixture]
88
public class WeekdayTests
99
{
10-
[SetUp]
11-
public void InitWeekday()
12-
{
13-
Initialize.InitEnumExt<Weekday>();
14-
}
15-
1610
[Test]
1711
public void Test_ConvertToInt()
1812
{
@@ -44,13 +38,5 @@ public void Test_PrintOutName()
4438

4539
day.Name.Should().Be("--Monday--");
4640
}
47-
48-
[Test]
49-
public void Test_ThrowsWhenSameId()
50-
{
51-
Action initializeWithSameId = () => Initialize.InitEnumExt<WrongEnum>();
52-
53-
initializeWithSameId.Should().Throw<TypeInitializationException>();
54-
}
5541
}
5642
}

Enum.Ext/Enum.Ext.Tests/WrongEnum.cs

Lines changed: 0 additions & 12 deletions
This file was deleted.

Enum.Ext/Enum.Ext.Tests/YearlyPriceTests.cs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,6 @@ namespace Enum.Ext.Tests
99
[TestFixture]
1010
public class YearlyPriceTests
1111
{
12-
[SetUp]
13-
public void InitYearlyPrice()
14-
{
15-
Initialize.InitEnumExt<YearlyPrice>();
16-
}
17-
1812
[Test]
1913
public void QueryByDate_ShouldReturnCorrectEnum()
2014
{

Enum.Ext/Enum.Ext/Initialize.cs

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,29 @@ namespace Enum.Ext
88
public static class Initialize
99
{
1010
/// <summary>
11-
/// Initializes the given class derived from <see cref="TypeSafeEnum{TValue, TKey}"/>.
12-
/// Throws <see cref="TypeInitializationException"/> when something unexpected happens
13-
/// (like multiple same ids on a enum)
11+
/// Obsolete, does nothing
1412
/// </summary>
13+
[Obsolete]
1514
public static void InitEnumExt<T>()
1615
{
17-
RuntimeHelpers.RunClassConstructor(typeof(T).TypeHandle);
16+
//RuntimeHelpers.RunClassConstructor(typeof(T).TypeHandle);
1817
}
1918

2019
/// <summary>
21-
/// Initializes all classes derived from <see cref="TypeSafeEnum{TValue, TKey}"/> in the given assembly.
22-
/// Throws <see cref="TypeInitializationException"/> when something unexpected happens
23-
/// (like multiple same ids on a enum)
20+
/// Obsolete, does nothing
2421
/// </summary>
2522
/// <param name="assembly"></param>
23+
[Obsolete]
2624
public static void InitEnumExt(Assembly assembly)
2725
{
28-
var types = assembly.GetTypes()
29-
.Where(t => TypeUtil.IsDerived(t, typeof(TypeSafeEnum<,>)))
30-
.Distinct();
26+
//var types = assembly.GetTypes()
27+
// .Where(t => TypeUtil.IsDerived(t, typeof(TypeSafeEnum<,>)))
28+
// .Distinct();
3129

32-
foreach (var item in types)
33-
{
34-
RuntimeHelpers.RunClassConstructor(item.TypeHandle);
35-
}
30+
//foreach (var item in types)
31+
//{
32+
// RuntimeHelpers.RunClassConstructor(item.TypeHandle);
33+
//}
3634
}
3735
}
3836
}

Enum.Ext/Enum.Ext/TypeSafeEnum.cs

Lines changed: 71 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,37 +3,75 @@
33
using System;
44
using Newtonsoft.Json;
55
using Enum.Ext.Converter;
6+
using System.Reflection;
67

78
namespace Enum.Ext
89
{
910
[JsonConverter(typeof(JsonTypeSafeEnumConverter))]
10-
public abstract class TypeSafeEnum<TValue, TKey> where TKey : struct
11+
public abstract class TypeSafeEnum<TValue, TKey> : IEquatable<TypeSafeEnum<TValue, TKey>>, IComparable<TypeSafeEnum<TValue, TKey>>
12+
where TKey : struct, IEquatable<TKey>, IComparable<TKey>
13+
where TValue : TypeSafeEnum<TValue, TKey>
1114
{
12-
protected static readonly Dictionary<TKey, TypeSafeEnum<TValue, TKey>> Dictionary = new Dictionary<TKey, TypeSafeEnum<TValue, TKey>>();
15+
protected static readonly Lazy<Dictionary<TKey, TValue>> Dictionary = new Lazy<Dictionary<TKey, TValue>>(() => GetAllOptions().ToDictionary(e => e.Id));
1316

14-
private static IEnumerable<TValue> _list;
17+
private static IReadOnlyCollection<TValue> _list;
1518

1619
protected TypeSafeEnum(TKey id)
1720
{
18-
if (Dictionary.ContainsKey(id))
19-
{
20-
throw new ArgumentException("element with same id cannot be initialized multiple times", nameof(id));
21-
}
22-
2321
Id = id;
24-
Dictionary[id] = this;
2522
}
2623

2724
public TKey Id { get; private set; }
2825

2926
/// <summary>
3027
/// Holds all declared values of the specific enum.
3128
/// </summary>
32-
public static IEnumerable<TValue> List => _list ?? (_list = Dictionary.Values.Cast<TValue>());
29+
public static IReadOnlyCollection<TValue> List => _list ?? (_list = Dictionary.Value.Values.Cast<TValue>().ToList());
3330

3431
public static TypeSafeEnum<TValue, TKey> GetById(TKey value)
3532
{
36-
return Dictionary[value];
33+
return Dictionary.Value[value];
34+
}
35+
36+
#region overrides
37+
38+
public override int GetHashCode()
39+
{
40+
return Id.GetHashCode();
41+
}
42+
43+
public override bool Equals(object obj)
44+
{
45+
return obj is TypeSafeEnum<TValue, TKey> other && Equals(other);
46+
}
47+
48+
public bool Equals(TypeSafeEnum<TValue, TKey> other)
49+
{
50+
if (object.ReferenceEquals(this, other))
51+
return true;
52+
53+
if (other is null)
54+
return false;
55+
56+
return Id.Equals(other.Id);
57+
}
58+
59+
public int CompareTo(TypeSafeEnum<TValue, TKey> other)
60+
{
61+
return Id.CompareTo(other.Id);
62+
}
63+
64+
public static bool operator ==(TypeSafeEnum<TValue, TKey> left, TypeSafeEnum<TValue, TKey> right)
65+
{
66+
if (left is null)
67+
return right is null;
68+
69+
return left.Equals(right);
70+
}
71+
72+
public static bool operator !=(TypeSafeEnum<TValue, TKey> left, TypeSafeEnum<TValue, TKey> right)
73+
{
74+
return !(left == right);
3775
}
3876

3977
public static implicit operator TKey(TypeSafeEnum<TValue, TKey> value)
@@ -43,7 +81,28 @@ public static implicit operator TKey(TypeSafeEnum<TValue, TKey> value)
4381

4482
public static implicit operator TypeSafeEnum<TValue, TKey>(TKey value)
4583
{
46-
return Dictionary[value];
84+
return Dictionary.Value[value];
4785
}
86+
87+
#endregion overrides
88+
89+
#region static methods
90+
91+
private static IEnumerable<TValue> GetAllOptions()
92+
{
93+
Type baseType = typeof(TValue);
94+
IEnumerable<Type> enumTypes = Assembly.GetAssembly(baseType).GetTypes().Where(t => baseType.IsAssignableFrom(t));
95+
96+
List<TValue> options = new List<TValue>();
97+
foreach (Type enumType in enumTypes)
98+
{
99+
List<TValue> typeEnumOptions = enumType.GetFieldsOfType<TValue>();
100+
options.AddRange(typeEnumOptions);
101+
}
102+
103+
return options.ToList();
104+
}
105+
106+
#endregion static methods
48107
}
49108
}

Enum.Ext/Enum.Ext/TypeSafeNameEnum.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
namespace Enum.Ext
1+
using System;
2+
3+
namespace Enum.Ext
24
{
3-
public abstract class TypeSafeNameEnum<TValue, TKey> : TypeSafeEnum<TValue, TKey> where TKey : struct
5+
public abstract class TypeSafeNameEnum<TValue, TKey> : TypeSafeEnum<TValue, TKey>
6+
where TKey : struct, IEquatable<TKey>, IComparable<TKey>
7+
where TValue : TypeSafeEnum<TValue, TKey>
48
{
59
protected TypeSafeNameEnum(TKey id, string name) : base(id)
610
{

Enum.Ext/Enum.Ext/TypeUtil.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Linq;
34
using System.Reflection;
4-
using System.Text;
55

66
namespace Enum.Ext
77
{
@@ -46,5 +46,13 @@ public static Type GetKeyType(Type objectType, Type mainType)
4646

4747
return null;
4848
}
49+
50+
public static List<TFieldType> GetFieldsOfType<TFieldType>(this Type type)
51+
{
52+
return type.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy)
53+
.Where(p => type.IsAssignableFrom(p.FieldType))
54+
.Select(pi => (TFieldType)pi.GetValue(null))
55+
.ToList();
56+
}
4957
}
5058
}

0 commit comments

Comments
 (0)