在运行时使用存储在字典中的类实例的方法c#

时间:2014-09-26 05:08:53

标签: c# class inheritance reflection dictionary

您好我的代码中有一个问题,我必须在运行时创建一个类的实例。这些类继承自泛型接口,这种类存储在字典中。然后在运行时,使用这个新实例类的方法。

继承我的代码:

  public interface ILetters<T> where T : Item
    {
        Item SearchItem(T item);
    }

Item是一个Absract类,ItemA,ItemB,ItemC继承自它。

子类从ILetters继承,让我们说它们实现了不同的SearchItem()

public class ClassA : ILetters<ItemTypeA>
public class ClassB : ILetters<ItemTypeB>
public class ClassC : ILetters<ItemTypeC>

主:

Dictionary<string, Type> dictTypeSelected = new Dictionary<string, Type>()
            {
                {"A", typeof(ClassA)},
                {"B", typeof(ClassB},
                {"C", typeof(ClassC)},
            };

// Gets a string from user input
string type = combobox.SelectedItem.ToString();
var selectedType = Activator.CreateInstance(dictTypeSelected[type]);

selectedType.SearchItem() // <---- doesn't work. 

有什么不同的方法或方法可以解决这个问题吗?提前谢谢

2 个答案:

答案 0 :(得分:1)

虽然有几种解决方案,但我认为,主要问题是通用接口。 乍一看,这里没有必要。

我建议你重建类型层次结构:

abstract class Item { }

interface ILetters
{
    Item SearchItem(Item item);
}

abstract class Letters<T> : ILetters
    where T : Item
{
    public Item SearchItem(Item item)
    {
        return SearchItemOverride((T)item);
    }

    protected abstract Item SearchItemOverride(T item);
}

class ItemA : Item { }
class ClassA : Letters<ItemA> 
{
    protected override Item SearchItemOverride(ItemA item)
    {
        // ...
    }
}

然后你可以轻松地做到这一点:

var selectedType = (ILetters)Activator.CreateInstance(dictTypeSelected[type]);

selectedType.SearchItem(...);

答案 1 :(得分:0)

我认为这里的主要问题是var。使用var会将您的实例强制转换为对象。 您可以在这里尝试不同的替代方案。

  1. 您可以将实例打包成动态对象,只需调用具有运行时异常风险的方法
  2. 您可以将实例强制转换为具体类型,但在这种情况下,我认为您不了解它
  3. 您可以使用反射
  4. 调用该方法

    具体:

    1) dynamic selectedType = Activator.CreateInstance(...)
    selectedType.SearchItem(...)
    2) ClassA selectedType = Activator.CreateInstance(...)
    selectedType.SearchItem(...)
    3) object selectedType = Activator.CreateInstance(...)
    MethodInfo searchMethod = selectedType.GetMethod("SearchItem")
    searchMethod.Invoke(...)