Closed xumix closed 1 year ago
Do you mean an enum type used as an attribute argument? It would be nice to see c# code snippet to remove any chance for misunderstanding.
Do you mean an enum type used as an attribute argument? It would be nice to see c# code snippet to remove any chance for misunderstanding.
[AttributeUsage(AttributeTargets.Field, AllowMultiple = true)]
public class StatisticsGroupAttribute : Attribute
{
protected StatisticsGroupAttribute(StatisticsGroupTypeEnum type, params object[] values)
{
var ids = new List<Guid>();
Type = type;
foreach (var value in values)
{
if (value is Enum @enum)
{
ids.Add(@enum.GetId());
}
else
{
throw new ArgumentException($"'{value}' не является '{nameof(Enum)}'", nameof(value));
}
}
Values = ids;
}
public StatisticsGroupAttribute(StatisticsGroupTypeEnum type, params RegionStatTypeEnum[] values)
: this(type, values.Cast<object>().ToArray())
{
}
public StatisticsGroupAttribute(StatisticsGroupTypeEnum type, params FederalLawEnum[] values)
: this(type, values.Cast<object>().ToArray())
{
}
public StatisticsGroupTypeEnum Type { get; set; }
public IEnumerable<Guid> Values { get; }
}
Usage:
public enum RegionStatTypeEnum
{
[Display(Name = "Число контрактов по 44-ФЗ, заключенных по результатам КС")]
[StatisticsGroup(StatisticsGroupTypeEnum.Restriction, FederalLawEnum.FZ44)]
AuctionContractCount44,
[Display(Name = "Сумма по всем контрактам")]
[StatisticsGroup(StatisticsGroupTypeEnum.Variation, ContractSum223, ContractSum44)]
ContractSum,
}
When I try to get the StatisticsGroupAttribute Arguments I get type object
containing int
as a value
var args = enumValue.Attributes.First(f => f.Name == "StatisticsGroup").Arguments;
so I can't get what it the actual type of the argument
I have made a unit test:
input code:
namespace NTypewriter.Tests.CodeModel
{
public enum RegionStatTypeEnum
{
[StatisticsGroup(StatisticsGroupTypeEnum.Restriction, FederalLawEnum.FZ44)]
AuctionContractCount44,
[StatisticsGroup(StatisticsGroupTypeEnum.Variation, 2, FederalLawEnum.FZ69)]
ContractSum,
}
[AttributeUsage(AttributeTargets.Field, AllowMultiple = true)]
public class StatisticsGroupAttribute : Attribute
{
public StatisticsGroupAttribute(StatisticsGroupTypeEnum type, params object[] values)
{
}
public StatisticsGroupAttribute(StatisticsGroupTypeEnum type, params FederalLawEnum[] values)
: this(type, values.Cast<object>().ToArray())
{
}
public StatisticsGroupTypeEnum Type { get; set; }
public IEnumerable<Guid> Values { get; }
}
public enum StatisticsGroupTypeEnum
{
Restriction = 1,
Variation = 3,
}
public enum FederalLawEnum
{
FZ44 = 44,
FZ69 = 69,
}
}
template:
{{- capture captured}}
{{- for enum in data.Enums | Symbols.WhereNamespaceStartsWith "NTypewriter.Tests.CodeModel" | Symbols.WhereNameEndsWith "RegionStatTypeEnum"}}
{{- for enum_item in enum.Values }}
{{- enum_item.Name}}
{{- for attr in enum_item.Attributes }}
[{{ attr.Name }}]
{{- for arg in attr.Arguments }}
name : {{ arg.Name }}
type : {{ arg.Type }}
value : {{ arg.Value }}
-------------
{{~ end}}
{{- end }}
{{- end}}
{{ end }}
{{- end }}
{{- Save captured "result" }}
output:
AuctionContractCount44
[StatisticsGroup]
name : type
type : StatisticsGroupTypeEnum
value : StatisticsGroupTypeEnum.Restriction
-------------
name : values
type : FederalLawEnum[]
value : [44]
-------------
ContractSum
[StatisticsGroup]
name : type
type : StatisticsGroupTypeEnum
value : StatisticsGroupTypeEnum.Variation
-------------
name : values
type : object[]
value : [2, 69]
-------------
As you can see there is no problem with determining the type of argument of an attribute. The only problem that I see is inconsistency:
IEnumValue
cannot be used here, because the parameters of attributes are TypedConstant, a completely different type.
NTypewriter will follow Roslyn design and return ITypedConstant for the value of the attribute argument.
In the upcoming version for the input from previous comment, the output will be:
AuctionContractCount44
[StatisticsGroup]
name : type
type : StatisticsGroupTypeEnum
value : StatisticsGroupTypeEnum.Restriction
-------------
name : values
type : FederalLawEnum[]
value : [FederalLawEnum.FZ44]
-------------
ContractSum
[StatisticsGroup]
name : type
type : StatisticsGroupTypeEnum
value : StatisticsGroupTypeEnum.Variation
-------------
name : values
type : object[]
value : [2, FederalLawEnum.FZ69]
-------------
Thank you so much, I'll try this!
Which leads to problems like inability to get the enum value name when working with Attribute arguments. I think that better alternative is to store them as
IEnumValue
so that it is possible to get useful info from the value.