Pek çok kez denedim, ancak yine de özel özelliklerin kullanımını anlayamıyorum (zaten birçok bağlantıdan geçtim).
Herhangi biri bana kodlu özel bir özniteliğin çok basit bir örneğini açıklayabilir mi?
Pek çok kez denedim, ancak yine de özel özelliklerin kullanımını anlayamıyorum (zaten birçok bağlantıdan geçtim).
Herhangi biri bana kodlu özel bir özniteliğin çok basit bir örneğini açıklayabilir mi?
Yanıtlar:
Özel bir Öznitelik oluşturma kodu oldukça basit olsa da, özniteliklerin ne olduğunu anlamanız çok önemlidir:
Öznitelikler, programınızda derlenen meta verilerdir. Özniteliklerin kendileri bir sınıfa, özelliğe veya modüle herhangi bir işlevsellik eklemez - yalnızca veri. Bununla birlikte, yansıma kullanarak, işlevsellik oluşturmak için bu niteliklerden yararlanılabilir.
Öyleyse, örneğin, Microsoft Enterprise Library'den Validation Application Block'a bakalım . Bir kod örneğine bakarsanız şunları görürsünüz:
/// <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; }
Yukarıdaki kod parçasından, her değiştirildiğinde, Doğrulayıcı kurallarına göre kodun her zaman doğrulanacağı tahmin edilebilir (örnekte, en az 8 karakter ve en fazla 8 karakter vardır). Ancak gerçek şu ki, Öznitelik hiçbir şey yapmaz; daha önce belirtildiği gibi, mülke yalnızca meta verileri ekler.
Bununla birlikte, Enterprise Library Validation.Validate
nesnenize bakacak bir yönteme sahiptir ve her özellik için, içeriğin öznitelik tarafından bildirilen kuralı ihlal edip etmediğini kontrol eder.
Yani, öznitelikler hakkında böyle düşünmelisiniz - daha sonra diğer yöntemler / sınıflar / vb. Tarafından kullanılabilecek verileri kodunuza eklemenin bir yolu.
Öznitelikten türetilen bir sınıf yazarak başlarsınız :
public class MyCustomAttribute: Attribute
{
public string SomeProperty { get; set; }
}
Daha sonra bu nitelikle her şeyi (sınıf, yöntem, özellik, ...) dekore edebilirsiniz:
[MyCustomAttribute(SomeProperty = "foo bar")]
public class Foo
{
}
ve nihayet onu getirmek için yansıma kullanırsınız:
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 özelliğini kullanarak bu özel özelliğin uygulanabileceği hedef türlerini sınırlayabilirsiniz :
/// <summary>
/// This attribute can only be applied to classes
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class MyCustomAttribute : Attribute
Öznitelikler hakkında bilinmesi gereken önemli şeyler:
var value = typeof(Foo).GetCustomAttributes<MyCustomAttribute>().First().SomeProperty;
Darin Dimitrov'un harika yanıtını kullanarak / kopyalayarak , bir sınıfta değil, bir mülkte özel bir özelliğe nasıl erişilir:
Dekore edilmiş mülk [sınıfın Foo
]:
[MyCustomAttribute(SomeProperty = "This is a custom property")]
public string MyProperty { get; set; }
Getiriliyor:
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;
}
Sen bu özel özellik erişmek için bir döngü ve kullanım yansımada bu atabilir her sınıfın özellik Foo
sıra,:
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
}
}
Sayende büyük teşekkürler, Darin !!
object[] attribute = propertyInfo.GetCustomAttributes(typeof(???), true);
Ben sadece hepsini yinelemek ve m1()
bilinmeyen her özniteliğin bir yöntemini çağırmak istiyorum
Kısa cevap, c # 'da bir öznitelik oluşturmak içindir, onu yalnızca Öznitelik sınıfından devralmanız gerekir, Sadece bu :)
Ancak burada özellikleri ayrıntılı olarak açıklayacağım:
temelde öznitelikler, mantığımızı derlemelere, sınıflara, yöntemlere, özelliklere, alanlara, ... uygulamak için kullanabileceğimiz sınıflardır.
.Net'te Microsoft, ([Gerekli], [StringLength (100)], [Range (0, 999.99)]) gibi Eski veya Doğrulama Öznitelikleri gibi önceden tanımlanmış Öznitelikler sağlamıştır, ayrıca asp.net'te ActionFilters gibi özniteliklere sahibiz. İstediğimiz mantığı kodlarımıza uygulamak için çok yararlı olabilir ( öğrenmek için tutkuluysanız, eylem filtreleri hakkındaki bu makaleyi okuyun )
Bir başka nokta, AttibuteUsage aracılığıyla özniteliğinize bir tür yapılandırma uygulayabilirsiniz.
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = true)]
AttributeUsage ile bir öznitelik sınıfını dekore ettiğinizde, c # derleyicisine bu özniteliği nerede kullanacağımı söyleyebilirsiniz: Bunu sınıflarda, özelliklerdeki derlemelerde veya üzerinde kullanacağım ... ve özniteliğimin kullanımına izin verilir tanımlanmış hedefler üzerinde (sınıflar, derlemeler, özellikler, ...) birkaç kez mi ?!
Niteliklerle ilgili bu tanımdan sonra size bir örnek göstereceğim: Üniversitede yeni bir ders tanımlamak istediğimizi ve üniversitemizdeki yöneticilerin ve yüksek lisansların yeni bir Ders tanımlamasına izin vermek istediğimizi hayal edin, tamam mı?
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();
}
}
}
Gerçek programlama dünyasında belki bu yaklaşımı öznitelikleri kullanmak için kullanmayız ve bunu öznitelikleri kullanmadaki eğitimsel noktası nedeniyle söyledim.