Saya telah mencoba berkali-kali tetapi masih tidak dapat memahami penggunaan atribut khusus (saya telah melalui banyak tautan).
Adakah yang bisa menjelaskan kepada saya contoh yang sangat dasar dari atribut khusus dengan kode?
Saya telah mencoba berkali-kali tetapi masih tidak dapat memahami penggunaan atribut khusus (saya telah melalui banyak tautan).
Adakah yang bisa menjelaskan kepada saya contoh yang sangat dasar dari atribut khusus dengan kode?
Jawaban:
Meskipun kode untuk membuat Atribut khusus cukup sederhana, sangat penting bagi Anda untuk memahami apa itu atribut:
Atribut adalah metadata yang dikompilasi ke dalam program Anda. Atribut itu sendiri tidak menambahkan fungsionalitas apa pun ke kelas, properti, atau modul - hanya data. Namun, dengan menggunakan refleksi, seseorang dapat memanfaatkan atribut tersebut untuk menciptakan fungsionalitas.
Jadi, sebagai contoh, mari kita lihat Blok Aplikasi Validasi , dari Perpustakaan Perusahaan Microsoft . Jika Anda melihat contoh kode, Anda akan melihat:
/// <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; }
Dari potongan di atas, orang mungkin menebak bahwa kode akan selalu divalidasi, setiap kali diubah, sesuai dengan aturan Validator (dalam contoh, memiliki setidaknya 8 karakter dan paling banyak 8 karakter). Tetapi kenyataannya adalah bahwa Atribut tidak melakukan apa-apa; seperti yang disebutkan sebelumnya, ini hanya menambahkan metadata ke properti.
Namun, Enterprise Library memiliki Validation.Validate
metode yang akan melihat objek Anda, dan untuk setiap properti, akan memeriksa apakah konten melanggar aturan yang diinformasikan oleh atribut.
Jadi, begitulah seharusnya Anda memikirkan atribut - cara untuk menambahkan data ke kode Anda yang mungkin nantinya digunakan oleh metode / kelas / dll.
Anda mulai dengan menulis kelas yang berasal dari Atribut :
public class MyCustomAttribute: Attribute
{
public string SomeProperty { get; set; }
}
Kemudian Anda bisa mendekorasi apa saja (class, method, property, ...) dengan atribut ini:
[MyCustomAttribute(SomeProperty = "foo bar")]
public class Foo
{
}
dan akhirnya Anda akan menggunakan refleksi untuk mengambilnya:
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
}
Anda dapat membatasi jenis target tempat atribut khusus ini dapat diterapkan menggunakan atribut AttributeUsage :
/// <summary>
/// This attribute can only be applied to classes
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class MyCustomAttribute : Attribute
Hal penting yang perlu diketahui tentang atribut:
var value = typeof(Foo).GetCustomAttributes<MyCustomAttribute>().First().SomeProperty;
Memanfaatkan / Menyalin respons bagus Darin Dimitrov , berikut adalah cara mengakses atribut khusus pada properti dan bukan kelas:
Properti yang didekorasi [kelas Foo
]:
[MyCustomAttribute(SomeProperty = "This is a custom property")]
public string MyProperty { get; set; }
Mengambilnya:
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;
}
Anda dapat melempar ini dalam satu putaran dan menggunakan refleksi untuk mengakses atribut khusus ini pada setiap properti kelas Foo
, juga:
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
}
}
Terima kasih banyak untukmu, Darin !!
object[] attribute = propertyInfo.GetCustomAttributes(typeof(???), true);
Saya hanya ingin mengulang semuanya dan memanggil metode m1()
dari setiap atribut yang tidak diketahui
Jawaban singkatnya adalah untuk membuat atribut di c # Anda hanya perlu mewarisinya dari kelas Atribut, Hanya ini :)
Tapi di sini saya akan menjelaskan atribut secara detail:
pada dasarnya atribut adalah kelas yang dapat kita gunakan untuk menerapkan logika kita ke rakitan, kelas, metode, properti, bidang, ...
Di .Net, Microsoft telah menyediakan beberapa Atribut yang telah ditentukan sebelumnya seperti Atribut Kedaluwarsa atau Validasi seperti ([Wajib], [Panjang String (100)], [Rentang (0, 999,99)]), juga kami memiliki jenis atribut seperti ActionFilters di asp.net yang bisa sangat berguna untuk menerapkan logika yang kita inginkan ke kode kita (baca artikel ini tentang filter tindakan jika Anda ingin mempelajarinya)
satu sama lain, Anda dapat menerapkan semacam konfigurasi pada atribut Anda melalui AttibuteUsage.
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = true)]
Ketika Anda mendekorasi kelas atribut dengan AttributeUsage, Anda dapat memberi tahu c # compiler di mana saya akan menggunakan atribut ini: Saya akan menggunakan ini di kelas, pada rakitan pada properti atau di ... dan atribut saya diizinkan untuk digunakan beberapa kali pada target yang ditentukan (kelas, rakitan, properti, ...) atau tidak ?!
Setelah definisi tentang atribut ini, saya akan menunjukkan kepada Anda sebuah contoh: Bayangkan kita ingin mendefinisikan pelajaran baru di universitas dan kita ingin mengizinkan hanya admin dan master di universitas kita untuk menentukan Pelajaran baru, 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();
}
}
}
Dalam dunia nyata pemrograman mungkin kita tidak menggunakan pendekatan ini untuk menggunakan atribut dan saya mengatakan ini karena poin edukasinya dalam menggunakan atribut