Is resharper right about this code being unreachable? - c#

Reshaper said the left hand side of ?? was never null even though its type is int?
_savedMediaFileId = mediaFile.MediaFileId ?? _savedMediaFileId;
The auto refactor "remove unreachable code" turned it into this:
_savedMediaFileId = (int) mediaFile.MediaFileId;
Is that right or is Resharper making a mistake here?
My idea was that since int? is nullable, then then I could use ?? to keep the existing value in the case it is null.
Here's my unit test (in progress)
[TestClass]
public class MediaRepositoryTest
{
private const string SiteId = "3";
private const string ConnectionString =
#"Data Source=dvmind\mssqlsites;Database=***********;User Name=sa;Password=**************";
private string _mediaSourceName = "TestMediaSourceName";
private string _mediaTypeName = "TestMediaTypeName";
private string _mediaSourceAddress = "TestMediaSourceAddress";
private string _mediaFileAddress = "TestMediaFileAddress";
private int _savedMediaFileId = 0;
private string GetGuidString()
{
return Convert.ToBase64String(Guid.NewGuid().ToByteArray());
}
[TestInitialize]
public void TestInitialize()
{
_mediaSourceName = _mediaSourceName + GetGuidString();
_mediaTypeName = _mediaTypeName + GetGuidString();
_mediaSourceAddress = _mediaSourceAddress + GetGuidString();
_mediaFileAddress = _mediaFileAddress + GetGuidString();
}
[TestCleanup]
public void TestCleanup()
{
using (var db = new SiteContext(ConnectionString))
{
if (_savedMediaFileId != 0)
{
(from c in db.MediaFiles where c.MediaFileId == _savedMediaFileId select c).ToList()
.ForEach(c => db.MediaFiles.Remove(c));
}
(from c in db.MediaSources where c.MediaSourceName == _mediaSourceName select c).ToList()
.ForEach(c => db.MediaSources.Remove(c));
(from c in db.MediaTypes where c.MediaTypeName == _mediaTypeName select c).ToList()
.ForEach(c => db.MediaTypes.Remove(c));
}
}
[TestMethod]
public void SaveMediaTest()
{
var mediaSource = new MediaSource
{
MediaSourceName = _mediaSourceName,
MediaSourceAddress = _mediaSourceAddress
};
var mediaType = new MediaType
{
MediaTypeName = _mediaTypeName
};
var mediaFile = new MediaFile
{
SiteId = SiteId,
MediaFileAddress = _mediaFileAddress,
MediaSource = mediaSource,
MediaType = mediaType
};
var connectionStringProvider =
Mock.Of<IConnectionStringProvider>(c => c.GetConnectionString() == ConnectionString);
var repository = new MediaRepository(connectionStringProvider);
Assert.IsTrue(mediaFile.MediaFileId == 0);
repository.SaveMedia(mediaFile);
Assert.IsTrue(mediaFile.MediaFileId != 0);
_savedMediaFileId = mediaFile.MediaFileId ?? _savedMediaFileId;
//using (var db = new SiteContext(ConnectionString))
//{
//}
}

Now that you've posted a complete example, I think the reason you are getting unreachable code, is due to the Assert conditions that precede this line;
Assert.IsTrue(mediaFile.MediaFileId == 0);
If mediaFile.MediaFileId is null, the program exits on this line, if its not, then the warning is correct; mediaFile.MediaFileId cannot be null on the line you highlight;
_savedMediaFileId = mediaFile.MediaFileId ?? _savedMediaFileId;
Also, if the definition of SaveMedia took a ref MediaFile that would also impact the warning, because it is then possible (as far as ReSharper is concerned) that the value is changed again to Null by;
repository.SaveMedia(mediaFile);
Either of these changes will impact the presence of the warning.

ReSharper is likely inferring here that mediaFile.MediaFileId can never have the value null even though the type is int?. Hence it's suggesting that you skip the null check entirely and go straight for the value
A clearer example is the following
string s = "hello world";
if (s != null) {
...
}
In this case s can be null practically because it is of type string and null is a valid value. However in this specific context s can never be null hence ReSharper would flag this check as unnecessary

This is a bit of a guess, but I think what's happening here (based on MSDN
When you declare someting int?, it doesn't create a reference type that can be null. Instead, it creates Nullable<T> which is a struct meaning it cannot be Null b/c it is a value type. That struct besides the value contains a boolean flag that tells it if it is null of if value is valid.
Hence, doing int? ?? is essentially testing a struct for null value which it can never be. It does not test Nullable<T>.HasValue which is a way to test if is "null" or not.
Hence the ReSharper complaint.

Related

Find the null value of a Datatable

I am building a AWS lambda function .net core.
The issue I am encountering is, when there is no data in the row / column of the datatable I still get a count of one, in turn getData != null && getData.Count() > 0 defaults true and then throws a NullRefrenceError since the value is null when it goes to the loop, I have tried checking for multiple null types in datatable with them still defaulting to true.
Is there another way to check for nullable values, to avoid the assignment causing the error in a datatable column / row.
public object emailGets ( AType invoiceNum, ILambdaContext context )
{
Connection conn = new Connection();
try
{
string query = "SELECT QUERY";
conn.getData(query);
DataRow[] getData = conn.Dt.Select();
if(getData != null && getData.Count() > 0)
{
foreach (var item in getData)
{
string yourItem = item.Field<String>("email").ToString();
}
return new userData { email = yourItem};
}
else
{
return new userEmailAddress { email = null};
}
} catch ( Exception e )
{
throw e;
}
}
}
public class userEmailAddress
{
public string email { get; set; }
}
ToString() will throw a NullReferenceException when the source is null. So when you do
string yourItem = item.Field<String>("email").ToString();
and the item.Field<String>("email") part returns null, you'll get that exception.
Luckily, that ToString() call is redundant, so you can simply remove it and just have:
string yourItem = item.Field<String>("email");
Keep in mind that yourItem can now be null here.

