非泛型类列表上的C#调用方法

时间:2019-07-17 05:17:08

标签: c# generics

我的主班Computer与许多外部系统进行交互,并且目前具有将其信息塞入/更新到其中的逻辑。

我想将每个系统的逻辑移到它自己的单独的类中,我已经能够部分解决该问题,但是我无法在它们上调用方法。

我只是最近才开始使用泛型,所以这可能是写得不好的代码,请您提前道歉。

这些是我的System

public class System
{
    public string Name { get;set; }
}

public class System<T> : System
{
    public virtual T GetData() => default(T);
    public virtual void UpdateData() {}
}

public interface ISystem<T>
{
    T GetData();
    void UpdateData();
}       

这些是我使用System类创建的系统:

public class ComplexSystem : ISystem<RegistryKey>
{
    public string GetData() => MethodThatGetsRegistryData();
    public bool UpdateData() => MethodThatUpdatesRegistry();
}

public class IntSystem : ISystem<int>
{
    private int value = 9;
    public int GetData() => this.value;
    public void UpdateData()
    {
        this.value = 3;
    }
}

public class StringSystem : ISystem<string>
{
    private string value = "hello";
    public string GetData() => this.value;
    public void UpdateData()
    {
        this.value = "updated";
    }
}

这就是我试图使用整个东西的方式:

public class Computer
{   
    public List<System> AssociatedSystems = new List<System>();

    public Computer()
    {
        this.AssociatedSystems.Add(new System<ComplexSystem> {Name="ComplexSystem"});
        this.AssociatedSystems.Add(new System<IntSystem> {Name="IntSystem"});
        this.AssociatedSystems.Add(new System<StringSystem> {Name="StringSystem"});
    }

    public void UpdateDataWhenComputerIsChanged()
    {           
        // is it possible to loop through them and call UpdateData on each one without know what generic they are?
        foreach (var associatedSystem in this.AssociatedSystems)
        {
            // something like...
            associatedSystem.UpdateData();
        }
    }
}

这将导致

  

系统不包含UpdateData()的定义,并且找不到扩展方法

我不喜欢上面的代码,因此,如果有更好的方法,我将全力以赴。我本质上是在寻找一种包含数据逻辑的类列表的方法(例如GetData()UpdateData()),因此我不必将该逻辑放入我的主类({{1 }})

2 个答案:

答案 0 :(得分:2)

因此UpdateData中不存在函数System,这就是为什么您不能调用它的原因。我建议引入一个ISystem接口,并在其中插入Name(如果需要)和UpdateData,并让通用的ISystem<T>接口从该接口继承。

public interface ISystem
{
    string Name {get;set;}
    void UpdateData();
}

public interface ISystem<T> : ISystem
{
    T GetData();
}

public class Computer
{
    public List<ISystem> AssociatedSystems = new List<ISystem>();
    .....
    foreach (var associatedSystem in this.AssociatedSystems)
    {
        associatedSystem.UpdateData();
    }
}

答案 1 :(得分:0)

是的,有多种方法可以做到这一点。我能想到的是:

  1. 对循环中的每个TextView进行类型检查
  2. 向系统添加System属性
  3. 添加TypeUpdateData(object)

如果您需要更多帮助,请指定系统的性质。它们是否仅限于某些特定类型,或者您想要永久扩展,并且您的项目对速度至关重要?我可以详细说明