Properties are making trouble - c#

In my application I have added a Properties.cs file which contains properties that I am would use through out the application. I am getting NullReferenceException => Object reference not set to an instance of an object.
Here is the code for Properties.cs
public class Properties
{
private static string type1;
public static string Type1
{
get
{
return type1;
}
set
{
type1= value;
}
}
}
And when I access this property in one of my form I am getting error. e.g.
if (Properties.Type1.Equals(string.Empty) || Properties.Type1.Equals(null))
{
// Do something
}

Firstly, you're making life hard for yourself. This is fine (or at least, just as fine, but a lot easier; whether or not static members is a good idea is a separate question, and depends a lot on the context):
public class Properties
{
public static string Type1 { get;set; }
}
Secondly, this has nothing to do with properties, and everything to do with calling a method on a null instance. You can just use == which avoids this issue, i.e.
if (Properties.Type1 == "" || Properties.Type1 == null)
{
// Do something
}
However, for convenience there is also string.IsNullOrEmpty:
if (string.IsNullOrEmpty(Properties.Type1))
{
// Do something
}

Use this instead:
if (string.IsNullOrEmpty(Properties.Type1))
{
// Do something
}

You are doing the null and empty check in the wrong way.
The correct way is:
if (string.IsNullOrEmpty(Properties.Type1))
{
....
}

You can do this
if (String.IsNullOrEmpty(Properties.Type1))
{
// Do something
}
but if you want a default value for this then I suggest you set it in a static constructor.

Related

Load property lazy loading

I have a property which getter should load its value only the first time. The second time it returns the loaded value without loading it again:
private Object _MemberValue;
public Object MemberValue
{
get
{
if(_MemberValue == null)
{
_MemberValue = LoadMember();
}
return _MemberValue;
}
}
In VB.NET there is the Static keyword. With it you don't have to declare a class wide member.
Public Property MemberValue as Object
Get
Static value as Object = Nothing
If (value is Nothing) Then
value = LoadMember()
End If
Return value
End Get
End Property
In C# there isn't such a keyword.
Are there better C# implementations of this problem or other patterns?
Are there better C# implementations of this problem or other patterns?
Probably not. You can use Lazy<T> as an replacement if you like, but basically it is the same as your first example. Using Static in VB.NET has some serious drawbacks, so I wouldn't use it either way.
If you prefer Lazy<T>, this is what I would use:
private Lazy<object> _MemberLazy = new Lazy<object>(LoadMember);
public object MemberValue
{
get
{
return _MemberLazy.Value;
}
}
Your initial approach seems appropriate, I have never had reason to do something different. That said if your goal here is to avoid a class level field that could potentially be written to outside the getter, perhaps something like this would work. There are a number of other ReadOnly, WriteOnce, SetOnce implementations that would also work similarly.
ReadOnlyField.cs
public class ReadOnlyField<T>
{
private bool _frozen;
private T _value;
public T Value
{
get { return _value; }
set
{
if (_frozen)
throw new InvalidOperationException();
_value = value;
}
}
public void Freeze()
{
_frozen = true;
}
}
YourObject.cs
public class YourObject
{
private readonly ReadOnlyField<object> _someMember;
public object MemberValue
{
get
{
if(_someMember.Value == null)
{
_someMember.Value = LoadMember();
_someMember.Freeze();
}
return _someMember.Value;
}
}
public YourObject()
{
_someMember = new ReadOnlyField<object>();
}
}
It's not perfect. Unlike your VB.Net example; code outside of the getter could write to the field first, but at least you're protected from it being overwritten after Freeze is called.

Is this good way of using .NET's System.Lazy

