I am having trouble using an IList property which always seems to return null, even though the member is is getting is instantiated:
private List<ModelRootEntity> _validTargets = new List<ModelRootEntity>();
public IList<IModelRootEntity> ValidTargets
{
get
{
return _validTargets as IList<IModelRootEntity>;
}
protected internal set
{
if (value == null)
_validTargets.Clear();
else
_validTargets = value as List<ModelRootEntity>;
}
}
ModelRootEntity implements IModelRootEntity. I watched both values during debugging, whilst the member shows a positive count, the property stays null.
I also tried raising an exception within the property getter to throw if the counts of _validTargets and _validTargets as List<ModelRootEntity> are different, but it never threw.
Found question [Dictionary properties are always null despite dictionaries being instantiated, which seems similar, however in my case this seems to happen regardless of serialization.
Any ideas?
If you set your property to any value that isn't a List<ModelRootEntity>, the as expression will return null and the property will become null.
I found the answer, thanks to #Nilesh comment above.
Replacing:
private List<ModelRootEntity> _validTargets = new List<ModelRootEntity>();
with:
private List<IModelRootEntity> _validTargets = new List<ModelRootEntity>();
exposed the real issue. The second line will not compile. The following post explained why:
C# newbie List<Interface> question
The only odd thing was the exception I tried to force which never threw, and "threw" me off.
Related
I have a problem, under http://www.pathofexile.com/api/public-stash-tabs link there is a huge API that returns a JSON string. Many of fields in this JSON are optional, that means they only appear if there is value present.
So theoretical "Item1" can have "abyssJewel" property but
"item2" doesnt have to have "abyssJewel" property
When i try to query this JSON with JSON.Linq like this
AbyssJewel = (bool)item["abyssJewel"];
in the case of Item1 everything is good and it returns proper value
but in case of Item2 i get exception "InvalidOperationException, Cannot access child value on Newtonsoft.Json.Linq.JProperty"
I understand its because for Item2 no abyssJewel property in JSON exists so it throws exception.
My question is this, how can i handle it so that instead of throwing exception it would return a default or null value for this particular field?
I have tried playing with Activator but couldnt make anything working on my own. Any tips?
im instantiating it like this:
apiPages.Add(new Page
{
Next_Change_Id = (string)jsonObject["next_change_id"],
Stashes = jsonObject["stashes"].Select(stash => new Stash
{
AccountName = (string)stash["accountName"],
StashName = (string)stash["stash"],
StashType = (string)stash["stashType"],
Public = (bool)stash["public"],
LastCharacterName = (string)stash["lastCharacterName"],
UniqueId = (string)stash["id"],
Items = stash.Select(item => new Item
{
AbyssJewel = (bool)item["abyssJewel"],
...tl;dr...
Instead of casting directly you should try to use the TryParse() method from the Boolean class, if something goes wrong it must return false. See here
Hope it will fix your problem.
So, First of all. Code:
I've got a class:
public class Myobject
{
public string Code { get; set; }
public DateTime? StartDate { get; set; }
}
And this is part of very simple source:
MyObject mo = new MyObject();
mo.Code= "sth";
// NO action on StartDate property!
if (mo.StartDate.HasValue)
{
sc.Parameters.Add(new SqlParameter("#inStartDate", mo.StartDate.Value));
}
else
{
sc.Parameters.Add(new SqlParameter("#inStartDate", DBNull.Value));
}
Simple 'if' - Sql Server 2008, throw an error - when gets null Datetime (it has to be DBNull.Value)
So I want to check it first, and then pass right value or DBNull.
My problem is - this 'if' always retruns true! Why!?
Also tried that:
if (mo.StartDate.Value == null)
but it always returns false. How come it is not a null? It was not even created..
So.. How to check if DateTime object was not assigned?
Try this:
if (mo.StartDate.GetValueOrDefault() != DateTime.MinValue)
{
// True - mo.StartDate has value
}
else
{
// False - mo.StartDate doesn't have value
}
should just be able to do
mo.StartDate != null
instead of
mo.StartDate.Value != null
Running the simplest test with that class (as you presented it) yields false:
var mo = new Myobject();
Console.WriteLine(mo.StartDate.HasValue);
Output is False.
I'd put a breakpoint on your constructor (if you have one), make sure nothing else is getting assigned, and walk through any methods called along the way to make sure there's nothing else setting the property that may not be immediately obvious...
Can you post more code, perhaps? There must be something in code not posted setting the property.
.HasValue and ==null are the ways to check whether DateTime? is assigned a value or not. You are doing it right. There might be problem somewhere else that .HasValue returns true always.
The way you're checking for null is fine, there must be something else that's setting the field's value.
To find what's setting the field you could right-click it then do find all references, then scan the list for any assignments.
Failing that, you could change it to an explicitly defined property temporarily and set a breakpoint within the set method, then execution will pause whenever the value is set and you can look up the call stack.
I'm upgrading a system and am going through another developers code (ASP.NET in C#).
I came across this:
private ReferralSearchFilterResults ReferralsMatched
{
get
{
if (Session[SESSION_REFERRAL_SEARCHFILTERRESULTS] == null || Session[SESSION_REFERRAL_SEARCHFILTERRESULTS].GetType() != typeof(ReferralSearchFilterResults))
return null;
else
return (ReferralSearchFilterResults)Session[SESSION_REFERRAL_SEARCHFILTERRESULTS];
}
set
{
if (value == null)
{
Session[SESSION_REFERRAL_SEARCHFILTERRESULTS] = value;
}
else if (value.GetType() == typeof(ReferralSearchFilterResults))
{
Session[SESSION_REFERRAL_SEARCHFILTERRESULTS] = value;
}
}
}
Is checking the type on the setter unnecessary? Surely, if I set the property to something other than a ReferralSearchFilterResults object, the code wouldn't even compile? Am I missing something or am I right to think this can be achieved just by using:
set
{
Session[SESSION_REFERRAL_SEARCHFILTERRESULTS] = value;
}
The original code prevents any subclasses of ReferralSearchFilterResults from being set or get to or from the property. This is because value.GetType() will return the actual Type of the object referenced by value. If that Type is a subclass of ReferralSearchFilterResults, then it will not equals typeof(ReferralSearchFilterResults).
I'm not sure of your context here, so I can't tell you whether that's correct behaviour or not. If it's intended behaviour, it does smell a bit dirty as it will silently ignore any assignments of subclasses. But I can't really judge without more context.
I think you're right - the setter shouldn't compile if provided with something of that cannot be implicitly cast to a ReferralSearchFilterResults.
For the get part, you can use
return Session[SESSION_REFERRAL_SEARCHFILTERRESULTS] as ReferralSearchFilterResults;
This returns the value if it can be casted to ReferralSearchFilterResults, otherwise null.
Jamie you are correct. The Type check on the Setter is unnecessary in this case because value must be a ReferralSearchFilterResults.
One other change you might consider is using the is and as keywords in place of comparing Type objects.
private ReferralSearchFilterResults ReferralsMatched
{
get
{
if (Session[SESSION_REFERRAL_SEARCHFILTERRESULTS] == null || !(Session[SESSION_REFERRAL_SEARCHFILTERRESULTS] is ReferralSearchFilterResults))
return null;
else
return Session[SESSION_REFERRAL_SEARCHFILTERRESULTS] as ReferralSearchFilterResults;
}
set
{
Session[SESSION_REFERRAL_SEARCHFILTERRESULTS] = value;
}
}
Session variables are of type object, so you can store anything inside those. But in this case the setter itself prevents the programmer from assigned an other object type than ReferralSearchFilterResults and derived objects.
So the check, as you pointed out, itself is unneccessary. Additionally it does not let a programmer assign a object that derives from ReferralSearchFilterResults.
But I would use Session.Remove rather than just setting the variable to null, because the session variable would still exists in the http context if only set to null.
So:
set
{
if (value == null)
Session.Remove(SESSION_REFERRAL_SEARCHFILTERRESULTS);
else
Session[SESSION_REFERRAL_SEARCHFILTERRESULTS] = value;
}
I can understand the type check in the get bit, but as you say, in the setter, you can't pass in anything that's not a ReferralSearchFilterResults, as the code would fail at the time of compilation.
(Could be some old habit, the other developer had)
I have a class property that is a list of strings, List.
Sometimes this property is null or if it has been set but the list is empty then count is 0.
However elsewhere in my code I need to check whether this property is set, so currently my code check whether it's null and count is 0 which seems messy.
if(objectA.folders is null)
{
if(objectA.folders.count == 0)
{
// do something
}
}
Any recommendation on how this should be handled?
Maybe I should always initialise the property so that it's never null?
When I have List as a property, I usually have something that looks like the following (this is not a thread safe piece of code):
public class SomeObject
{
private List<string> _myList = null;
public List<string> MyList
{
get
{
if(_myList == null)
_myList = new List<string>();
return _myList;
}
}
}
Your code would then never have to check for null because the Property would be initialized if used. You would then only have to check for the Count.
Right now your code will Always throw a Null Pointer exception, you are checking for Null and if it IS null - you're trying to access an object which does not exist.
If for your application the collection being a null reference never has a different meaning than the collection being empty, then yes, I would say you should always initialize it and this way remove the null checks from the remaining code.
This approach only makes sense if the property setter does not allow to change it to a null reference after initialization.
You have three options (and you need to decide based on your project):
Create a method to check for NullOrNoElements. Pro: Allows both null and no entries. Con: You have to call it everywhere you want to use the property.
Preinitialize with a list. Pro: Thread-save and very easy. Con: will use memory even when not used (depending on how many instances you have this may be a problem)
Lazy initialize Pro: Does only use memory when really used. Con: NOT thread save.
private List<string> lp = null;
public List<string> ListProp
{
get
{
if(lp == null)
lp = new List<string>();
return lp;
}
}
You could always initialize the property so it's an empty List. Then you can just check the count property.
List<String> Folder = Enumerable.Empty<String>();
I once wrote an extension method for ICollection objects that checked if they were null or empty
public static Boolean IsNullOrEmpty<T>(this ICollection<T> collection)
{
return collection == null ? true : collection.Count() == 0;
}
public static Boolean IsPopulated<T>(this ICollection<T> collection)
{
return collection != null ? collection.Count() > 0 : false;
}
You could do this in a single IF
if(objectA.folders is null || objectA.folders.count == 0)
Or you could create a boolean property in the class which checks this status for you and returns a result
public bool objectA.FolderIsNullOrEmpty
{
get { return objectA.folders is null || objectA.folders.count == 0;}
}
If it does not make a difference to your application, I would rather recomend initializing the List to start with.
You could handle this by initializing the object in the constructor. This is usually where this type of thing is done. Although I see nothing wrong with your current code. No point in initializing stuff that doesn't exist yet, it just wastes memory.
Its a good question. I would add a method to objectA FoldersNullOrEmpty() that you can use eg
public virtual FoldersNullOrEmpty()
{
return (folders == null || folders.count == 0)
}
I almost always initialize lists and even make sure they can't be set to null if exposed by any setters. This makes using them much easier.
i have a class with a static public property called "Info".
via reflection i want to get this properties value, so i call:
PropertyInfo pi myType.GetProperty("Info");
string info = (string) pi.GetValue(null, null);
this works fine as long as the property is of type string. but actually my property is of type IPluginInfo and a PluginInfo type (implementing IPluginInfo) is instatiated and returned in the Info properties get accessor, like this:
public static IPluginInfo PluginInfo
{
get
{
IPluginInfo Info = new PluginInfo();
Info.Name = "PluginName";
Info.Version = "PluginVersion";
return Info;
}
}
like this when i call:
IPluginInfo info = pi.GetValue(null, null) as IPluginInfo;
info is always null, whiel PropertyInfo pi is still valid. am i missing something obvious here?
Could you create a short but complete program that demonstrates the problem?
Given that you're talking about plugins, my guess is that you've got the problem of having IPluginInfo defined in two different assemblies. See if this article helps at all.
The easiest way to verify it is to call pi.GetValue and store the result in an object variable first, then do the cast or "as" in another line. That way you can break the debugger and look at the return value before it's lost.
My first guess would be that you have re-declared the IPluginInfo interface. All .NET types are scoped by their assembly; if you have the same class file in 2 assemblies, you have 2 different interfaces that happen to have the same name.
ok, thanks for all the answers.
i indeed already had the plugininterface in a separate .dll but had placed this .dll in the pluginhosts directory as well as in the directory with all the plugins.
Um, first of all I'd implement that property a little differently:
private static PluginInfo _PluginInfo = null;
public static IPluginInfo PluginInfo
{
get
{
if (_PluginInfo == null)
{
_PluginInfo = new PluginInfo();
_PluginInfo.Name = "PluginName";
_PluginInfo.Version = "PluginVersion";
}
return _PluginInfo;
}
}
Note that this needs a little more work because it isn't threadsafe, but hopefully you get the idea: build it one time rather than repeatedly.
I'll stop here now, since it looks like two others already finished the rest of my answer while putting together the first part.
In C#, AS returns null if the value does not match the type.
If you write:
object info = pi.GetValue(null, null);
Console.WriteLine(info.GetType().ToString());
what type do you receive?