我现有的代码有一个带有一些常见属性的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更改为使用接口,则有太多的地方需要修改代码。
如果条件为真,有没有办法可以处理转换为不同的类。
答案 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)
和两个不相关的子base
和DerivedClass
。由于两个孩子之间没有继承,因此您无法在另一个类型中投射一种类型。这些兄弟姐妹之间没有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";
}
}