Should I be using IEquatable to ease testing of factories? - c#

I often work with classes that represent entities produced from a factory.
To enable easy testing of my factories easily I usually implement IEquatable<T>, whilst also overriding GetHashCode and Equals (as suggested by the MSDN).
For example; take the following entity class which is simplified for example purposes. Typically my classes have a bunch more properties. Occasionally there is a also collection, which in the Equals method I check using SequenceEqual.
public class Product : IEquatable<Product>
{
public string Name
{
get;
private set;
}
public Product(string name)
{
Name = name;
}
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
Product product = obj as Product;
if (product == null)
{
return false;
}
else
{
return Equals(product);
}
}
public bool Equals(Product other)
{
return Name == other.Name;
}
public override int GetHashCode()
{
return Name.GetHashCode();
}
}
This means I can then do simple unit tests like so (assuming the constructor is tested elsewhere).
[TestMethod]
public void TestFactory()
{
Product expected = new Product("James");
Product actual = ProductFactory.BuildJames();
Assert.AreEqual(expected, actual);
}
However this raises a number of questions.
GetHashCode isn't actually used but I've spent time implementing it.
I rarely actually want to use Equals in my actual application beyond testing.
I spend more time writing more tests to ensure the Equals actually works correctly.
I now have another three methods to maintain, e.g. add a property to the class, update methods.
But, this does give me a very neat TestMethod.
Is this an appropriate use of IEquatable, or should I take another approach?

