如何在基类使用泛型时隐藏成员函数

本文关键字:隐藏 成员 函数 泛型 基类 | 更新日期: 2023-09-27 18:36:52

我有以下类,当我在 BaseScriptConfigurationList 上调用 CreateQuerySettings 时,它会从 ConfigurationList 返回新QuerySettings,而不是BaseScriptConfigurationList中的HierarchicalQuerySettings值:

public abstract class ConfigurationList<TConfigurationObject, TPropertyEnum>
{
  public QuerySettings<TConfigurationObject, TPropertyEnum> CreateQuerySettings()
  {
    return new QuerySettings<TConfigurationObject, TPropertyEnum>();
  }
}
public class BaseScriptConfigurationList : EditableConfigurationList<BaseScriptConfiguration, BaseScriptConfiguration.Property>
{
  public BaseScriptConfigurationList(ConfigurationManager configurationManager)
    : base(configurationManager, InternalAdminObjectType.BaseScript)
  {
     _BaseScriptPageListWatcher = new ConfigurationList<BaseScriptPageConfiguration, BaseScriptPageConfiguration.Property>.
     ConfigurationWatcher(null);
      _ConfigurationWatcher.ChildWatchers.Add(_BaseScriptPageListWatcher);
  }
  public new QuerySettings<BaseScriptConfiguration, BaseScriptConfiguration.Property> CreateQuerySettings()
  {
    return new HierarchicalQuerySettings<BaseScriptConfiguration, BaseScriptConfiguration.Property, BaseScriptQueryChildrenSettings>();
  }
}

编辑:我从另一个班级拨打电话,TConfigurationObjectList BaseScriptConfigurationList。我已经将构造函数添加到上面的代码中,以便您可以看到它在做什么。请注意,EditableConfigurationList 继承自 ConfigurationList。

TConfigurationObjectList cl = (TConfigurationObjectList)typeof(TConfigurationObjectList).GetConstructor(new Type[] { typeof(ConfigurationManager) }).Invoke(new object[] { Manager.ConfigurationManager });
var querySettings = cl.CreateQuerySettings();

当我进行此调用时,它会进入 ConfigurationList.CreateQuerySettings 方法。

如何隐藏 CreateQuerySettings 方法,以便在从 BaseScriptConfigurationList 类调用它时,得到一个HierarchicalQuerySettings对象?

如何在基类使用泛型时隐藏成员函数

new修饰符可以是野兽。请注意,您在示例中隐藏而不是覆盖。您没有显示代码的那部分,但我假设您有这种情况:

class Base
{
   public static void BaseMethod() { Console.WriteLine("BASE!"); }
}
class Derived : Base
{
   // Hides Base.BaseMethod()
   new public static void BaseMethod() { Console.WriteLine("DERIVED!"); }   
}
Base a = new Base();
a.BaseMethod(); // -> "BASE!"
Base b = new Derived();
b.BaseMethod(); // -> "BASE!"
Derived b = new Derived();
b.BaseMethod(); // -> "DERIVED!"

In BaseScriptConfigurationList.CreateQuerySettings()您的返回类型是QuerySettings<T,T>因此您将始终将该类型作为返回值,但您返回的是HierarchicalQuerySettings。您可以一,将CreateQuerySettings()的返回类型更改为HierarchicalQuerySettings或两个,将对象强制转换为其子类型" HierarchicalQuerySettings "。如果你真的想隐藏它,你可以这样做:

public class newclass : BaseScriptConfigurationList
{
    public new HierarchicalQuerySettings<BaseScriptConfiguration, BaseScriptConfiguration.Property> CreateQuerySettings()
    {
        return (HierarchicalQuerySettings<BaseScriptConfiguration, BaseScriptConfiguration.Property>)base.CreateQuerySettings();
    }
}

但这似乎并不有效,我建议不要这样做。就像我说的,我可能错过了一些其他要求,但基于你提供的信息。


基本上,我所看到的(并做出假设)TConfigurationObjectList Inhertis从ConfigurationList沿着线的某个地方,依此类推,一直到EditableConfigurationList。 由于您正在动态创建类 TConfigurationObjectList 的实例,并从该点调用该方法,因此您将调用基ConfigurationList成员CreateQuerySettings。您无权访问新的创建查询设置。如果此时正在创建类BaseScriptConfigurationList实例,请将对象强制转换为 ((BaseScriptConfigurationList)cl).CreateQuerySettings() 。话虽如此。如果您不知道运行时拥有什么:

var obj = typeof(TConfigurationObjectList).GetConstructor(new Type[] { typeof(ConfigurationManager) }).Invoke(new object[] { Manager.ConfigurationManager });
var cl = (obj  as BaseScriptConfigurationList) ?? (TConfigurationObjectList)obj;
// or do something else
var querySettings = cl.CreateQuerySettings();

请注意,我假设您的架构大致设置如下:

public abstract class ConfigurationList<TConfigurationObject, TPropertyEnum>
{
    public QuerySettings<TConfigurationObject, TPropertyEnum> CreateQuerySettings()
    {
        return new QuerySettings<TConfigurationObject, TPropertyEnum>();
    }
}
public class TConfigurationObjectList : ConfigurationList<BaseScriptConfiguration, BaseScriptConfiguration.Property>
{
}
public class EditableConfigurationList<T, T1> : TConfigurationObjectList
{
    protected EditableConfigurationList(ConfigurationManager configurationManager, object baseScript)
    {
        throw new NotImplementedException();
    }
}
public class BaseScriptConfigurationList : EditableConfigurationList<BaseScriptConfiguration, BaseScriptConfiguration.Property>
{
    public BaseScriptConfigurationList(ConfigurationManager configurationManager)
        : base(configurationManager, InternalAdminObjectType.BaseScript)
    {
    }
    public new QuerySettings<BaseScriptConfiguration, BaseScriptConfiguration.Property> CreateQuerySettings()
    {
        return new HierarchicalQuerySettings<BaseScriptConfiguration, BaseScriptConfiguration.Property, BaseScriptQueryChildrenSettings>();
    }
}
public class QuerySettings<T, T1>
{
}
public class HierarchicalQuerySettings<T, T1, T2> : QuerySettings<BaseScriptConfiguration, BaseScriptConfiguration.Property>
{
}
public class BaseScriptQueryChildrenSettings
{
}
public class BaseScriptPageConfiguration
{
    public class Property
    {
    }
}
public class InternalAdminObjectType
{
    public static object BaseScript { get; set; }
}
public class ConfigurationManager
{
}
public class BaseScriptConfiguration
{
    public class Property
    {
    }
}

ConfigurationList 类创建一个基接口(比如 IConfigurationList ),并使用此接口作为变量 cl 的数据类型,而不是 TConfigurationList