C# - Call a derived base method in the derived context - c#

Tried to search the web but found nothing so far so here my question:
I want to index model-information via attributes on the different members.
To do this i created a function in a base class that gathers all needed information when called.
This method is derived into the different models so that they can all be indexed.
Base()
{
public virtual void Index() {...}
}
In the base class I'm calling a generic method that gives me acces to the indexing server for the specific model that I want to save there
using (var indexFacade = IndexFacadeFactory.GetIndexFacade(configuration, this))
{
indexFacade.Execute(this, operation);
}
The issue I'm currently having is that when calling the factory it retrieves the information for the base-class.
What I want to acomplish is something like this:
Derived : Base
{
[IndexingKey]
long Id { get; set; }
[IndexingField]
string SomeValue { get; set; }
}
var derived = new Derived();
derived.Index();
My indexFacade holds the type of
IndexFacadeBase<Base>
I'm aware of the polimorphism here and why this happens.
My question is:
How can i call
derived.Index();
so that the context from which it is called is not from the base-class without overwriting it?
Further information:
The method that is called looks like this:
public static IndexFacadeBase<T> GetIndexFacade<T>(IndexInfo.IndexConfiguration config, T model)
{
IndexFacadeBase<T> retVal;
.....
return retVal;
}
The T has the type of Base.
The model has the type of Derived.
Maybe that clears up some of the Problems.
I get back:
IndexFacadeBase<Base>
I would need back:
IndexFacadeBase<Derived>
Thanks in advance for all the help.

I may not be fully understanding your question, but aren't you simply looking to override the method in the derived class?
class Base
{
public virtual void Index() { }
}
class Derived : Base
{
public override void Index() { } // here is the override.
long Id { get; set; }
string SomeValue { get; set; }
}
Then when you do this:
var derived = new Derived();
derived.Index();
The derived class' Index method is called.

Maybe it would work if your IndexFacadeBase<Base> was changed to IndexFacadeBase<T> where T:Base.

Related

How to Override a Virtual method with Object type in the parameter

I want to override BuildFilter Method in the derived class. I have a virual BuildFilter Method with the following signatures
public abstract class BaseSearchProperty <TEntity> : ISearchResultProperty<TEntity>
{
public virtual List<AppliedFilter> BuildFilter(object value)
{
return new List<AppliedFilter>();
}
}
i know the BuildFilter method override types one is string and another one is a List of String List<string>. i have written the override methods in the derived class as below
public class IndustrySearchProperty : BaseSearchProperty<API.ISearchResult>
{
public override List<AppliedFilter> BuildFilter(string filterValue,)
{
var appliedFilters = new List<AppliedFilter>();
return appliedFilters;
}
public override List<AppliedFilter> BuildFilter(List<string> filterValue)
{
var appliedFilters = new List<AppliedFilter>();
return appliedFilters;
}
}
but am getting error like no suitable method found to override. I know what this error is both parent class signature and child class signature needs to be same. Is there any other way that i solve this problem??
both parent class signature and child class signature needs to be same
Yes. There is no clean way.
Two things you can do:
Get the object in the overrided method and cast to whatever type needed or
Add a new type parameter
like this:
public abstract class BaseSearchProperty <TEntity,TFilter> : ISearchResultProperty<TEntity>
{
public virtual List<AppliedFilter> BuildFilter(TFilter value)
{
return new List<AppliedFilter>();
}
}
I recommend neither. This is a code smell in my mind showing you are not using inheritance correctly. And it probably doesn't support Liskov and other principles.

Covariance with derived classes in C#

I have the following code (ready to paste into linqpad). Basically there is a base 'model' class with a 'treemembermodel' class deriving from it.
class MemberModel
{
public List<Member> Team = new List<Member>();
public void IncreaseAge()
{
// Would like this to modify the Treemember
Team[0].Age++;
}
}
class TreeMemberModel : MemberModel
{
public new List<TreeMember> Team = new List<TreeMember>();
public void UpdateName(string newName)
{
}
}
Same for a Member class with a 'TreeMember' deriving from it.
public class Member
{
public string Name;
public int Age;
}
public class TreeMember: Member
{
public string ParentName;
}
The idea is that the base member model stores a list of normal members, while the 'tree' model (and member) classes ensure a 'tree' structure by maintaining integrity between parent and subordinate fields.
This all seemed a good idea (the below example is stylised) - I figured any 'common' methods applying to both object types (eg 'increaseage' below) would modify the treeMember in the TreeModel when called from that model. However, calling 'increaseage' in my main method instead tries to access the 'Team' collection from the base 'MemberModel' instead, which of course doesn't exist.
void Main()
{
TreeMemberModel t = new TreeMemberModel();
t.Team.Add(new TreeMember() { Name = "original", Age = 10 });
// Call method within derived class
t.UpdateName("changed");
Console.WriteLine (t.Team[0].Name);
// Call method which drops down to base class method, and would like it to modify the TreeMemberModel's Team collection, not MemberModel's.
t.IncreaseAge();
Console.WriteLine (t.Team[0].Age);
}
I figure this is a covariance issue, and have tried a few things around making classes generic and so forth. Can I configure this so it drops back to the base class's methods while manipulating the elements of the TreeModel collection?
You should try following:
class MemberModel<TMember> where TMember : Member
{
public List<TMember> Team = new List<TMember>();
public void IncreaseAge()
{
// Would like this to modify the Treemember
Team[0].Age++;
}
}
class TreeMemberModel : MemberModel<TreeMember>
{
public void UpdateName(string newName)
{
}
}

