Is there ever a case where holding the necessary data to create an object and only creating it when is absolutely necessary, is better/more efficient than holding the object itself?
A trivial example:
class Bar
{
public string Data { get; set; }
}
class Foo
{
Bar bar;
readonly string barData;
public Foo(string barData)
{
this.barData = barData;
}
public void MaybeCreate(bool create)
{
if (create)
{
bar = new Bar { Data = barData };
}
}
public Bar Bar { get { return bar; } }
}
It makes sense if the object performs some complex operation on construction, such as allocate system resources.
You have Lazy<T> to help you delay an object's instantiation. Among other things, it has thread safety built in, if you need it.
In general, no. (If I understand your question correct).
Allocations/constructions are cheap in terms of performance. Unless you are doing something crazy, construct your objects when it feels natural for the design - don't optimize prematurely.
Yes if creating the object means populating it, and to populate it you need to do a slow operation.
For example,
List<int> ll = returnDataFromDBVeryVerySlowly();
or
Lazy<List<int>> ll = new Lazy<List<int>>(() =>
{
return returnDataFromDBVeryVerySlowly();
});
In first example returnDataFromDBVeryVerySlowly will be called always, even if you don't need it. In the second one it will be called only if it's necessary. This is quite common, for example, in ASP.NET where you want to have "ready" many "standard" datasets, but you don't want them to be populated unless they are needed and you want to put them as members of your Page, so that multiple methods can access them (otherwhise a method could call directly returnDataFromDBVeryVerySlowly)
Related
I've deserialized JSON into a c# object, but with an incomplete JSON such that some properties are missing. At the time of deserializing the object, I don't have access to the full JSON. I can get the full JSON by making another API call, but I don't want to make that call if I don't have to.
I would like my property getters to work such that they return the property if it's not null. If it is null, it should make the call to the API to get the full JSON and update all of the JsonProperties in the class, and then return the property I've asked for.
public class Car
{
private string _make;
private string _model;
[JsonProperty("make")]
public string Make
{
get
{
if (_make != null)
{
return _make;
}
else
{
UpdateProperties();
return _make;
}
}
}
[JsonProperty("model")]
public string Model
{
get
{
if (_model != null)
{
return _model;
}
else
{
UpdateProperties();
return _model;
}
}
}
[JsonProperty("self")]
public Uri Self { get; set; }
public void UpdateProperties()
{
}
}
In the UpdateProperties() method above, I can make it use the Self property to get and deserialize a new instance of a Car class, but I want it to refresh the properties of the current Car class instance instead. I can do this manually by setting each property individually again, but since I need to do this for many classes, I would appreciate a better way. Is this possible?
Or am I going about this all wrong?
EDIT:
Here is an example of the JSON the API would return. Lets say I make a call to get information about the vehicle fleet. It would return:
{
"details" : "something"
"car": {
"make": "Ford",
"self": "https://..."
}
"truck": {
"age": 30,
"self": "https://..."
}
}
where when you access the url provided by car.self, it would return the following JSON:
{
"make" : "Toyota",
"model" : "Camry",
"self" : "https://..."
}
So, let me offer a different perspective. The problem description seems straightforward enough- I have two API calls, one which returns a partial object, and one which returns a complete object. I don't want to make two calls if I don't have to. So, I'll just make the second call and "fill in the details" if I need to, right?
Wrong.
The proposed approach is not a good idea.
This goes off the rails from the beginning with the design of the API. The objects returned by the API should not be so complicated so as to require multiple calls to return the "full" object as described in the code. But, let's assume I have no control over the design of the API - what should I do?
Programmers are frequently faced with the task of confronting a badly-designed API. These create leaky abstractions like the one described in this problem, where there is a strong desire to "paper over" the bad API design. The problem is that not all bad designs can be papered over. This is one.
What is proposed here is to introduce a painful side-effect of a get accessor. This is arguably the worst way to solve the problem of a bad API design. A typical get method returns with a negligible amount of time - it's a simple memory access. This proposed get accessor could potentially take seconds to return, it could fail, it could throw an exception. Worse yet, there is no indication to the caller that this is, in fact, access to an external interface. At the end of the day, the state of your object is not deterministic, which is the arguably the worst thing you can have in a program.
If that wasn't bad enough, get accessors have no provision for asynchronous operations, which are common when dealing with remote APIs. User experience will suffer. By taking this approach, I will have actually taken one problem and made a new problem everywhere this class is used.
A better approach:
The API has two separate functions, so really, this implies two separate result types. I would create one type for the partial class and a second type for the full class. After all, I'm writing code - and unless the code is in the habit of re-writing itself, I should know at the time of writing whether I need the full or the partial representation of the object.
To get the full representation, I'll provide a separate access to the API, with appropriate methods to allow for asynchronous execution (e.g. observables). This will have the added benefit of allowing me to examine (via the "where used" function) where in the program these different API calls are used. This might build a case for me to return to the API designer and suggest a change to the design, based on how I'm using it.
The only way with your current setup to reset all of the properties manually.
You're right to want to have this be automatic, since that's a lot of boilerplate code. This is a common problem and the most common solution to it is to use the DTO or Data Transfer Object pattern.
You would introduce a new class called a CarDto and instead of Car exposing private fields, it would expose the properties on the CarDto.
See Below:
public class Car {
private CarDto _dto = null;
public Car(CarDto dto = null) {
//If we pass in a dto, use it, otherwise create a new one
_dto = dto ?? new CarDto();
}
[JsonProperty("make")]
public string Make {
get {
if (_dto.Make == null) {
UpdateProperties();
}
return _dto.Make;
}
}
[JsonProperty("model")]
public string Model {
get {
if (_dto.Model == null) {
UpdateProperties();
}
return _dto.Model;
}
}
[JsonProperty("self")]
public Uri Self { get; set; }
public void UpdateProperties() {
//The API would return a CarDto.
CarDto newDto = APICall(); //Mock code
_dto = newDto;
}
}
public class CarDto {
public string Make { get;set; }
public string Model { get;set; }
}
So now, if you ever have a null property, you will make a call to UpdateProperties. This will then return a new CarDto that you use as your private _dto field.
This is a SUPER useful and common pattern, and one that makes things a lot easier so it's great to implement and get practice using! Let me know if anything is unclear.
This is probably a terrible way of doing things, but here goes anyway...
I want to re-initialise an object from within the object itself.
I have an object called Quote, one of the methods is Calculate() and it does a lot of things. One thing is that if certain major properties are changed, we call it a Big Change and we need to create a new Quote (not just update the existing one).
In the middle of Calculate() it would be really easy (IMO) to just do this:
public class Quote {
public bool Calculate() {
//... do lots of things
if(IsBigChange) {
this = new Quote();
}
//... do more things
// later when it is saved it will be a new quote
}
}
Calculate() is called from lots of places, so I don't really want to kick out when Big Change is detected and create the new object 'outside', if you know what I mean.
So if you can't set this, is there another way of achieving the same result?
No, you can't change this. Man, that would be confusing.
That being said, you can set this (sort of) from a static method, which has no this to begin with. You just create a new object and return it. This is a pretty traditional way to do it. Example:
class Quote
{
static public Quote Calculate(int inputData)
{
var foo = DoComputations(inputData);
return new Quote(foo);
}
public Quote(Foo foo)
{
//Initialize member variables based on the output of the calculations (a.k.a. foo)
}
}
Then instead of calling it like this:
var q = new Quote();
q.Calculate(data);
You'd do this:
var q = Quote.Calculate(data);
Say I have a class with a number of methods - some private, some public.
In one of the public methods, I create a list of objects. This is then used across a number of other methods, which have simply been abstracted out to make code simpler.
So I might have:
public class MyClass
{
public void CreateList()
{
List<MyClass> MyList = new List<MyClass>();
... populate list
DedupeList();
ValidateList();
}
void DedupeList()
{
// do something using MyList
}
void ValidateList()
{
// do something using MyList
}
}
I was wondering what the best approach would be in this instance.
Make the list created by CreateList() a class level variable;
Pass the list a parameter to each of the sub-methods.
Ok, so it depends on what you're trying to achieve and what your classes responsibility is.
If you class represents a real thing which represents part of your domain, and which has state, then your private methods act on that state and I would therefore choose the former.
So
public class Basket
{
private IList<string> Contents;
public Basket()
{
Contents = new Contents();
}
public void Add(string Item)
{
Contents.Add(Item);
}
public void Empty()
{
Contents.Clear();
}
}
This is a trite example, but all I could think of.
If however your class doesn't represent an object with state, such as the calculator below which takes some input, acts on it, and returns it without storing anything, then the latter is better.
That said, there are other considerations, such as keeping code clean and easy to read (should be very high on your priority list), limiting the number of parameters etc being passed (any more than three is often regarded as messy). Example below of when I would elect to pass parameters.
public class InvestmentCalculator
{
pubilc IEnumerable<Stock> CalculateInvestmentValue(IEnumerable<Stock> Stocks)
{
foreach (var stock in stocks)
{
var itemValue = GetSotckValueFromMarket(stock);
stock.UpdateValue(itemValue)
AddProjection(stock);
}
}
public decimal GetStockValueFromMarket(Stock stock)
{
//Do something
}
public decimal AddProjection(Stock stock)
{
//Do something
}
}
I hope that this helps
It depends on meaning of the list. You have to find some answers. Should it be a part of the class or just a temporary variable that should live just along the method call? Is it a part of behavior of the class? How about threading? Even you may rethink if DedupeList and ValidateList methods have to be part of this class or do they deserve a separate class?
I recommend you to read "Implementation Patterns" by Kent Beck and "Clean Code" by Robert C. Martin. There are dozens of very helpful tips for these kind of little but frequent cases.
Context: this is based on a question that was asked and then deleted before I could answer it - but I think it is a good question, so I've tidied it, rephrased it, and re-posted it.
In a high-throughput scenario using protobuf-net, where lots of allocations are a problem (in particular for GC), is it possible to re-use objects? For example by adding a Clear() method?
[ProtoContract]
public class MyDTO
{
[ProtoMember(1)]
public int Foo { get; set; }
[ProtoMember(2)]
public string Bar { get; set; }
[ProtoMember(3, DataFormat = DataFormat.Group)]
public List<int> Values { get { return values; } }
private readonly List<int> values = new List<int>();
public void Clear()
{
values.Clear();
Foo = 0;
Bar = null;
}
}
protobuf-net will never call your Clear() method itself, but for simple cases you can simply do this yourself, and use the Merge method (on the v1 API, or just pass the object into Deserialize in the v2 API). For example:
MyDTO obj = new MyDTO();
for(...) {
obj.Clear();
Serializer.Merge(obj, source);
}
This loads the data into the existing obj rather than creating a new object each time.
In more complex scenarios where you want to reduce the number of object allocations, and are happy to handle the object pooling / re-use yourself, then you can use a custom factory. For example, you can add a method to MyDTO such as:
// this can also accept serialization-context parameters if
// you want to pass your pool in, etc
public static MyDTO Create()
{
// try to get from the pool; only allocate new obj if necessary
return SomePool.GetMyDTO() ?? new MyDTO();
}
and, at app-startup, configure protobuf-net to know about it:
RuntimeTypeModel.Default[typeof(MyDTO)].SetFactory("Create");
(SetFactory can also accept a MethodInfo - useful if the factory method is not declared inside the type in question)
With this, what should happen is the factory method is used instead of the usual construction mechanisms. It remains, however, entirely your job to cleanse (Clear()) the objects when you are finished with them, and to return them to your pool. What is particularly nice about the factory approach is that it will work for new sub-items in lists, etc, which you can't do just from Merge.
It is likely that I am going about this all wrong, but I have a user control called CategoryControl, there can be many like it, for that reason I decided that many of its functions would be better served as static methods. I wanted to know if there is a "better" way of accessing these methods then passing an instance all over the class. The methods are public static as they will be updated by other methods. The though of making extension methods comes to mind..?
public CategoryControl(UserCategory userCategory)
{
InitializeComponent();
PopulateControl(userCategory, this);
}
private static void PopulateControl(UserCategory userCategory, CategoryControl instance)
{
SetCategoryTitle(userCategory, instance);
SetPercentCorrect(userCategory, instance);
SetQuestionsMissed(userCategory, instance);
SetBackgroundBar(userCategory, instance);
SetForegroundBar(userCategory, instance);
}
Updated::
The longer story is that I have a Panel on the screen, the panel contains relevant user categories. By relevant I mean that the user has the option of changing courses thus displaying a new set of categories. A user can also change the values of a category based on their interaction with the software. So...
A panel shows the categories of a course.
I maintain a list of the active Category Controls in the panel, and the main form tells the panel when to draw a new set of categories.
public void InitializeProgressPanel(UserCategories parentCategories)
{
Contract.Requires(parentCategories != null, "parentCategories is null.");
RemoveAllControlsFromList(_categoryControls);
UserCategories sortedUserCategories = parentCategories.SortByWorst();
int categoriesCount = parentCategories.Count();
int spacer = (Height - (CategoryControl.Controls_Height * categoriesCount)) / categoriesCount+1;
for (int i = 0; i < sortedUserCategories.Count; i++)
{
CategoryControl cc = new CategoryControl((UserCategory)sortedUserCategories[i]);
cc.Left = 0;
if (i == 0)
cc.Top = spacer;
else
cc.Top = (Controls[i - 1].Bottom + spacer);
Controls.Add(cc);
_categoryControls.Add(cc);
}
}
I would certainly not make extension methods if I had a class in hand that I could extend. Remember, the purpose of extension methods is to extend types that you cannot extend yourself.
The question at hand then is, should you say:
class C
{
public void Foo() { ... }
}
or
class C
{
public static void Foo(C c) { ... }
}
I would ask some questions like:
Is the class ever going to be subclassed? If so, should this be a virtual method?
Is Foo the kind of thing that an instance does to itself, or the sort of thing that it has done to it? An animal eats on its own, but an animal is fed by someone else.
UPDATE:
Some more questions I'd ask myself:
Are the properties and whatnot you are setting ever going to change? The less mutability you have in a class, the easier it is to test, the easier it is to reason about, and the fewer bugs you'll have. If the properties and whatnot are never going to change then do not set them in any kind of method. Set them in the constructor and then never worry about them again; they're correct.
Why not make them instance members, and do it like this
private UserCategory _userCategory;
public CategoryControl(UserCategory userCategory)
{
InitializeComponent();
this._userCategory = userCategory;
this.PopulateControl();
}
private void PopulateControl()
{
// to see userCategory you'd do "this._userCategory"
// to see the specific instance you could simply do "this"
SetCategoryTitle();
SetPercentCorrect();
SetQuestionsMissed();
SetBackgroundBar();
SetForegroundBar();
}
Seems better to have the functionality on one of the two classes involved in the interaction, rather than on some third party.
Here are two ways that spring to mind:
CategoryControl could have a public function PopulateCategory(UserCategory userCat)
UserCategory could have a public function PopulateFromControl(CategoryControl ctrl)
If all those operations about title and percent etc need to be separate actions, you'd just follow the model above but have separate functions for each item.
Just a shot in the dark here, but I'd probably try for something more like this:
private void PopulateControl(UserCategory userCategory)
{
CategoryTitle = GetCategoryTitle(userCategory);
PercentCorrect = GetPercentCorrect(userCategory);
...
}
Some questions may help...(?)
What benefit do you perceive in making the methods static? Converting the method to static, you are taking away the implicit passing of "this", and passing it in manually every time. How does that help? (It won't make the code any more efficient, it just means you have to pass 'instance' into every call you make, so you need to write more code)
Does the user category change a lot? If not, rather than passing it in for every call, would it make more sense to make it a member variable?
Would you really want to call all these static methods one by one to change all the different parameters of the control? Look at how the client will use this class and you may find that you can roll all of those options into one or two methods that take a bunch of parameters and apply them all in one hit. (Often if you want to change one setting, you will want to change several settings together)