Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当只添加新方法而不添加数据时,使用什么OOP模式?_C#_Oop_Casting - Fatal编程技术网

C# 当只添加新方法而不添加数据时,使用什么OOP模式?

C# 当只添加新方法而不添加数据时,使用什么OOP模式?,c#,oop,casting,C#,Oop,Casting,在我的应用程序中,我处理了几个不同的“参数”,它们来自IParameter接口,也来自ParamBase抽象基类。我目前有两种不同的参数类型,分别称为FooParameter和BarParameter,它们都源自ParamBase。显然,当我需要一般性地处理它们时,我可以将它们视为I参数s,或者当我需要处理它们的特定功能时,可以检测它们的特定类型 我的问题在于具体的foopparameters。我目前有一些特定的类,它们有自己的类,这些类派生自FooParameter,我们将它们称为FP12,F

在我的应用程序中,我处理了几个不同的“参数”,它们来自
IParameter
接口,也来自
ParamBase
抽象基类。我目前有两种不同的参数类型,分别称为
FooParameter
BarParameter
,它们都源自
ParamBase
。显然,当我需要一般性地处理它们时,我可以将它们视为
I参数
s,或者当我需要处理它们的特定功能时,可以检测它们的特定类型

我的问题在于具体的
foopparameter
s。我目前有一些特定的类,它们有自己的类,这些类派生自
FooParameter
,我们将它们称为
FP12
FP13
FP14
,等等。这些都具有某些特性,这使得我在UI中对它们的处理方式有所不同。(大多数具有与单个位或位范围相关联的名称)。请注意,这些特定的派生FP没有与之关联的其他数据,只有属性(以不同方式引用相同的数据)或方法

现在,我想将所有这些参数保存在
字典中
,以便于一般访问。问题是,如果我想引用具有特殊GUI功能的特定GUI,我无法编写:
FP12 FP12=(FP12)paramList[“FP12”]
因为您不能向下转换为派生类型(这是理所当然的)。但就我而言,我没有添加任何数据,所以演员阵容理论上是可行的

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

如果
paramList[“FP12”]
是FP12,则该强制转换将起作用。当然,如果不是的话,它会抛出一个InvalidCastException。如果不确定对象的类型,也可以使用


这是否是一个理想的设计是一个单独的问题。理想情况下,您希望选择多态性,这意味着FooParameter的子类知道在内部使用其新的特殊函数,并且外部代码不必强制转换,也不必使用
as
is
这种方法没有什么真正的错误,只是可能将参数存储在字典中。这样做的目的是什么?特别是如果你在他们的类名上键入他们

我只需要使用一个
列表
,让一个控件遍历集合并从中选择正确的子类

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;
  }
}

我不能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");
        }
    }
}
类程序
{
静态void Main(字符串[]参数)
{
var paramList=新列表();
添加(新的FooParameter());
添加(新的BarParameter());
paramList.Add(新F1());
paramList.Add(新的F2());
foreach(参数列表中的变量p)
{
p、 DoCommonOperation();
剂量比浊法(p);
}
Console.ReadKey();
}
专用静态空隙剂量规格(I参数p)
{
如果(p是F1)
{
(p为F1)。F1方法();
}
else if(p是F2)
{
(p为F2)。F2方法();
}
}
接口参数
{
void docomonoperation();
}
抽象类paramber:ipParameter
{
公共虚拟void docomonoperation()
{
控制台写入线(“ParamBase”);
}
}
类参数:ParamBase
{
公共覆盖无效DoCommonOperation()
{
Console.WriteLine(“FooParameter”);
}
}
类参数:ParamBase
{
公共覆盖无效DoCommonOperation()
{
Console.WriteLine(“BarParameter”);
}
}
F1类:参数
{
公共覆盖无效DoCommonOperation()
{
控制台写入线(“F1”);
}
公共方法()
{
Console.WriteLine(“F1.F1方法”);
}
}
类F2:参数
{
公共覆盖无效DoCommonOperation()
{
控制台写入线(“F2”);
}
公共方法()
{
控制台写入线(“F2.F2方法”);
}
}
}

本质上,类中有一个方法控制IParameter对象的列表,该对象知道如何调用特定的实现,并使用is/as来执行此操作。

为了理智起见,为什么不使用
字典呢?使用一些泛型,您可以做到:

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)];
    }
}

我实现了一件事,然后注释掉了,那就是当从文件中读入参数时,我尝试使用参数名中的
Type.GetType(string)
来获取
System.Type
,以查看是否应该创建一个特定的
FP12
,等等,还是一个更通用的
foopparameter
。这些都可以存储在
字典中
。我考虑过这一点,这将非常有效,但前提是每个参数类型都实现为
FooParameter
的子类。它们中的大多数只是整数值,我对它们不做任何特殊处理,只是按名称引用它们(即“FP26”)。但其中一些是位模式,所以我创建了子类,带有指向特定位或范围的属性。现在只有我的子类只添加属性,所以我原来的路由现在可以工作了。如果我添加任何其他数据或方法,您的建议将非常有效。
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