Inherit from an abstract base with a more specific method

Lots of questions with these keywords; I sifted through the first 30 or so then gave up.
I have interfaces like so:
public interface IColumnRule
{
int Length { get; set; }
string Name { get; set; }
object Parse(string toParse);
int Position { get; set; }
Type Type { get; }
}
public interface IColumnRule<T> : IColumnRule
{
ColumnRule<T>.RuleFluentInterface<T> Configure { get; }
new T Parse(string rowdata);
Func<string, T> ParsingFunction { get; set; }
}
... the idea being, one would implement the IColumnRule<T> to create a strongly-typed column parser utilizing the Func<string, T>.
The problem is, I store these IColumnRule<T> concretes in an IList<IColumnRule> container. There are multiple types of IColumnRule<T>, each implementing on a different type. When I invoke the Parse method on the IColumnRule interface, I am expecting the new Parse(string) method of the subclass to be called, but the base Parse is the one actually being called.
How can I invoke the subclass generic T Parse(string) method from a collection of IColumnRule using the interface's object Parse(string) ... or is this impossible?
Your implementation of IColumnRule<T> would have to provide a compliant Parse method. Given your code, the easiest way to do that is with an protected abstract method in your base class which is overridden in your subclass.
public abstract class ColumnRule : IColumnRule
{
...
public object Parse(string rowdata)
{
return this.ParseInternal(rowdata);
}
protected abstract object ParseInternal(rowdata);
}
public class ColumnRule<T> : ColumnRule, IColumnRule<T>
{
...
public new T Parse(string rowdata)
{
// strong-typed parse method
}
protected override object ParseInternal(string rowdata)
{
return this.Parse(rowdata); // invokes strong-typed method
}
}
When I invoke the Parse method on the IColumnRule interface, I am expecting the new Parse(string) method of the subclass to be called, but the base Parse is the one actually being called.
Yes, it would. You've got two methods which are unrelated as far as the type system, CLR and compiler are concerned.
How can I invoke the subclass generic T Parse(string) method from a collection of IColumnRule using the interface's object Parse(string) ... or is this impossible?
The simplest approach would be to have an abstract class implementing this as:
public abstract ColumnRuleBase<T> : IColumnRule<T>
{
public object Parse(string toParse)
{
IColumnRule<T> genericThis = this;
return genericThis.Parse(toParse);
}
...
}
(If you had the two method names being different, it would be slightly simpler.)
You'd have to know the type somehow:
List<IColumnRule> rules; // populated from somewhere
foreach (IColumRule<int> rule in rules.OfType<IColumnRule<int>>()) {
int foo = rule.Parse(rowData);
}
Or just cast a known element:
int foo = ((IColumnRule<int>)rules[5]).Parse(rowData);

What is the best way to design this class hierarchy?

