답변:
사용자 지정 속성 을 만드는 코드 는 매우 간단하지만 속성이 무엇인지 이해하는 것이 매우 중요합니다.
속성은 프로그램으로 컴파일 된 메타 데이터입니다. 속성 자체는 클래스, 속성 또는 모듈에 기능을 추가하지 않고 데이터 만 추가합니다. 그러나 리플렉션을 사용하면 기능을 생성하기 위해 이러한 속성을 활용할 수 있습니다.
예를 들어 Microsoft Enterprise Library 의 Validation Application Block을 살펴 보겠습니다 . 코드 예제를 보면 다음과 같이 표시됩니다.
/// <summary>
/// blah blah code.
/// </summary>
[DataMember]
[StringLengthValidator(8, RangeBoundaryType.Inclusive, 8, RangeBoundaryType.Inclusive, MessageTemplate = "\"{1}\" must always have \"{4}\" characters.")]
public string Code { get; set; }
위의 스 니펫에서 유효성 검사기의 규칙에 따라 변경 될 때마다 코드가 항상 유효성이 검사 될 것이라고 추측 할 수 있습니다 (예제에서는 8 자 이상 8 자 이하). 그러나 진실은 속성이 아무것도하지 않는다는 것입니다. 앞서 언급했듯이 속성에 메타 데이터 만 추가합니다.
그러나 엔터프라이즈 라이브러리에는 Validation.Validate
개체를 조사 하는 방법이 있으며 각 속성에 대해 콘텐츠가 속성에 의해 통보 된 규칙을 위반하는지 확인합니다.
따라서 이것이 나중에 다른 메서드 / 클래스 / 등에서 사용될 수있는 코드에 데이터를 추가하는 방법 인 속성에 대해 생각해야하는 방법입니다.
Attribute 에서 파생되는 클래스를 작성하여 시작합니다 .
public class MyCustomAttribute: Attribute
{
public string SomeProperty { get; set; }
}
그런 다음이 속성을 사용하여 무엇이든 (클래스, 메서드, 속성 등) 장식 할 수 있습니다.
[MyCustomAttribute(SomeProperty = "foo bar")]
public class Foo
{
}
마지막으로 리플렉션을 사용하여 가져옵니다.
var customAttributes = (MyCustomAttribute[])typeof(Foo).GetCustomAttributes(typeof(MyCustomAttribute), true);
if (customAttributes.Length > 0)
{
var myAttribute = customAttributes[0];
string value = myAttribute.SomeProperty;
// TODO: Do something with the value
}
AttributeUsage 속성을 사용하여이 사용자 정의 속성을 적용 할 수있는 대상 유형을 제한 할 수 있습니다 .
/// <summary>
/// This attribute can only be applied to classes
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class MyCustomAttribute : Attribute
속성에 대해 알아야 할 중요한 사항 :
var value = typeof(Foo).GetCustomAttributes<MyCustomAttribute>().First().SomeProperty;
Darin Dimitrov의 훌륭한 응답을 활용 / 복사 하면 다음은 클래스가 아닌 속성의 사용자 지정 속성에 액세스하는 방법입니다.
장식 된 속성 [등급 Foo
] :
[MyCustomAttribute(SomeProperty = "This is a custom property")]
public string MyProperty { get; set; }
가져 오는 중 :
PropertyInfo propertyInfo = typeof(Foo).GetProperty(propertyToCheck);
object[] attribute = propertyInfo.GetCustomAttributes(typeof(MyCustomAttribute), true);
if (attribute.Length > 0)
{
MyCustomAttribute myAttribute = (MyCustomAttribute)attribute[0];
string propertyValue = myAttribute.SomeProperty;
}
이것을 루프에 던지고 리플렉션을 사용 하여 class의 각 속성에 대한이 사용자 정의 속성에 액세스 할 수도 Foo
있습니다.
foreach (PropertyInfo propertyInfo in Foo.GetType().GetProperties())
{
string propertyName = propertyInfo.Name;
object[] attribute = propertyInfo.GetCustomAttributes(typeof(MyCustomAttribute), true);
// Just in case you have a property without this annotation
if (attribute.Length > 0)
{
MyCustomAttribute myAttribute = (MyCustomAttribute)attribute[0];
string propertyValue = myAttribute.SomeProperty;
// TODO: whatever you need with this propertyValue
}
}
고마워요, 다린 !!
object[] attribute = propertyInfo.GetCustomAttributes(typeof(???), true);
나는 그들 모두를 반복하고 m1()
각각의 알려지지 않은 속성 의 메소드 를 호출하고
짧은 대답은 C #에서 속성을 만드는 것입니다. Attribute 클래스에서 상속하면됩니다. Just this :)
하지만 여기서는 속성에 대해 자세히 설명하겠습니다.
기본적으로 속성은 어셈블리, 클래스, 메서드, 속성, 필드 등에 논리를 적용하는 데 사용할 수있는 클래스입니다.
.Net에서 Microsoft는 Obsolete 또는 ([Required], [StringLength (100)], [Range (0, 999.99)])와 같은 유효성 검사 속성과 같은 미리 정의 된 속성을 제공했으며 asp.net에는 ActionFilters와 같은 종류의 속성도 있습니다. 원하는 로직을 코드에 적용하는 데 매우 유용 할 수 있습니다 ( 배우고 싶다면 액션 필터에 대한 이 기사를 읽으 십시오).
서로 다른 지점에서 AttibuteUsage를 통해 속성에 일종의 구성을 적용 할 수 있습니다.
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = true)]
AttributeUsage를 사용하여 특성 클래스를 장식 할 때이 특성을 사용할 위치를 C # 컴파일러에 알릴 수 있습니다. 클래스, 속성의 어셈블리 또는 ...에서이 특성을 사용할 것입니다. 정의 된 대상 (클래스, 어셈블리, 속성 등)에 대해 여러 번?!
속성에 대한이 정의 이후에 예를 보여 드리겠습니다. 대학에서 새로운 강의를 정의하고 우리 대학의 관리자와 석사 만 새로운 강의를 정의 할 수 있도록 허용한다고 가정 해 보겠습니다. Ok?
namespace ConsoleApp1
{
/// <summary>
/// All Roles in our scenario
/// </summary>
public enum UniversityRoles
{
Admin,
Master,
Employee,
Student
}
/// <summary>
/// This attribute will check the Max Length of Properties/fields
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = true)]
public class ValidRoleForAccess : Attribute
{
public ValidRoleForAccess(UniversityRoles role)
{
Role = role;
}
public UniversityRoles Role { get; private set; }
}
/// <summary>
/// we suppose that just admins and masters can define new Lesson
/// </summary>
[ValidRoleForAccess(UniversityRoles.Admin)]
[ValidRoleForAccess(UniversityRoles.Master)]
public class Lesson
{
public Lesson(int id, string name, DateTime startTime, User owner)
{
var lessType = typeof(Lesson);
var validRolesForAccesses = lessType.GetCustomAttributes<ValidRoleForAccess>();
if (validRolesForAccesses.All(x => x.Role.ToString() != owner.GetType().Name))
{
throw new Exception("You are not Allowed to define a new lesson");
}
Id = id;
Name = name;
StartTime = startTime;
Owner = owner;
}
public int Id { get; private set; }
public string Name { get; private set; }
public DateTime StartTime { get; private set; }
/// <summary>
/// Owner is some one who define the lesson in university website
/// </summary>
public User Owner { get; private set; }
}
public abstract class User
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime DateOfBirth { get; set; }
}
public class Master : User
{
public DateTime HireDate { get; set; }
public Decimal Salary { get; set; }
public string Department { get; set; }
}
public class Student : User
{
public float GPA { get; set; }
}
class Program
{
static void Main(string[] args)
{
#region exampl1
var master = new Master()
{
Name = "Hamid Hasani",
Id = 1,
DateOfBirth = new DateTime(1994, 8, 15),
Department = "Computer Engineering",
HireDate = new DateTime(2018, 1, 1),
Salary = 10000
};
var math = new Lesson(1, "Math", DateTime.Today, master);
#endregion
#region exampl2
var student = new Student()
{
Name = "Hamid Hasani",
Id = 1,
DateOfBirth = new DateTime(1994, 8, 15),
GPA = 16
};
var literature = new Lesson(2, "literature", DateTime.Now.AddDays(7), student);
#endregion
ReadLine();
}
}
}
프로그래밍의 실제 세계에서 우리는 속성을 사용하는 데이 접근 방식을 사용하지 않을 수 있으며 속성 사용에 대한 교육적 관점 때문에 이렇게 말했습니다.