子类化 Microsoft.Exchange.WebServices.Data.Item

Subclassing Microsoft.Exchange.WebServices.Data.Item

如何从中创建一个子class?

我想向此 class 添加一些方法,但是当我尝试创建子 class 时,我收到此错误:

Error   CS1729  'Item' does not contain a constructor that takes 0 arguments

这是我写的代码(大部分是自动生成的):

    using Microsoft.Exchange.WebServices.Data;

    public class ItemEx : Item
    {
        public override bool IsNew => base.IsNew;

        public override bool Equals(object obj)
        {
            return base.Equals(obj);
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        public override string ToString()
        {
            return base.Subject;
            //return base.ToString();
        }
    }

此基本代码出错。另外据我所知,Item 没有构造函数,那么 c# 真正想要的是什么?

如果我们看一下 documentation (or here),它确实没有显示类型 Microsoft.Exchange.WebServices.Data.Item 的任何构造函数,但是,如果您看一下从 Item,它们都实现了如下构造函数:

public InheritedFromItem(
    ExchangeService service
)

所以我想也许你也应该实施它。
刚刚确认查看 Item 类型的源代码:

ews-managed-api/Item.cs at master · OfficeDev/ews-managed-api - GitHub https://github.com/OfficeDev/ews-managed-api/blob/master/Core/ServiceObjects/Items/Item.cs

namespace Microsoft.Exchange.WebServices.Data
{
    using System;
    using System.Collections.Generic;
    using System.Linq;

    /// <summary>
    /// Represents a generic item. Properties available on items are defined in the ItemSchema class.
    /// </summary>
    [Attachable]
    [ServiceObjectDefinition(XmlElementNames.Item)]
    public class Item : ServiceObject
    {
        private ItemAttachment parentAttachment;

        /// <summary>
        /// Initializes an unsaved local instance of <see cref="Item"/>. To bind to an existing item, use Item.Bind() instead.
        /// </summary>
        /// <param name="service">The ExchangeService object to which the item will be bound.</param>
        internal Item(ExchangeService service)
            : base(service)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Item"/> class.
        /// </summary>
        /// <param name="parentAttachment">The parent attachment.</param>
        internal Item(ItemAttachment parentAttachment)
            : this(parentAttachment.Service)
        {
            // [...]
        }

        // [...]

看到它实际上有两个内部构造函数,一个接收 ExchangeService 对象,另一个接收 ItemAttachment 对象。

以继承自ItemContact为例,它将ExchangeService构造函数实现为publicItemAttachment 构造函数为 internal:

ews-managed-api/Contact.cs at master · OfficeDev/ews-managed-api - GitHub
https://github.com/OfficeDev/ews-managed-api/blob/master/Core/ServiceObjects/Items/Contact.cs

namespace Microsoft.Exchange.WebServices.Data
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Text;

    /// <summary>
    /// Represents a contact. Properties available on contacts are defined in the ContactSchema class.
    /// </summary>
    [Attachable]
    [ServiceObjectDefinition(XmlElementNames.Contact)]
    public class Contact : Item
    {
        private const string ContactPictureName = "ContactPicture.jpg";

        /// <summary>
        /// Initializes an unsaved local instance of <see cref="Contact"/>. To bind to an existing contact, use Contact.Bind() instead.
        /// </summary>
        /// <param name="service">The ExchangeService object to which the contact will be bound.</param>
        public Contact(ExchangeService service)
            : base(service)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Contact"/> class.
        /// </summary>
        /// <param name="parentAttachment">The parent attachment.</param>
        internal Contact(ItemAttachment parentAttachment)
            : base(parentAttachment)
        {
        }

        // [...]

所以,尝试在您的代码中模仿它:

using Microsoft.Exchange.WebServices.Data;

public class ItemEx : Item
{
    public ItemEx(ExchangeService service)
        : base(service)
    {
    }

    internal ItemEx(ItemAttachment parentAttachment)
        : base(parentAttachment)
    {
    }
}

但是你不能像这样实例化你的 class 的对象:

ItemEx myItem = new ItemEx();

你应该这样做:

ExchangeService service = new ExchangeService();
ItemEx myItem = new ItemEx(service);

更新

抱歉我之前的无知。 Item class 的构造函数上的 internal 访问修饰符使它们只能在同一程序集中的文件中访问。

因此,这意味着此 Item class 不能在 Microsoft.Exchange.WebServices.dll 程序集之外从其他人继承 class。一些参考:

虽然不是完美的解决方案,但似乎无法使用 ToString 方法扩展 class,因为它们通常已经在其上实现了此方法。

另一个解决方案是这样使用它:

class MailData
{
    public string subject;
    public Item mailItem;

    public MailData(string subject, Item mailItem)
    {
        this.subject = subject;
        this.mailItem = mailItem;
    }

    public override string ToString() => subject;

}

有了这个,就可以像这样使用它了:

        if (findResults.Items.Count > 0)
        {
            foreach (Item item in findResults.Items)
                comboBox1.Items.Add(new MailData(item.Subject,item));
        }

以后这样使用:

                    EmailMessage item = (selectedItem as MailData).mailItem as EmailMessage;
                    textBox1.Text = $"From: {item.From.Address}";
                    wb.DocumentText = item.Body.Text;
                    wb.Update();

是的,它有点复杂,实际上不是我想要的,但它达到了它的目的。

PS:我也将 item 用于其他目的,但在这里我将它用于电子邮件..