I have a database table which contains an ID column and a Name column. I am tasked with designing a program that accepts one of the IDs as an argument to Main().
Bold is edit 2
I need to use that ID which must exist in the database, to correspond to some code to run. Each row in the table corresponds to slightly different code, but a lot of them share a lot of code. I need a design that will minimize code duplication.
So far what I've developed is an abstract base class that has an abstract Int32 field ID to enforce derived classes having their corresponding ID in the database. That way I can reflect over the derived classes to find the one whose ID matches the Main() argument and instantiate that class. Then I just call the virtual methods from Main() which runs the most derived code that has been defined.
public abstract class Base {
public abstract Int32 Id { get; }
public void Foo() {
// Do something
}
}
public class Derived {
public override Int32 Id { get { return 42; } }
public void Foo() {
// Do something more specific
}
}
Does anyone have any better ideas how to achieve what I want? I like the idea of keeping the ID right in the class definition, but I'm open to changing that if it makes sense.
Thanks!
EDIT:
One thing I don't like about this is that I have to reflect over each derived type and instantiate that type to check the ID. Does anyone have a better idea on how to do that?
Instead of using a property to define the ID of the class, use a custom attribute. That way, you don't have to instantiate the object to check what its ID is.
When your program runs, it can scan the assembly for all classes with that attribute tag, and find the one with the matching ID, instantiate that class, and then run it's Foo method. If you perform this kind of lookup multiple times per application run, you could instatiate all the classes with your custom attribute and then put them into a Dictionary to provide quick lookups by ID.
Your code might look something like this:
[AttributeUsage(AttributeTargets.Class)]
public class CommandAttribute {
public CommandAttribute(int id) {
ID = id;
}
public int ID { get; private set; }
}
public abstract class Command {
public abstract void Execute();
}
[Command(2)]
public class MyCommand : Command {
public override void Execute() {
//Do something useful
}
}
The other advantage of using a custom attribute is that you have to explicitly tag everything that is a candidate for being instantiated and executed by ID, rather than assuming than anything derived from your base class is a candidate. If you are sharing code between the classes, you might want to make a common base class for them that derives from your base class, but should not be instantiated or executed on its own.
One thing I don't understand is, what is the point of the "Name" field if the class you want to run is identified by the ID? If you can decide what the name of each ID is, then you could use the name field as the fully qualified type name of the class you want to execute, which then avoid having to scan through all the types in your assembly (or application domain, depending upon the scope of your search). That setup is a bit more prone to typos, however.
It sounds like you need to implement a factory pattern.
I would define an interface:
public interface IWidget
{
void Foo();
}
Then the base class:
public abstract class WidgetBase : IWidget
{
public void Foo()
{
this.Bar()
}
protected virtual void Bar()
{
// Base implementation
}
}
The factory:
public static WidgetFactory
{
public static IWidget Create(int id)
{
// Get class name from id, probably use the name in your database.
// Get Type from class name
// Get constructor for Type
// Create instance using constructor and return it.
}
}
A derived class:
public class DerivedWidget : WidgetBase
{
protected override void Bar()
{
// call base implementation
base.Bar();
// derived implementation
}
}
In your main:
public void Main(int id)
{
var widget = WidgetBase.Create(id);
widget.Foo();
}
I like #Xint0's idea of using a Factory for this kind of task, but I thought I'd still contribute another answer.
A better way to implement your original design would be to pass the ID to the base constructor as follows:
public abstract class Base {
public Int32 Id { get; private set; }
protected Base(Int32 id) {
this.Id = id;
}
public void Foo() {
// Do something
}
}
public class Derived : Base {
public Derived : base(42) {}
public void Foo() {
// Do something more specific
}
}

Really bizarre C# generics question

This code compiles but looks very strange.
I have a typical and simple parent/child relationship here which is implemented using generics in a very strange way.
But I can't seem to find any other way of doing it.
class SampleObject<T> //I don't want to make this a generic but am forced to
{
//The SampleContainer this object is in
//This must be located in this base class
public SampleContainer<T> Parent { get; set; }
}
class SpecificObject : SampleObject<SpecificObject>
//SampleObject<SpecificObject> !!? This is the bizzare bit
//It seems really strange but necessary for compilation to work
{
}
//A class to contain a List of objects derived from SampleObjects
class SampleContainer<T>
{
public List<T> List;
}
class Start
{
public void Test()
{
SampleContainer<SpecificObject> container = new SampleContainer<SpecificObject>();
SpecificObject o = new SpecificObject(); //create an object
container.List.Add(o); //add it to the list
o.Parent = container; //set its parent
}
}
Can this code be simplified?
This seems to work without the type.
Is this what you were looking for?
class SampleObject //I don't want to make this a generic but am forced to
{
//The SampleContainer this object is in
//This must be located in this base class
public SampleContainer<SampleObject> Parent;//{ get; set; }
}
class SpecificObject : SampleObject
//SampleObject<SpecificObject> !!? This is the bizzare bit
//It seems really strange but necessary for compilation to work
{
}
//A class to contain a List of objects derived from SampleObjects
class SampleContainer<T>
{
public List<T> List;
}
class Start
{
public void Test()
{
SampleContainer<SampleObject> container = new SampleContainer<SampleObject>();
SpecificObject o = new SpecificObject(); //create an object
container.List.Add(o); //add it to the list
o.Parent = container; //set its parent
}
}
In the MSDN documentation, it states that:
When deriving from a generic base
class, you must provide a type
argument instead of the base-class's
generic type parameter:
public class BaseClass<T>
{...}
public class SubClass : BaseClass<int>
{...}
It's probably a constraint that the C# designers set up in the compiler. They require that a derived type must specify the type of the generic argument at compile time. I'm not quite sure why.
Generics can create some unwieldy class hierarchies. However, the syntax for SpecificObject : SampleObject does make sense, since you're stating that the object has a parent relationship. The only other way I could see you do this, would be to split out the hierarchy with an interface. It doesn't buy much, but it may help clarify the intent.
interface IHasParent<T>
{
T Parent { get; set; }
}
public class SpecificObject : IHasParent<SpecificObject>
{
public SpecificObject Parent { get; set; }
}
If you're concerned about how verbose your collection is, you can tame the angle brackets a bit by using:
public SpecificObjectContainer : Container<SpecificObject>
{
}

Categories

Resources