2010-06-03 36 views
2

在我的应用程序中,我处理了几个不同的“参数”,它们来自IParameter接口,还有ParamBase抽象基类。我目前有两种不同的参数类型,分别叫做FooParameterBarParameter,它们都来自ParamBase。很显然,当我需要处理它们时,我可以将它们当作IParameter,或者当我需要处理它们的特定功能时检测它们的具体类型。仅在添加新方法时使用哪些OOP模式,而不是数据?

我的问题在于具体FooParameter s。我目前有几个具有自己的类的衍生自FooParameter的特定的类,我们将其称为FP12,FP13FP14等。这些都具有某些特征,这使得我在UI中以不同的方式对待它们。 (大部分名称都与各个位相关联,或位的范围)。请注意,这些特定派生的FP没有与它们关联的附加数据,只有属性(以不同方式引用相同的数据)或方法。

现在,我想保留所有这些参数在一个Dictionary<String, IParameter>为简单的通用访问。问题是,如果我想引用特定的GUI函数,我不能写: FP12 fp12 = (FP12)paramList["FP12"],因为您不能向下派生到派生类型(正确如此)。但在我的情况下,我没有添加任何数据,因此演员理论上将工作。

应该使用什么类型的编程模型?谢谢!

回答

2

这种方法没有什么错,除了可能将参数存储在字典中。这样做的目的是什么?特别是如果你把他们放在他们的班名上。

我只是使用List<IParameter>并有一个控件通过集合并从那里选择正确的子类。

m_Parameters = new List<IParameter>(); 
//This control needs FP12 
foreach(var param in Parameters) { 
    var fp12 = param as FP12; 
    if (fp12 != null) { 
    //do something with the param. 
    break; 
    } 
} 

写完上面的内容后,我想我终于明白你在做什么了。如果您想对FooParameter的任何子类执行FP12上的操作,那么您需要完全从FooParameter中取出该操作。由于您的参数是数据,并且该数据在FooParameter的不同子类中是相同的,因此只有一个实施FooParameter(“数据”类)和多个“操作”类是有意义的。

//The one implementation of IParameter for all FooParameters 
public class FooParameter : IParameter { 
    string Data1 {get;set;} 
} 

//base class for Foo Operation, only stores FooParameter 
public class FooOperationBase { 
    protected readonly FooParameter m_Param; 
    public FooOperationBase (FooParameter param) { 
    m_Param = param; 
    } 
} 

//specific operations on FooParameter go in this class 
public class FooOperation12 : FooOperationBase { 
    public FooOperation12(FooParameter param) : base(param) {} 

    public void DoSomeOperation() { 
    return m_Param.Data1 + " transformed"; 
    } 
} 
+0

现在只有我的子类只添加属性,所以我原来的路线现在工作。如果我添加任何其他数据或方法,您的提案将完美工作。 – 2010-06-06 23:00:59

1

如果paramList["FP12"]是FP12,则该投射将起作用。当然,如果不是,它会抛出一个InvalidCastException。如果您不确定该对象的类型,您也可以使用as

这是一个理想的设计是一个单独的问题。理想情况下,您希望更喜欢多态,这意味着FooParameter的子类知道在内部使用其新的特殊功能,并且外部代码不必投射,或使用asis

+0

有一件事我会实现,那么注释掉,是当从一个文件读入参数时,我试着从参数名称中使用'Type.GetType(string)'得到'System.Type',看看是否应该创建一个特定的'FP12'等。或更通用的'FooParameter'。这些都可以存储在'Dictionary '中。 – 2010-06-03 01:34:31

1

我不是100%肯定,你是从这个问题来了,但你可以做这样的事情:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var paramList = new List<IParameter>(); 
     paramList.Add(new FooParameter()); 
     paramList.Add(new BarParameter()); 
     paramList.Add(new F1()); 
     paramList.Add(new F2()); 

     foreach (var p in paramList) 
     { 
      p.DoCommonOperation(); 
      DoSpecificOperation(p); 
     } 

     Console.ReadKey(); 
    } 

    private static void DoSpecificOperation(IParameter p) 
    { 
     if (p is F1) 
     { 
      (p as F1).F1Method(); 
     } 
     else if (p is F2) 
     { 
      (p as F2).F2Method(); 
     } 

    } 

    interface IParameter 
    { 
     void DoCommonOperation(); 
    } 

    abstract class ParamBase : IParameter 
    { 
     public virtual void DoCommonOperation() 
     { 
      Console.WriteLine("ParamBase"); 
     } 
    } 

    class FooParameter : ParamBase 
    { 
     public override void DoCommonOperation() 
     { 
      Console.WriteLine("FooParameter"); 
     } 
    } 

    class BarParameter : ParamBase 
    { 
     public override void DoCommonOperation() 
     { 
      Console.WriteLine("BarParameter"); 
     } 
    } 

    class F1 : FooParameter 
    { 
     public override void DoCommonOperation() 
     { 
      Console.WriteLine("F1"); 
     } 

     public void F1Method() 
     { 
      Console.WriteLine("F1.F1Method"); 
     } 
    } 

    class F2 : FooParameter 
    { 
     public override void DoCommonOperation() 
     { 
      Console.WriteLine("F2"); 
     } 

     public void F2Method() 
     { 
      Console.WriteLine("F2.F2Method"); 
     } 
    } 
} 

基本上你必须在控制类的方法知道如何调用特定实现的IParameter对象列表,以及使用是/如此。

1

只是为了理智,为什么不使用Dictionary<Type, IParameter>?随着一点点的仿制药,你可以这样做:

public interface IParameter { } 
public class FP12 : IParameter { public string fieldFP12 { get; set; } } 
public class FP11 : IParameter { public string fieldFP11 { get; set; } } 

public static class DictionaryHelper 
{ 
    public static T GetParameter<T>(this Dictionary<System.Type, 
     IParameter> target) where T : IParameter 
    { 
     return (T)target[typeof(T)]; 
    } 
} 

示例程序和输出:

class Program 
{ 
    static void Main() 
    { 
     Dictionary<Type, IParameter> parameters = 
      new Dictionary<Type, IParameter>(); 
     parameters.Add(typeof(FP12), new FP12 { fieldFP12 = "This is FP12" }); 
     parameters.Add(typeof(FP11), new FP11 { fieldFP11 = "This is FP11"}); 

     // THIS IS WHERE YOU GET THE IPARAMETER YOU WANT - THE GENERICS WAY... 
     var fp12 = parameters.GetParameter<FP12>(); 
     var fp11 = parameters.GetParameter<FP11>(); 

     Console.WriteLine(fp12.fieldFP12); 
     Console.WriteLine(fp11.fieldFP11); 
     Console.ReadLine(); 
    } 
} 

输出结果:

This is FP12 
This is FP11 
+0

我曾考虑过这个问题,它会工作的很好,但前提是每个参数类型都是作为FooParameter的子类实现的。他们大多数只是整数值,我没有做任何特别的事情,只是通过名字来引用它们(即“FP26”)。但其中一些是位模式,所以我制作了子类,并使用属性指向特定的位或范围。 – 2010-06-05 19:36:58

相关问题