子类化 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
对象。
以继承自Item
的Contact
为例,它将ExchangeService
构造函数实现为public 和 ItemAttachment
构造函数为 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。一些参考:
- Is there a way to derive from a class with an internal constructor? - Stack Overflow
- Preventing third-party derivation, part one - Fabulous Adventures In Coding
- Preventing third-party derivation, part two - Fabulous Adventures In Coding
虽然不是完美的解决方案,但似乎无法使用 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 用于其他目的,但在这里我将它用于电子邮件..
如何从中创建一个子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
对象。
以继承自Item
的Contact
为例,它将ExchangeService
构造函数实现为public 和 ItemAttachment
构造函数为 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.csnamespace 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。一些参考:
- Is there a way to derive from a class with an internal constructor? - Stack Overflow
- Preventing third-party derivation, part one - Fabulous Adventures In Coding
- Preventing third-party derivation, part two - Fabulous Adventures In Coding
虽然不是完美的解决方案,但似乎无法使用 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 用于其他目的,但在这里我将它用于电子邮件..