C# 继承把一个孩子传给另一个
我有一个简单的结构:一个父母,两个不同的孩子 我有一个ChildA类型的对象objA,我想将其转换为ChildB。我天真的做法是:C# 继承把一个孩子传给另一个,c#,inheritance,casting,C#,Inheritance,Casting,我有一个简单的结构:一个父母,两个不同的孩子 我有一个ChildA类型的对象objA,我想将其转换为ChildB。我天真的做法是: ChildA objA = new ChildA(); ChildB objB = (ChildB)objA; 但这不可能直接实现——为什么?这是因为我需要实现一些功能,还是因为我天真的方法是错误的 关于Casper,这是不可能的,因为objA引用的对象不是一个ChildB。换一种说法,这里有一个你正在尝试做的例子: string x = "hi"; Fil
ChildA objA = new ChildA();
ChildB objB = (ChildB)objA;
但这不可能直接实现——为什么?这是因为我需要实现一些功能,还是因为我天真的方法是错误的
关于Casper,这是不可能的,因为objA引用的对象不是一个
ChildB
。换一种说法,这里有一个你正在尝试做的例子:
string x = "hi";
FileStream y = (FileStream) x;
它们都有一个共同的父类--System.Object
,但它们是完全不同的类。如果您试图从y
读取,您希望发生什么
假设您的ChildB
类型具有特定于该类型的某个字段-在强制转换objA
后,您希望该字段的值是多少
为什么要假装一个ChildA
实际上是一个ChildB
?您是否可以在父类中添加一个方法来满足您的需要?在ChildA
中添加如下方法:
ChildB ToChildB()
var a = new ClassA() {Property1 = "test"};
ClassB b = a;
要执行适当的转换?您不能,因为ChildA不是ChildB(您只能从ChildA或ChildB向上转换到父级,或从父级向下转换到ChildB或ChildA,在C#中没有旁转换)
如果您想使强制转换成为可能(这是一个值得商榷的尝试,但很好),您应该实现从ChildA到ChildB的强制转换操作符。objA不是ChildB类型的,即使两者都是来自类父的“子级”。您尝试做的事情不会起作用 您只能将objA装箱到它的基类(父类)或ChildA和ChildB可能实现的任何公共接口
想象一下,ChildB定义了一个名为Foo的方法。你的objA实例如何处理一个叫Foo的人?显然,它无法工作。即使它们有一个父对象,也不可能简单地将一个对象强制转换为其他类型,因为它们可能有不同的接口 您需要实现ChildA(或ChildB)的显式或隐式运算符 或 在实现转换后,以下代码可以正常工作:
var a = new ClassA() {Property1 = "test"};
ClassB b = (ClassB)a;
Console.WriteLine(b.Property2); // output is "test"
在第一种情况下,您可以明确省略类型转换,并按如下方式编写:
ChildB ToChildB()
var a = new ClassA() {Property1 = "test"};
ClassB b = a;
最后,如果只想同步父类的属性,可以直接在父类中编写转换器:
class Parent
{
public string ParentProperty { get; set; }
public static T1 Convert<T1>(Parent obj) where T1 : Parent, new()
{
var result = new T1();
result.ParentProperty = obj.ParentProperty;
return result;
}
}
类父类
{
公共字符串ParentProperty{get;set;}
公共静态T1转换(父对象),其中T1:Parent,new()
{
var结果=新的T1();
result.ParentProperty=obj.ParentProperty;
返回结果;
}
}
使用(父母的A类和B类子女):
var a=new ClassA();
a、 ParentProperty=“test”;
ClassB=父级转换(a);
Console.WriteLine(b.ParentProperty);//输出为“测试”
ChildA
和ChildB
是共享同一父项的不同类型。因此,您可以将ChildA
和ChildB
的实例视为它们的基础,Parent
,但由于它们是不同的类型,您不能将一个转换为另一个 正如其他人所说,ChildA不是ChildB。如果ChildA和B具有相同的属性/功能,则应执行以下操作:
public class Parent{}
public class Child : Parent{}
Child objA = new Child();
Child objB = objA;
但我想这只是一个例子,你有一个真实的例子,为什么你想实现这样的目标?我很确定我已经想出了一个方法来模拟这个,这在某个时候可能是有用的。即:
- 从Dictionary或IDictionary继承,并在需要其他基础继承时实现它
- 将属性存储在两个位置-字典和实字段
- 保留第三个布尔字段,用于标记是否已设置实字段
- 如果设置了实字段,则取实字段
- 如果没有,则获取字典值(以及将其分配给实字段并标记)
- 如果没有字典值,则将该属性视为不存在
- 添加一个构造函数,该构造函数接受字典并使用字典中的值填充该字典
public class CSharepointStoredResults : Dictionary<string, object>
{
public CSharepointStoredResults(Dictionary<string, object> SourceDict = null)
{
// Populate class dictionary from passed dictionary. This allows for some degree of polymorphism sideways.
// For instance it becomes possible to treat one CSharepointStoredResults as another (roughly like treating
// a cat as a dog
foreach (string key in SourceDict.Keys) { this.Add(key, SourceDict[key]); }
}
public Type MyType
{
get {
if (!__MyType && !this.ContainsKey(bObj.GetPropertyNameFromExpression(() => this.MyType)))
{
// Neither a dictionary nor a field set
// return the field
}
else if (!__MyType)
{
// There is a dictionary entry, but no volatile field set yet.
__MyType = true;
_MyType = this[bObj.GetPropertyNameFromExpression(() => this.MyType)] as Type;
}
else
{
// Volatile value assigned, therefore the better source. Update the dictionary
this[bObj.GetPropertyNameFromExpression(() => this.MyType)] = _MyType;
}
return _MyType;
}
set {
// Verify the value is valid...
if (!(value.IsInstanceOfType(typeof(CSharepointStoredResults))))
throw new ArgumentException("MyType can only take an instance of a CSharePointResults object");
_MyType = value;
this[bObj.GetPropertyNameFromExpression(() => this.MyType)] = value;
}
}
private volatile Type _MyType;
private volatile bool __MyType;
公共类CSharepointStoredResults:字典
{
公共CSharepointStoredResults(字典SourceDict=null)
{
//从传递的字典填充类字典。这允许某种程度的侧向多态性。
//例如,可以将一个CSharepointStoredResults视为另一个CSharepointStoredResults(大致类似于
//像狗一样的猫
foreach(SourceDict.Keys中的字符串键){this.Add(key,SourceDict[key]);}
}
公共类型MyType
{
得到{
如果(!\uuu MyType&!this.ContainsKey(bObj.GetPropertyNameFromExpression(()=>this.MyType)))
{
//既不是字典也不是字段集
//退场
}
else if(!\uuuuu MyType)
{
//有一个字典条目,但尚未设置易失性字段。
__MyType=true;
_MyType=this[bObj.GetPropertyNameFromExpression(()=>this.MyType)]作为类型;
}
其他的
{
//分配了Volatile值,因此是更好的源。请更新字典
this[bObj.GetPropertyNameFromExpression(()=>this.MyType)]=\u MyType;
}
返回_MyType;
}
设置{
//请验证该值是否有效。。。
public class Parent{}
public class Child : Parent{}
Child objA = new Child();
Child objB = objA;
public class CSharepointStoredResults : Dictionary<string, object>
{
public CSharepointStoredResults(Dictionary<string, object> SourceDict = null)
{
// Populate class dictionary from passed dictionary. This allows for some degree of polymorphism sideways.
// For instance it becomes possible to treat one CSharepointStoredResults as another (roughly like treating
// a cat as a dog
foreach (string key in SourceDict.Keys) { this.Add(key, SourceDict[key]); }
}
public Type MyType
{
get {
if (!__MyType && !this.ContainsKey(bObj.GetPropertyNameFromExpression(() => this.MyType)))
{
// Neither a dictionary nor a field set
// return the field
}
else if (!__MyType)
{
// There is a dictionary entry, but no volatile field set yet.
__MyType = true;
_MyType = this[bObj.GetPropertyNameFromExpression(() => this.MyType)] as Type;
}
else
{
// Volatile value assigned, therefore the better source. Update the dictionary
this[bObj.GetPropertyNameFromExpression(() => this.MyType)] = _MyType;
}
return _MyType;
}
set {
// Verify the value is valid...
if (!(value.IsInstanceOfType(typeof(CSharepointStoredResults))))
throw new ArgumentException("MyType can only take an instance of a CSharePointResults object");
_MyType = value;
this[bObj.GetPropertyNameFromExpression(() => this.MyType)] = value;
}
}
private volatile Type _MyType;
private volatile bool __MyType;