C# LDAP SearchResult to class properties

I hope someone can help with this. For a few years now, I've been iterating through my searchresult using a LOT of If statements to populate all of the properties in my class. There are over 300 properties that I need to populate.. but that is an awful lot of if statements. As an example, this is what I mean:
var myCon = StarfishLDAPCon.CreateDirectoryEntry(objectContainer, whichCM);
var ds = new DirectorySearcher(myCon);
ds.Filter = "(deftyAgentID=07629)";
var result = ds.FindOne();
AgentID returnValue = new AgentID();
if (result.Properties.Contains("deftyAgentID"))
{
returnValue.DeftyAgentID = result.Properties["deftyAgentID"][0].ToString();
}
if (result.Properties.Contains("deftySecuritycode"))
{
returnValue.DeftyAgentID = result.Properties["deftySecuritycode"][0].ToString();
}
if (result.Properties.Contains("deftyAgentACWAgentConsdrdIdle"))
{
returnValue.DeftyAgentACWAgentConsdrdIdle = result.Properties["deftyAgentACWAgentConsdrdIdle"][0].ToString();
}
I have over 300 of those if statements. I'm hoping there's some cool way to do this without all those if statements? Anyone have any ideas?
Thanks for any help!
Dave M.
Well pretty simple - just write a small extension method like this:
public static class SearchResultExtension
{
public string GetPropertyValue(this SearchResult result, string propName)
{
if (result == null || result.Properties == null)
{
return null;
}
if (result.Properties.Contains(propName))
{
return result.Properties[propName][0].ToString();
}
return null;
}
}
Now you can handle the 80% "normal" cases like this:
SearchResult result = ds.FindOne();
AgentID returnValue = new AgentID();
returnValue.DeftyAgentID = result.GetPropertyValue("deftyAgentID");
returnValue.DeftySecurityCode = result.GetPropertyValue("deftySecuritycode");
returnValue.DeftyAgentACWAgentConsdrdIdle = result.GetPropertyValue("deftyAgentACWAgentConsdrdIdle");
and so forth. Any cases that should not return the first element of the Properties collection as a string need to be handled separately, obviously

Xamarin iOS cant get a specific variable from a PushNotification Payload

