繁体   English   中英

使用属性来满足接口要求

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM