diff --git a/samples/Thinktecture.Runtime.Extensions.Samples/EnumLikeClasses/EnumLikeClassDemos.cs b/samples/Thinktecture.Runtime.Extensions.Samples/EnumLikeClasses/EnumLikeClassDemos.cs
index 0e55beef..07e7010f 100644
--- a/samples/Thinktecture.Runtime.Extensions.Samples/EnumLikeClasses/EnumLikeClassDemos.cs
+++ b/samples/Thinktecture.Runtime.Extensions.Samples/EnumLikeClasses/EnumLikeClassDemos.cs
@@ -22,6 +22,9 @@ private static void DemoForNonValidatableEnum(ILogger logger)
var productType = ProductType.Get("Groceries");
logger.Information("Product type: {type}", productType);
+ productType = (ProductType)"Groceries";
+ logger.Information("Explicitly casted product type: {type}", productType);
+
if (ProductType.TryGet("Housewares", out var housewares))
logger.Information("Product type {type} with TryGet found", housewares);
diff --git a/src/Thinktecture.Runtime.Extensions.SourceGenerator/CodeAnalysis/EnumSourceGenerator.cs b/src/Thinktecture.Runtime.Extensions.SourceGenerator/CodeAnalysis/EnumSourceGenerator.cs
index 16a71b7c..67a2d417 100644
--- a/src/Thinktecture.Runtime.Extensions.SourceGenerator/CodeAnalysis/EnumSourceGenerator.cs
+++ b/src/Thinktecture.Runtime.Extensions.SourceGenerator/CodeAnalysis/EnumSourceGenerator.cs
@@ -119,6 +119,7 @@ internal static void ModuleInit()
GeneratedTryGet();
GenerateImplicitConversion();
+ GenerateExplicitConversion();
GenerateEqualityOperators();
GenerateTypedEquals();
@@ -216,7 +217,7 @@ private void GenerateImplicitConversion()
_sb.Append($@"
///
- /// Implicit conversion to the type of .
+ /// Implicit conversion to the type .
///
/// Item to covert.
/// The of provided or default if is null.
@@ -239,6 +240,22 @@ private void GenerateImplicitConversion()
}}");
}
+ private void GenerateExplicitConversion()
+ {
+ _sb.Append($@"
+
+ ///
+ /// Explicit conversion from the type .
+ ///
+ /// Value to covert.
+ /// An instance of if the is a known item or implements .
+ [return: NotNullIfNotNull(""{_state.KeyArgumentName}"")]
+ public static explicit operator {_state.EnumIdentifier}{_state.NullableQuestionMarkEnum}({_state.KeyType}{_state.NullableQuestionMarkKey} {_state.KeyArgumentName})
+ {{
+ return {_state.EnumIdentifier}.Get({_state.KeyArgumentName});
+ }}");
+ }
+
private void GenerateTypedEquals()
{
_sb.Append($@"
diff --git a/src/Thinktecture.Runtime.Extensions.SourceGenerator/CodeAnalysis/ValueTypeSourceGenerator.cs b/src/Thinktecture.Runtime.Extensions.SourceGenerator/CodeAnalysis/ValueTypeSourceGenerator.cs
index 44174143..3b4408ad 100644
--- a/src/Thinktecture.Runtime.Extensions.SourceGenerator/CodeAnalysis/ValueTypeSourceGenerator.cs
+++ b/src/Thinktecture.Runtime.Extensions.SourceGenerator/CodeAnalysis/ValueTypeSourceGenerator.cs
@@ -123,6 +123,7 @@ internal static void ModuleInit()
{
GenerateFactoryMethod(_state.KeyMember);
GenerateImplicitConversion(_state.KeyMember);
+ GenerateExplicitConversion(_state.KeyMember);
}
GenerateConstructor();
@@ -140,7 +141,7 @@ private void GenerateImplicitConversion(InstanceMemberInfo keyMember)
_sb.Append($@"
///
- /// Implicit conversion to the type of .
+ /// Implicit conversion to the type .
///
/// Object to covert.
/// The of provided or default if is null.
@@ -163,6 +164,21 @@ private void GenerateImplicitConversion(InstanceMemberInfo keyMember)
}}");
}
+ private void GenerateExplicitConversion(InstanceMemberInfo keyMember)
+ {
+ _sb.Append($@"
+
+ ///
+ /// Explicit conversion from the type .
+ ///
+ /// Value to covert.
+ /// An instance of .
+ public static explicit operator {_state.TypeIdentifier}({keyMember.Type} {keyMember.ArgumentName})
+ {{
+ return {_state.TypeIdentifier}.Create({keyMember.ArgumentName});
+ }}");
+ }
+
private void GenerateFactoryMethod(InstanceMemberInfo keyMember)
{
_sb.Append($@"
diff --git a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/EnumSourceGeneratorTests.cs b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/EnumSourceGeneratorTests.cs
index 8803a0ef..71df8dd0 100644
--- a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/EnumSourceGeneratorTests.cs
+++ b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/EnumSourceGeneratorTests.cs
@@ -62,7 +62,7 @@ internal static void ModuleInit()
Expression> convertToKeyExpression = item => item.Key;
var enumType = typeof(TestEnum);
- var metadata = new ValueTypeMetadata(enumType, typeof(string), convertFromKey, convertFromKeyExpression, convertToKey, convertToKeyExpression);
+ var metadata = new ValueTypeMetadata(enumType, typeof(string), false, convertFromKey, convertFromKeyExpression, convertToKey, convertToKeyExpression);
ValueTypeMetadataLookup.AddMetadata(enumType, metadata);
}
@@ -144,7 +144,7 @@ public static bool TryGet([AllowNull] string key, [MaybeNullWhen(false)] out Tes
}
///
- /// Implicit conversion to the type of .
+ /// Implicit conversion to the type .
///
/// Item to covert.
/// The of provided or default if is null.
@@ -154,6 +154,17 @@ public static bool TryGet([AllowNull] string key, [MaybeNullWhen(false)] out Tes
return item is null ? default : item.Key;
}
+ ///
+ /// Explicit conversion from the type .
+ ///
+ /// Value to covert.
+ /// An instance of if the is a known item or implements .
+ [return: NotNullIfNotNull(""key"")]
+ public static explicit operator TestEnum?(string? key)
+ {
+ return TestEnum.Get(key);
+ }
+
///
/// Compares to instances of .
///
@@ -336,7 +347,7 @@ internal static void ModuleInit()
Expression> convertToKeyExpression = item => item.Key;
var enumType = typeof(TestEnum);
- var metadata = new ValueTypeMetadata(enumType, typeof(string), convertFromKey, convertFromKeyExpression, convertToKey, convertToKeyExpression);
+ var metadata = new ValueTypeMetadata(enumType, typeof(string), true, convertFromKey, convertFromKeyExpression, convertToKey, convertToKeyExpression);
ValueTypeMetadataLookup.AddMetadata(enumType, metadata);
}
@@ -447,7 +458,7 @@ public static bool TryGet([AllowNull] string key, [MaybeNullWhen(false)] out Tes
}
///
- /// Implicit conversion to the type of .
+ /// Implicit conversion to the type .
///
/// Item to covert.
/// The of provided or default if is null.
@@ -457,6 +468,17 @@ public static bool TryGet([AllowNull] string key, [MaybeNullWhen(false)] out Tes
return item is null ? default : item.Key;
}
+ ///
+ /// Explicit conversion from the type .
+ ///
+ /// Value to covert.
+ /// An instance of if the is a known item or implements .
+ [return: NotNullIfNotNull(""key"")]
+ public static explicit operator TestEnum?(string? key)
+ {
+ return TestEnum.Get(key);
+ }
+
///
/// Compares to instances of .
///
@@ -609,7 +631,7 @@ internal static void ModuleInit()
Expression> convertToKeyExpression = item => item.Key;
var enumType = typeof(TestEnum);
- var metadata = new ValueTypeMetadata(enumType, typeof(string), convertFromKey, convertFromKeyExpression, convertToKey, convertToKeyExpression);
+ var metadata = new ValueTypeMetadata(enumType, typeof(string), true, convertFromKey, convertFromKeyExpression, convertToKey, convertToKeyExpression);
ValueTypeMetadataLookup.AddMetadata(enumType, metadata);
}
@@ -717,7 +739,7 @@ public static bool TryGet([AllowNull] string key, [MaybeNullWhen(false)] out Tes
}
///
- /// Implicit conversion to the type of .
+ /// Implicit conversion to the type .
///
/// Item to covert.
/// The of provided or default if is null.
@@ -727,6 +749,17 @@ public static bool TryGet([AllowNull] string key, [MaybeNullWhen(false)] out Tes
return item.Key;
}
+ ///
+ /// Explicit conversion from the type .
+ ///
+ /// Value to covert.
+ /// An instance of if the is a known item or implements .
+ [return: NotNullIfNotNull(""key"")]
+ public static explicit operator TestEnum(string? key)
+ {
+ return TestEnum.Get(key);
+ }
+
///
/// Compares to instances of .
///
@@ -898,7 +931,7 @@ internal static void ModuleInit()
Expression> convertToKeyExpression = item => item.Name;
var enumType = typeof(TestEnum);
- var metadata = new ValueTypeMetadata(enumType, typeof(string), convertFromKey, convertFromKeyExpression, convertToKey, convertToKeyExpression);
+ var metadata = new ValueTypeMetadata(enumType, typeof(string), true, convertFromKey, convertFromKeyExpression, convertToKey, convertToKeyExpression);
ValueTypeMetadataLookup.AddMetadata(enumType, metadata);
}
@@ -1009,7 +1042,7 @@ public static bool TryGet([AllowNull] string name, [MaybeNullWhen(false)] out Te
}
///
- /// Implicit conversion to the type of .
+ /// Implicit conversion to the type .
///
/// Item to covert.
/// The of provided or default if is null.
@@ -1019,6 +1052,17 @@ public static bool TryGet([AllowNull] string name, [MaybeNullWhen(false)] out Te
return item is null ? default : item.Name;
}
+ ///
+ /// Explicit conversion from the type .
+ ///
+ /// Value to covert.
+ /// An instance of if the is a known item or implements .
+ [return: NotNullIfNotNull(""name"")]
+ public static explicit operator TestEnum?(string? name)
+ {
+ return TestEnum.Get(name);
+ }
+
///
/// Compares to instances of .
///
diff --git a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/ValueTypeSourceGeneratorTests.cs b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/ValueTypeSourceGeneratorTests.cs
index 79563312..86d751b1 100644
--- a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/ValueTypeSourceGeneratorTests.cs
+++ b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/ValueTypeSourceGeneratorTests.cs
@@ -295,7 +295,7 @@ internal static void ModuleInit()
Expression> convertToKeyExpression = obj => obj.ReferenceField;
var type = typeof(TestValueType);
- var metadata = new ValueTypeMetadata(type, typeof(string), convertFromKey, convertFromKeyExpression, convertToKey, convertToKeyExpression);
+ var metadata = new ValueTypeMetadata(type, typeof(string), false, convertFromKey, convertFromKeyExpression, convertToKey, convertToKeyExpression);
ValueTypeMetadataLookup.AddMetadata(type, metadata);
}
@@ -330,7 +330,7 @@ public static bool TryCreate(
static partial void ValidateFactoryArguments(ref string referenceField);
///
- /// Implicit conversion to the type of .
+ /// Implicit conversion to the type .
///
/// Object to covert.
/// The of provided or default if is null.
@@ -340,6 +340,16 @@ public static bool TryCreate(
return obj is null ? default : obj.ReferenceField;
}
+ ///
+ /// Explicit conversion from the type .
+ ///
+ /// Value to covert.
+ /// An instance of .
+ public static explicit operator TestValueType(string referenceField)
+ {
+ return TestValueType.Create(referenceField);
+ }
+
private TestValueType(string referenceField)
{
ValidateConstructorArguments(ref referenceField);