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.
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.
So, I want to create an interface which has a method that can take in any model class. For example
I have these three property class
class A
{
public long id { get; set; }
public string description { get; set; }
public string code { get; set; }
}
class B
{
public long someID { get; set; }
}
class C
{
public long anydesign { get; set; }
}
class D
{
public long Router { get; set; }
}
I have an interface
public interface IModel
{
void Dosomething(A model); // Now in this example it takes the A model,But I want it to be set, so that that class that implements the interface can put any model as required
}
Now, I have a class that implements the mode Since the interface only takes the A model, I can pass in the A model in the class during implementation
public class ImplemenationA: IModel
{
public void Dosomething(A model)
{
Console.WriteLine(model.description);
}
}
Say i have another implemenation Class Now, I am guessing the below one wouldnt work, as the interface signature enforces only to take a Model A and not any other model
public class ImplementationB:IModel
{
public void Dosomething(B model)
{
Console.WriteLine(model.someID);
}
}
I want to the interface method to be invoked by any implementation class and use any model
Based on your description you may want to use Generics. Since you're creating separate implementations you can apply the interface below to achieve a similar result.
public interface IModel<T>
{
void Dosomething(T model);
}
public class ImplementationB : IModel<B>
{
public void Dosomething(B model)
{
Console.WriteLine(model.someID);
}
}
Some sort of Decorator pattern can solve it, postpone your actual implementation to inner classes and insist on separation of concern, please leave a comment if I miss understood your question:
//added to support inner implementation
interface IModelImpl {
void Do();
}
class A: IModelImpl
{
public long id { get; set; }
public string description { get; set; }
public string code { get; set; }
public void Do(){
console.WriteLine(this.description);
}
}
class B: IModelImpl
{
public long someID { get; set; }
public void Do(){
console.WriteLine(this.someID);
}
}
class C: IModelImpl
{
public long anydesign { get; set; }
public void Do(){
...
}
}
Here is your IModel, pretty much the same, considered like an outer implementation:
public interface IModel
{
void Dosomething(IModelImpl model); //put any model as long it implements IModelImpl
}
Your class implementation should now changed to:
public class ImplemenationA: IModel
{
public void Dosomething(IModelImpl model)
{
//Do more specific work to ImplementationA
model.Do();
}
}
Another class implementation:
public class ImplementationB:IModel
{
public void Dosomething(IModelImpl model)
{
//Do more specific work to ImplementationB like validation
model.Do();
}
}
I had abstract base class.
public abstract class TurnBasedGameReferee
{
public ITurnBasedGamePlayer CurrentPlayer { get; private set; }
public TurnBasedGameField PlayingField { get; protected set; }
/*snipped*/
}
And I had inheriting class:
public class TicTacToeReferee : TurnBasedGameReferee { /*snipped*/ }
In TicTacToeReferee I supposed to refer to properties like this:
(ITicTacToePlayer)this.CurrentPlayer;
(TicTacToeGameField)this.PlayingField;
I think, what use of explicit conversions here every time isn't correct.
Is there a way to do so in the context of TicTacToeReferee, these CurrentPlayer and PlayingField were ITicTacToePlayer and TicTacToeGameField type without using explicit conversion every time?
You could use Generics.
public abstract class TurnBasedGameReferee<TPlayer, TField>
where TPlayer : ITurnBasedGamePlayer
where TField : TurnBasedGameField
{
public TPlayer CurrentPlayer { get; private set; }
public TField PlayingField { get; protected set; }
/*snipped*/
}
public class TicTacToeReferee : TurnBasedGameReferee<ITicTacToePlayer, TicTacToeGameField>
It assumes, that ITicTacToePlayer inherits from ITurnBasedGamePlayer and TicTacToeGameField from TurnBasedGameField , but i think was what you was meaning.
Based on Maksim Simkin's answer and your comments you could enforce the type safety you want, but at the cost of an extra generic type parameter and added complexity to your solution:
public interface ITurnBasedGame { }
public interface ITurnBasedGamePlayer<TGame> where TGame : ITurnBasedGame { }
public abstract class TurnBasedGameField<TGame> where TGame : ITurnBasedGame { }
public abstract class TurnBasedGameReferee<TGame, TPlayer, TField>
where TGame: ITurnBasedGame
where TPlayer: ITurnBasedGamePlayer<TGame>
where TField: TurnBasedGameField<TGame>
{
public TPlayer CurrentPlayer { get; private set; }
public TField PlayingField { get; protected set; }
}
And now, considering the following types:
public class TicTacToeGame : ITurnBasedGame { }
public class TicTacToePlayer : ITurnBasedGamePlayer<TicTacToeGame> { }
public class TicTacToeGameField : TurnBasedGameField<TicTacToeGame> { }
public class ChessGame : ITurnBasedGame { }
public class ChessPlayer : ITurnBasedGamePlayer<ChessGame> { }
public class ChessGameField : TurnBasedGameField<ChessGame> { }
The following would be a compile time error:
public class TicTacToeReferee: TurnBasedGameReferee<TicTacToeGame, ChessPlayer, ChessGameField> { }
All that said, this is certainly not worth it just to avoid casting the interface to the concrete type of the class. If you don't like all the casts, then you could always implement private helper properties to clean up your code a little:
public class TicTacToeReferee : TurnBasedGameReferee
{
private TicTacToePlayer CurrentTicTacToePlayer => CurrentPlayer as TicTacToePlayer;
private TicTacToeGameField TicTacToePlayingField => PlayingField as TicTacToeGameField;
....
}
And simply use these properties in your inner implementation.
I have the following two classes:
abstract class LogItem {
public String payload { get; set; }
public String serverId { get; set; }
public DateTime timeRecieved { get; set; }
}
class MyLogItem : LogItem
{
//No I want this to have to have the members from the abstract class above, as if it where an interface?
}
So in other words I am wanting a type if interface that can have definitions or variables which all classes that implement it have to have, but they could add more if they required ?
The above example builds, even if i dono add the members from the abstract class.
edit
Forget what I've said before. These are attributes, not methods. For them to be accessible on derived classes, you make them protected or public. The difference is that public members are visible to the world, while protected ones are visible to the class and subclasses.
Any class derived from your LogItem may have other variables.
abstract class LogItem {
public String payload { get; set; }
public String serverId { get; set; }
public DateTime timeRecieved { get; set; }
}
class MyLogItem : LogItem
{
//No I want this to have to have the members from the abstract class above, as if it where an interface?
private void TestMethod(){
String test = payload;
}
}
check out this post for more information
Your MyLogItem class can reference any of the above members directly. They are accessible
You may declare an interface with those
public interface MyInterface {
public String payload { get; set; }
public String serverId { get; set; }
public DateTime timeRecieved { get; set; }
}
and your class
public class MyLogItem : MyInterface
{
String _payload;
public String payload { get{ return _payload; } set {_payload=value;} }
...
}
The abstract keyword can also be applied to methods, as described here.
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; }