C# 我可以扩展基类并将基类强制转换为扩展类吗

C# 我可以扩展基类并将基类强制转换为扩展类吗,c#,C#,我写了以下代码: using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Text; using System.Net.Mail; using System.Net; public partial class Test : System.Web.UI

我写了以下代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text;
using System.Net.Mail;
using System.Net;

public partial class Test : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        Foo m_oFoo = new Foo() { 
            S1 = "N"
        };

        List<Foo> m_List = new List<Foo>();
        m_List.Add(m_oFoo);

        IFoo m_oIFoo = (IFoo)m_List[0];
        m_oIFoo.S2 = "C";

        Response.Write(m_oIFoo.S1);
        Response.Write(m_oIFoo.S2);
    }
}

public class Foo
{
    public string S1 { get; set; }
    public Foo()
    {

    }
}

public class IFoo: Foo
{
    public string S2 { get; set; }
    public IFoo(){}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Web;
使用System.Web.UI;
使用System.Web.UI.WebControl;
使用系统文本;
使用System.Net.Mail;
Net系统;
公共部分类测试:System.Web.UI.Page
{
受保护的无效页面加载(对象发送方、事件参数e)
{
Foo m_oFoo=新的Foo(){
S1=“N”
};
List m_List=新列表();
m_List.Add(m_of oo);
IFoo m_oIFoo=(IFoo)m_列表[0];
m_oIFoo.S2=“C”;
答复.书面答复(m_oIFoo.S1);
答复.书面答复(m_oIFoo.S2);
}
}
公开课Foo
{
公共字符串S1{get;set;}
公共食物(
{
}
}
公共类IFoo:Foo
{
公共字符串S2{get;set;}
公共IFoo(){}
}
但是编译器说“无法将'Foo'类型的对象强制转换为'IFoo'类型。” 如何将Foo转换为Foo1,而不使用所有Foo方法声明caster,因为这是一个示例,Foo有100多个方法


感谢您的帮助

您不能将基类强制转换为它的派生(扩展)类之一。如果您考虑扩展类的一般过程,这是非常直观的。扩展类时,扩展类可能会添加基类中不存在的成员,因此如果编译器允许强制转换,则可能会发生灾难性的事情

对不起,没有内置的方法。最好的选择是使用反射来检索两个类中存在的所有属性并以此方式设置值,或者可能序列化对象,然后将其反序列化为另一种类型


这两种方法都不是完美的。

您不能将基类强制转换为子类,但您可以使用一个

我怎样才能把Foo变成Foo1

你不能。曾经该对象实际上是一个
Foo
对象,而不是
IFoo
,因此任何强制转换都不会成功。您需要“转换”对象,这是一件非常不同的事情。您需要根据
Foo
实例中提供的数据创建一个新的
IFoo
对象。一种方法是通过
IFoo
中接受
Foo
对象的构造函数:

public class IFoo: Foo
{
    public string S2 { get; set; }
    public IFoo(){}
    public IFoo(Foo other)
    {
        S1 = other.S1;
    }
}
然后你可以做:

IFoo m_oIFoo = new IFoo(m_List[0]);

首先,请不要在类中使用大写字母First I,这通常用于接口。其次,你不能向上施放,因为IFoo继承了Foo,而不是相反

这样想:IFoo是Foo,但不是反过来

但是,您可以将其改写为:

IFoo m_oIFoo = m_List[0] as IFoo; // this might be null now
if (m_oIFoo != null)
{
    m_oIFoo.S2 = "C";

    Response.Write(m_oIFoo.S1);
    Response.Write(m_oIFoo.S2);
}

使用运算符进行强制转换,但请注意它可能返回null。

不能从基类强制转换为派生类。相反,尝试编写一个
显式
转换器,并使用它映射所有属性。

使用
I
前缀调用类似乎不是一个好主意。前缀为
I
是接口的标准约定。请不要将其用于某一类型的子类,您完全违反了人们的期望。您不能将基类的实例强制转换为其子类之一,因为根据定义,它不会实现该子类。请更详细地解释您的实际业务问题,以便开发技术上合适的解决方案。这只会导致变量始终为
null
,因为它永远不会是
IFoo
。但它可以是,因为列表参数是协变的。不,列表参数不是协变的。它实际上是不变的。最后,我们可以看到添加到列表中的所有值,它们是硬编码的,它们不是
IFoo
实例,而是
Foo
实例。他需要转换对象,而不是转换对象。
IFoo m_oIFoo = m_List[0] as IFoo; // this might be null now
if (m_oIFoo != null)
{
    m_oIFoo.S2 = "C";

    Response.Write(m_oIFoo.S1);
    Response.Write(m_oIFoo.S2);
}