C# 强制类型转换和继承

3

我有一个经常传递的对象。

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

因此,我有:

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;
  }
}

我该如何做到这一点?
4个回答

2
您不能将一个OriginalThing赋值给一个NewThing,因为它根本不是NewThing。反过来可以,因为NewThing可以做OriginalThing所能做的一切,但反之则不行。
只需创建一个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(而不是OriginalThings),否则您将无法访问任何其他功能。但如果需要,您可以将它们作为OriginalThing传递。


很好的解释,Ed。我只想补充一点,在面试中你可能会听到这个讨论被称为协变性与逆变性。http://blogs.msdn.com/b/csharpfaq/archive/2010/02/16/covariance-and-contravariance-faq.aspx - Eric J.
EnhancedThing ething = new OriginalThing(); 当我执行这个操作时,它会提示你不能隐式转换类型。 - Jeff
@Jeff:那是从您的原始代码复制过来时留下的错别字,抱歉。 - Ed S.

1
你需要做这个:
EnhancedThing ething = new EnhancedThing();

0

这是因为OriginalThing不是EnhancedThing,但EnhancedThing是OriginalThing。

你可以做的一件事是为EnhancedThing创建一个构造函数,该构造函数接受OriginalThing并复制适用的成员。

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

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

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中,这种技术被广泛使用,以从共同的基础实现提供不同的数据类型模型。但是有一个注意点,如果您打算添加新的数据字段,则会在上转换时丢失。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接