private Lazy<Image> _headshot = new Lazy<Image>(LoadHeadshotFromHDD);
public Image Headshot
{
get
{
return _headshot.Value;
}
set
{
_headshot = new Lazy<Image>(() => value);
}
}
Let's say I have a Person class and Headshot property is in that class. Headshot is loaded from HDD so I want it to be lazy, but I also want to implement setter for that property. Will there be a problem with the way that I've implemented this? I'm just not sure that I'm using it correctly.
There's really no point in using lazy loading if you already have the object in memory (in the setter case), but it's perfectly fine to do it this way. One thing I can think of, is if you'd check the _headshot.IsValueCreated, it'll return false, even though you already have the object in memory. Another alternative would be
private Image _headshot;
public Image Headshot
{
get { return _headshot ?? (_headshot = LoadHeadshotFromHDD()); }
set { _headshot = value; }
}
This will lazy load the headshot when the property is accessed, just like when using Lazy<T>, but it'll set the value directly, so you can check _headshot != null instead of _headshot.IsValueCreated. You should check out Jon Skeet's Singleton Pattern post.
Looks ok, however, if you'd take the initialization to the constructor, you could have less code.
public class Foo
{
public Foo()
{
this.Headshot = new Lazy<Image>( () => LoadHeadshotFromHDD );
}
public Lazy<Image> Headshot { get; set; }
}

Container for properties values

When .NET 4.5 was released i started using such great Attribute as CallerMemberName. It's easier to understand code, developers can write it faster also. It's like a snippet, not only a feature for debug/test purposes.
So I have a question. Is it normal to create and use something like this?
public class PropertyStore
{
Dictionary<string, object> data = new Dictionary<string,object>();
ViewModelBase modelBase;
internal PropertyStore(ViewModelBase _base)
{
modelBase = _base;
}
public void SetValue<T>(T value = default(T), [CallerMemberName] string prop = "")
{
T prev = GetValue<T>(prop);
if ((prev == null && value == null) || (prev != null && prev.Equals(value))) return;
data[prop] = value;
modelBase.OnPropertyChanged(prop);
}
public T GetValue<T>([CallerMemberName] string prop = "")
{
if (!data.ContainsKey(prop))
data[prop] = default(T);
return (T)data[prop];
}
}
Class-helper, that makes other class more readable, and also we have list of our properties without need to use Reflection.
The usage is:
public class SampleClass : ViewModelBase
{
PropertyStore PropertyStore;
public SampleClass ()
{
PropertyStore = new PropertyStore(this);
}
public string Key
{
get { return PropertyStore.GetValue<string>(); }
set { PropertyStore.SetValue(value); }
}
public DateTime Date
{
get { return PropertyStore.GetValue<DateTime>(); }
set { PropertyStore.SetValue(value); }
}
public bool IsSelected
{
get { return PropertyStore.GetValue<bool>(); }
set { PropertyStore.SetValue(value); }
}
}
The class ViewModelBase here simply implements INotifyPropertyChanged interface.
As I understand, this approach is something like Microsoft Dependency Properties, but I don't need all power of DependencyObject class, and I don't want inherit it.
With something like this I can use Binding, because it's enough to implement INotifyPropertyChanged, also we have no fields (as for me, i try to use properties smarter, than using fields directly (however, there is no problem to use Dictionary directly ^_^))
Sorry for my bad English... Not main language and not much practice.
Another Sample (after moving Methods to base class)
public class SampleClass : ViewModelBase
{
public string Key
{
get { return GetValue<string>(); }
set { SetValue(value); }
}
public DateTime Date
{
get { return GetValue<DateTime>(); }
set { SetValue(value); }
}
public bool IsSelected
{
get { return GetValue<bool>(); }
set { SetValue(value); }
}
}
No diff with Microsoft's WPF Property System.
Only feature you'll get with it is an ability to access property values via Dictionary.Get|Set methods.
You can get this ability with field based implementation of INotifyPropertyChanged. You can access property values by its name using dictionary, with property name to precompiled delegate mapping like it done in Yappi project.
var dateValue= Property<SampleClass>.Get<DateTime>(this,"Date");
Property<SampleClass>.Set<DateTime>(this,"Date",DateTime.Now);
Both can be rewritten as extension methods.
Nice idea, property bag without reflection and it will even work with obfuscation.
I don't see major problems with it but you may consider the following:
The prop parameter is optional so potentially a bug can be introduced by given a value in the call.
Value types will get boxed.
Access to the fields is relatively more expensive, can be a factor more expensive as you have much more code in a simple get (especially with boxing).
Dictionary takes more space than the number of properties you keep in (especially with boxing).
Each property also stores a string of the property name adding to the overhead.

How to use multi properties in class that contain one variable?

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?

Property as parameter? C#

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.

Categories