I'm currently finishing work on object change log functionality and would like to polish few things. Since we have a lot of web forms/reports where historical data should appear, I'm wondering if there is a way to implement that without changing controls/reports.
Currently, I have this situation:
public class Foo {
public string Property1 { get; set; }
public DateTime CreatedDate { get; set;}
public string GetHistoricalValue(string propertyName)
{
HistoryHelper historyHelper = CreateHistoryHelper(this);
return historyHelper.GetHistoricalValue(propertyName, CreatedDate);
}
...
public class HistoryHelper {
public string GetHistoricalValue(string propertyName, DateTime date) {
...
So, when someone wants to fetch historical data for Property1:
string historicalValue = fooInstance.GetHistoricalValue("Property1");
It's obvious that this approach requires a lot of changes in current application.
Is there a way to make Foo class returns historical value when I access Property1 in regular way:
string historicalValue = fooInstance.Property1;
Something like dynamically generating subclass with overriden properties or some other solution?
Is this possible?
INITIAL ANSWER
Something like this:
public class Foo {
public bool HistoricalMode { get; set; }
private string _property1;
public string Property1 {
get {
if (HistoricalMode) {
return GetHistoricalValue("Property1");
} else {
return _property1;
}
set {
if (HistoricalMode){
throw new NotSupportedException("Updates not possible in historical mode.");
} else {
_property1 = value;
}
}
}
public DateTime CreatedDate {
get {
// Similar pattern as above
}
set {
// Similar pattern as above
}
}
public string GetHistoricalValue(string propertyName) {
HistoryHelper historyHelper = CreateHistoryHelper(this);
return historyHelper.GetHistoricalValue(propertyName, CreatedDate);
}
}
Basically the idea is to keep a boolean in your objects which indicates in the object is in 'history mode'. If so, use your helper method. If not, normal properties getters/setters apply.
UPDATE
The solution to this question I think would require a change in your framework (if you have a single framework for all your applications). I would seek the solution in the way you are loading your objects. Hopefully you can detect when an object is required in 'historical mode' and when in 'normale mode'. Where you now 'just read' the object (record) from the database, in historical mode you need to compose the original object (from when the change happened) from your change log functionality. That way, all your current application can (hopefully) stay the way they are. The 'only' change you need to do is at the repository class.
This is all just speculation btw.
Can you easily affect how Foo instances are created? If so, you can for example create derived class HistoricalFoo : Foo, make Property1 virtual and use its getter to change its behaviour. Then use HistoricalFoo whenever you need historical data. It is not a very clean object model, but can get the job done.
public class Foo
{
protected string _property1;
public virtual string Property1
{
get { return _property1; }
set { _property1 = value; }
}
public DateTime CreatedDate { get; set;}
/* ... */
}
public class HistoricalFoo : Foo
{
public override string Property1
{
get
{
return GetHistoricalValue("Property1");
}
}
}
If this is not applicable, it's possible to embed some decision logic into the Property1 getter. In this scenario, you would have to change the internal state of the Foo instance - for example by setting a boolean flag IsInHistoryMode. Changing object states can be very tricky though, expecially in multithreaded environment.
public class Foo
{
public bool IsInHistoryMode { get; set; }
protected string _property1;
public virtual string Property1
{
get
{
if(IsInHistoryMode)
{
return GetHistoricalValue("Property1");
}
return _property1;
}
set
{
_property1 = value;
}
}
public DateTime CreatedDate { get; set;}
/* ... */
}
Related
I have multiple web requests that post JSON object and I have serializable classes with all the fields. For example:
[Serializable]
public class RequestOne()
{
public string date;
public string information;
public string subject;
}
[Serializable]
public class RequestTwo()
{
public int ID;
public string Data;
public string message;
}
And my method takes partially filled request class and I want to fill in any missing fields with default values declared in constant class.
And I want to avoid writing each method with for each request, like :
public static void FillWithDefault(this RequestOne request)
{ if (request.date.Equals(null)) request.date = DEFAULT_DATE;
if (request.information.Equals(null)) request.information = DEFAULT_INFO;
if (request.subject.Equals(null)) request.subject = DEFAULT_SUBJECT;
}
public static void FillWithDefault(this RequestTwo request)
{
//do the same for the fields in RequestTwo
}
I want to know if there is any way to achieve this using generic?
I want to do something similar to this:
public static void FillWithDefault<T>(this T request)
{
if(typeof(T) == typeof(request))
{
//check each member in request and fill with default if it's null
}
.
.
.
}
So that in my main method I can use like this :
RequestOne request = new RequestOne();
request.FillWithDefault();
RequestTwo request2 = new RequestTwo();
request2.FillWithDefault();
Can someone please help with idea on this? Am I overthinking on this? I'm new to generic so please feel free to advise on my code.
Edit
Sorry guys, I did not mention that I will be using this method for test automation. Those request contracts cannot be changed since it's by design. Sorry again for the confusion!
Use constructors. Also make use of properties. Don't gather the default filling code to one place, it's the responsibility of the classes so keep them there.
[Serializable]
public class RequestOne()
{
public string date { get; set; };
public string information { get; set; };
public string subject { get; set; };
public RequestOne()
{
Date = DEFAULT_DATE;
Information = DEFAULT_DATE;
Subject = DEFAULT_SUBJECT;
}
}
[Serializable]
public class RequestTwo()
{
public int ID { get; set; };
public string Data { get; set; };
public string Message { get; set; };
public RequestTwo()
{
Data = DEFAULT_DATA;
message = DEFAULT_MESSAGE;
}
}
Generics are used when the types have common operations/properties defined so you can apply the same routine for each type in one place instead of declaring different methods for each type.
However in this case, you have two different types with different properties, so I would not use generics here. You can achieve it with manual type checking and using reflection to get properties and set them but it's not a good way and definitely wouldn't be a good usage of generics.
Overloading is the way to go.
you can use property
[Serializable]
public class RequestOne()
{
private string _date;
public string date { get { return _date;} set { _date = value ?? DEFAULT_DATE; }};
public string information; // same here
public string subject; //same here
}
I have a WebApi Controller which returns a List. My problem is, that I do not want xxxx.0 in the resulting JSON as this makes serious problems in my javascript. Is there a way to prevent .net serialization with .0 values so that they get truncated?
Current output:
{"Temperature":[[1465434000.0,4.00],[1465437600.0,15.40],[1465441200.0,15.26],
Wanted:
{"Temperature":[[1465434000,4.00],[1465437600,15.40],[1465441200,15.26],
Object which is serialized:
public class ChartDataMonthly
{
public List<decimal[]> Temperature { get; set; }
public class ChartDataMonthly
{
public List<decimal[]> Temperature { get; set; }
public List<decimal[]> Round()
{
List<decimal[]> NewTemp = new List<decimal[]>();
foreach(var t in Temperature)
{
t[0] = Math.Round(t[0], 0);
NewTemp.Add(t)
}
return NewTemp;
}
}
I saw a new answer similar to this one get posted about two minutes before mine, but this is roughly how I would start. You can either use the return List or Json.SerializeObject and return the string by modifying the method slightly to return a string similar to #dckuehn's answer.
I guess where I would start is to create a new property on your object for your javascript model:
public class ChartDataMonthly
{
public List<decimal[]> Temperature { get; set; }
// This can be "unmapped" to ignore object mappers
public List<string> RoundedTemperature
{
get
{
return Temperature.Select(t => Math.Round(t).ToString()).ToList();
}
}
// rest of model
}
public class ChartDataMonthly
{
public List<decimal[]> _temperature;
public List<decimal[]> Temperature
{
get { return _temperature; }
set
{
_temperature = value;
//edit each value by reference
_temperature.ForEach(x => x.ToList().ForEach(y =>y= Convert.ToDecimal(Math.Round(Convert.ToDouble(y)))));
}
}
}
Untested but i think it should do the work automatically
You just round every field of each array in your list.
If you do it inside a setter/getter it will automatically do it when the .net binder bind the JavaScript to your object
LogEvent represents information like log level, message, user, process name, ...
Some of these properties' values require pretty much effort for generation, e. g. the process name. Those properties' generated values are usually not changed, BUT despite this fact it should be possible to change them.
I considered the prototype pattern starting with a protoype, whose generic properties are pre-allocated. The protoype stays the same object during the lifetime of the application, but its properties' values might change as described above. New LogEvent objects should use the current prototype's values, objects created before the change should continue using the old values, that means, referencing the prototype from the "real" LogEvent object is not an option.
However the "real" LogEvent requires some properties to be not null, whereas this requirement is not useful for the prototype. I would like to prevent invalid objects of LogEvent. However if I use usual protoype pattern I would have to add a constructor to create the prototype, but this constructor would not create a valid object and I want to avoid, that an invalid object (the prototype itself or a clone of it) is used accidentally.
I spent some time on searching a solution, but the approaches listed below are pretty ugly. I hope, that there is an elegant solution. Meanwhile I tend to option 3, because 1 and 2 do not seem to be clean.
General structure
public interface ILogEvent
{
string PreAllocatedProperty1 { get; set; }
string PreAllocatedProperty2 { get; set; }
string IndividualProperty1 { get; set; }
string IndividualProperty2 { get; set; }
}
Option 1
Pros
LogEventPrototype can not be used as ILogEvent.
properties do not have to be declared in multiple classes
Cons
properties have to be mapped manually
static methods => interface for prototypes not possible
Code
class LogEventPrototype
{
public string PreAllocatedProperty1 { get; set; }
public string PreAllocatedProperty2 { get; set; }
public string IndividualProperty1 { get; set; }
public string IndividualProperty2 { get; set; }
public LogEventPrototype() { GeneratePreAllocatedProperties(); }
private void GeneratePreAllocatedProperties()
{
// if you invoke the helper functions later again,
// they might return different results (e. g.: user identity, ...)
PreAllocatedProperty1 = Helper.ComplexFunction();
PreAllocatedProperty2 = Helper.AnotherComplexFunction();
}
}
class LogEvent : LogEventPrototype, ILogEvent
{
// just for creating the prototype, object will be in an INVALID state
private LogEvent() : base() { }
// object will be in a VALID state
public LogEvent(string individualProperty2)
: this()
{
if (individualProperty2 == null)
throw new ArgumentNullException();
IndividualProperty2 = individualProperty2;
}
public static LogEvent FromPrototype(LogEventPrototype prototype)
{
// clone manually
return new LogEvent(prototype.IndividualProperty2)
{
IndividualProperty1 = prototype.IndividualProperty1,
PreAllocatedProperty1 = prototype.PreAllocatedProperty1,
PreAllocatedProperty2 = prototype.PreAllocatedProperty2
};
}
}
Option 2
Similar to option 1, but:
Pros
it is "ensured", that LogEventPrototype is never instantiated, it is just used as return type
no manual mapping
Cons: It seems to be hacky.
class LogEventPrototype
{
// properties ... (same as in option 1)
protected LogEventPrototype()
{
GeneratePreAllocatedProperties();
}
}
class LogEvent : LogEventPrototype, ILogEvent
{
// constructors same as in option 1; FromPrototype() removed
public static LogEventPrototype CreateProtoype()
{
return new LogEvent();
}
public static LogEvent FromPrototype(LogEventPrototype prototype)
{
if(prototype.IndividualProperty2 == null)
throw new ArgumentException();
return (LogEvent)prototype;
}
public static LogEventPrototype CreateProtoype()
{
return new LogEvent();
}
}
Option 3
Do not use a dedicated class for prototypes, but make the LogEvent constructor public and risk invalid LogEvent objects. Use a Validate() method instead and hope, that a client does not forget to use it.
private List<T> newList;
public List<T> NewList
{
get{return newList;}
set{newList = value;}
}
I want to create something like this, but this is won't work. it's just an example to demonstrate my goal as it's pretty common creating proprties for string and int and even T but I've never seen a List property
Is it even possible do such a thing, creating a property for type List ?
EDIT
I have a normal class that has normal properties (string properties, int properties, etc) but I have this property that stores user options, So on the presentation layer I had to convert them into a string so I could be able to store them in the Object. Now is it possible to have a property of type List to store the multivalues in a better and clean way, instead of converting information into one string and then split it and again join it! Thanks Again =D
EDIT2
private List<KeyValuePair<string, string>> _settings;
public List<KeyValuePair<string, string>> MySettings
{
get { return _settings; }
set { _settings = value; }
}
I used the exact code you posted but the property still won't appear in the object's instance, so I tried adding code in the get and set (I wonder why you left them empty or does it means something?) and also added a private variable in the class but still it doesn't appear in the properties of the object's instance!
I hope you could provide the exact code to implement this property and a simple code that assigns or retrieves from/to an instance of this class object
It's the first time to even hear about this KeyValuePair and all the tutorials are pretty simple and not for my case, sorry!
The Last Edit: After a lot of researching and the help of Mark Avenius I found the perfect answer. hope everyone can benefit from this.
NOW! HOW TO CREATE A PROPERTY FOR A LIST :
The Options Class
Public Class Options
{
private string id;
private int option;
public int ID
{
get { return id; }
set { id= value; }
}
public string Option
{
get { return option; }
set { option = value; }
}
}
The Users Class
public class Users
{
private int userId;
private string pass;
private List<Options> userOptions = new List<Options>();
public int ID
{
get { return userId; }
set { user = userId; }
}
public string Pass
{
get { return pass; }
set { pass = value; }
}
public List<Options> OptionsList
{
get { return userOptions; }
set { userOptions = value; }
}
}
The Presentation Layer
Users newUser = new Users ();
Options userOption = new Options ();
userOption.ID = int.Parse(txtBxID.Text);
userOption.Option = txtBxOption.Text;
Item.Options.Add(userOption);
T must be defined within the scope in which you are working. Therefore, what you have posted will work if your class is generic on T:
public class MyClass<T>
{
private List<T> newList;
public List<T> NewList
{
get{return newList;}
set{newList = value;}
}
}
Otherwise, you have to use a defined type.
EDIT: Per #lKashef's request, following is how to have a List property:
private List<int> newList;
public List<int> NewList
{
get{return newList;}
set{newList = value;}
}
This can go within a non-generic class.
Edit 2:
In response to your second question (in your edit), I would not recommend using a list for this type of data handling (if I am understanding you correctly). I would put the user settings in their own class (or struct, if you wish) and have a property of this type on your original class:
public class UserSettings
{
string FirstName { get; set; }
string LastName { get; set; }
// etc.
}
public class MyClass
{
string MyClassProperty1 { get; set; }
// etc.
UserSettings MySettings { get; set; }
}
This way, you have named properties that you can reference instead of an arbitrary index in a list. For example, you can reference MySettings.FirstName as opposed to MySettingsList[0].
Let me know if you have any further questions.
EDIT 3:
For the question in the comments, your property would be like this:
public class MyClass
{
public List<KeyValuePair<string, string>> MySettings { get; set; }
}
EDIT 4: Based on the question's edit 2, following is how I would use this:
public class MyClass
{
// note that this type of property declaration is called an "Automatic Property" and
// it means the same thing as you had written (the private backing variable is used behind the scenes, but you don't see it)
public List<KeyValuePair<string, string> MySettings { get; set; }
}
public class MyConsumingClass
{
public void MyMethod
{
MyClass myClass = new MyClass();
myClass.MySettings = new List<KeyValuePair<string, string>>();
myClass.MySettings.Add(new KeyValuePair<string, string>("SomeKeyValue", "SomeValue"));
// etc.
}
}
You mentioned that "the property still won't appear in the object's instance," and I am not sure what you mean. Does this property not appear in IntelliSense? Are you sure that you have created an instance of MyClass (like myClass.MySettings above), or are you trying to access it like a static property (like MyClass.MySettings)?
Simple and effective alternative:
public class ClassName
{
public List<dynamic> MyProperty { get; set; }
}
or
public class ClassName
{
public List<object> MyProperty { get; set; }
}
For differences see this post: List<Object> vs List<dynamic>
public class MyClass<T>
{
private List<T> list;
public List<T> MyList { get { return list; } set { list = value; } }
}
Then you can do something like
MyClass<int> instance1 = new MyClass<int>();
List<int> integers = instance1.MyList;
MyClass<Person> instance2 = new MyClass<Person>();
IEnumerable<Person> persons = instance2.MyList;
You could do this but the T generic parameter needs to be declared at the containing class:
public class Foo<T>
{
public List<T> NewList { get; set; }
}
It's possible to have a property of type List<T> but your class needs to be passed the T too.
public class ClassName<T>
{
public List<T> MyProperty { get; set; }
}
Either specify the type of T, or if you want to make it generic, you'll need to make the parent class generic.
public class MyClass<T>
{
etc
Martin Fowler's Refactoring discusses creating Null Objects to avoid lots of
if (myObject == null)
tests.
What is the right way to do this? My attempt violates the "virtual member call in constructor" rule.
Here's my attempt at it:
public class Animal
{
public virtual string Name { get; set; }
public virtual string Species { get; set; }
public virtual bool IsNull
{
get { return false; }
}
}
public sealed class NullAnimal : Animal
{
public override string Name
{
get{ return "NULL"; }
set { }
}
public override string Species
{
get { return "NULL"; }
set { }
}
public virtual bool IsNull
{
get { return true; }
}
}
Go look up the amount of pain that interesting concepts, such as DbNull, have caused and think about if this is actually a good idea.
Protip: if you are constantly checking for null references, you probably should rethink the API a bit to help preclude null objects closer to the top of the stack.
Protip II: having something throw an exception when there is an unexpected null is actually fine and dandy. Things should go boom if you have nulls where there shouldn't be null.
I tend to agree with Wyatt Barnett's answer in that you should show restraint when creating these kinds of "null" objects. That said, there are some nice reasons for doing so. On occasion.
I also tend to agree with Supertux's answer in that the whole point of a null object is to not need to check whether or not it is null, so you should lose the IsNull property. If you really feel you need the IsNull property, then read Wyatt's response again and reconsider.
And thank you CraigTP for the nice links for more info. Good stuff.
Now I will assume that in your real code you actually have a constructor that is attempting to set the values of Name or Species (whatever your real code equivalent might be called). Otherwise, why would you get the "virtual member call in constructor" warning/error? I've run into a couple of similar problems when using the newfangled MyProperty { get; set; } shortcut myself (particularly when used in structs, and don't get me started about serialization versioning). Your solution is to not use the shortcut, but instead do it the old-fashioned way.
public class Animal {
protected Animal() { }
public Animal(string name, string species) {
_Name = name;
_Species = species;
}
public virtual string Name {
get { return _Name; }
set { _Name = value; }
}
private string _Name;
public virtual string Species {
get { return _Species; }
set { _Species = value; }
}
private string _Species;
}
public sealed class NullAnimal : Animal {
public override string Name {
get { return String.Empty; }
set { }
}
public override string Species {
get { return String.Empty; }
set { }
}
}
This solves the problem of setting your virtual properties in the constructor. Instead, you are setting your private field values (something you don't have the ability to reference if you use the shortcut). For extra credit, compile both methods, and use the Reflector to look at the resulting assemblies.
The more I use the { get; set; } shortcut, the more I dislike it.
The point of the Null Object pattern is that it doesn't require a null check to prevent a crash or error.
For example if you tried to perform an operation on the Species property and it was null - it would cause an error.
So, you shouldn't need an isNull method, just return something in the getter that won't cause the app to crash/error e.g.:
public class Animal
{
public virtual string Name { get; set; }
public virtual string Species { get; set; }
}
public sealed class NullAnimal : Animal
{
public override string Name
{
get{ return string.Empty; }
set { ; }
}
public override string Species
{
get { return string.Empty; }
set { ; }
}
}
You only use this approach if it is appropriate. Your example of an Animal object might not be a good example because it doesn't present an appropriate case where you would use this approach. For example:
Animal animal = new Animal();
if (animal.tail == null)
{
//do nothing because wagging a tail that doesn't exist may crash the program
}
else
{
animal.wagTail();
}
In this example, you should build the Animal object so that if the animal doesn't have a tail, it can successfully handle the wagTail() command without crashing.
Class Animal
{
Tail tail;
void wagTail()
{
if (this.tail == null)
{
//do nothing
}
else
{
this.tail.doTheWag();
}
}
}
Now you don't need to do a null check, but can just call animal.wagTail() regardless of whether the animal has a tail or not.
I'd like to mention here some interesting detail. Look at your class. Does it has any logic in it? This is not a class in its sense, this is a data structure. What you are trying to do is apply null object pattern to something it is not applicable to. Data structures is closer to value types, than to classes. There fore null check can be right in place to solve your problem.
Null object pattern is not something you should always follow. Null object pattern is a thing you can use to avoid Liskov's substitution principle violation, to represent a class that does nothing, because null is not appropriate substitution for a class as it is a value, but not a class.
But things are different with value types and data structures. Null is value! So in this case null check is the right thing to do.