ฉันได้ลองหลายครั้งแล้ว แต่ก็ยังไม่เข้าใจการใช้คุณลักษณะที่กำหนดเอง (ฉันได้ดูลิงก์มากมายแล้ว)
ใครช่วยอธิบายตัวอย่างพื้นฐานของแอตทริบิวต์ที่กำหนดเองพร้อมรหัสให้ฉันได้ไหม
ฉันได้ลองหลายครั้งแล้ว แต่ก็ยังไม่เข้าใจการใช้คุณลักษณะที่กำหนดเอง (ฉันได้ดูลิงก์มากมายแล้ว)
ใครช่วยอธิบายตัวอย่างพื้นฐานของแอตทริบิวต์ที่กำหนดเองพร้อมรหัสให้ฉันได้ไหม
คำตอบ:
แม้ว่าโค้ดในการสร้างแอตทริบิวต์ที่กำหนดเองจะค่อนข้างเรียบง่าย แต่สิ่งสำคัญมากที่คุณต้องเข้าใจว่าแอตทริบิวต์คืออะไร
แอตทริบิวต์เป็นข้อมูลเมตาที่รวบรวมไว้ในโปรแกรมของคุณ แอตทริบิวต์เองไม่ได้เพิ่มฟังก์ชันการทำงานใด ๆ ให้กับคลาสคุณสมบัติหรือโมดูล - เพียงแค่ข้อมูล อย่างไรก็ตามการใช้การสะท้อนกลับสามารถใช้ประโยชน์จากคุณสมบัติเหล่านั้นเพื่อสร้างฟังก์ชันการทำงานได้
ดังนั้นสำหรับตัวอย่างให้ดูที่การตรวจสอบบล็อกโปรแกรมประยุกต์จากไมโครซอฟท์โครงการห้องสมุด หากคุณดูตัวอย่างโค้ดคุณจะเห็น:
/// <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; }
จากตัวอย่างด้านบนอาจมีคนเดาได้ว่าโค้ดจะได้รับการตรวจสอบความถูกต้องเสมอทุกครั้งที่มีการเปลี่ยนแปลงตามกฎของ Validator (ในตัวอย่างมีอักขระอย่างน้อย 8 ตัวและไม่เกิน 8 อักขระ) แต่ความจริงก็คือ Attribute ไม่ได้ทำอะไรเลย ดังที่ได้กล่าวไว้ก่อนหน้านี้จะเพิ่มเฉพาะข้อมูลเมตาให้กับคุณสมบัติเท่านั้น
อย่างไรก็ตามไลบรารีขององค์กรมีValidation.Validate
วิธีการที่จะตรวจสอบวัตถุของคุณและสำหรับแต่ละคุณสมบัติจะตรวจสอบว่าเนื้อหาละเมิดกฎที่แอตทริบิวต์แจ้งหรือไม่
นั่นคือวิธีที่คุณควรคิดเกี่ยวกับแอตทริบิวต์ - วิธีเพิ่มข้อมูลลงในโค้ดของคุณซึ่งอาจใช้ในภายหลังโดยวิธีการ / คลาส / ฯลฯ อื่น ๆ
คุณเริ่มต้นด้วยการเขียนคลาสที่มาจากแอตทริบิวต์ :
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;
}
คุณสามารถโยนสิ่งนี้ในการวนซ้ำและใช้การสะท้อนเพื่อเข้าถึงแอตทริบิวต์ที่กำหนดเองนี้ในแต่ละคุณสมบัติของคลาส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 เพียงเท่านี้ :)
แต่ที่นี่ฉันจะอธิบายรายละเอียดคุณลักษณะ:
โดยทั่วไปแอตทริบิวต์คือคลาสที่เราสามารถใช้เพื่อใช้ตรรกะของเรากับแอสเซมบลีคลาสเมธอดคุณสมบัติฟิลด์ ...
ใน. Net Microsoft ได้จัดเตรียมแอตทริบิวต์ที่กำหนดไว้ล่วงหน้าเช่นแอตทริบิวต์ที่ล้าสมัยหรือการตรวจสอบความถูกต้องเช่น ([จำเป็น], [StringLength (100)], [Range (0, 999.99)]) นอกจากนี้เรายังมีแอตทริบิวต์ประเภทต่างๆเช่น ActionFilters ใน asp.net ที่สามารถเป็นประโยชน์มากสำหรับการใช้ตรรกะที่ต้องการของเราที่จะรหัสของเรา (อ่านนี้บทความเกี่ยวกับตัวกรองการกระทำถ้าคุณมีความกระตือรือร้นที่จะเรียนรู้มัน)
อีกประเด็นหนึ่งคุณสามารถใช้การกำหนดค่าชนิดหนึ่งกับแอตทริบิวต์ของคุณผ่าน AttibuteUsage
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = true)]
เมื่อคุณตกแต่งคลาสแอ็ตทริบิวต์ด้วย AttributeUsage คุณสามารถบอกกับคอมไพเลอร์ c # ว่าฉันจะใช้แอ็ตทริบิวต์นี้: ฉันจะใช้สิ่งนี้กับคลาสแอสเซมบลีในคุณสมบัติหรือบน ... และแอ็ตทริบิวต์ของฉันได้รับอนุญาตให้ใช้ หลายครั้งกับเป้าหมายที่กำหนด (คลาสแอสเซมบลีคุณสมบัติ ... ) หรือไม่!
หลังจากคำจำกัดความเกี่ยวกับแอตทริบิวต์นี้ฉันจะแสดงตัวอย่างสมมติว่าเราต้องการกำหนดบทเรียนใหม่ในมหาวิทยาลัยและเราต้องการอนุญาตให้เฉพาะผู้ดูแลระบบและปริญญาโทในมหาวิทยาลัยของเรากำหนดบทเรียนใหม่ได้ไหม
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();
}
}
}
ในโลกแห่งการเขียนโปรแกรมบางทีเราอาจจะไม่ใช้แนวทางนี้ในการใช้คุณลักษณะและฉันก็พูดแบบนี้เพราะประเด็นทางการศึกษาในการใช้แอตทริบิวต์