将使用泛型的基类强制转换为派生类型的正确方法是什么?
我实现了以下对象。
请注意,“Save”方法在此处调用“WriteSettings”方法(接受BaseSettings对象)
public class Settings1
{
public string strData;
}
public class BaseSettings<T>
{
T settings;
public iSettingsDestination Destination;
public bool Save()
{
return Destination.WriteSettings(this);
}
}
public class Settings1Manager : BaseSettings<Settings1>
{
public bool DoSomething()
{
return true;
}
}
我创建了一个接口iSettingsDestination,它始终使用基类(BaseSettings)来传递对象。从iSettingsDestination派生的类可以选择要处理的对象类型。 我希望能够将此对象作为基类型传递给方法,确定派生类型,并反转强制转换。 (见下文)我在尝试强制转换为派生类型时收到编译错误。
public interface iSettingsDestination
{
bool WriteSettings<T>(BaseSettings<T> settings);
}
public class FileDestination : iSettingsDestination
{
bool WriteSettings1ManagerToFile(Settings1Manager settings)
{
// write to file
return true;
}
bool WriteSettings<T>(BaseSettings<T> settings)
{
if (typeof(Settings1Manager).IsAssignableFrom(settings.GetType()))
{
// generates error
// Cannot convert type 'BaseSettings<T>' to 'Settings1Manager'
return WriteSettings1ManagerToNetwork((Settings1Manager)settings);
}
// unhandled object type
return false;
}
}
我希望能够像下面这样调用代码。对于此处的示例,我只显示1种类型的“目的地”和“设置”,但您可以想象这里可以使用许多不同的类型。
void main()
{
Settings1Manager settings1 = new Settings1Manager();
settings1.Destination = new FileDestination();
settings1.Save(); // saves to a file
}
我能够与其他基类一起使用,但似乎在这里使用泛型会导致问题。
1)如何在调用WriteSettings1ManagerToNetwork((Settings1Manager)设置中)正确地将强制转换回派生类型;
2)有没有人在这里看到任何明显滥用泛型/接口/等逻辑的问题?
提前感谢您的帮助。
答案 0 :(得分:4)
声明为BaseSettings<T>
的引用可能会或可能不会引用Settings1Manager
的实际实例。这就是继承的工作原理。实际上,您正在做的是投射基本类型引用,该引用实际上指的是您刚刚确认 派生类型的对象。
settings as Settings1Manager
将进行编译,因为如果演员失败,as
将返回null
。你和我都知道特定的演员不会失败,但编译器只是遵循它的规则。
if (typeof(Settings1Manager).IsAssignableFrom(settings.GetType()))
{
return WriteSettings1ManagerToNetwork(settings as Settings1Manager);
}
这也有效,因为您可以向object
投射任何内容,并且可以将object
投射到任何内容。但是,您不希望人们在代码上看到您的名字。
return WriteSettings1ManagerToFile((Settings1Manager)(object)settings);