我有各种类生成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;
}
但当然不能这样做。
有什么想法吗?
答案 0 :(得分: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;
}
您也可以使用抽象基类而不是接口。这有点限制性,但这意味着图表也可以共享通用实现。
(你甚至可以创建一个由抽象基类实现的接口,如果你真的想要灵活性而且还需要代码重用。)
答案 1 :(得分:4)
但当然不能这样做。
它可以使用接口。定义包含要运行的方法的接口:
public interface IGraphWithImageFile
{
string ImageFile { get; }
}
然后将接口应用于所有类,并将列表声明为List<IGraphWithImageFile>
。
答案 2 :(得分:2)
使所有类继承自常见的GraphBase抽象类。将您的公共属性作为抽象放在此类上,然后在派生类中覆盖它们。
答案 3 :(得分: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;
}
答案 4 :(得分:0)
在这种情况下,您只需要实施Strategy Pattern 要了解一下这段代码
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();
}