2013-03-11 22 views
0

我写这样的代码:我可以延长一个基类,投基的延伸

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(){} 
} 

但是编译器说的。“无法投类型的对象‘富’的类型‘的IFoo’” 如何将Foo投射到Foo1而不用所有Foo方法声明一个施法者,因为这是一个例子,Foo有超过100个方法。

感谢您的帮助

+4

调用一个带'I'前缀的类似乎不是一个好主意。 – BoltClock 2013-03-11 17:01:41

+4

具有“I”的前缀是接口的标准约定。请不要将它用于某个类型的子类,这完全违反了人们的期望。 – Servy 2013-03-11 17:01:46

+0

您不能将基类的实例转换为其子类之一,因为根据定义,它不会实现该子类。请详细解释您的实际业务问题,以便开发技术上合适的解决方案。 – 2013-03-11 17:04:07

回答

2

我如何可以投美孚以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]); 
0

你不能投基类到它的一个派生(扩展)类。如果你考虑一般扩展类的过程,这很直观。扩展类时,扩展类可能会添加不会出现在基类中的成员,因此如果编译器允许投射,那么可能会发生灾难性事件!

0

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

两种方式都不是完美的。

0

您不能将基类转换为子类,但是您可以使用类似于conversion operator的方法。

public class IFoo: Foo 
{ 
    ... 

    public static explicit operator IFoo(Foo foo) // explicit byte to digit conversion operator 
    { 
     ... 
    } 
} 
-1

首先,请从你的类有资金开始我不要,通常用于接口。其次,你不能投“向上”,因为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); 
} 

使用as运营商铸造,但要注意,它可以返回null。

+1

这只会导致变量始终为'null',因为它永远不会是'IFoo'。 – Servy 2013-03-11 17:05:42

+0

但是它可以是List参数是协变的。 – 2013-03-11 17:07:23

+0

不,列表参数是* not * covariant。它实际上是不变的*。最后,我们可以看到所有添加到列表中的值,它们都是硬编码的,它们不是“IFoo”实例,而是“Foo”实例。他需要*转换*对象,而不是*猫*对象。 – Servy 2013-03-11 17:12:45

0

您不能从基类转换为派生类。相反,请尝试编写一个explicit转换器并使用AutoMapper来映射所有属性。