派生 class 是否可以在 C# 中保存对现有基础 class 的引用?
Is it possible for a derived class to hold a reference to an existing base class in C#?
假设下面的代码。是否可以使用现有基础 class 的实例创建派生 class?还是使用扩展方法是这里的最佳解决方案?
public class TestThis
{
public void Test1()
{
A a = GetAFromExternalSystem();
B b = new B(a);
a.Value = 5;
b.Value == 5; //want this line to return true. In other words, b to hold a reference to a.
}
private A GetAFromExternalSystem()
{
return new A();
}
}
public class A
{
public string Name { get; set; }
public int Value { get; set; }
}
public class B : A
{
public B(A a)
{
this = a; //Cannot assign to 'this' because it is read-only
}
public int Ranking { get; set; }
}
不,你不能这样做。
创建派生 class 时,基础 class 也被创建 并且是派生 class 的 "part" ].您不能简单地将派生 class 的基数部分重新分配给其他东西。
虽然修复非常简单,只需复制您关心的成员即可。
您通常会这样做:
public class A
{
public A(string name, int value)
{
this.Name = name;
this.Value = value;
}
public string Name { get; set; }
public int Value { get; set; }
}
public class B : A
{
public B(A a) : this(a.Name, a.Value, 0)
{
}
public B(string name, int value, int ranking) : base(name, value)
{
this.Ranking = ranking;
}
public int Ranking { get; set; }
}
仔细研究并确保您了解其工作原理。如果您对它的工作原理有疑问,post 一个新的、精确的、明确的问题。
现在,这没有你想要的 属性,即更新 A 也更新 B。做那件奇怪的事情的方法是放弃 B 之间的 is-a-kind-of 关系和答:
public class B
{
private A a;
public B(A a)
{
this.a = a;
}
public int Ranking { get; set; }
public int Value
{
get { return this.a.Value; }
set { this.a.Value = value; }
}
public string Name
{
get { return this.a.Name; }
set { this.a.Name = value; }
}
}
现在,如果您既想让 B 服从 A,又想让 B 成为 A 的实例,那么您的问题就更难了; A 的属性必须是虚拟的,并且在 B 中被覆盖。我把它留作练习。
但实际上,您似乎想在这里做一些非常奇怪的事情。您能描述一下您实际要解决的问题吗?你做错的可能性很大。
您不能使用派生的 class 执行此操作,尽管这可能是 X / Y Problem。要实现您在测试用例中想要实现的目标,可以使用包装器 class
public class TestThis
{
public void Test1()
{
A a = GetAFromExternalSystem();
B b = new B(a);
a.Value = 5;
b.Value == 5;
}
private A GetAFromExternalSystem()
{
return new A();
}
}
public class A
{
public string Name { get; set; }
public int Value { get; set; }
}
public class B // B acts as a 'wrapper' for A
{
public B(A a)
{
this.A = a;
}
public A A { get; set; }
public int Value {
get { return A.Value; }
}
public int Ranking { get; set; }
}
假设下面的代码。是否可以使用现有基础 class 的实例创建派生 class?还是使用扩展方法是这里的最佳解决方案?
public class TestThis
{
public void Test1()
{
A a = GetAFromExternalSystem();
B b = new B(a);
a.Value = 5;
b.Value == 5; //want this line to return true. In other words, b to hold a reference to a.
}
private A GetAFromExternalSystem()
{
return new A();
}
}
public class A
{
public string Name { get; set; }
public int Value { get; set; }
}
public class B : A
{
public B(A a)
{
this = a; //Cannot assign to 'this' because it is read-only
}
public int Ranking { get; set; }
}
不,你不能这样做。
创建派生 class 时,基础 class 也被创建 并且是派生 class 的 "part" ].您不能简单地将派生 class 的基数部分重新分配给其他东西。
虽然修复非常简单,只需复制您关心的成员即可。
您通常会这样做:
public class A
{
public A(string name, int value)
{
this.Name = name;
this.Value = value;
}
public string Name { get; set; }
public int Value { get; set; }
}
public class B : A
{
public B(A a) : this(a.Name, a.Value, 0)
{
}
public B(string name, int value, int ranking) : base(name, value)
{
this.Ranking = ranking;
}
public int Ranking { get; set; }
}
仔细研究并确保您了解其工作原理。如果您对它的工作原理有疑问,post 一个新的、精确的、明确的问题。
现在,这没有你想要的 属性,即更新 A 也更新 B。做那件奇怪的事情的方法是放弃 B 之间的 is-a-kind-of 关系和答:
public class B
{
private A a;
public B(A a)
{
this.a = a;
}
public int Ranking { get; set; }
public int Value
{
get { return this.a.Value; }
set { this.a.Value = value; }
}
public string Name
{
get { return this.a.Name; }
set { this.a.Name = value; }
}
}
现在,如果您既想让 B 服从 A,又想让 B 成为 A 的实例,那么您的问题就更难了; A 的属性必须是虚拟的,并且在 B 中被覆盖。我把它留作练习。
但实际上,您似乎想在这里做一些非常奇怪的事情。您能描述一下您实际要解决的问题吗?你做错的可能性很大。
您不能使用派生的 class 执行此操作,尽管这可能是 X / Y Problem。要实现您在测试用例中想要实现的目标,可以使用包装器 class
public class TestThis
{
public void Test1()
{
A a = GetAFromExternalSystem();
B b = new B(a);
a.Value = 5;
b.Value == 5;
}
private A GetAFromExternalSystem()
{
return new A();
}
}
public class A
{
public string Name { get; set; }
public int Value { get; set; }
}
public class B // B acts as a 'wrapper' for A
{
public B(A a)
{
this.A = a;
}
public A A { get; set; }
public int Value {
get { return A.Value; }
}
public int Ranking { get; set; }
}