转换为 OrganizationServiceContext 时出现 InvalidCastException

Posted

技术标签:

【中文标题】转换为 OrganizationServiceContext 时出现 InvalidCastException【英文标题】:InvalidCastException while casting to OrganizationServiceContext 【发布时间】:2020-10-13 13:10:42 【问题描述】:

我有一个由 CrmSvcUtil 生成的早期绑定类:

public partial class CustomerCrmServiceContext : Microsoft.Xrm.Sdk.Client.OrganizationServiceContext

  ...
  ...

然后我就有了这样的课(短版):

public abstract class PluginClass<T, C> : PluginClassBase<T> where T : Entity where C : OrganizationServiceContext

        protected new C ServiceContext;

        protected PluginClass(IOrganizationService service, ITracingService tracer) : base(service, tracer)
        
            ServiceContext = (C)base.ServiceContext;
        

Base 类是这样的:

public abstract class PluginClassBase: IDisposable

    ...
    ...
    protected readonly OrganizationServiceContext ServiceContext;
    ...
    ...

我正在像这样使用这个类:

public class DoWomethingWorkerPlugin : PluginClass<account, CustomerCrmServiceContext>

  ...

我的问题是以下陈述:

ServiceContext = (C)base.ServiceContext;

这会抛出一个 InvalidCastException 说:

“无法转换类型的对象 'Microsoft.Xrm.Sdk.Client.OrganizationServiceContext' 键入 'Customer.DataModel.CustomerCrmServiceContext"

我很困惑,因为生成的类“CustomerCrmServiceContext”具有基类型“OrganizationServiceContext”,因此转换应该可以工作。

有没有人知道当基类型相同时什么会导致 InvalidCastException?

【问题讨论】:

【参考方案1】:

虽然 CustomerCrmServiceContextOrganizationServiceContext,但事实并非如此,这就是您遇到异常的原因。

强制转换不能在运行时神奇地改变对象的类型。

通过使用强制转换,您实际上是在告诉编译器 “虽然您认为这个对象是 SomeBaseType,但我知道,在运行时,它始终是 SomeDerivedType 的一个实例,所以请这样对待它".

如果在运行时发现该对象不是您尝试转换为的类型,您将获得InvalidCastException,而OrganizationServiceContext 不是CustomerCrmServiceContext

【讨论】:

@PaulRichardson CustomerCrmServiceContext 是一种更具体的类型。它将对OrganizationServiceContext 具有附加行为,并且编译器无法知道如何将OrganizationServiceContext 的实例转换为CustomerCrmServiceContext 的实例,除非您定义了自定义转换运算符。当您使用CustomerCrmServiceContext 的实例代替OrganizationServiceContext(可替代性)时,运行时类型不会改变,但编译器知道它实现了OrganizationServiceContext 的所有行为。

以上是关于转换为 OrganizationServiceContext 时出现 InvalidCastException的主要内容,如果未能解决你的问题,请参考以下文章

javascript中的数据类型转换

为啥 list 应该先转换为 RDD 再转换为 Dataframe?有啥方法可以将列表转换为数据框?

CSS标签显示模式 ③ ( 标签显示模式转换 | 行内元素转换为块级元素 | 块级元素转换为行内元素 | 块级元素行内元素转换为行内块元素 )

在php中将 1 转换为 001 ,将 2 转换为 002 等,将 99 转换为 099 等 [重复]

怎么用ABBYY将PDF转换为JPEG图像

VBA 如何将数字转换为中文大写