これは、特にキャストではなく、そのコンバージョンとコンバージョンがストレートキャストとは少し異なる動作をします。
As
互換性の参照型またはnull許容型の間の変換の特定のタイプを実行するために演算子として使用することができ...としてオペレータがキャスト動作と同様です。ただし、変換が不可能な場合は、例外が発生する代わりにnullが返されます。
私はあなたのContact
がCrmSvcUtilによって作成されたクラスであると仮定しています。 public partial class Contact : Microsoft.Xrm.Sdk.Entity
およびservice.Retrieve
はIOrganizationService.Retrieveであり、返品タイプはEntity
です。
Contact
は、基本クラスEntity
の派生クラスです。ベースクラスをより具体的な派生クラスにキャストすることはできません(Is it possible to assign a base class object to a derived class reference with an explicit typecast in C#?参照)。 Entity
からContact
へのキャストを実行しようとすると例外が発生し、変換ではnullオブジェクトが返されます。
例:CrmSvcUtilのGeneratedCodeが含まれていますが、CRMへの実際の接続はありません。
var entity = new Entity();
Console.WriteLine($"Type of local entity: {entity.GetType()}");
Console.WriteLine($"Local entity as Contact is null? {entity as Contact == null}");
出力:Contact
にキャストすることはできません
Type of local entity: Microsoft.Xrm.Sdk.Entity
Local entity as Contact is null? True
だから、与えられたRetrieve
戻りEntity
、コード(var contact = service.Retrieve("contact", id, new ColumnSet()) as Contact;
)のあなたのラインにもどのように動作しますか?
これは魔法です。明らかに、アプリケーション内でCrmSvcUtilからGeneratedCodeをインクルードすると、Retrieve
関数は汎用のEntity
の代わりに特定の派生クラスを返します。 CrmSvcUtilからGeneratedCodeと
例が含まれる:
CrmServiceClient service = new CrmServiceClient(ConfigurationManager.ConnectionStrings["Crm"].ConnectionString);
Contact c = new Contact()
{
LastName = "Test"
};
Guid contactId = service.Create(c);
var response = service.Retrieve("contact", contactId, new ColumnSet());
Console.WriteLine($"Type of response from CRM: {response.GetType()}");
Console.WriteLine($"Response from CRM as contact is null? {response as Contact == null}");
出力:なし生成されたコードと
Type of response from CRM: Contact
Response from CRM as contact is null? False
例が含まれる:
CrmServiceClient service = new CrmServiceClient(ConfigurationManager.ConnectionStrings["Crm"].ConnectionString);
Entity c = new Entity("contact");
c["lastname"] = "Test";
Guid contactId = service.Create(c);
var response = service.Retrieve("contact", contactId, new ColumnSet());
Console.WriteLine($"Type of response: {response.GetType()}");
出力:
Type of response: Microsoft.Xrm.Sdk.Entity
質問に戻るプロジェクトに生成コードを含める場合は、Retrieve
がContact
を返していれば、単純なキャスト(例:(Contact)service.Retrieve(...)
)または変換(as
)である。 ToEntity
の意味では、実際にキャストや変換を行っていません。新しいオブジェクトを作成し、他のオブジェクトとの間でシャローコピーを実行します。あなたの必要を満たすならそれを使用しますが、おそらくそれなしで逃げることができます。
Decompliedコード:
public T ToEntity<T>() where T : Entity
{
if (typeof(T) == typeof(Entity))
{
Entity entity = new Entity();
this.ShallowCopyTo(entity);
return entity as T;
}
if (string.IsNullOrWhiteSpace(this._logicalName))
{
throw new NotSupportedException("LogicalName must be set before calling ToEntity()");
}
string text = null;
object[] customAttributes = typeof(T).GetCustomAttributes(typeof(EntityLogicalNameAttribute), true);
if (customAttributes != null)
{
object[] array = customAttributes;
int num = 0;
if (num < array.Length)
{
EntityLogicalNameAttribute entityLogicalNameAttribute = (EntityLogicalNameAttribute)array[num];
text = entityLogicalNameAttribute.LogicalName;
}
}
if (string.IsNullOrWhiteSpace(text))
{
throw new NotSupportedException("Cannot convert to type that is does not have EntityLogicalNameAttribute");
}
if (this._logicalName != text)
{
throw new NotSupportedException(string.Format(CultureInfo.InvariantCulture, "Cannot convert entity {0} to {1}", new object[]
{
this._logicalName,
text
}));
}
T t = (T)((object)Activator.CreateInstance(typeof(T)));
this.ShallowCopyTo(t);
return t;
}
したがって、基本的にenable proxyタイプを呼び出すと、あなたのためにtoEntityが呼び出されますが、IOrganizationServiceリクエストに対してのみ呼び出されます。プラグインコンテキストには影響しませんか? – Daryl
ToEntity関数(正確には私の更新された答えをチェックすることができます)を呼び出すのではなく、基本的に同じことを行います。これはプラグインコンテキストには影響しません。なぜなら、これを実行する唯一の方法は、早期にバインドされたエンティティをターゲットに注入することです。プラグインは多くの異なるエンティティに登録できるため不可能です。 –