我应该对常规字段使用什么模式



我有一个类Field其中有两个子类AccountFieldDecimalField

class Field{//some properties} 
class DecimalField : Field {...}
class AccountField : Field {...}

然后我有另一个类Data它有一个类型 Field 的成员属性。

但它有问题。如果我将DecimalField变量分配给Data中的Field属性,那么我不能使用DecimalFields的某些属性,也不能使用Accountfield变量的属性......

我该怎么办?我必须使用哪种模式?

我正在使用 C# 4.0 和 MS Studio 2010

是的,你可以。

假设你有这样的字段类

public class Field
{
   public string Property1{get;set;}
   public int Property2 {get;set;}
}

和像这样的十进制字段类

  public class DecimalField:Field
   {
    public int DecimalFieldProperty {get;set;}
}

,以及像这样的帐户字段

public class AccountField:Field
    {
       public double Balance{get;set;}
}

,假设您有一个名为 DoSomething 的方法,该方法需要字段类型的参数,如下所示

void DoSomething(Field field)
{}

然后,要传入具体类型,您可以执行以下操作:

    void DoSomething(Field field)
    {
        var decimalField = field as DecimalField;
        //Do something with the decimal field instance
        if(decimalField  !=null)
         {
           Console.WriteLine("Decimal Field Property {0}",decimalField .DecimalFieldProperty );
          return;
        }
        //Cast the field as a account field instance
      var accountField = field as AccountField;
       if(accountField !=null)
       {
         Console.WriteLine("Balance {0}", accountField.Balance );
        return;
      }
      //Do something else with the normal field
    Console.WriteLine("Normal Field");
    }

一般抽象的方法是:

  • 创建一个具有可在子类中重写的虚拟函数/属性的公共泛型类。
  • 并对严格实现为指定类型的子类成员,因此不能一概而论,做一个cast

如果要使用同时位于"十进制字段"和"帐户字段"类型的属性,则这些属性应该/可能位于"字段"类型中。

如果要使用只有 DecimalField 已知的属性,则需要将该字段强制转换为 DecimalField:

Data data = new Data();
data.Field = new DecimalField();
Field field = data.Field;
DecimalField df = data.Field as DecimalField;
if(df != null)
{
    // use df
}

多态性并不是真正的模式,但是是的,它按照您描述的方式正确工作。如果将十进制字段分配给字段类型的变量,您将只能使用该字段的属性。如果您需要DecimalField的属性,则需要将其转换回DecimalField。

在 Data 类中,不要将字段声明为 Field,而应根据需要使用 DecimalField 或 AccountField。

这行不通:

Field field = myData.Fields[0];
Console.Writeline(field.Name); //assuming Name only exists in AccountField

但如果该字段是帐户字段,则可以执行引用转换并使用帐户字段特定属性:

if(myData.Fields[0] is AccountField)
{
    var acctField = (AccountField)myData.Fields[0];
    Console.Writeline(acctField.Name);
}

最新更新