运行时显式操作符强制转换

本文关键字:转换 操作符 运行时 | 更新日期: 2023-09-27 18:02:02

我正在Kentico做一个asp.net项目。

目前我创建了一个模型,我们称它为PartnerModel。它包含一个TreeNode类型的私有变量,它基本上以不同的形式保存相同的信息。

我希望能够将PartnerModel的实例显式转换为TreeNode。这应该在运行时发生(在WebForms用户控件中)。

编辑:我不是在寻找"更好"的方法来实现我所要求的东西。这是一个没有显式用例的通用目的。下面的代码正是我想要做的。我只是想知道,如果它是可能的cast我的模型显式运行期间,如果是这样的话,我怎么能做到这一点。

这可能吗?我刚得到一个InvalidCast异常。

PartnerModel.cs

public class PartnerModel
{
        #region Public Properties
        public TreeNode Node { get { return node; } }
        ...
        public static explicit operator TreeNode(PartnerModel model)
        {
            return model.node;
        }
}

PartnerOverview.ascx

...
<cms:BasicRepeater runat="server" ID="RepeaterPartner">
                <ItemTemplate>
                    <a href="<%# ((CMS.DocumentEngine.TreeNode)Container.DataItem).RelativeURL %>">
...

运行时显式操作符强制转换

这不是处理这个场景的好方法。特别是在MVC中(但也在其他类型的项目中),您应该在表示层中使用投影,而不是直接使用底层数据库模型。这就是像AutoMapper这样的项目存在的原因

在你的情况下,最好的做法是创建一个包含所有属性的模型从TreeNode类,你想在你的转换+自定义的,然后在演示中使用这个模型。

模型示例:

public class PartnerViewModel
{
    // partner specific properties
    public string PartnerName { get; set; }
    public int PartnerID { get; set; }
    // node properties
    public int NodeID { get; set; }
    public string NodeName { get; set; }
}

在你的表示层中,你应该只使用这个PartnerViewModel

假设您正在绑定PartnerModel对象的集合,您可以将Container.DataItem强制转换为您的类型,然后访问Node属性。

...
<cms:BasicRepeater runat="server" ID="RepeaterPartner">
    <ItemTemplate>
        <a href="<%# ((PartnerModel)Container.DataItem).Node.RelativeURL %>">
...

c#中的强制转换操作符,无论是隐式的还是显式的,都是在编译时处理的(使用编译时可用的类型信息),它只是语法糖。

你在这里真正做的是将Object (DataItem属性的类型)转换为TreeNode。编译器实际上没有任何方法来识别它,应该使用您的操作符。

你必须通过这样写来告诉它源类型是什么,我猜这并没有带来你期望的值:

<%# ((CMS.DocumentEngine.TreeNode)(PartnerModel)Container.DataItem).RelativeURL %>

您在异常中看到的是来自默认强制转换操作符的消息,该操作符不知道您的操作符,并且可能没有任何代码在运行时附加一些自定义,因此无法执行转换。