如何在基 class 使用泛型时隐藏成员函数
How to hide a member function when the base class uses generics
我有以下 classes,当我在 BaseScriptConfigurationList 上调用 CreateQuerySettings
时,它 returns 来自 ConfigurationList
的新 QuerySettings
,而不是比 HierarchicalQuerySettings
中的值 BaseScriptConfigurationList
:
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>();
}
}
编辑:我从另一个 class 拨打电话,其中 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
class 调用它时,我得到一个 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!"
在BaseScriptConfigurationList.CreateQuerySettings()
你的 return 类型是 QuerySettings<T,T>
所以你总是会得到那个类型作为 return 值,但你 return 是 HierarchicalQuerySettings
。您可以将 CreateQuerySettings()
的 return 类型更改为 HierarchicalQuerySettings
,或者将对象转换为其子类型“HierarchicalQuerySettings
”。如果你真的想隐藏它,你可以这样做:
public class newclass : BaseScriptConfigurationList
{
public new HierarchicalQuerySettings<BaseScriptConfiguration, BaseScriptConfiguration.Property> CreateQuerySettings()
{
return (HierarchicalQuerySettings<BaseScriptConfiguration, BaseScriptConfiguration.Property>)base.CreateQuerySettings();
}
}
但这看起来效率不高,我建议不要这样做。就像我说的,我可能遗漏了一些其他要求,但根据您提供的信息..
基本上,我所看到的(并做出假设)TConfigurationObjectList
从 ConfigurationList
沿线某处继承,依此类推,一直到 EditableConfigurationList
.由于您正在动态创建 class TConfigurationObjectList 的实例,并从该点调用该方法,因此您将调用基础 ConfigurationList
成员 CreateQuerySettings
。您无权访问新的 CreateQuerySettings。如果此时正在创建 class 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
class(比如 IConfigurationList
)创建一个基本接口,并将此接口用作变量 cl
而不是 [=13] 的数据类型=].
我有以下 classes,当我在 BaseScriptConfigurationList 上调用 CreateQuerySettings
时,它 returns 来自 ConfigurationList
的新 QuerySettings
,而不是比 HierarchicalQuerySettings
中的值 BaseScriptConfigurationList
:
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>();
}
}
编辑:我从另一个 class 拨打电话,其中 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
class 调用它时,我得到一个 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!"
在BaseScriptConfigurationList.CreateQuerySettings()
你的 return 类型是 QuerySettings<T,T>
所以你总是会得到那个类型作为 return 值,但你 return 是 HierarchicalQuerySettings
。您可以将 CreateQuerySettings()
的 return 类型更改为 HierarchicalQuerySettings
,或者将对象转换为其子类型“HierarchicalQuerySettings
”。如果你真的想隐藏它,你可以这样做:
public class newclass : BaseScriptConfigurationList
{
public new HierarchicalQuerySettings<BaseScriptConfiguration, BaseScriptConfiguration.Property> CreateQuerySettings()
{
return (HierarchicalQuerySettings<BaseScriptConfiguration, BaseScriptConfiguration.Property>)base.CreateQuerySettings();
}
}
但这看起来效率不高,我建议不要这样做。就像我说的,我可能遗漏了一些其他要求,但根据您提供的信息..
基本上,我所看到的(并做出假设)TConfigurationObjectList
从 ConfigurationList
沿线某处继承,依此类推,一直到 EditableConfigurationList
.由于您正在动态创建 class TConfigurationObjectList 的实例,并从该点调用该方法,因此您将调用基础 ConfigurationList
成员 CreateQuerySettings
。您无权访问新的 CreateQuerySettings。如果此时正在创建 class 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
class(比如 IConfigurationList
)创建一个基本接口,并将此接口用作变量 cl
而不是 [=13] 的数据类型=].