简体   繁体   中英

C# call derived class property using base class reference

I have a class RequestDetail . There are 2 classes classA and classB derived from it such that each of them has their own property:

public partial classA : RequestDetail { ..... }
public partial classB : RequestDetail { ..... }

I am writing a method CreateMethod1(ClassA a) and CreateMethod2(ClassB b) .

Both methods doing the same stuff except some minor difference. I would like to write a generic method and call that method by passing the reference in CreateMethod1 and CreateMethod2.

Can anyone help me in doing this?

THanks

EDIT:

What I have excluded is I have received a WSDL which when generated gives me four separate classes that inherit from a base class with around 20 properties. They only differ very slightly, to be exact 2 classes contain the same field (IsUrgent), the third contains (Ticket and Reason) and the fourth contains (BudgetCode) The persistance however is exactly the same for all implementations. I dont want to create 4 seperate methods to persist the same information.

Its worth noting the classes are partial.

xsd looks like following

<xs:complexType name="ClassA">
    <xs:complexContent>
      <xs:extension base="IARequestDetails">
        <xs:sequence>
          <xs:element name="IsUrgent" type="IAUrgency"/>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="ClassB">
    <xs:complexContent>
      <xs:extension base="IARequestDetails">
        <xs:sequence>
          <xs:element name="BudgetCode" type="ProjectBudgetCode"/>
          <xs:element name="IsUrgent" type="IAUrgency"/>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

您应该在基类中创建一个virtualabstract方法,在每个派生类中重写它,然后正常调用它。

Specify your base class as abstract, write the method "CreateMethod" inside it and create abstract functions where different behavior is required (or virtual if the behavior overriding is optional). Override the abstract functions, adding the desired behaviors inside them.

public abstract RequestDetail
{
    public void CreateDetail()
    {
        CustomBehavior();
    }
    protected abstract CustomBehavior();
}
public RequestDetailA : RequestDetail
{
    protected override void CustomBehavior()
    {
        // Foo
    }
}

if those method are in RequestDetails i suggest you make it receive a RequestDetail instead and in that method you can call an abstract method from RequestDetail that does those minor differences and each of ClassA and ClassB implement the different approach something like

class RequestDetail{
    public void CreateMethod(RequestDetails reqD){ 
        //do what you need
        AbstCreateMethod(reqD);
    }
    public abstract void AbstCreateMethod(RequestDetails reqD);

}

class ClassA : RequestDetails{
    public void AbstCreateMethod(RequestDetails reqD){
        //do classA things  
    }
}

class ClassB : RequestDetails{
    public void AbstCreateMethod(RequestDetails reqD){
        //do classB things  
    }
}

if it's in another class follow a similar solution to this but with the class that has those methods. For more information on this read the design pattern Template method

class mybase 
{ 
   virtual void DoStuff(){...}

}

class Der1:mybase
{
    virtual override void DoStuff(){
       base.DoStuff(); // Call the Common Code 
       .... Custom Code for this class
 }

 Der1 A = new Der1(); 
 mybase B = new Der1();
 A.DoStuff(); // this will call the derived version 
 B.DoStuff(); // So will this 

Here is a solution using partial classes an interface and generic constraints ... you will need to build the list of parameters that need to be returned in the Params implemenation for each of your sub classes, super class properties are naturally available.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

namespace ConsoleApplication3
{
    public interface IABInterface
    {
        //Could be your SqlParameters
        string[] Params { get; }
    }

    public partial class IARequestDetails
    {
        public int One
        {
            get; set; 
        }

        public int Two
        {
            get;set;
        }
    }

    public partial class ClassA : IARequestDetails
    {
        public int IsUrgent 
        {
            get;set;
        }
    }

    public partial class ClassB : IARequestDetails
    {
        public int BudgetCode
        {
            get;
            set;
        }

        public int IsUrgent
        {
            get;
            set;
        }
    }

    public partial class ClassA : IABInterface
    {
        #region IABInterface Members

        public string[] Params
        {
            //Create your list of parameters
            get { return null; }
        }

        #endregion
    }

    public partial class ClassB : IABInterface
    {
        #region IABInterface Members

        public string[] Params
        {
            get
            {
                return null;
            }
        }
        #endregion
    }

    public class Persist
    {
        public void Save<T>(T obj)
            where T : IARequestDetails, IABInterface
        {
            //Do you saving here ... 
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Persist persist = new Persist();

            persist.Save(new ClassA());
            persist.Save(new ClassB());
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM