English 中文(简体)
从母子类参数中挑选子女类别
原标题:Getting child class type from parent class parameter

我将拥有多个物体的“型号”,我确实不相信,在不为每种类型单独提供储蓄/回收的情况下,如何最好地检索/拯救这些多种类型。

我的班子:

public class Evaluation {
  public int Id
  public string Comment
}

public class EvaluationType_1 : Evaluation {
  public string field
}

public class EvaluationType_1 : Evaluation {
  public string field
}

我想在我的存放处做些什么:

public interface IEvaluationRepository {
  public Evaluation getEvaluation(int id);
  public SaveEvaluation(Evaluation);
}

在“假肢”方法之外:

// Save/get common fields
Id
Comments

// Get child type, perform switch
Type childType = ???
switch(childType) {
  // Set child-specific fields
}

我没有增加一个“类型”栏,因为我在数据库的另一部分有这个栏目,我并不真正对它非常感兴趣。

Update

如有必要,更有助于澄清。

我热爱使用接口和通用物的想法,真的是在如何将它们纳入我的储存模式方面损失的。

当我打电话getEvaluation时,我想回去一份抽象的评价,但我与这一守则作斗争。 Same with Saving。

Update 2

Daniel正在帮助我清醒地了解我试图问什么。

数据库:

Evaluations
  Id (PK)
  Comment

EvaluationType1
  Id (FK to Evaluations.Id)
  Field

EvaluationType1
  Id (FK to Evaluations.Id)
  Field

因此,在<代码>植被评价(int id)中,我需要说明他们想要哪类评价。 这是否意味着我应该通过某种方式? 在<代码>saveEvaluation上是正确的。 但是,我可以做一个开关/运行图,看<代码>。 类型

最佳回答

引言

public interface ISaveable {
   void SaveFields();
}

public abstract class Evaluation : ISaveable {
  public int Id
  public string Comment

  public virtual void SaveFields() {
     //Save ID and Comments
  }
}

public class EvaluationType_1 : Evaluation {
    public string field1

  public override void SaveFields() {
     //Save field1
     base.SaveFields();
  }

}

public class EvaluationType_2 : Evaluation {
   public string field2

  public override void SaveFields() {
     //Save field2
     base.SaveFields();
  }

}

然后,你可以收集各种可挽救的物品,如<代码>List<ISaveable>和“Save Fields on each one,regardless。 现在,你是针对接口而不是针对具体类型的方案。 走向编码脱钩的第一步。

Edited: In response to your comment In your repository, you would no longer program against the Evaluation class. Instead you would program agains t the methods in the interface that it implements:

而不是:

public interface IEvaluationRepository {
  public Evaluation getEvaluation(int id);
  public SaveEvaluation(Evaluation);
}

也许有:

 public interface ISaveableRepository {
   public ISaveable getSavable(int id);
   public Save(ISaveable saveable);
 }

存放处的实施可能好像是:

 public class SaveableEvaluationRepository : ISaveableRepository {
   public ISaveable getSavable(int id) {
       //Add your logic here to retrieve your evaluations, although I think that 
       //this logic would belong elsewhere, rather than the saveable interface.
   }

   public Save(ISaveable saveable) {
       saveable.SaveFields();
   }
 }
问题回答

你的问题不明确,从我所理解的角度来看,你重新寻找目标类型。 这里是你们如何做的。

EvaluationType_1 objOfEvalType1 = new EvaluationType_1();
Type childType = objOfEvalType1.GetType();

如果你需要基础/父母阶层的儿童类别,则更新以下评价类别。

public class Evaluation {
  public int Id;
  public string Comment;

  //call this.GetType() anywhere you wish to get the type of the object.
  public Type MyType = this.GetType();
}

这种声音像一个非常好的通用人选一样,而且许多存放处和办公室管理框架都使用这些候选人。

public interface IEvaluationRepository<TEvaluation> 
{ 
  public TEvaluation getEvaluation(int id); 
  public SaveEvaluation(TEvaluation evaluation); 
} 

您还可能希望有一个评价基础小组来履行共同职能,并限制您的接口只使用评价基础课程:

