如何动态地将基类型的列表强制转换为派生类型
本文关键字:类型 列表 转换 派生 基类 何动态 动态 | 更新日期: 2023-09-27 17:55:02
我有一个dll与以下层次结构:
Interface ISchema {}
class Schema:ISchema{}
class TableSchema:Schema{}
class ViewSchema:Schema{}
我有另一个具有以下层次结构的dll:
Interface ISearch {}
class Table:ISearch{}
class View:ISearch{}
以下代码根据用户选择触发对Table或View的搜索操作:
private void FindNowButton_Click(object sender, EventArgs e)
{
// return Table or View according to user selection. (Property is an internal class helping to retrieve the selected type)
var type = (ObjectsTypeComboBox.SelectedItem as Property).Type;
// Create an instance of table or View as ISearch
var instance = (ISearch)Activator.CreateInstance(type);
// Call to relevant Search (table.Search or View.Search)
// _dataManager help to get the records from Schema hierarchy
// text is the text to search
var result = instance.Search(_dataManager, FindWhatTextBox.Text);
// Show in DataGridView the result
FindResultsDGV.DataSource = result;
}
每个搜索方法返回一个List。我需要在网格上显示不同的列。TableSchema和ViewSchema有不同的属性,按照下面的方式进行转换。
FindResultsDGV.DataSource = result.Cast<TableSchema> ; // or result.Cast<ViewSchema>
我如何在这个阶段动态地获得正确的类型?
欢迎任何其他解决方案
更新:
根据@GiladGreen
public interface ISearchSchemaFactory
{
ISearch<ISchema> GetSearch(Type schemaType);
}
public class Factory : ISearchSchemaFactory
{
public ISearch<ISchema> GetSearch(Type schemaType)
{
if (schemaType.Equals(typeof(Table)))
{
return new BL.AdvancedSearch.Table(); // Getting an error here
// Cannot implicitly convert type 'Table' to 'ISearch<ISchema>'. An explicit conversion exists (are you missing a cast?)
}
else if (schemaType.Equals(typeof(View)))
{
// TODO
}
return null; // TODO
}
}
我建议你这样修改ISearch:
Interface ISearch<out TSchema> where TSchema: ISchema
{
TSchema Search(....);
}
class Table : ISearch<TableSchema>
{
public TableSchema Search(....)
{
//Some searching code
}
}
class View:ISearch<ViewSchema>
{
public ViewSchema Search(....)
{
//Some searching code
}
}
然后你还可以做的是有一个ISearchSchemaFactory
,它会根据你给它的TSchema
给你一个正确的ISearch
的实例:
public interface ISearchSchemaFactory
{
ISearch<ISchema> GetSearch(Type schemaType);
}
和用法:var search = factory.GetSearch(type);
Factoy实现示例
public class MappingSearchSchemaFactory : ISearchSchemaFactory
{
public MappingSearchSchemaFactory(Dictionary<Type, ISearch<ISchema>> mapping)
{
Mapping = mapping;
}
ISearch<ISchema> GetSearch(Type schemaType)
{
ISearch<ISchema> result;
if(!Mapping.TryGetValue(schemaType, out result)
{
//Some logging or throwing exception behavior - depends what you want
}
return result;
}
public Dictionary<Type, ISearch<ISchema>> Mapping { get; set; }
}
这个特定的实现为"某人"获取映射。一个可能的初始化代码可以是:
ISearchSchemaFactory factory = new MappingSearchSchemaFactory(
new Dictionary<Type,ISearch<ISchema>>
{ new TableSchema(), new Table() },
{ new ViewSchema(), new view() }
);
但是我不太推荐这个。我会查看Dependency Injection
和IoC Containers
来管理对象的初始化。我个人使用Castle Windsor