2011-08-31 104 views
3

我有一个对象,我传递了很多。C#铸造和继承

我需要一段数据添加到它,不能修改基类

所以我

static OriginalThing GetNewThing() 
{ 
    return new OriginalThing(); 
} 

现在我想加我一块数据

class EnhancedThing : OriginalThing 
{ 
    string name; 
    static EnhancedThing GetNewThing(string name) 
    { 
    EnhancedThing ething = new OriginalThing(); <---doesnt work even if i cast it 
    ething.Name = name; 
    } 
} 

我该怎么做呢?

回答

0

这是因为一个OriginalThing不是一个EnhancedThing,而是一个EnhancedThing是一个OriginalThing。

您可以做的一件事就是拥有一个EnhancedThing的构造函数,该构造函数接受一个OriginalThing并复制应用的成员。

class EnhancedThing : OriginalThing 
{ 
    public EnhancedThing() 
    { 
     // default constructor 
    } 

    public EnhancedThing(OriginalThing src) 
    { 
     // copy over the significant items 
    } 
} 
1

你需要这样做:

EnhancedThing ething = new EnhancedThing(); 
3

不能分配OriginalThingNewThing,因为它根本就不是一个NewThing。反过来也可以正常工作,因为NewThing能够处理所有的事情,但事实并非如此。

只需创建一个EnhancedThing的实例,指定名称并将其返回。您可以将EnhancedThing视为OriginalThing,因为它的OriginalThing

class EnhancedThing : OriginalThing 
{ 
    public string Name { get; private set; } 
    static EnhancedThing GetNewThing(string name) 
    { 
    EnhanedThing thing = new EnhancedThing(); 
    thing.Name = name; 
    return thing; 
    } 
} 

// ... 

OriginalThing foo = EnhancedThing.GetNewThing("someName"); 

也意识到,不买你多name目前是私有成员变量(在你的例子),除非你把他们当作你将不能访问NewThing对象的任何附加功能NewThing s(与OriginalThings相反,但如果需要,您可以将它们作为OriginalThing s传递)

+0

很好的解释Ed。我只想补充一点,你可能会听到这种讨论为协变与反变换(特别是在采访中;-) http://blogs.msdn.com/b/csharpfaq/archive/2010/02/16/covariance-and-contravariance -faq.aspx –

+0

EnhancedThing ething = new OriginalThing(); 当我这样做时,它声明你不能隐式转换类型 – Jeff

+0

@Jeff:这是一个从复制原始代码遗留下来的错字,很抱歉。 –

0

如果其他类是密封的,则可以在新类中使用封装,然后修改/扩展API。然后,您可以定义从一个对象到另一个对象的隐式投射,并可以互换使用这些类型而不投射

这是否适合您的情况归结于您打算做什么,以及您想要实现的目标,但这是一项有价值的技术。这对于隐藏原始的一些/全部成员并重新定义API更为有用。

// no need to cast 
EnhancedThing thing = new OriginalThing(); 
var result = thing.NewMethod(); 

// again no need to cast, treat as original when passing around 
OriginalThing original = thing; 

public class EnhancedThing 
{ 
    private readonly OriginalThing originalThing; 

    public static implicit operator OriginalThing(EnhancedThing enhancedThing) 
    { 
     return enhancedThing.originalThing; 
    } 

    public static implicit operator EnhancedThing(OriginalThing originalThing) 
    { 
     return new EnhancedThing(originalThing); 
    } 

    private EnhancedThing(OriginalThing originalThing) 
    { 
     this.originalThing = originalThing; 
    } 

    public string OriginalMethod() 
    { 
     return originalThing.OriginalMethod(); 
    } 

    public string NewMethod() 
    { 
     var value = originalThing.OriginalMethod(); 
     // extra processing ... 
     return value; 
    } 
} 

该技术广泛用于Sitecore中,以提供不同的数据类型模型,从一个通用的基础实现。一个警告,如果你打算添加一个新的数据字段,它将在upcast上丢失。