C#의 값 기반 특성
18568 단어 dotnetcsharpattributes
C Sharp의 값 기반 속성
This code is a snippet from the https://github.com/ZacharyPatten/Towel project.
Please check out the project if you want to see more code like it. :)
C#의 속성은 훌륭합니다. 런타임 시 동적으로 조회할 수 있는 코드 멤버에 메타데이터를 추가할 수 있습니다. 그러나 그것들은 또한 다루기에는 약간의 고통입니다. 일반적으로 System.Attribute
를 상속하는 고유한 클래스를 만들고 리플렉션을 사용하여 속성을 조회하기 위해 적절한 상용구 코드를 추가해야 합니다. 다음은 고유한 속성을 만드는 예입니다.
using System;
using System.Linq;
using System.Reflection;
static class Program
{
static void Main()
{
MyAttribute attribute = typeof(MyClass).GetCustomAttributes<MyAttribute>().FirstOrDefault();
Console.WriteLine("MyCustomAttribute...");
if (!(attribute is null))
{
Console.WriteLine("Found: " + true);
Console.WriteLine("Value: " + attribute.Value);
}
else
{
Console.WriteLine("Found: " + false);
Console.WriteLine("Value: " + null);
}
}
}
public class MyAttribute : Attribute
{
public string Value { get; private set; }
public MyAttribute(string value)
{
Value = value;
}
}
[MyAttribute("hello world")]
public class MyClass { }
물론... 많은 상용구는 아니지만... 여전히 짜증나네요... 그래서 새로운 속성 유형을 정의하는 대신 상수 값을 사용할 수 있도록 값 기반 속성을 만들었습니다.
using System;
using Towel;
static class Program
{
static void Main()
{
var (Found, Value) = typeof(MyClass).GetValueAttribute("MyCustomAttribute");
Console.WriteLine("MyCustomAttribute...");
Console.WriteLine("Found: " + Found);
Console.WriteLine("Value: " + Value);
}
}
[Value("MyCustomAttribute", "hello world")]
public class MyClass { }
ValueAttribute
의 첫 번째 매개변수는 키와 같으며 두 번째 매개변수는
속성은 실제 값입니다. 그런 다음 키(첫 번째 매개변수)와 함께 GetValueAttribute
확장 메서드를 사용하면 자동으로 반영됩니다. 코드 멤버당 여러 개ValueAttributes
를 추가할 수 있습니다.
[Value("Name", "Array Benchmarks")]
[Value("Description", "These benchmarks do...")]
[Value("Source URL", "google.com")]
public class MyBenchmarks
{
// code...
}
어떻게 작동합니까? 첫 번째 예와 정확히 동일한 작업을 수행하지만
일치하는 키 값을 포함하는 ValueAttribute
. 소스 코드는 다음과 같습니다.
using System;
using System.Reflection;
namespace Towel
{
/// <summary>A value-based attribute.</summary>
[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
public class ValueAttribute : Attribute
{
internal object Attribute;
internal object Value;
/// <summary>Creates a new value-based attribute.</summary>
/// <param name="attribute">The attribute.</param>
/// <param name="value">The value.</param>
public ValueAttribute(object attribute, object value)
{
Attribute = attribute;
Value = value;
}
}
/// <summary>Extension methods for reflection types and <see cref="ValueAttribute"/>.</summary>
public static class ValueAttributeExtensions
{
/// <summary>Gets a <see cref="ValueAttribute"/> on a <see cref="MemberInfo"/>.</summary>
/// <param name="memberInfo">The type to get the <see cref="ValueAttribute"/> of.</param>
/// <param name="attribute">The attribute to get the value of.</param>
/// <returns>
/// (<see cref="bool"/> Found, <see cref="object"/> Value)
/// <para>- <see cref="bool"/> Found: True if the attribute was found; False if not or if multiple attributes were found (ambiguous).</para>
/// <para>- <see cref="object"/> Value: The value if found or default if not.</para>
/// </returns>
public static (bool Found, object Value) GetValueAttribute(this MemberInfo memberInfo, object attribute)
{
_ = memberInfo ?? throw new ArgumentNullException(nameof(memberInfo));
bool found = false;
object value = default;
foreach (ValueAttribute valueAttribute in memberInfo.GetCustomAttributes<ValueAttribute>())
{
if (ReferenceEquals(attribute, valueAttribute.Attribute) || attribute.Equals(valueAttribute.Attribute))
{
if (found)
{
return (false, default);
}
found = true;
value = valueAttribute.Value;
}
}
return (found, value);
}
/// <summary>Gets a <see cref="ValueAttribute"/> on a <see cref="ParameterInfo"/>.</summary>
/// <param name="parameterInfo">The type to get the <see cref="ValueAttribute"/> of.</param>
/// <param name="attribute">The attribute to get the value of.</param>
/// <returns>
/// (<see cref="bool"/> Found, <see cref="object"/> Value)
/// <para>- <see cref="bool"/> Found: True if the attribute was found; False if not or if multiple attributes were found (ambiguous).</para>
/// <para>- <see cref="object"/> Value: The value if found or default if not.</para>
/// </returns>
public static (bool Found, object Value) GetValueAttribute(this ParameterInfo parameterInfo, object attribute)
{
_ = parameterInfo ?? throw new ArgumentNullException(nameof(parameterInfo));
bool found = false;
object value = default;
foreach (ValueAttribute valueAttribute in parameterInfo.GetCustomAttributes<ValueAttribute>())
{
if (ReferenceEquals(attribute, valueAttribute.Attribute) || attribute.Equals(valueAttribute.Attribute))
{
if (found)
{
return (false, default);
}
found = true;
value = valueAttribute.Value;
}
}
return (found, value);
}
}
}
Reference
이 문제에 관하여(C#의 값 기반 특성), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/zacharypatten/value-based-attributes-in-c-157l
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
This code is a snippet from the https://github.com/ZacharyPatten/Towel project.
Please check out the project if you want to see more code like it. :)
using System;
using System.Linq;
using System.Reflection;
static class Program
{
static void Main()
{
MyAttribute attribute = typeof(MyClass).GetCustomAttributes<MyAttribute>().FirstOrDefault();
Console.WriteLine("MyCustomAttribute...");
if (!(attribute is null))
{
Console.WriteLine("Found: " + true);
Console.WriteLine("Value: " + attribute.Value);
}
else
{
Console.WriteLine("Found: " + false);
Console.WriteLine("Value: " + null);
}
}
}
public class MyAttribute : Attribute
{
public string Value { get; private set; }
public MyAttribute(string value)
{
Value = value;
}
}
[MyAttribute("hello world")]
public class MyClass { }
using System;
using Towel;
static class Program
{
static void Main()
{
var (Found, Value) = typeof(MyClass).GetValueAttribute("MyCustomAttribute");
Console.WriteLine("MyCustomAttribute...");
Console.WriteLine("Found: " + Found);
Console.WriteLine("Value: " + Value);
}
}
[Value("MyCustomAttribute", "hello world")]
public class MyClass { }
[Value("Name", "Array Benchmarks")]
[Value("Description", "These benchmarks do...")]
[Value("Source URL", "google.com")]
public class MyBenchmarks
{
// code...
}
using System;
using System.Reflection;
namespace Towel
{
/// <summary>A value-based attribute.</summary>
[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
public class ValueAttribute : Attribute
{
internal object Attribute;
internal object Value;
/// <summary>Creates a new value-based attribute.</summary>
/// <param name="attribute">The attribute.</param>
/// <param name="value">The value.</param>
public ValueAttribute(object attribute, object value)
{
Attribute = attribute;
Value = value;
}
}
/// <summary>Extension methods for reflection types and <see cref="ValueAttribute"/>.</summary>
public static class ValueAttributeExtensions
{
/// <summary>Gets a <see cref="ValueAttribute"/> on a <see cref="MemberInfo"/>.</summary>
/// <param name="memberInfo">The type to get the <see cref="ValueAttribute"/> of.</param>
/// <param name="attribute">The attribute to get the value of.</param>
/// <returns>
/// (<see cref="bool"/> Found, <see cref="object"/> Value)
/// <para>- <see cref="bool"/> Found: True if the attribute was found; False if not or if multiple attributes were found (ambiguous).</para>
/// <para>- <see cref="object"/> Value: The value if found or default if not.</para>
/// </returns>
public static (bool Found, object Value) GetValueAttribute(this MemberInfo memberInfo, object attribute)
{
_ = memberInfo ?? throw new ArgumentNullException(nameof(memberInfo));
bool found = false;
object value = default;
foreach (ValueAttribute valueAttribute in memberInfo.GetCustomAttributes<ValueAttribute>())
{
if (ReferenceEquals(attribute, valueAttribute.Attribute) || attribute.Equals(valueAttribute.Attribute))
{
if (found)
{
return (false, default);
}
found = true;
value = valueAttribute.Value;
}
}
return (found, value);
}
/// <summary>Gets a <see cref="ValueAttribute"/> on a <see cref="ParameterInfo"/>.</summary>
/// <param name="parameterInfo">The type to get the <see cref="ValueAttribute"/> of.</param>
/// <param name="attribute">The attribute to get the value of.</param>
/// <returns>
/// (<see cref="bool"/> Found, <see cref="object"/> Value)
/// <para>- <see cref="bool"/> Found: True if the attribute was found; False if not or if multiple attributes were found (ambiguous).</para>
/// <para>- <see cref="object"/> Value: The value if found or default if not.</para>
/// </returns>
public static (bool Found, object Value) GetValueAttribute(this ParameterInfo parameterInfo, object attribute)
{
_ = parameterInfo ?? throw new ArgumentNullException(nameof(parameterInfo));
bool found = false;
object value = default;
foreach (ValueAttribute valueAttribute in parameterInfo.GetCustomAttributes<ValueAttribute>())
{
if (ReferenceEquals(attribute, valueAttribute.Attribute) || attribute.Equals(valueAttribute.Attribute))
{
if (found)
{
return (false, default);
}
found = true;
value = valueAttribute.Value;
}
}
return (found, value);
}
}
}
Reference
이 문제에 관하여(C#의 값 기반 특성), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/zacharypatten/value-based-attributes-in-c-157l텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)