Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I just found a class named HmeRevisionTracker that a colleague created. It merely contains a List<> of simple objects. CSimCharge, one of the most important classes in this project, contains an HmeRevisionTracker object as a public property declared like this:
public HmeRevisionTracker RevisionTracker { get; private set; }
There is no reason why the object cannot be created in the CSimCharge constructor, since the HmeRevisionTracker is completely hard-coded, and nothing will ever change it. But it isn't created there. Instead, it's initialized to jull. It's not created until it is used:
void CheckForHeatModelRevision()
{
// Find the next revision that needs to be performed
if (RevisionTracker == null && UseModel)
RevisionTracker = new HmeRevisionTracker(ActualBase.CoilLoad, ActualBase.IsHeating);
As far as I know, there's no problem with this, but I'm curious. Is there some disadvantage to this code that I'm not aware of?
Implementation shouldn't matter for this question, but here is some of it anyway:
public class HmeRevisionRule
{
public double CheckPointThreshold { get; private set; }
public bool RevisionNeeded { get; set; }
public bool IsHeatingRule { get; private set; }
public bool IsCoolingRule { get { return !IsHeatingRule; } }
public HmeRevisionRule(double threshold, bool isHeatingRule)
{
CheckPointThreshold = threshold;
RevisionNeeded = true;
IsHeatingRule = isHeatingRule;
}
}
public class HmeRevisionTracker
{
public LinkedList<HmeRevisionRule> CheckPointRules { get; private set; }
public HmeRevisionTracker(CSimCoilGroup coilLoad, bool isHeating)
{
CheckPointRules = new LinkedList<HmeRevisionRule>();
// Default Heating & Cooling Check Points
CheckPointRules.AddLast(new HmeRevisionRule(1.0 / 2.0, true));
CheckPointRules.AddLast(new HmeRevisionRule(3.0 / 4.0, true));
CheckPointRules.AddLast(new HmeRevisionRule(7.0 / 8.0, true));
CheckPointRules.AddLast(new HmeRevisionRule(15.0 / 16.0, true));
CheckPointRules.AddLast(new HmeRevisionRule(63.0 / 64.0, true));
CheckPointRules.AddLast(new HmeRevisionRule(1.0 / 2.0, false));
CheckPointRules.AddLast(new HmeRevisionRule(3.0 / 4.0, false));
CheckPointRules.AddLast(new HmeRevisionRule(7.0 / 8.0, false));
CheckPointRules.AddLast(new HmeRevisionRule(15.0 / 16.0, false));
CheckPointRules.AddLast(new HmeRevisionRule(63.0 / 64.0, false));
Initialize(coilLoad, isHeating);
}
Initialization sets individual rules depending on the state of the charge. Other methods of the class retrieve the required rule or change settings of a rule.
This is called Lazy Initialization, and is a common practice to improve performance. Labeling it "good" or "bad" is subjective, and dependent on the context in which it's being used.
In your example, it's possible that the HmeRevisionTracker class may be expensive to initialize and therefore it should only be done when it's actually needed. There also may be some other implications when RevisionTracker is null that other code may rely on (i.e. it may indicate that other methods have not been called yet, describing some internal state).
There is an article on the topic of lazy initialization topic here, which states, in part:
Lazy initialization is primarily used to improve performance, avoid wasteful computation, and reduce program memory requirements. The most common scenarios are:
When you have an object that is expensive to create, and the program might not use it.
When you have an object that is expensive to create, and you want to defer its creation until after other expensive operations have been completed.
As mentioned in the article, there is a Lazy<T> class that was introduced in .NET 4.0 which could be used to make this more intentional and possibly reduce lines of code.
Finally, in regards to your statement:
There is no reason why the object cannot be created in the CSimCharge constructor
Microsoft's Member Design Guidelines on Constructor Design state:
✓ DO minimal work in the constructor.Constructors should not do much work other than capture the constructor parameters. The cost of any other processing should be delayed until required.
(thanks #madreflection for this part!)
It is my personal opinion that an object should be "ready to use" when the constructor finishes with it: that the List object should therefore be built in the constructor. The handful of nanoseconds required to do this, today, do not matter. But the unexpected runtime errors and resulting (production?) application crashes could cost a lot of money. Construct all the necessary things in the constructor, even if they are not used, and tear them down in the destructor.
If the attribute is private and might not actually be used, expressly initialize it to null. The single most-important thing is that the value is not unpredictable. ("It isn't zero, and yet it isn't any good.")
Related
I realize this is probably a very stupid question but the documentation on Reactive Extensions is both opaque and scattered.
Suppose I have a class
public class Foo
{
public int FooState {get;set;}
}
and FooState is updated very frequently. This looks like an ideal case for an IObservable, especially since I'll have to track that state in another class.
public class Bar
{
public Foo Foo {get;set;}
private void DoStuffWithFooState()
{
//operate on Foo.FooState here
}
}
Now, I can't change FooState into an IObservable<int> because that would break other stuff that relies on Foo.
What I'd like to do is is declare an IObserver property on Bar that watches FooState.
Isn't this a basic use case? How do I go about it?
You can use a BehaviorSubject to allow you to turn the property into both an observable stream and a property from which you can just read the latest value.
public class Foo
{
private readonly BehaviorSubject<int> _fooSubject = new BehaviorSubject<int>(0);
public int FooState
{
get => _fooSubject.Value;
set => _fooSubject.OnNext(value);
}
public IObservable<int> ObservableFooState => _fooSubject;
}
If the value of FooState is changing frequently then you'll probably want to use the Sample operator prior to subscription. E.g.
//print out value every two seconds
foo.ObservableFooState
.Sample(TimeSpan.FromSeconds(2))
.Subscribe(Console.WriteLine);
Note that a common mistake is to use Throttle and then wonder why you hardly ever get any events! (The reason is that Throttle resets the timeout every time a new event arrives so when the stream is updated frequently you'll never exceed the timeout value.)
Although it's old and slightly outdated in parts, I find this guide to be very useful when trying to learn about Reactive. The Rx HOL is even older and even more outdated but still a very useful conceptual introduction - just don't take the code samples too literally.
If this class is actually a ViewModel, you might want to consider ReactiveUI but I would suggest steering away from that until you are really comfortable with Reactive.
Note that I haven't shown Dispose/Completion logic above. You should consider when (if ever) you want to call OnCompleted on _fooSubject. Also bear in mind that subscriptions are disposable and you probably want to ensure you dispose of them when your subscribers go out of scope.
This question already has answers here:
Is it abusive to use IDisposable and "using" as a means for getting "scoped behavior" for exception safety?
(12 answers)
Closed 8 years ago.
Background:
Similar to this question, I am looking to use IDisposable for something other than what it was designed for.
The goal:
The application for this isn't terribly relevant, but just for a good example: I have a Windows Forms application where I implement an Undo design pattern. Typically that is done by intercepting "Value Changed" sorts of events from UI elements. For a DataGridView, CellEndEdit and so forth. However there are cases in which I programmatically change data, and I want to do the things each Undo action tracks, without tracking them.
So far:
I have a way to do all that, but I manage my "Should I Undo" logic on a count:
private int _undoOverrides = 0;
public bool ShouldUndo { get { return _undoOverrides < 1; } }
public void DoNotUndo() { ++_undoOverrides; }
public void ResumeUndo() { --_undoOverrides; }
Now, this works well but you have to remember to call ResumeUndo() at the end of such business logic that begins with DoNotUndo(). And I thought:
Maybe I'm not too much of an idiot to screw that up, but what if I had to expose this interface in code I pass down? I would like if the compiler could take care of this for me, if possible.
The idea:
I am considering using a class implementing IDisposable for this. That way, a user of my code could use a using block and never worry about housekeeping chores. This is what I have so far:
private static int _refCount = 0;
public static int ReferenceCount { get { return _refCount; } }
class HallPass : IDisposable
{
protected bool bActive;
public HallPass()
{
++Program._refCount;
bActive = true;
Console.WriteLine("Acquired hallpass!");
}
public void Dispose()
{
if (bActive)
--Program._refCount;
bActive = false;
Console.WriteLine("Hallpass expired!");
}
}
I included a boolean so that I'm sure I don't double-count back down on Dispose(). So all you have to do to use a HallPass is:
using (new HallPass())
{
// do things...
}
The question is:
Is this a good idea? Why might this be a bad idea? Any gotchas I should know about?
Also, and I feel stupid for this, but I'm pretty sure reference count is not the right term for it. It's like a reference count, but there's no reference to manage or memory to free. Edit: It could be, it's just not right now.
It's like a mutex or a critical section in that you're trying to make an exception (another misnomer, because I don't mean the kind you throw) to a rule during a section of code, but it's not either of those because they're meant to be mutually exclusive within a scope--this is designed to be done in a nested fashion if you wish. That's why it's a count, not a boolean.
The first concern of mine is Program._refCount can be accessed from more than one threads and it is not being synchronized. But you can argue that your application is single threaded.
The next and bigger concern is you are not really using the disposable pattern in the way it is supposed to be used. I personally believe that using a pattern in the way it should be used is important, especially when you are not the only person who is working on the code.
Instead of remembering to call ResumeUndo(), now you need to keep in mind that you must call Dispose(). Question is: will it be natural for your team members to realize that they need to call Dispose () when they want to use the HallPass? (using statement is nice, but it cannot be used in every scenario. If there is a HallPass who lives longer than the scope of a single method, you cannot wrap it in a using statement)
Although it is bad to forget call Dispose() on IDisposible, it usually does not affect the correctness of your program - yes, your program will have performance problems, leaks etc., but functionally it usually is still correct. However for your HallPass, if anyone forgets to call Dispose(), I suppose there will be a functional bug. And the bug is hard to trace.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
What are the possible alternatives of global variables and which one is best one?
As I have heard that use of global variable is not good.
I am working on WCF application and there is possibility of multiple instances of WCF and little chances that I will use concurrency.
This WCF service will be deployed to a server and then a client will send a series of request but request one has some unique request which should be maintained in remaining requests.
As mentioned in the comments, there are no global variables but static properties/fields of a class are something that is close to what meant.
Be very careful of using any static properties/fields (static members that hold state) in WCF code. Each WCF call is a separate thread in the same process and as such they will share the values of static properties/fields. This may lead to unpredictable results and hard to debug problems.
...little chances that I will use concurrency
Your code is almost always concurrent if it's running in WCF. Be extremely careful.
You could use a threading mode that would help you in this case (single concurrency mode) but you still need to design your system carefully.
The "more global" a variable is, the easier it is to access it. However, as soon as every component in your application accesses it, your application depends more and more on that variable. You can't change the variable, because it's being used everywhere.
Automated tests become ugly and require modification with each modification to your application, and you can't reuse any component that uses the global variable.
If you do want to use "global variables" (public static members) try to limit its use as much as possible, for instance when you're creating an instance of a class, supply the value of the variable to its constructor, so that class won't depend on the "global" reference.
In more detail, say you have this class:
public class MyUsefulClass
{
public void DoSomethingUseful()
{
Console.WriteLine("The value is: " + MyGlobalVariables.Variable1);
}
}
new MyUsefulClass().DoSomethingUseful();
Then you can only use MyUsefulclass if you can reference MyGlobalVariables.Variable1. You can't reuse MyUsefulclass in a different project that does not have these globals.
Rewriting it to:
public class MyUsefulClass
{
public MyUsefulClass(string valueToWrite)
{
ValueToWrite = valueToWrite;
}
public string ValueToWrite { get; private set; }
public void DoSomethingUseful()
{
Console.WriteLine("The value is: " + ValueToWrite);
}
}
new MyUsefulClass(MyGlobalVariables.Variable1).DoSomethingUseful();
new MyUsefulClass("I don't need globals!").DoSomethingUseful();
In this case, you can reuse MyUsefulClass without requiring the globals to be present in your new project. You still have a "global"-ish variable, but with this modification less code depends on "it being global".
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
I've searched google and stackvoverflow to get the answers but it all boils down to: Create methods.
I want my code to be reusable. I don't want to create other methods in the same class. This class already contains a lot of code. How can I reduce the complexity while have a readable class?
I thought about creating another class and having all the new methods there.
The code
public Issue GetIssue(int issueId, IssueOption issueOption)
{
string resource = "issues/{id}.xml?";
if (issueOption.IncludeRelation)
{
resource += "include=relations&";
}
if (issueOption.IncludeChildren)
{
resource += "include=children";
}
//To fetch multiple associations use comma (e.g ?include=relations,journals
RestRequest request = new RestRequest(resource);
request.AddParameter("id", issueId, ParameterType.UrlSegment);
Issue issue = Execute<Issue>(request);
if (issueOption.IncludeVersion)
{
issue.Fixed_version = GetVersion(issue.Project.Id);
}
if (issue.Parent != null && issueOption.IncludeParent)
{
issue.Parent = GetIssue(issue.Parent.Id, issueOption);
}
if (issueOption.IncludeUsers)
{
if (issue.Author.Id == issue.Assigned_to.Id)
{
issue.Author = GetUser(issue.Author.Id);
issue.Assigned_to = issue.Author;
}
else
{
issue.Author = GetUser(issue.Author.Id);
if (issue.Assigned_to != null)
{
issue.Assigned_to = GetUser(issue.Assigned_to.Id);
}
}
}
if (issueOption.IncludeProject)
{
issue.Project = GetProject(issue.Project.Id);
}
return issue;
}
The road to readable code is very rough out of legacy code.
First off, you should have tests that fully cover the code you are refactoring otherwise you end up traversing that rough road in a blinding blizzard -- it's possible but not fun and very dangerous.
Once you've covered your butt there, you can start the refactorings. By and large, most of the early refactorings (assuming a lot of similar methods to what you have above) will be Extract Method. From there, some class behaviors should start becoming apparent and you can extract them out then.
I thought about creating another class and having all the new methods there.
This is analogous to cleaning your room by pushing everything under the bed. The room is clean but you've only hidden the mess. Don't do without any thought otherwise you'll end up with a Utility class that's even worse than what you have now.
From an OOP-perspective, working towards a SOLID solution is generally desired. The key tenet to focus on from a legacy standpoint is Single Responsibility for your classes. If you have that, the O-L-I-D tend to just fall into place (from my experience, though I've had way more brownfield development experience than I'd really like).
This class already contains a lot of code.
...
I thought about creating another class and
having all the new methods there.
That is exactly what you should do.
As you mentioned, breaking the code into smaller methods is the way to go. How about organizing your code using static extension methods, seeing as how Issue is the main subject of the code:
// top-down:
RestRequest request = GetRequestForIssueOption(issueId, issueOption);
Issue issue = Execute<Issue>(request);
// make it fluent...
return issue.SetVersion()
.SetParent()
.SetUsers()
.SetProject();
I think static extension methods make sense to use. Personally, I think making the static extensions fluent helps bring further clarity to code, not sure if that's your cup of tea though.
public static Issue SetVersion(this Issue issue_)
{
// code here
}
public static Issue SetParent(this Issue issue_)
{
// code here
}
public static Issue SetUsers(this Issue issue_)
{
// code here
}
public static Issue SetProject(this Issue issue_)
{
// code here
}
In existing code of my project, at number of places the property is declared like this:
public long ResourceID
{
get
{
return this.resourceID;
}
set
{
if (this.resourceID != value)
{
this.resourceID = value;
}
}
}
Note: private long resourceID is already declared.
Properties not only of value types but also of reference types (including string) too are declared like this.
Another example:
public Collection<Ability> Abilities
{
get
{
return this.abilities;
}
set
{
if (value == null)
{
throw new ArgumentNullException("Abilities");
}
this.abilities = value;
}
}
As per my knowledge, the setter in the first example does not make any sense and the if condition is meaningless there. So i decided to change the code (as part of refactoring) to make them Auto-Properties. (In second example I need setter since exception is handled there.)
I want to know from experts here, will whether making existing properties auto properties (or at least removing if condition from setter) cause any harm? Sometimes there are subtle things which a developer may not be aware of and some changes can have side effects too. That's why I am asking this question. (My libraries are used at many places.)
Note: Let me know if this is purely a homework question.
Converting:
private long resourceID;
public long ResourceID
{
get
{
return this.resourceID;
}
set
{
this.resourceID = value;
}
}
into:
public long ResourceID { get; set; }
won't cause any harm, guaranteed.
Removing the if statement might cause harm. For example in WPF when working with the MVVM pattern and implementing the INotifyPropertyChanged interface it is often good practice to check whether the value has changed before actually setting it. Removing this check will provoke notifications to be sent to the UI no matter whether the value changed or not. So it would be a breaking change.
I can only think of one kind of problem you could run into (which is fixable):
If you are using ORM or other external tool, they might rely on a naming convention for finding properties/fields. So, the 3rd party dll might be looking for a field resourceId that no longer exists.
So, code using reflection to access fields might break, but if you have control over the codebase, that is unlikely to be an issue.
There are some edge-cases where this might cause harm:
Changing to an automatically implemented property {get;set;}
if you are using field-based serialization at any point (for example, BinaryFormatter), then this will break when changing to an automatically implemented property, as the field-name will change. This will also impact any other scenario that uses reflection to access the (hopefully private) fields, but BinaryFormatter is the most common cause of confusion here.
Removing the if test
will be fine for most data-types such as long etc, however, if you use it with a type that implements a custom equality operation, you might find you are suddenly swapping a reference when previously (with the if) the objects reported equal for different references
The first is a more likely problem. If you are using BinaryFormatter, then keep the private field (byt maybe remove the if test). And then start refactoring your code away from BinaryFormatter ;p
What you have done is correct. The if statement is meaningless. I always think that less code is better, because the lines of code is directly proportional to the number of faults.
public long ResourceID { get; set; }
Your first example only sets the resourceID field if its value has changed.
The only difference you would see by removing the "if" test is a possible impact if multiple threads are reading the value. In which case they probably should be using a lock, so it's almost certainly safe to remove the test.
Your second example prevents a caller from setting the property value to null. Presumably the field is initialized to a non-null value, and this has value as it means that callers can read the property without needing to check for null.
Usually in such scenarios and how you've explained, it shouldn't be a concern.
You could just go ahead and change the code of all properties;
public long ResourceID { get; set; }
Or
public long ResourceID
{
get { return this.resourceID; }
set { this.resourceID = value; }
}
But it might cause an issue if upon
changing the value of the property,
it cascades to some other custom
function-call which is only executed
if the new value is different from
old ones. Usually when when you've implemented custom events or even maybe in case of property-changed events
Also might affect, when using
Data-Context classes
Both scenarios are totally application specific.
I'd suggest you reactor with caution. Or as you've written yourself, HOMEWORK.