C# 如何将基于类型的列表动态强制转换为派生类型

C# 如何将基于类型的列表动态强制转换为派生类型,c#,.net,oop,interface,polymorphism,C#,.net,Oop,Interface,Polymorphism,我有一个具有以下层次结构的dll: Interface ISchema {} class Schema:ISchema{} class TableSchema:Schema{} class ViewSchema:Schema{} Interface ISearch {} class Table:ISearch{} class View:ISearch{} 我有另一个具有以下层次结构的dll: Interface ISchema {} class Schema:ISchema{}

我有一个具有以下层次结构的dll:

Interface ISchema {}

class Schema:ISchema{}

class TableSchema:Schema{}

class ViewSchema:Schema{}
Interface ISearch {}

class Table:ISearch{}

class View:ISearch{}
我有另一个具有以下层次结构的dll:

Interface ISchema {}

class Schema:ISchema{}

class TableSchema:Schema{}

class ViewSchema:Schema{}
Interface ISearch {}

class Table:ISearch{}

class View:ISearch{}
以下代码根据用户选择触发表或视图上的搜索操作:

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;
}
每个搜索方法都返回一个列表。我需要在网格上显示不同的列。TableSchema和ViewSchema具有不同的属性,如下所示进行转换

FindResultsDGV.DataSource = result.Cast<TableSchema> ; // or result.Cast<ViewSchema>
FindResultsDGV.DataSource=result.Cast;//或者结果,投下
如何在此阶段动态获取正确的类型

欢迎任何其他解决方案

更新:

根据@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
    }
}
公共接口ISearchSchemaFactory
{
ISearch GetSearch(类型schemaType);
}
公共类工厂:ISearchSchemaFactory
{
公共ISearch GetSearch(类型schemaType)
{
if(schemaType.Equals(typeof(Table)))
{
返回新的BL.AdvancedSearch.Table();//此处出现错误
//无法将类型“Table”隐式转换为“ISearch”。存在显式转换(是否缺少强制转换?)
}
else if(schemaType.Equals(typeof(View)))
{
//待办事项
}
返回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
    }
}
用法:
var search=factory.GetSearch(type)


工厂实施示例

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; }
}
公共类映射SearchSchemaFactory:ISearchSchemaFactory
{
公共映射SearchSchemaFactory(字典映射)
{
映射=映射;
}
ISearch GetSearch(类型schemaType)
{
i研究结果;
if(!Mapping.TryGetValue(schemaType,out结果)
{
//某些日志记录或引发异常行为-取决于您想要什么
}
返回结果;
}
公共字典映射{get;set;}
}
此特定实现为“someone”获取映射。可能的初始化代码为:

ISearchSchemaFactory factory = new MappingSearchSchemaFactory(
    new Dictionary<Type,ISearch<ISchema>>
    { new TableSchema(), new Table() },
    { new ViewSchema(), new view() }
);
ISearchSchemaFactory工厂=新映射搜索SchemaFactory(
新词典
{new TableSchema(),new Table()},
{new ViewSchema(),new view()}
);

但是我不推荐这样做。我会去看
依赖注入
IoC容器
来管理我的对象的初始化。我个人使用
Castle Windsor

你考虑过使用泛型吗?你必须调用
GetSearch
这样的方法
GetSearch()
GetSearch())
所以问题仍然存在。正确。编辑了工厂的方法。现在您的方法不是泛型的,所以
ISearch GetSearch(键入schemaType);
将无法编译。@ehh-修复了它。请看我定义
ISearch
接口的那一行-我忘了添加“out”。请看@GiladGreen,您的解决方案运行得非常好。您是对的,我错过了接口ISearch。非常感谢您的耐心和合作。与您聊天非常有帮助。