2

我有各种生成 excel 图表的类。

每个类生成一个不同的图。

它们都共享相同的私有变量,但具有不同的值。

我希望编写一个通用代码,以防止“if”语句确定它是哪个图。

这是其中一个类的示例:

using System;

namespace GraphsGenerator
{
   public class GraphOne
   {
       #region Private Members

       private string m_baseDir = "";
       private static string m_graphName = "GraphOne";
       private string m_imageFile = m_graphName + Utils.ImageExtension;

       #endregion Private Members

       #region Properties

       public string BaseDir
       {
           set { m_baseDir = value; }
       }
       public string GraphName
       {
           get { return m_graphName; }
       }
       public string ImageFile
       {
           get { return m_imageFile; }
           set { m_imageFile = value; }
       }

       #endregion Properties

       #region Constructor


       public HandTrackingGraphs(string baseDir)
       {
           m_baseDir = baseDir;
       }

       #endregion Constructor
   }
 }

我试图在我的主要做到这一点:

List<object> listOfGraphs = new List<object>();
listOfGraphs.Add(new GraphOne());
listOfGraphs.Add(new GraphTwo());
listOfGraphs.Add(new GraphThree());

foreach (object currentGraph in listOfGraphs)
{
   string imageFile = currentGraph.ImageFile;
}

但是,这当然是做不到的。

有任何想法吗?

4

5 回答 5

8

它们都共享相同的私有变量,但具有不同的值。

它们都应该实现相同的接口,该接口公开ImageFile属性。例如:

public interface IGraph
{
    // TODO: Consider making this read-only in the interface...
    public string ImageFile { get; set; }
}

然后你可以拥有:

List<IGraph> listOfGraphs = new List<IGraph>();
listOfGraphs.Add(new GraphOne());
listOfGraphs.Add(new GraphTwo());
listOfGraphs.Add(new GraphThree());

foreach (IGraph currentGraph in listOfGraphs)
{
   string imageFile = currentGraph.ImageFile;
}

您也可以使用抽象基类而不是接口。这有点限制,但这意味着图也可以共享通用实现。

(你甚至可以创建一个由抽象基类实现的接口,如果你真的想要灵活性而且代码重用。)

于 2013-10-02T08:54:05.857 回答
4

但是,这当然是做不到的。

它可以,使用接口。定义一个包含要运行的方法的接口:

public interface IGraphWithImageFile
{
    string ImageFile { get; }
}

然后将该接口应用于所有类,并将列表声明为List<IGraphWithImageFile>.

于 2013-10-02T08:54:37.587 回答
2

使所有类都继承自一个通用的 GraphBase 抽象类。将您的公共属性作为抽象放在此类上,然后在派生类中覆盖它们。

于 2013-10-02T08:54:15.420 回答
1

接口已经被建议了,所以给你另一种选择——你可以使用基类,因为你不仅共享通用属性/方法,而且还共享通用实现,例如

public abstract class Graph
{
   #region Private Members

   private string m_baseDir = "";
   private string m_imageFile = m_graphName + Utils.ImageExtension;

   #endregion Private Members

   #region Properties

   public string BaseDir
   {
       set { m_baseDir = value; }
   }
   public string GraphName
   {
       get { return m_graphName; }
   }

   public abstract string ImageFile { get; }

   #endregion Properties

   #region Constructor


   public HandTrackingGraphs(string baseDir)
   {
       m_baseDir = baseDir;
   }

   #endregion Constructor
}

public class GraphOne : Graph
{
    public override string ImageFile { get { return "GraphOne"; } }
}

public class GraphTwo : Graph
{
    public override string ImageFile { get { return "GraphTwo"; } }
}

public class GraphThree : Graph
{
    public override string ImageFile { get { return "GraphThree"; } }
}

然后你的用法变成

List<Graph> listOfGraphs = new List<Graph>();
listOfGraphs.Add(new GraphOne());
listOfGraphs.Add(new GraphTwo());
listOfGraphs.Add(new GraphThree());

foreach (IGraph currentGraph in listOfGraphs)
{
    string imageFile = currentGraph.ImageFile;
}
于 2013-10-02T08:57:27.443 回答
0

在这种情况下,您只需要实现策略模式 要了解一些想法,请参阅此代码

abstract class AbsGraph
{
    public string ImageFile { get; protected set; }
    //other properties

    public abstract void DrawGraph();
    //other methods

    public void CommonMethod()
    { }
    //other common method
}

class Graph1 : AbsGraph
{
    public override void DrawGraph()
    {
        //do graph specific task
    }
}

class Graph2 : AbsGraph
{
    public override void DrawGraph()
    {
        //do graph specific task
    }
}

class Graph3 : AbsGraph
{
    public override void DrawGraph()
    {
        //do graph specific task
    }
}

现在你可以做

var absGraphs = new List<AbsGraph>
                    {
                        new Graph1(),
                        new Graph2(),
                        new Graph3()
                    };
foreach (var graph in absGraphs)
{
    graph.DrawGraph();
}
于 2013-10-02T09:00:54.427 回答