无法将NewDerivedClass类型隐式转换为DerivedClass

时间:2018-03-25 18:32:52

标签: c# inheritance

我现有的代码有一个带有一些常见属性的Base类和一个带有一些额外属性的派生类:Property1& Property2。

我有以下功能填充一些属性详细信息:

public void MyFunction(BaseClass base)
{ 
    var derivedClass = base as DerivedClass;

    derivedClass.Property1 = "blah";
    derivedClass.Property2 = "blahblah";
}

现在我有了另一个新类 NewDerivedClass ,它也是从BaseClass派生的,需要修改现有的代码来应对这个问题。

理想情况下,我想做这样的事情:

public void MyFunction(BaseClass base)
{ 
    var derivedClass = base as DerivedClass;

    if(SomeConditionTrue)
    {
        derivedClass = base as NewDerivedClass
    }

    derivedClass.Property1 = "blah";
    derivedClass.Property2 = "blahblah";
}

但我得到错误:无法隐式将NewDerivedClass类型转换为DerivedClass。

理想情况下,我会使用像这里建议的泛型:Cannot implicitly convert type 'customtype' to 'othercustomtype'但是如果我将现有的DerivedClass更改为使用接口,则有太多的地方需要修改代码。

如果条件为真,有没有办法可以处理转换为不同的类。

4 个答案:

答案 0 :(得分:2)

您有一个父web_page = requests.get(url) # write binary if you expect a future html or xml processor to # read it with open(filename, 'wb') as file: file.write(web_page.content) # ---- or ---- write text if you expect humans to read it with open(filename) as file: file.write(web_page.text) 和两个不相关的子baseDerivedClass。由于两个孩子之间没有继承,因此您无法在另一个类型中投射一种类型。这些兄弟姐妹之间没有NewDerivedClass的关系。

答案 1 :(得分:2)

As I understand it, you initially had a type hierarchy like this:

public class BaseClass
{
}

public class DerivedClass : BaseClass
{
    public string Property1 { get; set; }
    public string Property2 { get; set; }
    // Many additional properties omitted.
}

You are now introducing a new derived class that happens to have identically named and properties, and you would like a clean way to work with both that avoids lots of copy/pasted code:

public class NewDerivedClass : BaseClass
{
    public string Property1 { get; set; }
    public string Property2 { get; set; } 
    // Many additional properties omitted.
}

You have two options to do this.

Firstly, you could extract an intermediate class IntermediateClass to hold both properties, and insert it in the inheritance hierarchy like so:

public class BaseClass
{
}

public abstract class IntermediateClass : BaseClass
{
    public string Property1 { get; set; }
    public string Property2 { get; set; }
}

public class DerivedClass : IntermediateClass 
{
}

public class NewDerivedClass : IntermediateClass 
{
}

Then in MyFunction check to see if the incoming object is of type IntermediateClass not DerivedClass.

Secondly, you could extract an interface, say IHasDerivedProperties and have both derived classes implement it.

public class BaseClass
{
}

public interface IHasDerivedProperties
{
    string Property1 { get; set; }
    string Property2 { get; set; }
}

public class DerivedClass : BaseClass, IHasDerivedProperties
{
    public string Property1 { get; set; }
    public string Property2 { get; set; }
}

public class NewDerivedClass : BaseClass, IHasDerivedProperties
{
    public string Property1 { get; set; }
    public string Property2 { get; set; }
}

Visual Studio's Extract Interface can make this change quite easily.

Then in MyFunction check to see if the incoming object is of type IHasDerivedProperties not DerivedClass. With this design, you can also create methods that take either DerivedClass or NewDerivedClass by using generic constraints:

public void MyFunction<TBaseClass>(TBaseClass derivedClass) 
    where TBaseClass : BaseClass, IHasDerivedProperties
{ 
    derivedClass.Property1 = "blah";
    derivedClass.Property2 = "blahblah";
}       

答案 2 :(得分:1)

Your two derived classes might share a base class, but they are not the same, even if they have the same properties. Imagine you have this structure:

public class Mammal
{
 //some properties & methods
}

public class Lion : Mammal
{
   void Roar()
   {
   }
}

public class Tiger : Mammal
{
   void Roar()
   {
   }
}

Both lions and tigers roar, but are lions tigers? No.

So, what you need to do in this case is create a new instance of NewDerivedClass on if(SomeConditionTrue) and set its properties.

public void MyFunction(BaseClass base)
{ 

if(SomeConditionTrue)
{
    var newDerivedClass = base as NewDerivedClass;
    newDerivedClass.Property1 = "blah";
    newDerivedClass.Property2 = "blahblah";
}
else
{
    var derivedClass = base as DerivedClass;
    derivedClass.Property1 = "blah";
    derivedClass.Property2 = "blahblah";
}


}  

答案 3 :(得分:0)

One option is to use the C# 7´s is-expression with type pattern

public void MyFunction(BaseClass baseClass)
{ 
    if(baseClass is DerivedClass derivedClass)
    {
        derivedClass.Property1 = "blah";
        derivedClass.Property2 = "blahblah";
    }
    else if(baseClass is NewDerivedClass newDerivedClass)
    {
        newDerivedClass.Property1 = "blah";
        newDerivedClass.Property2 = "blahblah";
    }
}