This all got a little trickier than I had intended. I'm using the HistoricalReportWrapper class because I retrieve my data through an API which has made it not realistic to have HistoricalReport implement IReport directly.
public abstract class CormantChart : Chart
{
public abstract IReport Report { get; protected set; }
}
public abstract class HistoricalChart : CormantChart
{
public override HistoricalReportWrapper Report { get; protected set; }
public HistoricalChart(HistoricalChartData chartData) : base(chartData)
{
Report = GetHistoricalReport(chartData.ReportID);
}
protected HistoricalReportWrapper GetHistoricalReport(int reportID)
{
return SessionRepository.Instance.HistoricalReports.Find(historicalReport => int.Equals(historicalReport.ID, reportID));
}
}
public class HistoricalReportWrapper : IReport
{
public HistoricalReport inner;
public int ID
{
get { return inner.ID; }
set { inner.ID = value; }
}
public string Name
{
get { return inner.Name; }
set { inner.Name = value; }
}
public HistoricalReportWrapper(HistoricalReport obj)
{
inner = obj;
}
}
public interface IReport
{
string Name { get; set; }
int ID { get; set; }
}
The idea here is that when I am working inside of the HistoricalChart class I need to be able to access specific properties of the HistoricalReport. The rest of my program, however, only needs to have access to the HistoricalReport's ID and Name. As such, I would like to expose IReport's properties to the world, but then keep the details contained to the class.
As it stands, all the classes which inherit HistoricalChart generate a "does not implement inherited abstract member" as well as a warning on HistoricalChart indicating that I am hiding CormantChart's Report.
What's the proper way to declare this to achieve what I'd like?
Thanks
EDIT: Whoops, I missed an override. Now, when I try to override CormantChart Report I receive:
'CableSolve.Web.Dashboard.Charting.Historical_Charts.HistoricalChart.Report': type must be 'CableSolve.Web.Dashboard.IReport' to match overridden member 'CableSolve.Web.Dashboard.Charting.CormantChart.Report' C
EDIT2: Taking a look at C#: Overriding return types might be what I need.
Because
public HistoricalReportWrapper Report { get; protected set; }
is not an implementation of
public abstract IReport Report { get; protected set; }
Related
Say I have the following classes:
public abstract class A
{
protected abstract ReturnA Foo();
public void UseFoo()
{
var foo = Foo();
if (foo != null)
{
//logic here
}
}
}
public class B : A
{
protected override ReturnA Foo()
{
// Implementation specific code that returns ReturnB instead.
}
}
public class C : A
{
protected override ReturnA Foo()
{
// Implementation specific code that returns ReturnC instead.
}
}
public class ReturnA
{
public int Id { get; set; }
public string Address { get; set; }
}
public class ReturnB
{
public string Id { get; set; }
public string PhoneNumber { get; set; }
}
public class ReturnC
{
public Guid Id { get; set; }
public string Name { get; set; }
}
I know that C# does not support derived return types, but this is not what I need either.
Classes B and C are implementation specific and therefore their return types have nothing to do with eachother.
The reason why I would want to handle this, is because the method UseFoo in class A may have some generic checks and other generic logic, that has nothing to do with the returned object itself.
So I want to "outsource" only the code that is implementation specific and not have to instead make UseFoo abstract and have every implementation write the same generic code.
Is there any way to solve this at all?
EDIT: Neither ReturnC nor ReturnB are derived from ReturnA. Updated with examples.
I can't use override since the types don't match and I've read I shouldn't use new to hide it, so how would I accomplish this?
SearchBase and ResultBase will work for 80% of my entities but a few will need specific implementations.
This main problem I see is when I do use new it's all typed during compile time and looks good in the debugger but passing this object to System.Web.Mvc.Controller.Json() seems to have a problem serializing it and they come out null.
public class SearchBase<T>
{
public virtual ResultBase result { get; set; }
}
public class SearchImp : SearchBase<SearchImp>
{
public override ResultImp result { get; set; }
}
public class ResultBase
{
}
public class ResultImp : ResultBase
{
}
You could use this instead:
public class SearchBase<T, TResult> where T: ResultBase
{
public TResult result { get; set; }
}
public class SearchImp : SearchBase<SearchImp, ResultImp>
{
public TResult result { get; set; }
}
public class ResultBase
{
}
public class ResultImp : ResultBase
{
}
This way you don't need to override anything (nothing really to override here) and you can keep it type-safe.
Slight newbie question.
I have a base class for payments. All share the same properties apart from additional extras. One of the properties is a postUrl. In the base this is empty but in the child classes each one has its own url. This should not be allowed to be accessed from outside the classes and it fixed and should not change. How do I go about overriding the property in a child class?
e.g.
class paymentBase
{
public int transactionId {get;set;}
public string item {get;set;}
protected virtual postUrl = String.empty; // can't be accessed from outside inheritance / public / protected?
public void payme();
}
class paymentGateWayNamePayment : paymentBase
{
protected override postUrl {
get { return "http://myurl.com/payme"; }
}
}
How would I go about doing this?
Thanks in advance
You should be able to accomplish it if you make your postUrl an actual virtual property, like this:
class paymentBase
{
public int transactionId {get;set;}
public string item {get;set;}
protected virtual postUrl { get { return String.Empty; }}
public void payme();
}
class paymentGateWayNamePayment : paymentBase
{
protected override postUrl {get { return "http://myurl.com/payme"; } }
}
I know this is a late entry but if you want the postUrl value to be set once by the sub class and then never again you need to make it a private value to the base class.
abstract class paymentBase
{
public paymentBase(string postUrl) { this.postUrl = postUrl; }
public int transactionId { get; set; }
public string item { get; set; }
protected string postUrl { get; private set; }
public void payme();
}
class paymentGateWayNamePayment : paymentBase
{
public paymentGateWayNamePayment() : base("http://myurl.com/payme") { }
}
Based on your requirements, I would recommend using an interface because posturl is a generic property that can be used on anything e.g. a page post back, a control post back, your class might use it etc.
This interface can be used as needed by any class.
interface IPostUrl
{
string postUrl { get; }
}
class paymentBase
{
public int transactionId {get;set;}
public string item {get;set;}
public void payme(){}
}
class paymentGateWayNamePayment : paymentBase, IPostUrl
{
public string postUrl
{
get { return "http://myurl.com/payme"; }
}
}
I have class:
internal class Stage
{
public long StageId { get; set; }
public string StageName { get; set; }
public int? Order { get; set; }
public Stage()
{
Order = 0;
}
}
I have also:
public class GroupStage : Stage
{
private override long StageId { set { StageId = value; } }
public GroupStage() : base() { }
public void InsertStage(long groupId)
{
}
public static void SetStageOrder(long stageId, int order)
{
....
}
public static void DeleteStage(long stageId)
{
....
}
public static GroupStage[] GetStages(long groupId)
{
....
}
}
and:
public class TaskStage : Stage
{
public DateTime? Time { get; set; }
public TaskStage()
: base()
{
....
}
public static Stage GetNextTaskStage(Guid companyId, long taskId)
{
....
}
public static Stage[] GetTaskStages(Guid companyId, long taskId)
{
....
}
}
This is not working and I get the exception:
Inconsistent accessibility: base class Stage is less accessible than class GroupStage
I want Stage class to be private and without access except to GroupStage and TaskStage. I also want to make StageId be private in GroupStage and in TaskStage.
How can I do that without duplicate the members of Stage in GroupStage and in TaskStage?
You can't make a derived class more accessible than it's base class. What you can do is make TaskStage and GroupStage internal as well, then inherit and expose public interfaces so that only the interface is visible outside of your assembly.
public interface IGroupStage
{
public string StageName{ get; set; }
...
}
interal class GroupStage : IGroupStage
{
...
}
You need to make you Stage class public or protected. if you make it abstract it cant be instantiated on that level, so if its public you dont have to worry about it being created as a base class
Make it protected instead of private. If you make it protected, you let classes that inherit from it call methods on the base class, and inherit the base class members.
What you probably actually want is for Stage to be an abstract base class which, therefore, cannot directly be instantiated regardless of its accessibility modifier. Change your definition of Stage:
public abstract class Stage
{
protected long StageId { get; set; }
public string StageName { get; set; }
public int? Order { get; set; }
protected Stage()
{
Order = 0;
}
}
The protected modifier means that your derived classes will be able to access that member, but it will not be accessible outside those classes.
I am fairly new to inheritance and wanted to ask something. I have a base class that has lots of functionality that is shared by a number of derived classes.
The only difference for each derived class is a single method called Name. The functionality is the same for each derived class, but there is a need for the Name distinction.
I have a property in the base class called Name. How do I arrange it so that the derived classes can each override the base class property?
Thanks.
Declare your method as virtual
public class A
{
public virtual string Name(string name)
{
return name;
}
}
public class B : A
{
public override string Name(string name)
{
return base.Name(name); // calling A's method
}
}
public class C : A
{
public override string Name(string name)
{
return "1+1";
}
}
Use a virtual property:
class Base
{
public virtual string Foo
{
get;
set;
}
}
class Derived : Base
{
public override string Foo
{
get {
// Return something else...
}
set {
// Do something else...
}
}
}
You can declare it with a virtual or abstract keyword in the base class, then the derived class can over-ride it
you need to declare your property (in the base clase) as virtual
To enable each derived class to override the property you just need to mark the property as virtual
class Base {
public virtual Property1 {
get { ... }
set { ... }
}
}
Well I'm not sure from your description that inheritance is actually the right solution to the problem but here's how you make it possible for a property to be overridden:
class Base
{
public virtual string Name { get; set; }
}
But do you need it to be writable? A readonly property may make more sense in which case this might work:
class Base
{
public virtual string Name
{
get { return "BaseName"; }
}
}
class Derived : Base
{
public override string Name
{
get { return "Derived"; }
}
}
In the base class:
public virtual string Name { get; set; }
In the derived classes:
public override string Name { get; set; }
However, if the only difference between the classes is that they have different names, I'd argue that instead of inheritance you should just use the base class with the Name set in the constructor:
e.g.
public class MyObject
{
public string Name { get; private set; }
public enum ObjectType { TypeA, TypeB, ... }
public MyObject(ObjectType obType)
{
switch (obType)
{
case ObjectType.TypeA:
Name = "Type A";
// and so on
}
}
}