gpt4 book ai didi

C# 泛型 : Modify hidden inherited member in derived class

转载 作者:行者123 更新时间:2023-11-30 14:30:04 25 4
gpt4 key购买 nike

假设我有以下类结构:

public class A {
public string Name { get; set; }
}

public class B : A {
public new string Name {
get { return base.Name; }
set { base.Name = value + " set in B"; }
}
}

public static class Test {
public static void SetAndPrintName<T>(T value, string name) where T : A {
value.Name = name;

Console.WriteLine(value.Name);
}
}

这是我期望运行以下代码的结果:

Test.SetAndPrintName(new A(), "a");
Test.SetAndPrintName(new B(), "b");
----
a
b set in B

相反,我得到:

a
b

由于这不起作用,我尝试在 SetAndPrintName 中转换 value,这很丑陋但按预期工作:

public static void SetAndPrintName<T>(T value, string name) where T : A {
if (value is B) {
((B)(object)value).Name = name;
} else {
value.Name = name;
}

Console.WriteLine(value.Name);
}
----
Test.SetAndPrintName(new A(), "a");
Test.SetAndPrintName(new B(), "b");
----
a
b set in B

我还尝试将 Name 属性设为虚拟/覆盖,这也奏效了:

public class A {
public virtual string Name { get; set; }
}

public class B : A {
public override string Name {
get { return base.Name; }
set { base.Name = value + " set in B"; }
}
}
----
Test.SetAndPrintName(new A(), "a");
Test.SetAndPrintName(new B(), "b");
----
a
b set in B

问题是:为什么 new 不像其他的那样工作?泛型方法知道 valueB 类型,那么为什么 C# 在三分之二的情况下将其视为 A

最佳答案

The generic method knows that value is of type B

不是在编译时它没有。当编译器看到 value.Name 时,它必须将其解析为 一个 成员...并且唯一可用的成员是 A< 中声明的成员.

将您的两个属性视为完全独立 - 就好像它们有不同的名称一样。我们称它们为 NameANameB

您的代码有效:

public static void SetAndPrintName<T>(T value, string name) where T : A {
value.NameA = name;
Console.WriteLine(value.NameA);
}

这是有效的,因为编译器可以根据 A 解析 NameA,并且 T 被限制为 A.

如果您尝试明确使用 NameB,但是:

// Invalid
public static void SetAndPrintName<T>(T value, string name) where T : A {
value.NameB = name;
Console.WriteLine(value.NameB);
}

...那是行不通的,因为编译器无法为 T 解析 NameB

当您使用虚拟 属性时,您将获得一个已声明的成员,该成员的实现B 中被覆盖...当您想要修改行为时,这正是您通常所做的。

如果你想根据执行时类型使用不同的声明成员(事先不知道)你可以使用dynamic:

public static void SetAndPrintName(dynamic value, string name) {
value.Name = name;
Console.WriteLine(value.Name);
}

关于C# 泛型 : Modify hidden inherited member in derived class,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24510209/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com