Whether this is a good idea or not really depends on what kind of type your factory creates. There are two kinds of types:
Types with value semantics (value types for short) and
Types with reference semantics (reference types for short.)
In C# it is common to use struct for value types and class for reference types, but you do not have to, you may use class for both. The point is that:
Value types are meant to be small, usually immutable, self-contained objects whose main purpose is to contain a certain value, while
Reference types are objects that have complex mutable state, possibly references to other objects, and non-trivial functionality, i.e. algorithms, business logic, etc.
If your factory is creating a value type, then sure, go ahead and make it IEquatable and use this neat trick. But in most cases, we don't use factories for value types, which tend to be rather trivial, we use factories for reference types, which tend to be rather complex, so if your factory is creating a reference type, then really, these kinds of objects are only meant to be compared by reference, so adding Equals() and GetHashCode() methods is anywhere from misleading to wrong.
Take a hint from what happens with hash maps: the presence of Equals() and GetHashCode() in a type generally means that you can use an instance of this type as a key in a hash map; but if the object is not an immutable value type, then its state may change after it has been placed in the map, in which case the GetHashCode() method will start evaluating to something else, but the hash map will never bother re-invoking GetHashCode() in order to re-position the object in the map. The result in such cases tends to be chaos.
So, the bottom line is that if your factory creates complex objects, then you should perhaps take a different approach. The obvious solution is to invoke the factory and then check each property of the returned object to make sure they are all as expected.
I could perhaps propose an improvement to this, though beware that I just thought of it, I have never tried it, so it may and may not turn out to be a good idea in practice. Here it is:
Your factory presumably creates objects that implement a particular interface. (Otherwise, what's the point of having a factory, right?) So, you could in theory stipulate that newly created instances of objects that implement this interface should have certain properties initialized to a particular set of values. This would be a rule imposed by the interface, so you could have some function tied to the interface which checks whether this is true, and this function could even be parametrized with some hint as to expect different initial values under different circumstances.
(Last I checked, in C# a method tied to an interface was usually an extension method; I do not remember off the top of my head whether C# allows static methods to be part of an interface, or whether the designers of C# have yet added to the language something as neat and elegant as the default interface methods of Java.)
So, with an extension method, it could perhaps look like this:
public boolean IsProperlyInitializedInstance( this IProduct self, String hint )
{
if( self.Name != hint )
return false;
//more checks here
return true;
}
IProduct product = productFactory.BuildJames();
Assert.IsTrue( product.IsProperlyInitializedInstance( hint:"James" ) );

For test code you could use a reflection based equality, something like: Comparing object properties in c#
Many testing libraries provide such a utility, this way you don't have to change the design of your production code to suit the tests.

Related

Is there any benefit (semantic or other) to using a static method that calls a constructor?

I just updated Visual Studio 2013 and I noticed that in the project template for an MVC application the ApplicationDbContext class now has a static method that just calls the constructor:
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
This seems like clutter to me but I imagine that there is some semantic reason that I should now start using ApplicationDbContext.Create() instead of new ApplicationDbContext(). Are there any benefits to doing so?
Actually. yes.
In your specific case, wrapping it thusly allows you to quickly start bolting on logic, such as making the ApplicationDbContext and singleton or handling an exception in a common way for the whole application. Since a constructor cannot return null, this can be very important to be able to catch an exception and return null.
Tuple.Create is the prime example of generic inference, which does not work with Constructors. This allows you say
Tuple.Create(Item1, Item2.. ItemN);
And the let the compiler infer types, rather than
new Tuple<T1, T2...Tn>(Item1, Item2...ItemN);
Which is more verbose, and takes a bit more work if you want to switch out one of those types.
There is also the case of Anonymous types, which cannot be specified explicitly and thus cannot be used in new statements. I have specifically had occasion where, while searching assemblies for a specific Attribute to link a command structure for, I wanted to make an enumerable (a Queue, in this case) out of an anonymous type during the search to pair class references with their constructor and string arguments, rather than looking these up every time they're needed. Since I can again use Generic inference in a method, I was able to wrap the constructor in an extension method and get the job done.
There are also cases for singleton patterns, wherein you want the "GetInstance" method to usually create a value, or get one if it exists. May not qualify since it does slightly more than wrap a constructor.
In addition, there are plenty of cases where you may want to control implementation procedures, such as forcing them onto other threads, logging them in a database to be undone later, or bolting on a permissions system, all of which can be done by making a constructor wrapper and adding a few more lines of logic, and then privatizing the constructor to avoid it being called directly.
There are also cases where I've created a factory method which delegates to known children in order to provide a different implementation of a returned interface or abstract based on provided parameters. This has the added benefit of being able to hide the implementing classes - the Type class and IEnumerable interface make use of this pattern.
This pattern can be very useful, especially if you use a private constructor, and return an interface type from the Create, rather than the concrete type.
private ApplicationDbContext()
{
}
public static IApplicationDbContext Create()
{
return new ApplicationDbContext();
}
Now consumers of your class are prevented from depending on the concrete implementation - they can only rely on the abstraction.
Wrapping the constructor with static methods (creation methods) allows you to chose a specific name that conveys information. You can also create several methods with the same parameter signature such as CreateX(float f) and CreateY(float f), which you cannot do with constructors.
A situation where this is really useful is e.g. for creating structs that represent physical quantities that may have several units, such as time, length or weight. Here, you could use creation methods to force the programmer to always explicitly specify the unit instead of just passing a unit-less number to a single constructor (which assumes a certain unit, and getting it wrong might have huge consequences).
Example:
public struct Length
{
private const double MetersPerYard = 0.9144;
private double _meters;
private Length(double meters)
{
_meters = meters;
}
public static Length FromMeters(double meters)
{
return new Length(meters);
}
public static Length FromYards(double yards)
{
return new Length(yards*MetersPerYard);
}
public double Meters
{
get { return _meters; }
}
public double Yards
{
get { return _meters / MetersPerYard; }
}
}
Or take a look at TimeSpan and methods like FromMinutes, FromSeconds etc.

C#, making public members their methods private

I the following class:
public class Humptydump
{
public Humptydump()
{ }
public Rectangle Rectangle { public get; private set; }
}
in this class the Rectangle class comes from system.drawing,
how do i make it so people cannot access the methods of the rectangle, but can get the rectangle itself?
In your case, it will "just work".
Since Rectangle is a struct, your property will return a copy of the Rectangle. As such, it will be impossible for anybody to modify your Rectangle directly unless you expose methods to allow this.
That being said, it's impossible, in general, to provide access to a type without also providing access to methods defined on the type. The methods go along with the type. The only alternative in those cases would be to create a new type that exposed the data you choose without the data or methods you wish to be exposed, and provide access to that.
If rectangle was not a struct, one possible thing would be deriving it and hiding those methods:
public class DerivedClass : BaseClass
{
new private SomeReturnType SomeMethodFromBaseClasse(SameParametersAsInBaseClassAndSameSignature
{
//this simply hides the method from the user
//but user will still have the chance to cast to the BaseClass and
//access the methods from there
}
}
Are you talking about the Rectangle object specifically, or on a more general term and just using that as an example?
If you're talking on a more general term, this is something that comes up very often in refactoring patterns. This most commonly happens with collections on objects. If you expose, for example, a List<T> then even if the setter is private then people can still modify the collection through the getter, since they're not actually setting the collection when they do so.
To address this, consider the Law of Demeter. That is, when someone is interacting with a collection exposed by an object, should they really be interacting with the object itself? If so, then the collection shouldn't be exposed and instead the object should expose the functionality it needs to.
So, again in the case of a collection, you might end up with something like this:
class SomeObject
{
private List<AnotherObject> Things;
public void AddAnotherObject(AnotherObject obj)
{
// Add it to the list
}
public void RemoveAnotherObject(AnotherObject obj)
{
// Remove it from the list
}
}
Of course, you may also want to expose some copy of the object itself for people to read, but not modify. For a collection I might do something like this:
public IEnumerable<AnotherObject> TheObjects
{
get { return Things; }
}
That way anybody can see the current state of the objects and enumerate over them, but they can't actually modify it. Not because it doesn't have a setter, but because the IEnumerable<T> interface doesn't have options to modify the enumeration. Only to enumerate over it.
For your case with Rectangle (or something similar which isn't already a struct that's passed by value anyway), you would do something very similar. Store a private object and provide public functionality to modify it through the class itself (since what we're talking about is that the class needs to know when its members are modified) as well as functionality to inspect it without being able to modify what's being inspected. Something like this, perhaps:
class SomeObject
{
private AnotherObject Thing;
public AnotherObject TheThing
{
get { return Thing.Copy(); }
}
public void RenameThing(string name)
{
Thing.Name = name;
}
// etc.
}
In this case, without going into too much detail about what AnotherObject is (so consider this in some ways pseudo-code), the property to inspect the inner object returns a copy of it, not the actual reference to the actual object. For value types, this is the default behavior of the language. For reference types, you may need to strike a balance between this and performance (if creating a copy is a heavy operation).
In this case you'll also want to be careful of making the interface of your object unintuitive. Consuming code might expect to be able to modify the inner object being inspected, since it exposes functionality to modify itself. And, indeed, they can modify the copy that they have. How you address this depends heavily on the conceptual nature of the objects and how they relate to one another, which a contrived example doesn't really convey. You might create a custom DTO (even a struct) which returns only the observable properties of the inner object, making it more obvious that it's a copy and not the original. You might just say that it's a copy in the intellisense comments. You might make separate properties to return individual data elements of the inner object instead of a single property to return the object itself. There are plenty of options, it's up to you to determine what makes the most sense for your objects.

Member verification vs Interface

I was ready up on Ruby's method of enforcing interfaces w/ dynamic typing by checking for the existence of methods/properties that satisfy an interface.
In what ways is this overall just a better design principle than using interfaces? What are the pros/cons. For example you could implement the same concept in C# but I'm not sure if it would have the same value,
public class Foo
{
public Foo(dynamic _obj)
{
MethodInfo[] methods= _obj.GetType().GetMethods();
if (!methods.Any(x => x.Name == "SomeRequiredMethod")
{
throw new ArgumentException("Object does not meet interface requirements.");
}
}
// proceed with functionality that requires the method
}
And of course you could extend this to check more than just the name, like the signature, return type, etc.
Thoughts?
I can see several major issues problems with this approach:
reflection is slow
dynamic calls are also much slower than strongly-typed calls
the code is more complicated
And I can't see any advantage, except perhaps for very specific needs...
C# was designed as a static, strongly-typed language, and even though it now has some dynamic capabilities, they should only be used when there is no strongly-typed alternative.
If you really need to use the object dynamically, don't check the members manually: instead, put the code in a try block, and catch the RuntimeBinderException that will occur if a member you call is missing.

Does MS Test provide a default value equals comparison?

I want to test for example
int orderId = myRepository.SubmitOrder(orderA);
orderB = myRepository.GetOrder(orderId);
Assert.AreEqual(orderA, orderB); // fail
Obviously I need a value comparison here, but I don't want to have to provide an overridden Equals implementation for all of my classes purely for the sake of testing (it wouldn't be of any use in the rest of the app).
Is there a provided generic method that just checks every field using reflection? Or if not, it is possible to write my own?
EDIT: As it seems people are kind of missing the point. I don't want to have to write my own comparison logic. That would require hundreds of lines of extra code. I'm looking for something like a generic
bool ContainSameValues<T>(T t1, T t2)
method which recursively uses reflection to pull out all the values in T.
FURTHER EDIT: Since it doesn't appear there is any built in support for doing something like this, you can see my (failed) attempt at writing my own here
Easiest thing to do is compare the "primitive" fields yourself:
Assert.AreEqual(orderA.ID, orderB.ID);
Assert.AreEqual(orderA.CustomerID, orderB.CustomerID);
Assert.AreEqual(orderA.OrderDate, orderB.OrderDate);
As the Assert class is static, it is impossible to create extension methods on it (as an instance is required). However, why not create a wrapper for the Assert class, where you can perform custom assertions?
e.g:
public static class MyAssertions
{
public static void AreOrdersEqual(Order a, Order b)
{
if (!OrdersAreEqual) // your comparison logic here
Assert.Fail("Orders arent equal");
}
}
Then in your test:
MyAssertions.AreOrdersEqual(orderA, orderB)
You'll have to implement IComparable(or ICompare?) in the Order class.method.

Immutable object pattern in C# - what do you think? [closed]

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 7 years ago.
Improve this question
I have over the course of a few projects developed a pattern for creating immutable (readonly) objects and immutable object graphs. Immutable objects carry the benefit of being 100% thread safe and can therefore be reused across threads. In my work I very often use this pattern in Web applications for configuration settings and other objects that I load and cache in memory. Cached objects should always be immutable as you want to guarantee they are not unexpectedly changed.
Now, you can of course easily design immutable objects as in the following example:
public class SampleElement
{
private Guid id;
private string name;
public SampleElement(Guid id, string name)
{
this.id = id;
this.name = name;
}
public Guid Id
{
get { return id; }
}
public string Name
{
get { return name; }
}
}
This is fine for simple classes - but for more complex classes I do not fancy the concept of passing all values through a constructor. Having setters on the properties is more desirable and your code constructing a new object gets easier to read.
So how do you create immutable objects with setters?
Well, in my pattern objects start out as being fully mutable until you freeze them with a single method call. Once an object is frozen it will stay immutable forever - it cannot be turned into a mutable object again. If you need a mutable version of the object, you simply clone it.
Ok, now on to some code. I have in the following code snippets tried to boil the pattern down to its simplest form. The IElement is the base interface that all immutable objects must ultimately implement.
public interface IElement : ICloneable
{
bool IsReadOnly { get; }
void MakeReadOnly();
}
The Element class is the default implementation of the IElement interface:
public abstract class Element : IElement
{
private bool immutable;
public bool IsReadOnly
{
get { return immutable; }
}
public virtual void MakeReadOnly()
{
immutable = true;
}
protected virtual void FailIfImmutable()
{
if (immutable) throw new ImmutableElementException(this);
}
...
}
Let's refactor the SampleElement class above to implement the immutable object pattern:
public class SampleElement : Element
{
private Guid id;
private string name;
public SampleElement() {}
public Guid Id
{
get
{
return id;
}
set
{
FailIfImmutable();
id = value;
}
}
public string Name
{
get
{
return name;
}
set
{
FailIfImmutable();
name = value;
}
}
}
You can now change the Id property and the Name property as long as the object has not been marked as immutable by calling the MakeReadOnly() method. Once it is immutable, calling a setter will yield an ImmutableElementException.
Final note:
The full pattern is more complex than the code snippets shown here. It also contains support for collections of immutable objects and complete object graphs of immutable object graphs. The full pattern enables you to turn an entire object graph immutable by calling the MakeReadOnly() method on the outermost object. Once you start creating larger object models using this pattern the risk of leaky objects increases. A leaky object is an object that fails to call the FailIfImmutable() method before making a change to the object. To test for leaks I have also developed a generic leak detector class for use in unit tests. It uses reflection to test if all properties and methods throw the ImmutableElementException in the immutable state.
In other words TDD is used here.
I have grown to like this pattern a lot and find great benefits in it. So what I would like to know is if any of you are using similar patterns? If yes, do you know of any good resources that document it? I am essentially looking for potential improvements and for any standards that might already exist on this topic.
For info, the second approach is called "popsicle immutability".
Eric Lippert has a series of blog entries on immutability starting here. I'm still getting to grips with the CTP (C# 4.0), but it looks interesting what optional / named parameters (to the .ctor) might do here (when mapped to readonly fields)...
[update: I've blogged on this here]
For info, I probably wouldn't make those methods virtual - we probably don't want subclasses being able to make it non-freezable. If you want them to be able to add extra code, I'd suggest something like:
[public|protected] void Freeze()
{
if(!frozen)
{
frozen = true;
OnFrozen();
}
}
protected virtual void OnFrozen() {} // subclass can add code here.
Also - AOP (such as PostSharp) might be a viable option for adding all those ThrowIfFrozen() checks.
(apologies if I have changed terminology / method names - SO doesn't keep the original post visible when composing replies)
Another option would be to create some kind of Builder class.
For an example, in Java (and C# and many other languages) String is immutable. If you want to do multiple operations to create a String you use a StringBuilder. This is mutable, and then once you're done you have it return to you the final String object. From then on it's immutable.
You could do something similar for your other classes. You have your immutable Element, and then an ElementBuilder. All the builder would do is store the options you set, then when you finalize it it constructs and returns the immutable Element.
It's a little more code, but I think it's cleaner than having setters on a class that's supposed to be immutable.
After my initial discomfort about the fact that I had to create a new System.Drawing.Point on each modification, I've wholly embraced the concept some years ago. In fact, I now create every field as readonly by default and only change it to be mutable if there's a compelling reason – which there is surprisingly rarely.
I don't care very much about cross-threading issues, though (I rarely use code where this is relevant). I just find it much, much better because of the semantic expressiveness. Immutability is the very epitome of an interface which is hard to use incorrectly.
You are still dealing with state, and thus can still be bitten if your objects are parallelized before being made immutable.
A more functional way might be to return a new instance of the object with each setter. Or create a mutable object and pass that in to the constructor.
The (relatively) new Software Design paradigm called Domain Driven design, makes the distinction between entity objects and value objects.
Entity Objects are defined as anything that has to map to a key-driven object in a persistent data store, like an employee, or a client, or an invoice, etc... where changing the properties of the object implies that you need to save the change to a data store somewhere, and the existence of multiple instances of a class with the same "key" imnplies a need to synchronize them, or coordinate their persistence to the data store so that one instance' changes do not overwrite the others. Changing the properties of an entity object implies you are changing something about the object - not changing WHICH object you are referencing...
Value objects otoh, are objects that can be considered immutable, whose utility is defined strictly by their property values, and for which multiple instances, do not need to be coordinated in any way... like addresses, or telephone numbers, or the wheels on a car, or the letters in a document... these things are totally defined by their properties... an uppercase 'A' object in an text editor can be interchanged transparently with any other uppercase 'A' object throughout the document, you don't need a key to distinguish it from all the other 'A's In this sense it is immutable, because if you change it to a 'B' (just like changing the phone number string in a phone number object, you are not changing the data associated with some mutable entity, you are switching from one value to another... just as when you change the value of a string...
Expanding on the point by #Cory Foy and #Charles Bretana where there is a difference between entities and values. Whereas value-objects should always be immutable, I really don't think that an object should be able to freeze themselves, or allow themselves to be frozen arbitrarily in the codebase. It has a really bad smell to it, and I worry that it could get hard to track down where exactly an object was frozen, and why it was frozen, and the fact that between calls to an object it could change state from thawed to frozen.
That isn't to say that sometimes you want to give a (mutable) entity to something and ensure it isn't going to be changed.
So, instead of freezing the object itself, another possibility is to copy the semantics of ReadOnlyCollection< T >
List<int> list = new List<int> { 1, 2, 3};
ReadOnlyCollection<int> readOnlyList = list.AsReadOnly();
Your object can take a part as mutable when it needs it, and then be immutable when you desire it to be.
Note that ReadOnlyCollection< T > also implements ICollection< T > which has an Add( T item) method in the interface. However there is also bool IsReadOnly { get; } defined in the interface so that consumers can check before calling a method that will throw an exception.
The difference is that you can't just set IsReadOnly to false. A collection either is or isn't read only, and that never changes for the lifetime of the collection.
It would be nice at time to have the const-correctness that C++ gives you at compile time, but that starts to have it's own set of problems and I'm glad C# doesn't go there.
ICloneable - I thought I'd just refer back to the following:
Do not implement ICloneable
Do not use ICloneable in public APIs
Brad Abrams - Design Guidelines, Managed code and the .NET Framework
System.String is a good example of a immutable class with setters and mutating methods, only that each mutating method returns a new instance.
This is an important problem, and I've love to see more direct framework/language support to solve it. The solution you have requires a lot of boilerplate. It might be simple to automate some of the boilerplate by using code generation.
You'd generate a partial class that contains all the freezable properties. It would be fairly simple to make a reusable T4 template for this.
The template would take this for input:
namespace
class name
list of property name/type tuples
And would output a C# file, containing:
namespace declaration
partial class
each of the properties, with the corresponding types, a backing field, a getter, and a setter which invokes the FailIfFrozen method
AOP tags on freezable properties could also work, but it would require more dependencies, whereas T4 is built into newer versions of Visual Studio.
Another scenario which is very much like this is the INotifyPropertyChanged interface. Solutions for that problem are likely to be applicable to this problem.
My problem with this pattern is that you're not imposing any compile-time restraints upon immutability. The coder is responsible for making sure an object is set to immutable before for example adding it to a cache or another non-thread-safe structure.
That's why I would extend this coding pattern with a compile-time restraint in the form of a generic class, like this:
public class Immutable<T> where T : IElement
{
private T value;
public Immutable(T mutable)
{
this.value = (T) mutable.Clone();
this.value.MakeReadOnly();
}
public T Value
{
get
{
return this.value;
}
}
public static implicit operator Immutable<T>(T mutable)
{
return new Immutable<T>(mutable);
}
public static implicit operator T(Immutable<T> immutable)
{
return immutable.value;
}
}
Here's a sample how you would use this:
// All elements of this list are guaranteed to be immutable
List<Immutable<SampleElement>> elements =
new List<Immutable<SampleElement>>();
for (int i = 1; i < 10; i++)
{
SampleElement newElement = new SampleElement();
newElement.Id = Guid.NewGuid();
newElement.Name = "Sample" + i.ToString();
// The compiler will automatically convert to Immutable<SampleElement> for you
// because of the implicit conversion operator
elements.Add(newElement);
}
foreach (SampleElement element in elements)
Console.Out.WriteLine(element.Name);
elements[3].Value.Id = Guid.NewGuid(); // This will throw an ImmutableElementException
Just a tip to simplify the element properties: Use automatic properties with private set and avoid explicitly declaring the data field. e.g.
public class SampleElement {
public SampleElement(Guid id, string name) {
Id = id;
Name = name;
}
public Guid Id {
get; private set;
}
public string Name {
get; private set;
}
}
Here is a new video on Channel 9 where Anders Hejlsberg from 36:30 in the interview starts talking about immutability in C#. He gives a very good use case for popsicle immutability and explains how this is something you are currently required to implement yourself. It was music to my ears hearing him say it is worth thinking about better support for creating immutable object graphs in future versions of C#
Expert to Expert: Anders Hejlsberg - The Future of C#
Two other options for your particular problem that haven't been discussed:
Build your own deserializer, one that can call a private property setter. While the effort in building the deserializer at the beginning will be much more, it makes things cleaner. The compiler will keep you from even attempting to call the setters and the code in your classes will be easier to read.
Put a constructor in each class that takes an XElement (or some other flavor of XML object model) and populates itself from it. Obviously as the number of classes increases, this quickly becomes less desirable as a solution.
How about having an abstract class ThingBase, with subclasses MutableThing and ImmutableThing? ThingBase would contain all the data in a protected structure, providing public read-only properties for the fields and protected read-only property for its structure. It would also provide an overridable AsImmutable method which would return an ImmutableThing.
MutableThing would shadow the properties with read/write properties, and provide both a default constructor and a constructor that accepts a ThingBase.
Immutable thing would be a sealed class that overrides AsImmutable to simply return itself. It would also provide a constructor that accepts a ThingBase.
I dont like the idea of being able to change an object from a mutable to an immutable state, that kind of seems to defeat the point of design to me. When are you needing to do that? Only objects which represent VALUES should be immutable
You can use optional named arguments together with nullables to make an immutable setter with very little boilerplate. If you really do want to set a property to null then you may have some more troubles.
class Foo{
...
public Foo
Set
( double? majorBar=null
, double? minorBar=null
, int? cats=null
, double? dogs=null)
{
return new Foo
( majorBar ?? MajorBar
, minorBar ?? MinorBar
, cats ?? Cats
, dogs ?? Dogs);
}
public Foo
( double R
, double r
, int l
, double e
)
{
....
}
}
You would use it like so
var f = new Foo(10,20,30,40);
var g = f.Set(cat:99);

Categories