C
C#2y ago
SWEETPONY

❔ ✅ How to get attributes values?

I have following property with custom attribute [CatalogComponent]:
[CatalogComponent]
[JsonProperty( PropertyName = "event_categories" )]
public HashSet<EventCategoryType>? EventCategories { get; set; }
[CatalogComponent]
[JsonProperty( PropertyName = "event_categories" )]
public HashSet<EventCategoryType>? EventCategories { get; set; }
EventCategoryType is enum:
public enum EventCategoryType
{
[EnumMember( Value = "undefined" )]
Undefined,

[EnumMember( Value = "diagnostics" )]
[TitleLocalized( typeof( Resources.EventCategoryTypeTitle ) )]
[DescriptionLocalized( typeof( Resources.EventCategoryTypeDescription ) )]
Diagnostics,

[EnumMember( Value = "warning" )]
[TitleLocalized( typeof( Resources.EventCategoryTypeTitle ) )]
[DescriptionLocalized( typeof( Resources.EventCategoryTypeDescription ) )]
Warning
}
public enum EventCategoryType
{
[EnumMember( Value = "undefined" )]
Undefined,

[EnumMember( Value = "diagnostics" )]
[TitleLocalized( typeof( Resources.EventCategoryTypeTitle ) )]
[DescriptionLocalized( typeof( Resources.EventCategoryTypeDescription ) )]
Diagnostics,

[EnumMember( Value = "warning" )]
[TitleLocalized( typeof( Resources.EventCategoryTypeTitle ) )]
[DescriptionLocalized( typeof( Resources.EventCategoryTypeDescription ) )]
Warning
}
So my question is it possible to get EnumMember value and TitleLocalized value from EventCategoryType in custom attribute?
11 Replies
Omnissiah
Omnissiah2y ago
using reflection, sure
SWEETPONY
SWEETPONYOP2y ago
okay, let's see we have this property:
[CatalogComponent]
[JsonProperty( PropertyName = "event_categories" )]
public HashSet<T>? EventCategories { get; set; }
[CatalogComponent]
[JsonProperty( PropertyName = "event_categories" )]
public HashSet<T>? EventCategories { get; set; }
how can I get T in CatalogComponent?
Omnissiah
Omnissiah2y ago
wait is it generic or is it EventCategoryTypes
SWEETPONY
SWEETPONYOP2y ago
[CatalogComponent]
public HashSet<A>? EventCategories { get; set; }

[CatalogComponent]
public HashSet<B>? EventCategories { get; set; }

[CatalogComponent]
public HashSet<C>? EventCategories { get; set; }
[CatalogComponent]
public HashSet<A>? EventCategories { get; set; }

[CatalogComponent]
public HashSet<B>? EventCategories { get; set; }

[CatalogComponent]
public HashSet<C>? EventCategories { get; set; }
different types but A, B, C will have EnumMember and TitleLocalized
Omnissiah
Omnissiah2y ago
anyway to get T you look into GetType() probably it would be GenericTypeArgument
SWEETPONY
SWEETPONYOP2y ago
[CatalogComponent<EventCategoryType>]
[JsonProperty( PropertyName = "event_categories" )]
public HashSet<EventCategoryType>? EventCategories { get; set; }

public class CatalogComponentAttribute<T> : Attribute
{
}
[CatalogComponent<EventCategoryType>]
[JsonProperty( PropertyName = "event_categories" )]
public HashSet<EventCategoryType>? EventCategories { get; set; }

public class CatalogComponentAttribute<T> : Attribute
{
}
I can do this..
Omnissiah
Omnissiah2y ago
for the attributes, you have to search into Field for GetCustomAttribute
SWEETPONY
SWEETPONYOP2y ago
hm I will try smth like that..?
static private string GetEnumMemberValue()
=> typeof(T).GetCustomAttribute<EnumMemberAttribute>()?.Value;
static private string GetEnumMemberValue()
=> typeof(T).GetCustomAttribute<EnumMemberAttribute>()?.Value;
[CatalogComponent<EventCategoryType>]
[JsonProperty( PropertyName = "event_categories" )]
public HashSet<EventCategoryType>? EventCategories { get; set; }

public class CatalogComponentAttribute<T> : Attribute
{
public InputType InputType =>
InputType.Catalog;

public string? EnumMemberValue =>
typeof(T).GetCustomAttribute<EnumMemberAttribute>()?
.Value;

public string? TitleLocalizedValue =>
typeof(T).GetCustomAttribute<TitleLocalizedAttribute>()?
.Value;
}
[CatalogComponent<EventCategoryType>]
[JsonProperty( PropertyName = "event_categories" )]
public HashSet<EventCategoryType>? EventCategories { get; set; }

public class CatalogComponentAttribute<T> : Attribute
{
public InputType InputType =>
InputType.Catalog;

public string? EnumMemberValue =>
typeof(T).GetCustomAttribute<EnumMemberAttribute>()?
.Value;

public string? TitleLocalizedValue =>
typeof(T).GetCustomAttribute<TitleLocalizedAttribute>()?
.Value;
}
is it good solution?
Omnissiah
Omnissiah2y ago
this is, generically, the part that would check the attribute of an enum one way to do it
[AttributeUsage(AttributeTargets.Enum | AttributeTargets.Field)] class TestAttribute : Attribute { }
enum TestEnum { [Test]TestValue }

var enumValue = TestEnum.TestValue;
var valueType = enumValue.GetType();
string valueName = enumValue.ToString();
var valueField = valueType.GetField(valueName);
var valueAttr = valueField.GetCustomAttribute(typeof(TestAttribute), false);
[AttributeUsage(AttributeTargets.Enum | AttributeTargets.Field)] class TestAttribute : Attribute { }
enum TestEnum { [Test]TestValue }

var enumValue = TestEnum.TestValue;
var valueType = enumValue.GetType();
string valueName = enumValue.ToString();
var valueField = valueType.GetField(valueName);
var valueAttr = valueField.GetCustomAttribute(typeof(TestAttribute), false);
so there's a step in between, GetField sadly it's not the easiest thing to do anyway you can inspect GetType() and look around for what you need
SWEETPONY
SWEETPONYOP2y ago
okay, I see I did this and it works well:
public class CatalogComponentAttribute<T> : Attribute
{
public InputType InputType =>
InputType.Catalog;

public IEnumerable<(string? title, string? enumMember)> LocalizedValues =>
typeof(T)
.GetProperties()
.Select(property => (
title: property.GetCustomAttribute<TitleLocalizedAttribute>()?.Value,
enumMember: property.GetCustomAttribute<EnumMemberAttribute>()?.Value
));
}
public class CatalogComponentAttribute<T> : Attribute
{
public InputType InputType =>
InputType.Catalog;

public IEnumerable<(string? title, string? enumMember)> LocalizedValues =>
typeof(T)
.GetProperties()
.Select(property => (
title: property.GetCustomAttribute<TitleLocalizedAttribute>()?.Value,
enumMember: property.GetCustomAttribute<EnumMemberAttribute>()?.Value
));
}
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server