C# 属性检查是一个值等于构造函数参数并获取构造函数值
C# Attribute check is an value equals the constructor argument and get constructor values
如何检查某个字符串是否等于属性的 "constructor" 参数?
以及如何获取所有构造函数值(TestArg1、TestArg2)?
struct MyData
{
[MyAttr("TestArg1", "TestArg2")] //check that some string equals TestArg1/TestArg2
public string TestArg;
}
这主要取决于您正在查看的属性及其编码方式。请参阅下面的代码作为示例,了解如何执行您所要求的操作。
//The attribute we're looking at
public class MyAtt : System.Attribute
{
public string name;
public string anotherstring;
public MyAtt(string name, string anotherstring)
{
this.name = name;
this.anotherstring = anotherstring;
}
}
public static class Usage
{
[MyAtt("String1", "String2")] //Using the attribute
public static string SomeProperty = "String1";
}
public static class Program
{
public static void Main()
{
Console.WriteLine(IsEqualToAttribute("String1"));
Console.WriteLine(IsEqualToAttribute("blah"));
Console.ReadKey();
}
public static bool IsEqualToAttribute(string mystring)
{
//Let's get all the properties from Usage
PropertyInfo[] props = typeof(Usage).GetProperties();
foreach (var prop in props)
{
//Let's make sure we have the right property
if (prop.Name == "SomeProperty")
{
//Get the attributes from the property
var attrs = prop.GetCustomAttributes();
//Select just the attribute named "MyAtt"
var attr = attrs.SingleOrDefault(x => x.GetType().Name == "MyAtt");
MyAtt myAttribute = attr as MyAtt; //Just casting to the correct type
if (myAttribute.name == mystring) //Compare the strings
return true;
if (myAttribute.anotherstring == mystring) //Compare the strings
return true;
}
}
return false;
}
}
如您所见,我们使用反射从 属性 中获取属性,然后只比较属性。
就获取构造函数属性而言,类似于
typeof(MyAtt).GetConstructor().GetParameters()
将检索构造函数的参数详细信息。
微软文档中也有这方面的信息:https://docs.microsoft.com/en-us/dotnet/api/system.reflection.customattributedata.constructor?view=netframework-4.7.2
这是一种完成您所要求的方法,但它的可扩展性不是特别好,需要大量手动代码才能开始工作,但可能会让您踏上实现目标的道路。假设我们有一个类似这样的属性,它的构造函数中有一个字符串数组:
public class MyAttrAttribute : Attribute
{
public string[] AllowedValues { get; }
public MyAttrAttribute(params string[] values)
{
AllowedValues = values;
}
}
您可以将您的字段更改为带有支持字段的 属性。这允许您覆盖 set
方法并在那里进行检查:
private string _testArg;
[MyAttr("TestArg1", "TestArg2")] //check that some string equals TestArg1/TestArg2
public string TestArg
{
get => _testArg;
set
{
var allowedValues = this.GetType() //Get the type of 'this'
.GetProperty(nameof(TestArg)) // Get this property
.GetCustomAttribute<MyAttrAttribute>() // Get the attribute
.AllowedValues; //Get the allowed values specified in the attribute
if(!allowedValues.Contains(value))
{
throw new ArgumentOutOfRangeException(nameof(value),
$"The value '{value}' is not allowed");
}
_testArg = value;
}
}
综上所述,我坚信有更好的方法可以实现您的要求。例如,如果您被限制为一组最小值,那么 enum
几乎肯定是比字符串更好的选择。
如何检查某个字符串是否等于属性的 "constructor" 参数? 以及如何获取所有构造函数值(TestArg1、TestArg2)?
struct MyData
{
[MyAttr("TestArg1", "TestArg2")] //check that some string equals TestArg1/TestArg2
public string TestArg;
}
这主要取决于您正在查看的属性及其编码方式。请参阅下面的代码作为示例,了解如何执行您所要求的操作。
//The attribute we're looking at
public class MyAtt : System.Attribute
{
public string name;
public string anotherstring;
public MyAtt(string name, string anotherstring)
{
this.name = name;
this.anotherstring = anotherstring;
}
}
public static class Usage
{
[MyAtt("String1", "String2")] //Using the attribute
public static string SomeProperty = "String1";
}
public static class Program
{
public static void Main()
{
Console.WriteLine(IsEqualToAttribute("String1"));
Console.WriteLine(IsEqualToAttribute("blah"));
Console.ReadKey();
}
public static bool IsEqualToAttribute(string mystring)
{
//Let's get all the properties from Usage
PropertyInfo[] props = typeof(Usage).GetProperties();
foreach (var prop in props)
{
//Let's make sure we have the right property
if (prop.Name == "SomeProperty")
{
//Get the attributes from the property
var attrs = prop.GetCustomAttributes();
//Select just the attribute named "MyAtt"
var attr = attrs.SingleOrDefault(x => x.GetType().Name == "MyAtt");
MyAtt myAttribute = attr as MyAtt; //Just casting to the correct type
if (myAttribute.name == mystring) //Compare the strings
return true;
if (myAttribute.anotherstring == mystring) //Compare the strings
return true;
}
}
return false;
}
}
如您所见,我们使用反射从 属性 中获取属性,然后只比较属性。
就获取构造函数属性而言,类似于
typeof(MyAtt).GetConstructor().GetParameters()
将检索构造函数的参数详细信息。
微软文档中也有这方面的信息:https://docs.microsoft.com/en-us/dotnet/api/system.reflection.customattributedata.constructor?view=netframework-4.7.2
这是一种完成您所要求的方法,但它的可扩展性不是特别好,需要大量手动代码才能开始工作,但可能会让您踏上实现目标的道路。假设我们有一个类似这样的属性,它的构造函数中有一个字符串数组:
public class MyAttrAttribute : Attribute
{
public string[] AllowedValues { get; }
public MyAttrAttribute(params string[] values)
{
AllowedValues = values;
}
}
您可以将您的字段更改为带有支持字段的 属性。这允许您覆盖 set
方法并在那里进行检查:
private string _testArg;
[MyAttr("TestArg1", "TestArg2")] //check that some string equals TestArg1/TestArg2
public string TestArg
{
get => _testArg;
set
{
var allowedValues = this.GetType() //Get the type of 'this'
.GetProperty(nameof(TestArg)) // Get this property
.GetCustomAttribute<MyAttrAttribute>() // Get the attribute
.AllowedValues; //Get the allowed values specified in the attribute
if(!allowedValues.Contains(value))
{
throw new ArgumentOutOfRangeException(nameof(value),
$"The value '{value}' is not allowed");
}
_testArg = value;
}
}
综上所述,我坚信有更好的方法可以实现您的要求。例如,如果您被限制为一组最小值,那么 enum
几乎肯定是比字符串更好的选择。