So I've got a whole bunch of options, every different page/tab can have their own local options. We'll have maybe 10-15 pages tabs open tops. I need to implement a way to show the global defaults, weather the all the tabs have consistent values. I'm working on the model/viewmodel portion of a WPF app.
I'd love to find a way that is more elegant since I'm having to cut and past roughly the same code 20+ times and just change property names. Maybe this is the problem Dynamics solve, but right now this feels both wrong and painful.
Here is an example of my current solution:
public class Foo
{
private bool fooVar1;
private bool fooVar2;
//lots of these
private decimal fooVar23;
public Foo()
{
}
public bool FooVar1
{
get;
set;
}
//you get the picture...
}
public class FooMonitor
{
private Foo defaultFoo;
private List<Foo> allFoos;
public FooMonitor(Foo DefaultFoo)
{
defaultFoo = DefaultFoo;
}
public void AddFoo(Foo newFoo)
{
allFoos.Add(newFoo);
}
public void AddFoo(Foo oldFoo)
{
allFoos.Remove(oldFoo);
}
public bool IsFooVar1Consistent
{
get
{
Foo[] tempFoos = allFoos.ToArray();
foreach (Foo tempFoo in tempFoos)
{
if (tempFoo.FooVar1 != defaultFoo.FooVar1) return false;
}
return true;
}
}
}
Or am I approaching this problem entirely incorrectly.
As I'm writing this question (After about 2000 lines of code) I'm thinking of how I read that WPF itself implements Dictionary look ups that crawl up to the parent to see if a Property is present and what the value should be.
Well, for a start you are defining both backing fields which will never be used and automatic properties. This is enough for a simple bool property:
public bool FooVar1 { get; set; }
No need for the private field. This greatly reduces the number of lines in your example.
I'd love to find a way that is more
elegant since I'm having to cut and
past roughly the same code 20+ times
and just change property names.
Code generators exist for exactly this purpose. But if you don't want to go that route, you can shorten your code to this:
return allFoos.All(foo => foo.FooVar1 == defaultFoo.FooVar1);
I'm not quite sure what the question is, but if you're looking for some way to unify the IsFoorVarXConsistent code, you could do it using reflection or by passing in an expression:
public bool IsConsistent(Func<Foo, bool> property)
{
foreach (Foo tempFoo in allFoos)
{
if (property(tempFoo) != property(defaultFoo))
return false;
}
return true;
}
Called like this:
bool is1Consistent = IsConsistent(f => f.FooVar1);
As shown this will only work for boolean properties. To extend it to other types, we can make it generic in the property type. However, in this case we cannot use != to test for inequality because not all types define a != operator. Instead we can use the .Equals method and the ! operator:
public bool IsConsistent<T>(Func<Foo, T> property)
where T : struct
{
foreach (Foo tempFoo in allFoos)
{
if (!property(tempFoo).Equals(property(defaultFoo)))
return false;
}
return true;
}
The where T : struct clause restricts this to value types like int, bool and decimal. In particular it will not work on strings. Removing the where constraint allows it to work on strings and other reference types, but creates the possibility of property(tempFoo) being null, which would cause a NullReferenceException when we called .Equals on it. So if you remove the value types constraint then you will need to add error handling for this scenario.
Related
I have a class that has a field that is being assigned a value from multiple methods.
public class Shape
{
private Point2D m_location;
public void Move()
{
m_location = ...
}
public void Rotate()
{
m_location = ...
}
public void Flip()
{
m_location = ...
}
}
I am getting a warning from NDepend that says:
Don't assign a field from many methods
https://www.ndepend.com/default-rules/Q_Don't_assign_a_field_from_many_methods.html
I am thinking of solving this problem by creating a separate method to assign the value of the field and calling this method from the other methods that currently assign a value to the field.
Here is an example of the code:
private void SetLocation(Point2D point)
{
m_location = location;
}
I want to know if this is a valid way to solve the problem and if it will just hide the code-smell that NDepend detected or actually fix the issue.
Is this a valid way to solve this problem?
No. As you suspect, this is a code smell. What NDepend is complaining about is mutable references; you have code where:
var s = new SomeObject(someInitialization);
var r = s.SomeResult();
// you now have no idea what s contains or if it is even usable any more.
The solution to this is to make SomeObject immutable and return new references instead of changing internals:
public SomeObject Something()
{
return new SomeObject(SomethingDifferentDependingOn(this.something));
}
Now instead of your first example you have:
var s = new SomeObject(someInitialization);
var r = s.Something().Result;
// s is guaranteed to be unchanged.
Yes some times you will need mutable references. In those cases; document them and explain why they have to be mutable. Then you can override NDepend rules on a case-by-case basis to prevent it showing a warning. If you have a code smell, warn people. Do not try to hide it.
The example after your edit is quite different, but the general principle still holds. If you have only a few internal fields that all change in method calls you can still return immutable references, e.g.:
public Shape Move()
{
return new Shape(m_location ...);
}
If you have many internal fields that don't all change, or you need to do something like share private fields you can't easily have immutable reference, but you can still avoid the warning by using accessors:
public Location
{
get { return m_location; }
private set { m_location = value; }
}
Then use Shape.Location exclusively in your internal methods.
In my C# testing, I often want to compare two objects of the same type (typically an expected object against the actual object), but I want to allow for some flexibility. For example, there may be timestamp fields that I know can't be equal or some fields that I just want to ignore when comparing the objects.
Most importantly, I want to provide an informative message that describes where the two object properties' values differ in order that I can quickly identify what the problem is. For example, a message that says "Source property Name value Fred does not match target property Name value Freda".
The standard Equals and Comparer methods just seem to return ints or Booleans which don't provide enough information for me. At the moment, my object comparison methods return a custom type that has two fields (a boolean and a message), but my thinking is that there must be a more standard way to do this. These days, perhaps a Tuple might be the way to go, but I would welcome suggestions.
"Comparison" might not be the word for what you're trying to do. That word already has a common meaning in this context. We compare objects for equality, which returns a boolean - they are equal or they are not. Or we compare them to see which is greater. That returns an int which can indicate that one or the other is greater, or that they are equal. This is helpful when sorting objects.
What you're trying to do is determine specific differences between objects. I wouldn't try to write something generic that handles different types of objects unless you intend for them to be extremely simple. That gets really complicated as you get into properties that return additional complex objects or collections or collections of complex objects. It's not impossible, just rarely worth the effort compared to just writing a method that compares the particular type you want to compare.
Here's a few interfaces and classes that could make the task a little easier and more consistent. But to be honest it's hard to tell what to do with this. And again, it gets complicated if you're dealing with nested complex properties. What happens if two properties both contain lists of some other object, and all the items in those lists are the same except one on each side that have a differing property. Or what if they're all different? In that case how would you describe the "inequality" of the parent objects? It might be useful to know that they are or are not equal, but less so to somehow describe the difference.
public interface IInstanceComparer<T>
{
IEnumerable<PropertyDifference> GetDifferences(T left, T right);
}
public abstract class InstanceComparer<T> : IInstanceComparer<T>
{
public IEnumerable<PropertyDifference> GetDifferences(T left, T right)
{
var result = new List<PropertyDifference>();
PopulateDifferences(left, right, result);
return result;
}
public abstract void PopulateDifferences(T left, T right,
List<PropertyDifference> differences);
}
public class PropertyDifference
{
public PropertyDifference(string propertyName, string leftValue,
string rightValue)
{
PropertyName = propertyName;
LeftValue = leftValue;
RightValue = rightValue;
}
public string PropertyName { get; }
public string LeftValue { get; }
public string RightValue { get; }
}
public class Animal
{
public string Name { get; }
public int NumberOfLimbs { get; }
public DateTime Created { get; }
}
public class AnimalDifferenceComparer : InstanceComparer<Animal>
{
public override void PopulateDifferences(Animal left, Animal right,
List<PropertyDifference> differences)
{
if(left.Name != right.Name)
differences.Add(new PropertyDifference("Name", left.Name, right.Name));
if(left.NumberOfLimbs!=right.NumberOfLimbs)
differences.Add(new PropertyDifference("NumberOfLimbs",
left.NumberOfLimbs.ToString(),
right.NumberOfLimbs.ToString()));
}
}
You could use extension methods to do this. For example:
public static Extensions
{
public static void CompareWithExpected(this <type> value, <type> expected)
{
Assert.AreEqual(expected.Property1, value.Property1, "Property1 did not match expected";
Assert.AreEqual(expected.Property2, value.Property2, "Property2 did not match expected";
}
}
Then this can be used as follows:
public void TestMethod()
{
// Arrange
...
// Act
...
// Assert
value.CompareWithExpected(expected);
}
You could have any number of these extension methods allowing you the flexibility to check only certain values etc.
This also means you do not need to pollute your types with what is essentially test code.
I have class named "config" that have private string variable named "param".
I need to get from "config" class "param" variable sometimes as int type sometimes as bool type or string.
As I understand I need create 3 properties in config class,each property have to convert type, as follow:
The first property converts string to int, the second converts string to bool, the third property gets me the string value.
The class should look something like this:
class Config
{
private string param;
public int ParamAsInt
{
get
{
return int.Parse(param);
}
}
public bool ParamAsBool
{
get
{
return bool.Parse(param);
}
}
public string ParamAsString
{
get
{
return param;
}
}
}
But I don't know how can those properties be used in accordance to the variable type that I want to get out of class.
This code won't compile - int and such are reserved keywords and cannot be used as identifiers. You can either try naming your properties something like Int32Value, StringValue, etc., or try this:
public static implicit operator bool (Config config)
{
return bool.Parse(config.param);
}
public static implicit operator int (Config config)
{
return int.Parse(config.param);
}
This will allow for much cleaner code:
Config c = GetConfig("foo");
var isFeatureEnabled = false || c;
var spacing = 23 + GetConfig("bar");
You forgot to give your properties names. How would you expect to reference them? Something like this:
class Config
{
private string param;
public int ParamAsInt
{
get
{
return int.Parse(param);
}
}
public bool ParamAsBool
{
get
{
return bool.Parse(param);
}
}
public string ParamAsString
{
get
{
return param;
}
}
}
Note that I also fixed the casing in your calls to .Parse(). C# is case-sensitive. I also replaced the call to bool.TryParse() with bool.Parse(). The former (when used correctly, which this wasn't because it was missing a parameter) will only tell you if it is a bool, it won't tell you what value the bool actually has. (For example, bool.TryParse('false' out someBool) will return true.)
Of course, this code is a bit dangerous. You'll want to start with some more defensive programming to check those values. Basically, look up TryParse() and how to use it correctly. Something like this, for example:
public int ParamAsInt
{
get
{
var tmp = default(int);
if (int.TryParse(param, out tmp))
return tmp;
else
// do something else? throw a specific exception?
}
}
Additionally, what is the purpose of this code? It seems like a very rushed and poor design. For any given value of param (how is that even being set, by the way?) this just sort of randomly tries to expose typed properties for it. If you guess the correct one, you're still left with others that will throw exceptions. Surely there's a much cleaner way to accomplish what you're trying to do. So what are you trying to do?
I'm looking to use "phantom types" to implement type-safe identifiers. There's a question here about doing this in F#.
I'd like to do this in C#. How?
I've got a solution (which has problems), so I'll post it as a possible answer to see if anyone can improve it.
Why not make it a sealed class with its constructor private?
public sealed class Id<TDiscriminator>
{
private Id() { }
//some static methods
}
I've come up with the following:
struct Id<TDiscriminator>
{
private readonly Guid _id;
private Id(Guid id)
{
_id = id;
}
public Guid Value
{
get { return _id; }
}
public static Id<TDiscriminator> NewId()
{
return From(Guid.NewGuid());
}
public static Id<TDiscriminator> From(Guid id)
{
return new Id<TDiscriminator>(id);
}
public static readonly Id<TDiscriminator> Empty = From(Guid.Empty);
// Equality operators ellided...
}
...which I can use as follows:
class Order { /* empty */ }
class Customer { /* empty */ }
void Foo()
{
var orderId = Id<Order>.NewId();
var customerId = Id<Customer>.NewId();
// This doesn't compile. GOOD.
bool same = (orderId == customerId);
}
I don't particularly want concrete classes for the discriminator, because I don't want anyone instantiating them.
I could get around that by using an interface or an abstract class. Unfortunately, these can still be derived from and instantiated.
C# won't let you use a static class as a type argument. I can't say that I'm totally happy with the answers to that question, because the answers basically say "just because".
How about?
public sealed class Order
{
private Order() {}
}
public static sealed class Id<T>
{
// ...
}
I think that's exactly what you say. No one (except some special cases) can construct it and no one can inherit from it.
Well, as far as I could understand, you would like to provide a mechanism for distinguishing different types by a custom identifier object. I think you are almost near a working solution. In .NET when having a generic class, each substitution of the generic argument (or each unique combination of the generic arguments, if more than one) creates a unique type in the runtime. In your code Id<Order> and Id<Customer> are two distinct types. The NewId() method returns an instance of Id<Order> for the orderId and Id<Customer> for the customerId variables. The two types do not implement the == operator and therefore cannot be compared. Moreover, such comparison would be difficult to implement, since you cannot determine all possible uses of the Id<TDsicriminator> - you cannot guess what type will the TDsicriminator be substituted with.
1
A fast and simple solution will be to do this:
class Order { /* skipped */ }
class Customer { /* skipped */ }
void Foo()
{
var orderId = Id<Order>.NewId();
var customerId = Id<Customer>.NewId();
bool sameIds = (orderId.Value == customerId.Value); // true
bool sameObjects = orderId.Equals(customerId); // false
}
Since the Value properties are both of the Guid type, comparison is possible.
2
If you need however, to implement the == operator, or some sort of equality comparisons for instances of Id<TDisciminator>, the approach will be different. What comes up to my mind is the following:
public abstract class IdBase
{
public abstract Guid Value { get; protected set; }
public static bool operator == (IdBase left, IdBase right)
{
return left.Value == right.Value;
}
}
public sealed class Id<TDiscriminator> : IdBase
{
// your implementation here, just remember the override keyword for the Value property
}
Many people would not recommend the second approach though, since different implementations of IdBase may happen to have the same Value property (if you used the constructor that passes an existing ID). For instance:
var guid = Guid.NewGuid();
var customerID = Id<Customer>.From(guid);
var orderID = Id<Order>.From(guid);
Here (customerID == orderID) will then return true which is probably not what you want.
Shortly, in such a case, two different types will count as equal, which is a big logical mistake, so I'd stick to the first approach.
If you need Id<Customer>.Value to always be different than Id<Order>.Value, because of the different generic arguments (Customer is different than Order), then the following approach will work:
public sealed class Id<in TDiscriminator>
{
private static readonly Guid _idStatic = Guid.NewGuid();
private Id()
{
}
public Guid Value
{
get { return _idStatic; }
}
}
Notice the in keyword used here. This is applicable for .NET 4.0 where generics can be covariant and ensures that your class uses contravariant generics. (see http://msdn.microsoft.com/en-us/library/dd469487.aspx). In the above code, the _idStatic field will have a unique value for every different type supplied as a generic argument.
I hope this info is helpful.
I have a class (Foo) which lazy loads a property named (Bar). What is your preferred way to protect against mistaken use (due to intellisense or inexperienced staff) of the uninitialized backing field?
I can think of 3 options:
class Foo {
// option 1 - Easy to use this.bar by mistake.
string bar;
string Bar {
get {
// logic to lazy load bar
return bar;
}
}
// option 2 - Harder to use this._bar by mistake. It is more obscure.
string _bar2;
string Bar2 {
get {
// logic to lazy load bar2
return _bar2;
}
}
//option 3 - Very hard to use the backing field by mistake.
class BackingFields {
public string bar;
}
BackingFields fields = new BackingFields();
string Bar3 {
get {
// logic to lazy load bar
return fields.bar;
}
}
}
Keep in mind, the only place I want people mucking around with the backing field bar is in setter and getter of the property. Everywhere else in the class they should always use this.Bar
Update
I am currently using the following Lazy implementation (not for all properties with backing fields, but for select ones that require lazy loading, synchronization and notification). It could be extended to support futures as well (force evaluation in a separate thread in a later time)
Note My implementation locks on read, cause it supports an external set.
Also, I would like to mention that I think this is a language limitation which can be overcome in Ruby for example.
You can implement lazy in this way.
x = lazy do
puts "<<< Evaluating lazy value >>>"
"lazy value"
end
puts x
# <<< Evaluating lazy value >>>
# lazy value
How about use of ObsoleteAttribute and #pragma - hard to miss it then!
void Test1()
{
_prop = ""; // warning given
}
public string Prop
{
#pragma warning disable 0618
get { return _prop; }
set { _prop = value; }
#pragma warning restore 0618
}
[Obsolete("This is the backing field for lazy data; do not use!!")]
private string _prop;
void Test2()
{
_prop = ""; // warning given
}
Option 5
Lazy<T>
works quite nicely in several situations, though option 1 should really be just fine for most projects so long as the developers aren't idiots.
Adding [EditorBrowsable(EditorBrowsableState.Never)] to the field won't help if it is private since this logic only kicks in for intellisense generated from metadata rather than the current code (current project and anything done via project references rather than dlls).
Note: Lazy<T> is not thread safe (this is good, there's no point locking if you don't need to) if you require thread safety either use one of the thread safe ones from Joe Duffy or the Parallel Exetensions CTP
I usually go for option 2, as it is easier to spot mistakes later on, although option 1 would pass a code review. Option 3 seems convoluted and whilst it may work, it's not going to be nice code to revisit 6 months down the line whilst trying to refactor/fix a bug/etc.
Option 1, coupled with some education.
Rationale: software is meant to be read more often than written, so optimize for the common case and keep it readable.
Code reviews will catch misuse so just go with the most readable. I dislike attempts to work around bad programmers in code, because 1) they don't work, 2) they make it harder for smart programmers to get their work done, and 3) it addresses the symptom rather than the cause of the problem.
I usually just go for option 1. Because it is a private field I don't think it really an issue, and using something like the wrapper class as in your option 3 only makes code difficult to read and understand.
I would just put a large comment block on the top of the class that would look like that:
/************************************************************
* Note: When updating this class, please take care of using *
* only the accessors to access member data because of *
* ... (state the reasons / your name, so they can ask *
* questions) *
*************************************************************/
Usually, just a note like that should be enough, but if this is the same for all the classes in the project, you might prefer to put it in a simple document that you give to programmers working on the project, and everytime you see code that isn't conform, you point them to the document.
Automatic properties:
public int PropertyName { get; set; }
will prevent access to the backing field. But if you want to put code in there (e.g. for lazy loading on first access) this clearly won't help.
The simplest route is likely to be a helper type which does the lazy loading, and have an private field of that type, with the public property calling to the correct property/method of the helper type.
E.g.
public class Foo {
private class LazyLoader {
private someType theValue;
public someType Value {
get {
// Do lazy load
return theValue;
}
}
}
private LazyLoader theValue;
public someType {
get { return theValue.Value; }
}
}
This has the advantage that the backing field is harder to use than the property.
(Another case of an extra level of indirection to solve problems.)
// option 4
class Foo
{
public int PublicProperty { get; set; }
public int PrivateSetter { get; private set; }
}
C# 3.0 feature, the compiler will generate anonymous private backing fields which can't be accessed by mistake, well unless you use reflection...
EDIT: Lazy instantiation
You can have laziness like this:
// I changed this with respect to ShuggyCoUk's answer (Kudos!)
class LazyEval<T>
{
T value;
Func<T> eval;
public LazyEval(Func<T> eval) { this.eval = eval; }
public T Eval()
{
if (eval == null)
return value;
value = eval();
eval = null;
return value;
}
public static implicit operator T(LazyEval<T> lazy) // maybe explicit
{
return lazy.Eval();
}
public static implicit operator LazyEval<T>(Func<T> eval)
{
return new LazyEval(eval);
}
}
Those implicit conversion make the syntax tidy...
// option 5
class Foo
{
public LazyEval<MyClass> LazyProperty { get; private set; }
public Foo()
{
LazyProperty = () => new MyClass();
}
}
And closures can be used to carry scope:
// option 5
class Foo
{
public int PublicProperty { get; private set; }
public LazyEval<int> LazyProperty { get; private set; }
public Foo()
{
LazyProperty = () => this.PublicProperty;
}
public void DoStuff()
{
var lazy = LazyProperty; // type is inferred as LazyEval`1, no eval
PublicProperty = 7;
int i = lazy; // same as lazy.Eval()
Console.WriteLine(i); // WriteLine(7)
}
}
Currently, I'm in a similar situation.
I have a field which should only be used by its property accessor.
I can't use automatic properties, since I need to perform additional logic when the property is set. (The property is not lazy loaded as well).
Wouldn't it be great if a next version of C# would allow something like this:
public class MyClass
{
public int MyProperty
{
int _backingField;
get
{
return _backingField;
}
set
{
if( _backingField != value )
{
_backingField = value;
// Additional logic
...
}
}
}
}
With such construct, the _backingField variable's scope is limited to the property.
I would like to see a similar language construction in a next version of C# :)
But, I'm afraid this feature will never be implemented:
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=381625
This might be overly simple, but why not abstract all the lazy to a base class
public class LazyFoo{
private string bar;
public string Bar{
get{
// lazy load and return
}
set {
// set
}
}
}
public class Foo : LazyFoo{
// only access the public properties here
}
I could see the argument that it is unnecessary abstraction, but it is the simplest way I can see to eliminate all access to backing fields.
This seems like trying to design-out mistakes that might not happen in the first place, and basically it's worrying about the wrong thing.
I would go with option 1 + comments:
///<summary>use Bar property instead</summary>
string bar;
///<summary>Lazy gets the value of Bar and stores it in bar</summary>
string Bar {
get {
// logic to lazy load bar
return bar;
}
}
If you do get a developer who keeps using the backing variable then I'd worry about their technical competence.
By all means design to make your code easier to maintain, but try to keep it simple - any rule that you make for yourself here is going to be more hassle than it's worth.
And if you're still really worried about it create an FxCop (or whatever you're using) rule to check for this sort of thing.
Option 6:
Makes it very dumb indeed if you use it.
string doNotUseThisBackingField_bar6;
string Bar6 {
get {
// logic to lazy load
return doNotUseThisBackingField_bar6;
}
}
Option 4 (a new solution):
See if the question is really about how to prevent people from using an uninitialized variable then init it with an KNOWN INVALID value.
I would say something like:
string str = "SOMETHING_WRONG_HERE";
Who ever is using 'str' will have some sort of warning.
Otherwise Option 3 if preventing users from using 'str' is more important than readability etc.