如何从属性中获取命名参数的构造函数
How to get constructor named arguments from attribute
我和this question有同样的问题。问题是,即使在属性的构造函数中使用命名参数,我仍然得到一个空集合。
这是我的属性定义:
public class MenuItemAttribute : Attribute
{
ApplicationCategoryEnum ApplicationCategory { get; }
string ControllerDisplayName { get; }
bool IsDefaultRoute { get; }
public MenuItemAttribute(ApplicationCategoryEnum applicationCategory, string controllerDisplayName, bool isDefaultRoute)
{
ControllerDisplayName = controllerDisplayName;
ApplicationCategory = applicationCategory;
IsDefaultRoute = isDefaultRoute;
}
}
这就是我的使用方式:
[MenuItem(
applicationCategory: ApplicationCategoryEnum.CONTROLPANEL,
controllerDisplayName: "Account Management",
isDefaultRoute: false)]
public class AccountController : Controller { /// }
这是我通过控制器的属性的方式:
var attributeData = controllerInfo
.CustomAttributes
.FirstOrDefault(attrs => attrs.AttributeType == typeof(MenuItemAttribute))
.NamedArguments;
如果我使用 ConstructorArguments
而不是 NamedArguments
,我可以看到参数在那里。
我错过了什么?
目前您所有的参数都是位置参数,因此它们在 ConstructorArguments
中返回。
如docs中所写:
Each non-static public read-write field and property for an attribute class defines a named parameter for the attribute class.
将您的 MenuItemAttribute
更改为例如:
public class MenuItemAttribute : Attribute
{
ApplicationCategoryEnum ApplicationCategory { get; }
public string ControllerDisplayName { get; set; }
public bool IsDefaultRoute { get; set; }
public MenuItemAttribute(ApplicationCategoryEnum applicationCategory)
{
ApplicationCategory = applicationCategory;
}
}
和用法
[MenuItem(ApplicationCategoryEnum.CONTROLPANEL, ControllerDisplayName = "asdsa", IsDefaultRoute = true)]
会给你 NamedArguments
集合中的 2 个元素。
语法:
[MenuItem(
applicationCategory: ApplicationCategoryEnum.CONTROLPANEL,
controllerDisplayName: "Account Management",
isDefaultRoute: false)]
表示构造函数参数;您想要的数据在 ConstructorArguments
成员中:
var attrib = typeof(AccountController)
.CustomAttributes
.FirstOrDefault(attrs => attrs.AttributeType == typeof(MenuItemAttribute));
if (attrib is object)
{
var declared = attrib.Constructor.GetParameters();
var values = attrib.ConstructorArguments;
for (int i = 0; i < values.Count; i++)
{
Console.WriteLine($"{declared[i].Name}={values[i].Value}");
}
}
(NamedArguments
用于涉及 =
的 ever-so-subtly-different 用法,即 IsDefaultRoute = true
调用 IsDefaultRoute
[=28] 的 property-setter =] 的值为 true
)
我和this question有同样的问题。问题是,即使在属性的构造函数中使用命名参数,我仍然得到一个空集合。
这是我的属性定义:
public class MenuItemAttribute : Attribute
{
ApplicationCategoryEnum ApplicationCategory { get; }
string ControllerDisplayName { get; }
bool IsDefaultRoute { get; }
public MenuItemAttribute(ApplicationCategoryEnum applicationCategory, string controllerDisplayName, bool isDefaultRoute)
{
ControllerDisplayName = controllerDisplayName;
ApplicationCategory = applicationCategory;
IsDefaultRoute = isDefaultRoute;
}
}
这就是我的使用方式:
[MenuItem(
applicationCategory: ApplicationCategoryEnum.CONTROLPANEL,
controllerDisplayName: "Account Management",
isDefaultRoute: false)]
public class AccountController : Controller { /// }
这是我通过控制器的属性的方式:
var attributeData = controllerInfo
.CustomAttributes
.FirstOrDefault(attrs => attrs.AttributeType == typeof(MenuItemAttribute))
.NamedArguments;
如果我使用 ConstructorArguments
而不是 NamedArguments
,我可以看到参数在那里。
我错过了什么?
目前您所有的参数都是位置参数,因此它们在 ConstructorArguments
中返回。
如docs中所写:
Each non-static public read-write field and property for an attribute class defines a named parameter for the attribute class.
将您的 MenuItemAttribute
更改为例如:
public class MenuItemAttribute : Attribute
{
ApplicationCategoryEnum ApplicationCategory { get; }
public string ControllerDisplayName { get; set; }
public bool IsDefaultRoute { get; set; }
public MenuItemAttribute(ApplicationCategoryEnum applicationCategory)
{
ApplicationCategory = applicationCategory;
}
}
和用法
[MenuItem(ApplicationCategoryEnum.CONTROLPANEL, ControllerDisplayName = "asdsa", IsDefaultRoute = true)]
会给你 NamedArguments
集合中的 2 个元素。
语法:
[MenuItem(
applicationCategory: ApplicationCategoryEnum.CONTROLPANEL,
controllerDisplayName: "Account Management",
isDefaultRoute: false)]
表示构造函数参数;您想要的数据在 ConstructorArguments
成员中:
var attrib = typeof(AccountController)
.CustomAttributes
.FirstOrDefault(attrs => attrs.AttributeType == typeof(MenuItemAttribute));
if (attrib is object)
{
var declared = attrib.Constructor.GetParameters();
var values = attrib.ConstructorArguments;
for (int i = 0; i < values.Count; i++)
{
Console.WriteLine($"{declared[i].Name}={values[i].Value}");
}
}
(NamedArguments
用于涉及 =
的 ever-so-subtly-different 用法,即 IsDefaultRoute = true
调用 IsDefaultRoute
[=28] 的 property-setter =] 的值为 true
)