[英]Using attributes to fulfill interface requirements
好吧,我正处于过度思考这个问题的边缘。 有没有办法组合接口和属性,以便实现类中的属性属性满足接口契约?
在我的应用程序中,我想显示一系列活动,这是系统中事件的集合,例如新消息,正在创建/分配/更新的新任务等。这只是一个快速的手册列表继续
我想过使用IIsActivity接口来标记需要成为此聚合一部分的实体。 我真的只需要显示一个活动标题,它发生的日期,并链接到应用程序中的相关区域。 我不想在继承类中强制执行其他属性,这些属性最终会导致重复信息。 例如,一个Task有一个AssignedOn(DateTime),一个Message有一个CreatedOn(DateTime)。 这两个都将满足被视为活动的日期要求。 我不想要的只是活动日期的单独属性。 同样可以用于标题(Message具有Title属性,Task具有Name属性)。
所以,我基本上希望能够说:“给我任何东西,这是一个IIsActivity。在每个实现者中,我希望有一个标有ActivityTitle属性的属性,一个带有ActivityDate属性的属性。”
太多了?
我认为您最好的方法是使用显式接口实现。
public interface IActivity
{
DateTime OccurredOn { get; }
}
public class Task : IActivity
{
public DateTime AssignedOn
{
get { /* implemenation */ }
}
DateTime IActivity.OccurredOn
{
get { return AssignedOn; }
}
}
public class Message : IActivity
{
public DateTime CreatedOn
{
get { /* implemenation */ }
}
DateTime IActivity.OccurredOn
{
get { return CreatedOn; }
}
}
然后你可以像这样使用你的类:
public static void Main()
{
Task task = new Task();
Console.WriteLine(task.AssignedOn); // OK
Console.WriteLine(task.OccurredOn); // Compile Error
IActivity activity = task as IActivity;
if (activity != null)
{
Console.WriteLine(activity.AssignedOn); // Compile Error
Console.WriteLine(activity.OccurredOn); // OK
}
}
这不完全是您的设计,但我使用属性强制执行我的类的某些属性具有所需的值。 我正在使用网络服务而且我必须发送一些信息,其中一些字段需要价值,其他字段不...
[Serializable]
[AttributeUsage(AttributeTargets.Property)]
public class RequiredAttribute : Attribute
{
private CheckType[] _requiredtype;
public RequiredAttribute(params CheckType[] type)
{
_requiredtype = type;
}
public CheckType[] Requires
{
get { return _requiredtype; }
}
public static bool CheckRequirements(object applyto, out string errormessages)
{ ... }
private static bool RequiredSucceeded(object applyto, StringBuilder resultmessage)
{ ... }
}
[Serializable]
public enum CheckType
{
HasValue, // Checks that the property value is not null
CheckMinRequirements, // Will enforce the validation of properties on defined types
IsNotNullorEmpty, // For strings
HasElements, // Elements exist on arrays
ElementsRequirements // for collections
}
现在有一个使用该属性的类的示例
[Serializable]
public class PurchaseInsurance
{
[Required(CheckType.IsNotNullorEmpty)]
public string PartnerBookingID
{
get;
set;
}
[Required(CheckType.IsNotNullorEmpty)]
public string Currency
{
get;
set;
}
public string ReferringURL;
[Required(CheckType.HasValue, CheckType.CheckMinRequirements)]
public PurchaserInfo Purchaser
{
get;
set;
}
[Required(CheckType.HasValue, CheckType.ElementsRequirements)]
public InsuranceProduct[] Products
{
get;
set;
}
...
}
在将数据发送到webService之前,我将检查每个属性是否符合其属性标记。
在CLR支持它的情况下,C#不支持接口实现别名。 你可以在VB.NET中实现它:
Public Interface IActivity ' this can even be in C# '
ReadOnly Property OccurredOn() As DateTime
End Interface
Public Class Task
Implements IActivity
Public ReadOnly Property AssignedOn() As DateTime Implements IActivity.OccurredOn
Get
' implementation... '
End Get
End Property
End Class
Public Class Message
Implements IActivity
Public ReadOnly Property CreatedOn() As DateTime Implements IActivity.OccurredOn
Get
' implementation... '
End Get
End Property
End Class
因此,正如Brian Gideon所提到的,显式接口实现更接近您在C#中的目标。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.