使用属性来满足接口要求

时间:2010-06-08 16:25:29

标签: c# interface attributes

好的,我正处于过度思考这个问题的边缘。有没有办法组合接口和属性,以便实现类中的属性属性满足接口契约?

在我的应用程序中,我想显示一系列活动,这是系统中事件的集合,例如新消息,正在创建/分配/更新的新任务等。这只是一个快速的手册发生了什么事。

我考虑使用IIsActivity接口来标记需要成为此聚合的一部分的实体。我真的只需要显示一个活动标题,它发生的日期,并链接到应用程序中的相关区域。我不想在继承类中强制执行其他属性,这些属性最终会导致重复信息。例如,一个Task有一个AssignedOn(DateTime),一个Message有一个CreatedOn(DateTime)。这两个都将满足被视为活动的日期要求。我不想要的只是活动日期的单独属性。同样可以用于标题(Message有一个Title属性,Task有一个Name属性)。

所以,我基本上希望能够说,“给我任何东西,这是一个IIsActivity。在每个实现者中,我希望有一个标有ActivityTitle属性的属性,以及一个具有ActivityDate属性的属性。”

太多了?

3 个答案:

答案 0 :(得分:1)

我认为您最好的方法是使用显式接口实现。

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
  }
}

答案 1 :(得分:0)

这不完全是你的设计,但是我使用了属性来强制我的类的某些属性具有所需的值。我正在使用网络服务而且我必须发送一些信息,其中一些字段需要价值,其他字段不需要......

[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之前,我将检查每个属性是否符合其属性标记。

答案 2 :(得分:0)

在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#中的目标。