By sending the following APNS-Payload:
{"aps":{"alert":"test Push","badge":1,"sound":"default"},
"objid":"SomeID","vid":"4229", "title":"aTitle","type":"queryform",
"idArray":["-100", "SomeID"]}`
The following method converts the NSDictionary to a class(notificationInfo is the userInfo from "receivedNotification".
Following problem: if the ObjectForKey:"idArray" to get the "idArray" is equal the key in the payload, the variable objid is null. But objid exists in the notificationInfo. If I rename "idArray" e.g. to Idarray, objid would be set.
ApnsNotificationInfo GetApnsNotificationInfo(NSDictionary notificationInfo)
{
var apnsInfo = new ApnsNotificationInfo();
if (notificationInfo == null || notificationInfo.Count == 0)
return apnsInfo;
var idArray = notificationInfo.ObjectForKey(new NSString("idArray")) as NSArray;
if (idArray != null && idArray.Count > 0)
{
var articleId = (idArray.Count == 2) ?
idArray.GetItem<NSNumber>(1) :
idArray.GetItem<NSNumber>(0);
if (articleId == null)
return apnsInfo;
apnsInfo.ArticleId = articleId.Int32Value;
if (idArray.Count == 2)
{
var categoryId = idArray.GetItem<NSNumber>(0);
if (categoryId != null)
apnsInfo.CategoryId = categoryId.Int32Value;
}
}
NSString message = null;
var aps = notificationInfo.ObjectForKey(new NSString("aps")) as NSDictionary;
if (aps != null)
message = aps.ObjectForKey(new NSString("alert")) as NSString;
if (message != null)
apnsInfo.Message = message.ToString();
var title = notificationInfo.ObjectForKey (new NSString ("title")) as NSString;
var type = notificationInfo.ObjectForKey (new NSString ("type")) as NSString;
var objid = notificationInfo.ObjectForKey (new NSString ("objid")) as NSString;
var vid = notificationInfo.ValueForKey (new NSString ("vid")) as NSString;
if(!string.IsNullOrEmpty (title)){
apnsInfo.Title = title;
}
if (!string.IsNullOrEmpty (type)) {
apnsInfo.Type = type;
if(objid != null){
apnsInfo.requestID = objid.ToString ();
}
if(vid != null){
apnsInfo.vid = Convert.ToInt32 (vid);
}
}
return apnsInfo;
}
Another explanation for my problem: if i send this payload:
{"aps":{"alert":"test Push","badge":1,"sound":"default"}, "objid":"SomeID","vid":"4229", "title":"aTitle","type":"queryform", "Idarray":["-100", "SomeID"]}
var objid = notificationInfo.ObjectForKey (new NSString ("objid")) as NSString;
objid would be set. If the array in the payload is called: idArray, objid = null
This is really weird. I hope someone can help.
So although I don't entirely understand your question, as you said yourself you can solve the problem by pulling out 'objid' directly, there are a few things that need to be amended in your payload and your code to adhere to best practices.
The payload I believe should be as follows: (You miss some defining brackets after objid, and at the end of the idArray).
{"aps":{"alert":"test Push","badge":1,"sound":"default"},
"objid":{"SomeID","vid":"4229", "title":"aTitle","type":"queryform",
"idArray":["-100", "SomeID"]}}
Also your code is not using null propagation correctly, and will cause you issues in the future. if your checking for null, you must also propogate the Count otherwise it will likely cause an exception to be thrown.
if (idArray != null && idArray?.Count > 0)
{
}
It's also worth noting that often JSON deserialises property names in lower case. This can differ between deserialisers however.

To Check Session is null or not

In the below code I have Session variable in which I want to check whether it is null or not. Please help me to do this.
(SearchDoc) is class.
var SearchDoc = (SearchDoc)Session["Documentname"];
var oDocumentID = SearchDoc.ClientID;
var Documentid = SearchDoc.DocumentID;
if (SearchDoc == null)
{
}
This is the safest approach :
if ((HttpContext.Current.Session !=null && Session["Documentname"] as SearchDoc!= null))
{
//do what you want with
((SearchDoc)Session["Documentname"])
}
2 things to notice :
Yes , sometime the session object is null. ( probably occurs with AShX's without appropriate interface)
use the AS operator. - once it's ok , you can safely cast to SearchDOC
Try this
if(Session["Documentname"] != null)
{
var SearchDoc = (SearchDoc)Session["Documentname"];
var oDocumentID = SearchDoc.ClientID;
var Documentid = SearchDoc.DocumentID;
if (SearchDoc == null)
{
}
}
You can simply try this:
string oDocumentID = string.Empty;
string Documentid = string.Empty;
if(Session["Documentname"] != null){
var SearchDoc = (YourSearchDocType)Session["Documentname"];
oDocumentID = SearchDoc.ClientID;
Documentid = SearchDoc.DocumentID;
// some code
}
dont try to access some property of object which can be null

C# short if statement

Is there a way to do this in C# without making a new method to overload for every var type there is?
$box = !empty($toy) : $toy ? "";
The only ways I can think of to do it is either:
if (toy != null)
{
box += toy;
}
or this:
public string emptyFilter(string s) ...
public int emptyFilter(int i) ...
public bool emptyFilter(bool b) ...
public object emptyFilter(object o)
{
try
{
if (o != null)
{
return o.ToString();
}
else
{
return "";
}
}
catch (Exception ex)
{
return "exception thrown":
}
}
box += this.emptyFilter(toy);
I basically wanna check to make sure that the variable/property is set/not empty/exists/has value/etc... and return it or "" without some ridiculous about of code like above.
You could use the conditional operator (?:):
string box = (toy != null) ? toy.ToString() : "";
return variable ?? default_value;
That what you're going for? I'm a little confused considering you're showing PHP code and tag this with C#.
There's also the Nullable<T> type you can use.
How bout an extender class?
public static class ToStringExtender
{
public static String ToStringExt(this Object myObj)
{
return myObj != null ? myObj.ToString() : String.Empty;
}
}
var myobject = foo.ToStringExt()
DEMO
I'm not sure of what he wants, BUT:
string str = String.Empty;
str += true;
str += 5;
str += new object();
str += null;
This is perfectly legal. For each one adition the ToString() will be called. For null, simply nothing will be added.
The value of str at the end: True5System.Object
or,
var s = (toy?? "").ToString();
or
var s = (toy?? string.Empty).ToString();
i think there may be a slight misunderstanding about how var is used; but that's a separate topic.
maybe this below will help:
box += (toy ?? "").ToString();

Categories

Resources