gpt4 book ai didi

c# - 如何对泛型约束类使用方法隐藏(新)

转载 作者:行者123 更新时间:2023-11-30 21:21:35 29 4
gpt4 key购买 nike

我有一个容器类,它有一个通用参数,该参数被限制到某个基类。提供给泛型的类型是基类约束的子类。子类使用方法隐藏(新)来更改基类方法的行为(不,我不能将其设为虚拟,因为它不是我的代码)。我的问题是"new"方法没有被调用,编译器似乎将提供的类型视为基类,而不是子类,就好像我已经将它向上转换为基类一样。

显然我误解了这里的一些基本内容。我认为泛型 where T: xxx 是一个约束,而不是向上转换类型。

这个示例代码基本上演示了我在说什么。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GenericPartialTest
{
class ContextBase
{
public string GetValue()
{
return "I am Context Base: " + this.GetType().Name;
}

public string GetOtherValue()
{
return "I am Context Base: " + this.GetType().Name;
}

}

partial class ContextSub : ContextBase
{
public new string GetValue()
{
return "I am Context Sub: " + this.GetType().Name;
}
}

partial class ContextSub
{
public new string GetOtherValue()
{
return "I am Context Sub: " + this.GetType().Name;
}
}

class Container<T> where T: ContextBase, new()
{
private T _context = new T();

public string GetValue()
{
return this._context.GetValue();
}

public string GetOtherValue()
{
return this._context.GetOtherValue();
}
}

class Program
{
static void Main(string[] args)
{
Console.WriteLine("Simple");
ContextBase myBase = new ContextBase();
ContextSub mySub = new ContextSub();

Console.WriteLine(myBase.GetValue());
Console.WriteLine(myBase.GetOtherValue());
Console.WriteLine(mySub.GetValue());
Console.WriteLine(mySub.GetOtherValue());

Console.WriteLine("Generic Container");
Container<ContextBase> myContainerBase = new Container<ContextBase>();
Container<ContextSub> myContainerSub = new Container<ContextSub>();

Console.WriteLine(myContainerBase.GetValue());
Console.WriteLine(myContainerBase.GetOtherValue());
Console.WriteLine(myContainerSub.GetValue());
Console.WriteLine(myContainerSub.GetOtherValue());


Console.ReadKey();
}
}
}

编辑:

我想我的困惑来自于可以做到这一点

class SomeClass<T> where T: AnotherType, new()
{
T foo = new T();
}

我希望 TT,尽管我知道编译器会将 T 视为具有 AnotherType的界面。我假设 T 的输入会在运行时发生,即使 T 的接口(interface)是在编译时设置的。 T foo 声明在这里似乎具有误导性,因为它确实在做

AnotherType foo = new T();

一旦我明白它并不是真的将 foo 声明为 T 类型,就可以理解为什么 new 方法隐藏不起作用.

这就是我要说的。

最佳答案

new 声明的方法与基类中具有相同名称/签名的方法没有任何关系(从编译器的角度来看)。这只是编译器允许的方式您可以在派生类中定义不同的方法,这些方法与基类层次结构中的方法共享一个签名。

现在,根据您的具体情况,意识到无论作为泛型参数提供的类型如何,泛型都必须编译为一组字节码。因此,编译器只知道在泛型类型 T 上定义的方法和属性——这将是您在泛型约束中指定的基类型。编译器对派生类型中的 new 方法一无所知,即使您使用派生类型作为参数创建泛型类型的实例也是如此。因此,泛型类中的调用将始终转到基类型的方法。

有很多关于新/虚拟/覆盖的混淆;look at this SO question - Jason 和 Eric 的回答非常好。 Jon Skeet's answer回答类似的问题也可能有助于您理解为什么您的实现会如此行事。

有两种可能的方法可以解决此问题:

  1. 对泛型类中的派生类型(或接口(interface))执行条件转换(基于运行时类型信息)。这会破坏封装并增加不需要的耦合。如果实现不当,它也很脆弱。
  2. 定义一个接口(interface),您可以在通用约束中使用该接口(interface)来公开您关心的方法。如果您派生的代码不是您可以更改的东西,这可能是不可能的。

关于c# - 如何对泛型约束类使用方法隐藏(新),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2649514/

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