I have an enum as follows. I also have a string in-progress
I am trying to parse this string to the appropriate enum.
The issue being that enum try parse is checking on the name which means its failing. I need to parse it on this custom attribute.
I have been trying to see how I could get a list back of all of the fields within the enum and then test on the literal.
This would work but i have to specify each of the values within the enum in getfield
var res = typeof(CarePlan.CarePlanActivityStatus)
.GetField(nameof(CarePlan.CarePlanActivityStatus.Cancelled))
.GetCustomAttribute<EnumLiteralAttribute>(false)
.Literal;
I tried something like this but Literal doesn't exist at this point apparently so this fails as well.
var hold = typeof(CarePlan.CarePlanActivityStatus).GetFields().Where(a =>
a.GetCustomAttributes<EnumLiteralAttribute>(false).Literal.Equals(data));
The enum
[FhirEnumeration("CarePlanActivityStatus")]
public enum CarePlanActivityStatus
{
/// <summary>
/// Care plan activity is planned but no action has yet been taken.
/// (system: http://hl7.org/fhir/care-plan-activity-status)
/// </summary>
[EnumLiteral("not-started", "http://hl7.org/fhir/care-plan-activity-status"), Hl7.Fhir.Utility.Description("Not Started")] NotStarted,
/// <summary>
/// Appointment or other booking has occurred but activity has not yet begun.
/// (system: http://hl7.org/fhir/care-plan-activity-status)
/// </summary>
[EnumLiteral("scheduled", "http://hl7.org/fhir/care-plan-activity-status"), Hl7.Fhir.Utility.Description("Scheduled")] Scheduled,
/// <summary>
/// Care plan activity has been started but is not yet complete.
/// (system: http://hl7.org/fhir/care-plan-activity-status)
/// </summary>
[EnumLiteral("in-progress", "http://hl7.org/fhir/care-plan-activity-status"), Hl7.Fhir.Utility.Description("In Progress")] InProgress,
/// <summary>
/// Care plan activity was started but has temporarily ceased with an expectation of resumption at a future time.
/// (system: http://hl7.org/fhir/care-plan-activity-status)
/// </summary>
[EnumLiteral("on-hold", "http://hl7.org/fhir/care-plan-activity-status"), Hl7.Fhir.Utility.Description("On Hold")] OnHold,
/// <summary>
/// Care plan activity has been completed (more or less) as planned.
/// (system: http://hl7.org/fhir/care-plan-activity-status)
/// </summary>
[EnumLiteral("completed", "http://hl7.org/fhir/care-plan-activity-status"), Hl7.Fhir.Utility.Description("Completed")] Completed,
/// <summary>
/// The planned care plan activity has been withdrawn.
/// (system: http://hl7.org/fhir/care-plan-activity-status)
/// </summary>
[EnumLiteral("cancelled", "http://hl7.org/fhir/care-plan-activity-status"), Hl7.Fhir.Utility.Description("Cancelled")] Cancelled,
/// <summary>
/// The planned care plan activity has been ended prior to completion after the activity was started.
/// (system: http://hl7.org/fhir/care-plan-activity-status)
/// </summary>
[EnumLiteral("stopped", "http://hl7.org/fhir/care-plan-activity-status"), Hl7.Fhir.Utility.Description("Stopped")] Stopped,
/// <summary>
/// The current state of the care plan activity is not known. Note: This concept is not to be used for "other" - one of the listed statuses is presumed to apply, but the authoring/source system does not know which one.
/// (system: http://hl7.org/fhir/care-plan-activity-status)
/// </summary>
[EnumLiteral("unknown", "http://hl7.org/fhir/care-plan-activity-status"), Hl7.Fhir.Utility.Description("Unknown")] Unknown,
/// <summary>
/// Care plan activity was entered in error and voided.
/// (system: http://hl7.org/fhir/care-plan-activity-status)
/// </summary>
[EnumLiteral("entered-in-error", "http://hl7.org/fhir/care-plan-activity-status"), Hl7.Fhir.Utility.Description("Entered in Error")] EnteredInError,
}
Isnt there a way to parse a string to an enum without making a large mess of a if statements to test it. Ideally i need to create a generic method as i have about 10 of these enums i need test.
CodePudding user response:
You can try with a extension method to read the Custom Atribute from Enums:
public static class EnumExtensions
{
public static T GetValueFromEnumMember<T>(string value) where T: Enum
{
var type = typeof(T);
foreach (var field in type.GetFields())
{
var attribute = Attribute.GetCustomAttribute(field,
typeof(EnumMemberAttribute)) as EnumMemberAttribute;
if (attribute != null)
{
if (attribute.Value == value)
return (T)field.GetValue(null);
}
else
{
if (field.Name == value)
return (T)field.GetValue(null);
}
}
throw new ArgumentException($"unknow value: {value}");
}
}
and use it like this:
EnumExtensions.GetValueFromEnumMember<CarePlanActivityStatus>(stringValueToTest)
it returns the Enum Value
CodePudding user response:
I tried something like this but Literal doesn't exist at this point apparently so this fails as well.
I assume you're seeing this fail with a NullReferenceException
? If you look at what GetFields()
is actually returning, the first field it returns is value__
, which doesn't have any attributes on it. So your GetCustomAttribute<EnumLiteralAttribute>()
returns null
, and accessing its Literal
member fails with a NullReferenceException
.
If you exclude this field from your test, or just make sure that you're safe to GetCustomAttribute
returning null
, everything works fine.
E.g.:
var hold = typeof(CarePlanActivityStatus).GetFields()
.Where(a => a.GetCustomAttribute<EnumLiteralAttribute>(false)?.Literal == data);