【问题标题】:Setting the Value of an ICollection Property in C#在 C# 中设置 ICollection 属性的值
【发布时间】:2012-12-31 03:59:20
【问题描述】:

我的类继承了一个接口,所以我需要在 Person 类中有 emailaddress 属性。

我的问题是获取属性和设置属性的最佳方法是什么

public class Contact : IPerson, ILocation
{
  ...
  [MaxLength(256)]
  public string EmailAddress { 
  get{
    return this.Emails.First().ToString();
  } 
  set{ ????  }
  }
  ....

  public virtual ICollection<Emails> Emails { get; set; }
}

基本上,我正试图让班级允许多封电子邮件。

为了全面披露,我对此很陌生,我可能没有问正确的问题,但我已经搜索了一天半并且没有看到这样的东西(并不是我认为这很不寻常)并且可以利用洞察力。

电子邮件类属性:

[Key]
public int Id { get; set; }

[MaxLength(256)]
    public string EmailAddress { get; set; }

【问题讨论】:

  • 如果您想访问集合中的不同索引,getter 和 setter 是不够的。您将不得不编写一个带有某种索引作为参数的方法
  • 从根本上说,拥有一个集合不寻常的,但也有一个试图处理一个 single 值的属性。你希望它如何表现?如果我多次设置EmailAddress 属性,最终应该是一个地址还是多个?您希望它如何与设置 Emails 属性进行交互?实际的实现可能很简单——但你需要先弄清楚你想要什么行为。
  • 我在联系人和他们的电子邮件之间有一对多(因此是集合)。因为我继承了一个接口,所以我不能排除 EmailAddress 属性(从接口中)。所以我不知道从哪里拿它。我可以忽略这个集合,只通过关系来做吗?
  • 你不能“忽略”set,如果它是由接口的实现所强制的。你能做的最好的就是让它在set正文中抛出一个NotImplementedException .不过它需要在那里..

标签: c# properties icollection


【解决方案1】:

您是否可以控制强制您实现EmailAddressIPerson 接口的设计?如果是这样,我建议重新考虑设计以避免在同一对象上同时需要单个属性和电子邮件地址列表。

您可能还需要考虑将Emails 属性设置器设置为protected,以防止外部代码更改您对象的数据。

如果您必须实现此接口,并且希望 EmailAddress 属性始终引用集合中的第一封电子邮件,您可以尝试此代码。

public class Contact : IPerson, ILocation
{
  public Contact()
  {
    // Initialize the emails list
    this.Emails = new List<Emails>();
  }

  [MaxLength(256)]
  public string EmailAddress
  { 
    get
    {
      // You'll need to decide what to return if the first email has not been set.
      // Replace string.Empty with the appropriate value.
      return this.Emails.Count == 0 ? string.Empty : this.Emails[0].ToString();
    } 
    set
    {
      if (this.Emails.Count == 0)
      {
        this.Emails.Add(new Emails());
      }
      this.Emails[0].EmailAddress = value;
    }
  }

  public virtual IList<Emails> Emails { get; set; }
}

【讨论】:

  • 这似乎让我更接近了。但是,它不喜欢 .Add() 方法(说它正在寻找电子邮件类型,而不是值的字符串类型。另外,我不确定我缺少什么,但长度不起作用this.Emails。顺便谢谢。更新:将长度更改为计数:/
  • Length 被 Array 暴露。其他收藏公开Count
  • 哎呀,Length 的东西很好。 Add() 需要根据我的评论进行更新,以创建一个新的 Emails 对象。由于您没有将其包含在代码中,因此我不确定它的外观,因此无法告诉您更具体的内容。
  • 这是一个非常基本的类,具有 EmailAddress 属性。它的唯一目的是保存每个联系人的电子邮件。更新了原件以显示电子邮件类。
  • 好的,我已经更新了代码以反映这一点。希望这对你有用。
【解决方案2】:

编辑:起初我不明白这个问题。

在这种情况下,我不确定您尝试做的事情是否有意义。您正在从 getter 上的电子邮件集合中取出第一封电子邮件;那么你想要二传手的行为是什么?它可以 (a) 将设置值更新或插入到集合中的第一个位置,或者 (b) 只需在设置时将电子邮件添加到集合中。我不确定我是否会允许设置它,只需获取并保留它。

我还将重命名属性 FirstEmail 或其他名称,因此很明显它来自可能的电子邮件集合。

  public string FirstEmailAddress { 
      get{
         return this.Emails.Count > 0 ? this.Emails.First().ToString() : string.Empty;
      } 
  }

【讨论】:

    【解决方案3】:

    通常,当您想向世界“展示”一个内部集合时,您所做的就是将其设为属性并仅创建一个 getter。这样您就不能像Contact.Emails = new ICollection&lt;Email&gt;() 那样设置整个集合,这是一种不好的做法。但是您可以通过Contacts.Emails 访问该集合并对其进行迭代或添加项目等。

    如果您愿意,还可以向该属性添加索引器:http://msdn.microsoft.com/en-us/library/vstudio/6x16t2tx(v=vs.100).aspx

    【讨论】:

      【解决方案4】:

      根据您的评论,

      我在联系人和他们的电子邮件之间有一对多(因此是集合)。因为我继承了一个接口,所以我不能排除 EmailAddress 属性(从接口中)。所以我不知道从哪里拿它。我可以忽略这个集合,只通过关系来做吗?

      你不应该允许public setter。将其设为protected,因为您已标记为虚拟。

      public virtual ICollection<Emails> Emails { get; protected set; }
      

      对于您的 EmailAddress 设置器,您可以使用以下方法

      [MaxLength(256)]
      public string EmailAddress 
      { 
          get
          {
              return this.Emails.DefaultIfEmpty(new EMail()).First().EmailAddress;
          } 
          set
          {
              if (Emails == null)
              {
                  Emails = new Collection<Email>(); 
              }
              Emails.Items.Insert(0, new EMail {EmailAddress = value}); 
          }
      }
      

      【讨论】:

      • 不喜欢新的 Collection 声明。或项目
      • 但是你已经这样暴露了。它应该公开为IList&lt;Email&gt;。然后Items 将消失。你无法避免Insert(直到它是双向链表或堆栈)
      • 抱歉,编译器没有:)
      • 我同意设置Emails 属性保护集,但我不喜欢这里的EmailAddress 实现。如果在没有初始化电子邮件的情况下调用 getter,这将引发错误,并且在 setter 中使用 Insert 会在每次调用 setter 时向列表中添加一个新项目,我认为这不是非常可取的。
      • @JeromyIrvine,否则第一个电子邮件地址将始终被覆盖。如果打算覆盖,可以使用 Emails[0] 。 Emails 应在 ctor 中初始化,并删除条件 if (Emails == null)
      猜你喜欢
      • 2021-06-07
      • 1970-01-01
      • 2016-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多