I was wondering if I can dynamically add values set in property using override method. I want to add the values (scores) from properties so that in the end, I can get the total points.
here my code
public abstract class player
{
public string nickName { get; set; }
public virtual int computeScore()
{
throw new NotImplementedException();
}
}
public class Bes : player
{
public int initScore =0;
public int score { get; set; }
public int ttlScore { get; set; }
public override int computeScore()
{
return this.ttlScore += this.score;
}
}
It's doubtful that want you want to do is a good idea. But the fact is, it's not really clear what you want to do.
I have a vague sense that you want, every time the score property is set, to add the value to the ttlScore property. If so, then sure...you can do that, but it's a terrible idea. Using a property to represent that operation would be extremely confusing; instead, you should have a method, e.g. named AddScore(), so it's clear reading the code that every time a score is passed to the method, it will be added to the running total.
For example, something like this:
public class Bes : player
{
public int MostRecentScore { get; private set; }
public int TotalScore { get; private set; }
public int AddScore(int score)
{
this.MostRecentScore = score;
return this.TotalScore += score;
}
}
Then the MostRecentScore property will still show whatever the most recent score was, while the TotalScore property will show the running total, but the class members make it clear that you must call AddScore() to report a new score, and that this will take care of updating both properties of interest.
This example of course does not use the virtual aspect of your code example. It's not clear from your question why the computescore() method was in fact made virtual, and it probably doesn't need to be — if you really want the base class to know about scoring, then the score-related properties belong there as well, and none of the members need to be virtual — so I've left it out.
If this does not address your question, please edit your question so that it's more clear what you're trying to do. Provide a good Minimal, Complete, and Verifiable code example that shows clearly what you've tried, along with a detailed and specific explanation of what the code does, and what you want it to do instead.
Related
I'm migrating a legacy application from C to C# (.NET Core 5), and implementing more modern software development practices. The C application had literally all of its data in structures in RAM, all of which were globally available. This is great for simple applications but violates the heck out of the principle of encapsulation. The closest equivalent of doing this in an object-oriented fashion is to make the datastore static (which I don't want to do, for obvious reasons).
The application at hand is highly technical and involves a great deal of math. The previous application calculated a lot of derived values (sometimes repeatedly!) on demand, however this doesn't take advantage of multi-threading or caching.
To demonstrate a simpler yet analogous example, let's say we have a program to manage the costs associated with a baseball team. A team has its own fixed operating costs, as well as one manager (who has a salary), and zero to many players (who also each have salaries).
This is my redesigned data model:
public class Team {
public int Costs { get; set; }
public Manager Manager { get; set; }
public HashSet<Player> Players { get; set; }
private int _operatingCosts;
public int OperatingCosts {
get {
return this._operatingCosts;
}
private set {
// Note the private setter -- this should only be recalculated within this
// method from its own values.
this._operatingCosts = value;
}
}
}
public class Manager {
public string Name { get; set; }
public int Salary { get; set; }
}
public class Player {
public string Name { get; set; }
public int Salary { get; set; }
}
The C code would have a function that runs and puts its fingers in all of the arrays, finds the appropriate elements, and adds them up. In the rewritten C# code, MOST of these calculations are reasonably simple, so they probably are best implemented as read-only calculated properties.
public class Manager {
public int MonthlySalary {
get {
return this.Salary / 12;
}
}
}
The challenge comes when trying to calculate the total cost of running the team. This might be a complex operation that I don't want to have to run each time, so I'll want to cache a value and only recalculate it when an event fires. We know which variables cause the change, so we can fire the event from within the dependent properties' setters.
public class Team : INotifyPropertyChanged {
private int _costs;
public int Costs {
get {
return this._costs;
}
set {
this._costs = value;
NotifyPropertyChanged(); // Fire recalculation on cost change.
}
}
public int Name {
get; set; // No INotifyPropertyChanged needed; cached values aren't
// dependent on this.
}
private int _totalOperatingCost;
public int TotalOperatingCost {
get {
return this._totalOperatingCost;
}
private set {
this._totalOperatingCost = value;
}
}
protected void RecalculateCosts() {
this._totalOperatingCost = this.Team.Cost + this.Manager.Salary + this.Players.Sum(p => p.Salary);
}
}
This has been working really well with INotifyPropertyChanged -- I fire a PropertyChanged event on fields that should trigger a recalculation, and the recalculation logic is there and in one place, and all is well.
Now here's the problem: what happens if the manager's salary changes?
public class Manager : INotifyPropertyChanged {
private int _salary;
public int Salary {
get {
return this._salary;
}
set {
this._salary = value;
NotifyParentPropertyChanged();
}
}
}
The Manager class does not contain a reference to the Team to which he belongs. There's a lot of potential for error retaining a backreference from the child bean to the parent when the parent knows about its own children. So if I call NotifyPropertyChanged() here, the Manager will update his own calculations but it has no idea it needs to update on the parent. This is also mostly resolvable using events, but there's a big hitch:
public class Team {
public string Name { ... }
private Manager _manager;
public Manager Manager {
get {
return this._manager;
}
set {
if (this._manager is not null) {
this._manager.PropertyChanged -= ProcessParentPropertyChangedEvent;
}
this._manager = value;
NotifyPropertyChanged();
if (this._manager is not null) {
this._manager.PropertyChanged += ProcessParentPropertyChangedEvent;
}
}
}
public Team() {
if (this.Manager is not null) {
this.Manager.PropertyChanged += ProcessParentPropertyChangedEvent;
}
}
public static void ProcessParentPropertyChangedEvent(object sender, EventArgs e) {
// ^^^^^^ THIS IS A STATIC METHOD, so "this" is unavailable.
//
// When called from Manager.Salary, sender.GetType().Name = "Manager" and
// e can ONLY carry information from the Manager and knows nothing about
// the Team.
//
// Literally nothing in this method knows about the current team, or I believe
// can know about the team to which the manager belongs.
}
}
public class Manager {
private int _salary;
public int Salary {
get {
return this._salary;
}
set {
this._salary = value;
NotifyParentPropertyChanged();
}
}
}
The event fires properly but because the callback method is static, there's no link to the Team whose Manager's salary just updated. Player would have a similar problem, there's no way to inform the Team class that a Player's salary updated since the recalculation would take place within a static method.
Similarly, we could need to add or subtract players from the team as well, which should also force a recalculation of our team costs. I've gone down this road some with INotifyCollectionChanged, but no luck -- we still end up in a static method with no information about where the changes need to be applied to.
I believe my options are as follows:
(1) Include backreferences to parent elements. This seems somewhat straightforward, but there is a lot that can go wrong here, and garbage collection may be one of them. There are probably going to be about a million elements in memory, and I'm not sure how well this would perform by everything basically being in a doubly-connected graph.
(2) I've looked into the Mediator pattern, but I'm not convinced this still solves my problems without a great deal of error-prone accounting. It also requires the Mediator class to be injected into all of my data elements, and requires me to use extensions for base .NET generic collections types -- I don't want to be forced to always use custom types like MyPlayersList or similar, instead of the more common List<Player> -- especially when NOT using the custom list would likely end in a subtle and silent bug when a recalculation just didn't quite pull the right values.
What are my options? Am I forced to carry tons of backreferences throughout the model?
Is there a different model for event handling that I'm not aware of? I've been working with INotifyPropertyChanged because I'm used to it from a WPF context and it's really fast -- 1,000,000 calls in 60 ms on my machine. That said I don't know if there are any other event handling paradigms that exist to handle this type of case.
This seems like way too straightforward an issue to not have appeared and been solved by someone else before. Thanks so much!
I am currently working on a game in XNA and I'm not sure on how I should go about doing the following...
I have a base class of buildings as such
public class BuildingsBase
{
private int _hp;
public int hp
{
get { return _hp; }
set { _hp= value; }
}
private int _woodRequired;
public int woodRequired
{
get { return _woodRequired; }
set { _woodRequired = value; }
}
}
I then have multiple subclasses for building types eg.
public class TownHall:BuildingsBase
{
public int foodHeld;
public TownHall()
{
foodHeld = 100;
woodRequired = 500;
}
}
My question is, what is the best way of setting the default values for building subclasses.
For example, the woodRequired for a townhall is set to 500 but at various places in code I need to access this value before I have an instance of townhall declared (When checking if there is enough wood to build).
I currently have a global array of default variables for each building type but im wondering if there is a better way of doing this.
if (Globals.buildingDefaults[BuildingType.Townhall].woodRequired < Globals.currentWood)
{
Townhall newTH = new Townhall();
}
Usually what happens is that they create a flyweight (see pattern). This object contains properties that are the same for every instance anyway. There's no need to change (or actually store) the required amount of wood for each instance separately.
In a very basic design it would look like:
class BuildingTemplate
{
public int WoodRequired { get; set; }
}
class Templates
{
public static BuildingTemplate TownHall { get; set; }
}
In the end you'd be calling a method like:
public bool CanBuildTownHall(Player player)
{
return player.HasEnoughResources(Templates.TownHall);
}
Of course, you can use a dictionary for template retrieval, and players shouldn't really know about building requirements. I'm just illustrating the pattern here.
If the player has enough resources, you can use the template to subtract the amount and create an actual instance of the TownHall. It's nice to have an reference to the actual template, because you'd probably be accessing other global properties that are valid for all TownHalls as well (such as audio/visuals/...).
class TownHall
{
public TownHall(BuildingTemplate template)
{
_template = template;
}
}
A project I'm working on would benefit from having a little more abstraction added to it and I'm faced with a problem I can't seem to get past.
Essentially is we have services that can be assigned and consumed, but the rates at which they are consumed are all a little different. This distinction is important for reporting and for scheduling the consumption of these services.
I'm not really sure how to take data I receive from the database and ensure that the correct concrete type is created. Am I overthinking this and there is something easier I can do? The only thing I can think of doing is having a switch statement determine which type to make based on the unit of time specified, but that seems sloppy.
UnitInterval (which I'm welcome to renaming it something that seems less confusing), is supposed to hold the service's consumption unit (1, 15, 30, 60) and then the UnitSize will be minutes, hours, or days. The UnitSizes are held in a reference table and ID'ed with their appropriate text of Day, Minute, Hour. So in my table Minute has an ID = 1, Hour = 2, Day = 3, and depending on if these intervals need to be adjusted they can be in the future.
How do I get something like the UnitSize from the database and ensure the correct implementation? Am I just going about this the entirely wrong way?
Essentially my end game is that I'll have another class which just contains List<WorkableService> that I can use to spit out a report with the correct units, any costing, duration, etc.
public abstract class WorkableService
{
public int UnitSizeId { get; set; }
public string UnitSizeText { get; set; }
public double UnitInterval { get; set; }
public abstract TimeSpan Duration { get; }
public double UnitsAvailable { get; set; }
public double Adjustment { get; set; }
public decimal Rate { get; set; }
}
public class MinuteService : WorkableService
{
public override TimeSpan Duration
{
get
{
return TimeSpan.FromMinutes(UnitInterval);
}
}
}
public class HourlyService : WorkableService
{
public override TimeSpan Duration
{
get
{
return TimeSpan.FromHours(UnitInterval);
}
}
}
public class DailyService : WorkableService
{
public override TimeSpan Duration
{
get
{
return TimeSpan.FromDays(UnitInterval);
}
}
}
The switch method is totally valid, if you know for sure at compile time all the options you might need. More basic info at the Wikipedia factory pattern, but switching on an enum value or a string identifier is the general concept.
Alternatively, look into Activator.CreateInstance, which you can use to create a new object based on the type's name that you might dynamically load from the database. We do that in some situations to let us add new supported types without recompiling the base service.
The switch statement you refer to as sloppy is something called the Factory pattern. Assuming your WorkableService base constructor takes UnitInterval:
static class WorkableServiceFactory
{
public static WorkableService Get(int unitSizeId, double unitInterval)
{
switch (unitSizeId)
{
case 1:
return new MinuteService(unitInterval);
case 2:
return new HourlyService(unitInterval);
case 3:
return new DailyService(unitInterval);
default:
throw new ArgumentOutOfRangeException("unitSizeId");
}
}
}
I'm usually not a fan of factories (they're the butt of every Java EE joke in the book for a reason), but this is actually a valid scenario for it.
As the code illustrates, passing down parameters is a rather frequent task. Instead of writing them by hand, is there a way to auto-generate the list isPriority, label, id, start, user with Resharper, Visual Studio natively, or another add-on?
public void TransformAndStore(
bool isPriority,
string label,
string id,
DateTimeOffset start,
string user)
{
if (this.IsValid(id)) {
label = this.Clean(label);
this.Reposit(isPriority, label, id, start, user);
}
}
The list generated should be based on the method signature, listing all parameters of the method without their types, in the order they appear.
Additionally, if the Reposit method were to use some but not all of the same parameters available in the calling method scope, as identified by parameter/variable names, then autocompleting that would speed up coding as well, and reduce RSI :)
You could create a class to store all the parameters so you only need to pass a single item around. Resharper can do this for you automatically by using Refactor -> Extract -> Extract class from parameters.
Also if you are always repeating the same groups of parameters, consider moving the methods that act upon them into the class too. Logically grouping the data with the methods can be a good practice. For example:
public class CleverName
{
public bool IsPriority { get; set; }
public string Label { get; set; }
public string Id { get; set; }
public DateTimeOffset Start { get; set; }
public string User { get; set; }
public bool IsValid()
{
//Check if Id is valid
}
public void TransformAndStore()
{
if (this.IsValid()) {
Label = this.Clean(Label);
this.Reposit();
}
}
public void Reposit()
{
}
}
While it doesn't answer the exact question you're asking, take a look at ReSharper's Smart Completion. It will filter the available items for completion based on the current context, and is often really good at suggesting exactly the right parameter to pass through.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
I was thinking about language constructs and how when we talk about classes and objects in Object oriented languages we draw comparisons to real world. Like when people talk of Inheritance people would quote an example of Parent and Children. One thing that i don't find in OO languages that i know , mainly C, C++, C#, is that they don't have a mechanism to declare a property as mandatory. What i mean by that is I cannot define a class called human and say that face, hands and lets say eye are mandatory property of my class. By having that construct i can enforce that anyone who is using my class need to set those properties before using my class. If user forgets to set those properties then i should get an compile time error.
Just wanted to see community thoughts on that.
Here is reason why i had asked above question:
When i build my user controls, i want to make sure that users should set some of the properties in their code when they use my control. For example, lets say i build a customer user control that would be used by other developers in my team. Some of the properties that i have exposed are: "CustomerId", "FirstName", "LastName", "Address1", "City", "State" and ZipCode. Now i want to make sure that any consumer of my control should set "CustomerId". Using Constructor to enforce that the value is set is a way but it will throw a run time exception plus how would user call that constructor from .cs file without dynamically creating the control and adding it to control collection.
You can do that, with a DDD principle: create a class with a private default constructor, and a public constructor that accept required parameters and validate its values. If a value is invalid, throw an exception so that the object cannot be created. Properties could also have private setters instead of public setters.
You can also create a 'Mandatory' attribute and put those on top of the properties that are mandatory; and have a mechanism that checks this based on whether a property has been decorated with the attribute or not.
Example:
public class BlogEntry
{
private BlogEntry() {}
public BlogEntry(string title, string body)
{
LastModifiedDate = DateTime.Now;
Title = title;
Body = body;
var blogEntryValidator = new BlogEntryValidator();
blogEntryValidator.ValidateAndThrow(this);
}
public int Id { get; private set; }
public string Title { get; private set; }
public string Body { get; private set; }
public DateTime? LastPublishDate { get; private set; }
public DateTime LastModifiedDate { get; private set; }
public virtual ICollection<Comment> Comments { get; private set; }
public void Publish()
{
LastPublishDate = DateTime.Now;
}
public void Unpublish()
{
LastPublishDate = null;
}
public void Modify(string title, string body)
{
Title = title;
Body = body;
LastModifiedDate = DateTime.Now;
}
public Comment AddComment(string commentText, string emailAddress, string name)
{
var comment = new Comment(this, commentText, emailAddress, name);
if (Comments == null) Comments = new List<Comment>();
Comments.Add(comment);
return comment;
}
public void RemoveComment(Comment comment)
{
Comments.Remove(comment);
}
}
public class Comment
{
private Comment() {}
public Comment(BlogEntry blogEntry, string name, string emailAddress, string commentText)
{
BlogEntry = blogEntry;
Name = name;
EmailAddress = emailAddress;
CommentText = commentText;
DateWritten = DateTime.Now;
var commentValidator = new CommentValidator();
commentValidator.ValidateAndThrow(this);
}
public int Id { get; private set; }
public string Name { get; private set; }
public string EmailAddress { get; private set; }
public string CommentText { get; private set; }
public DateTime DateWritten { get; private set; }
public BlogEntry BlogEntry { get; private set; }
}
Yes, C++ and C# allow for this via constructors.
class A
{
public:
A(int x, int y, int z)
: _x(x_, _y(y), _z(z) {}
private:
int _x;
int _y;
int _z;
};
You cannot create an instance of A without providing values for _x, _y, and _z.
The reason is that state needed to fulfil class invariants should be provided during object construction, so you should provide values of 'mandatory' properties as constructor parameters. Your question is based on false assumption that an object is characterized by setting state with properties. This is wrong for a handful of reasons, some of which are:
many, if not most OO languages have no properties: Java, C++,...
what you use is only formally an object, it is actually a plain record and it is not very object oriented, same as e.g. C++ struct without methods (see notes at the bottom about setters vs methods)
Allowing the client to create instances of the objects which are only later set up with correct values for mandatory state is sure-fire way to spend many hours in company of debugger.
Let's take some User with invariant that first and last name must always be set.
class User {
public User(string first, string last) { ... }
public User(string first, string last, uint age) : this(first, last) { ... }
}
// client code:
var user = new User("john", "doe");
var user2 = new User("Clint", "Eastwood", 82);
Compiler ensures that no one can instantiate the object without fulfilling the invariants.
Now compare it with your approach:
class User {
public User(string first, string last) { ... }
public User(uint age) { ... }
[Mandatory] public string FirstName { get; set; }
[Mandatory] public string LastName { get; set; }
}
// client code:
var actor = new User(82); // << invalid
actor.FirstName = "Clint";
actor.LastName = "Eastwood"; // << valid
This approach results in more code and allows for a period of time (between << invalid and << valid) where your object is not in a valid state. What if some of property setters throw an exception? You are left with broken object instance floating around. Do you expect the compiler to also verify that code in the setter can not throw? Do you think it is even possible? Besides that, every client which instantiates User instances must check what are the mandatory properties and make sure to set all of them. This effectively breaks encapsulation.
IMO, property setters should be rare, unlike getters. I believe that in such a class you should not have setters for FirstName/LastName, only getters. Instead there should be a method SetName(string first, string last) if you really want to allow name changing. Here's why:
// lets rename actor
actor.FirstName = "John";
actor.LastName = "Wayne";
If the last line throws, you are left with John Eastwood, an actor I have never heard about. With actor.SetName("John", "Wayne") this can't happen.
Additionally, what about property which have dependency in order you specify them, e.g.
obj.ErrorCode = 123; // imagine that error code must be != 0
obj.ErrorMsg = "foo"; // in order to be allowed to set error code
Would you also introduce attributes for that instead of having obj.SetErrorInfo(123, "foo")? This makes it obvious that properties break encapsulation as the order is caused by the implementation detail, unlike with method call.
Quite often, in languages like C#, required state or dependencies is provided in constructor while optional state can be set through properties. However, it is not properties or inheritance which make a language object-oriented.
Sure you can! Just use parameters in constructor to denote which are mandatory.
public class Human
{
public Face Face { get; set; }
public Hand Hand { get; set; }
public Human(Face face, Hand hand) {} etc...
}
In this instance, you cannot use the private constructor, so these properties are essentially "mandatory" in order to use the Human class.