public interface IEvaluationRepository<TEvaluation> where TEvaluation : EvaluationBase
...
public class SomeEvaluation : EvaluationBase
{
}

它将拯救大多数或所有承认和追踪物体类型的问题。

:Object.GetType 回到目前情况的确切操作时间类型,并不考虑相关变量的申报类型:

Type type = evaulation.GetType();

// Note that you can t switch on types

if (type == typeof(DerivedEvaluation1)) {
    // Perform custom operations        
}
else if (type == typeof(DerivedEvaluation2)) {
    // Perform custom operations
}

// Etc.

我将你的问题解释为了解一种方便的方式,即不采用“幻灯”改变儿童物体的类型,就发出习俗储蓄逻辑。 如果你们都想用一种简单的方式来控制参数的类型,那么你可以使用:/code>关键词。

采用两种方法,根据时间类型发出逻辑。

一种是,你可以总是为每个特定类型设立<代码>Save的发送字典:

private static readonly Dictionary<Type,Action<Evaluation>> s_SaveFunctions =
    new Dictionary<Type,Action<Evaluation>>();

s_SaveFunctions[typeof(ChildA)] = SaveChildA;
s_SaveFunctions[typeof(ChildB)] = SaveChildB;
// .. and so on.

public SaveEvaluation( Evaluation eval )
{
   // .. common save code ...

   // cal the appropriately typed save logic...
   s_SaveFunctions[eval.GetType()]( eval );
}

private static void SaveChildA( Evaluation eval ) { ... }

private static void SaveChildB( Evaluation eval ) { ... }

在NET4中,您可使用<代码>dynamic实现同一版本的更清洁版本:

public SaveEvaluation( Evaluation eval )
{
   // .. common save logic ..

   dynamic evalDyn = eval;

   SaveChild( evalDyn );
}

private void SaveChild( ChildA eval ) { ... }

private void SaveChild( ChildB eval ) { ... }

注:<代码>SaveChild方法所有名称相同,但仅凭其论点类型超载。 <代码>dnamic 参数,用于<编码>SaveEvaluation方法,将在操作时间进行评估,并发送给适当的超负荷。

你只能使你的方法变得虚拟——这一呼吁将根据实际操作时间类型向正确的方法发出。

public class Evaluation
{
    public Int32 Id { get; set; }
    public String Comment { get; set; }

    public virtual void Save()
    {
        // Save the common information.
        this.SaveToDatabase(this.Id);
        this.SaveToDatabase(this.Comment);
    }

    private void SaveToDatabase(Object value)
    {
        // Left as an exercise for the reader... :D
    }
}

public class EvaluationType1 : Evaluation
{
    public String Foo { get; set; }

    public override void Save()
    {
        // Save the common information.
        base.Save();

        // Save the specific information here.
        this.SaveToDatabase(this.Foo);
    }
}


public class EvaluationType2 : Evaluation
{
    public String Bar { get; set; }

    public override void Save()
    {
        // Save the common information.
        base.Save();

        // Save the specific information here.
        this.SaveToDatabase(this.Bar);
    }
}

或许你们也可以抽象地对待基类。 此外,你通常应当避免使田间公用,这可能会使该法典保持为一种 night梦,因此,我以我的榜样使用财产。





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

How to Add script codes before the </body> tag ASP.NET

Heres the problem, In Masterpage, the google analytics code were pasted before the end of body tag. In ASPX page, I need to generate a script (google addItem tracker) using codebehind ClientScript ...

Transaction handling with TransactionScope

I am implementing Transaction using TransactionScope with the help this MSDN article http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope.aspx I just want to confirm that is ...

System.Web.Mvc.Controller Initialize

i have the following base controller... public class BaseController : Controller { protected override void Initialize(System.Web.Routing.RequestContext requestContext) { if (...

Microsoft.Contracts namespace

For what it is necessary Microsoft.Contracts namespace in asp.net? I mean, in what cases I could write using Microsoft.Contracts;?

Separator line in ASP.NET

I d like to add a simple separator line in an aspx web form. Does anyone know how? It sounds easy enough, but still I can t manage to find how to do it.. 10x!

热门标签