I understand I cannot modify default(T).
How to change what default(T) returns in C#?
In my situation, we have several classes that implement functionality of the base class:
T RequestForData<T>(string request)
{
return default(T);
}
I need to modify this default functionality to handle a "Refresh" call, which I can write like this:
private DataContext _dc;
T RequestForData<T>(string request)
{
if (request == "Refresh")
{
if ((_dc != null) && !_dc.HasPendingChanges())
{
_dc.Refresh(System.Data.Linq.RefreshMode.OverwriteCurrentValues);
}
}
return default(T);
}
These can now be called from the MDI parent form:
foreach (var form in this.Forms)
{
form.RequestForData<bool>("Refresh");
}
As you can see from the way I have called it, RequestForData returns a Boolean value.
If I handle the call in one of my forms, I want to return TRUE, but this returns an error in Visual Studio.
Cannot implicitly convert type 'bool' to 'T'
FYI: I tried a cast, too, but the compiler says that is redundant.
How do I handle returning a value type as specified by ?
Perhaps you could use a Nullable<bool>:
var result = form.RequestForData<bool?>("Refresh") ?? true;
However, I don't see the point in your generic method returning a value at all. Why not just make it a void method? What's the information that this return value carries?
Assuming you are sure nobody will use your method with, let's say string generic argument, you could avoid the compiler error by doing the following:
return (T)(dynamic)true;
Of course it will lead to runtime error in case bool can't be cast to T. But for me such solution worked pretty well once while implementing typed data-reader from SQL-DataTable.
PS: But still I don't believe this hack is justified for this particular method. It's really primitive and can't return anything other then boolean, can't work with any other generic argument. So you better either make it return bool, or void as was suggested in other comments.
The question got a downvote.
I think people on here vote it down when they think they know everything and there is no way they can see to solve the problem.
Here is how we resolved the coding dilemma:
T RequestForData<T>(string request)
{
if (request == "Refresh")
{
if ((_dc != null) && !_dc.HasPendingChanges())
{
_dc.Refresh(System.Data.Linq.RefreshMode.OverwriteCurrentValues);
return (T)Convert.ChangeType(true, typeof(T));
}
}
return default(T);
}
If anyone sees why that will not work, feel free to comment.
try this implementation may work :
bool RequestForData<T>(string request)
{
return true;
}
or in a more flexible form :
object RequestForData<T>(string request)
{
if(conditionOk)
return default(T);
else
return false;
}
Related
I'm running into an odd scenario that doesn't happen on my PC, but does for a coworkers.
I have this piece of code:
LoaderHelpers.SetStringValue<blah>(this, "x", $"x response in Header",
() => jsonData.x.response[0].value, false);
The problem is that sometimes, "jsonData.x" is null and, for my coworker a 'cannot bind to null at runtime exception' is thrown, but not for me there isn't. I have code to handle the null scenario, but it's like his code never gets to that point and fails at the call level.
jsonData is of type dynamic.
The method code that handles the null scenario:
public static void SetStringValue<T>(IValidate data, string propertyName,
string valuePath, Func<string> value, bool required)
{
if (data.GetType().GetProperty(propertyName) != null)
{
try
{
if (string.IsNullOrEmpty(value()))
{
if (required)
data.DataValidationErrors.Add($"{valuePath} can't be empty");
data.GetType().GetProperty(propertyName).SetValue(data, null);
}
else
{
data.GetType().GetProperty(propertyName).SetValue(data, value());
}
}
catch
{
//property doesn't exist
if (required)
data.DataValidationErrors.Add($"{valuePath} doesn't exist");
data.GetType().GetProperty(propertyName).SetValue(data, null);
}
}
else
{
throw new NullReferenceException($"In {data.GetType()} => SetStringValue. " +
$"Passed property {propertyName}, but property doesn't exist.");
}
}
Again. Works perfect for me, but not for him. I'm completely lost. Maybe I don't understand how the lamba/function parameters work 100%, but I thought it only got evaluated when value() is invoked.
I should also mention that when I debug this code, I can step into the Nuget package and when he hits the same line, he can't. This maybe a useful hint.
If jsonData (or jsonData.x) is null (as it seems to be at this point) it will crash and give you that error every time you call the method value().
You need to check why jsonData.x is null. Maybe it´s a race condition caused by another thread setting this value to null, maybe it´s because a bad jsonData initialization... Can´t say since that code is not here.
There are so many things wrong with your code, i can't resist.
First of all, instead of copy/pasting the same stuff over and over, you might want to use a variable:
var property = data.GetType().GetProperty(propertyName);
Second, you pass a Func<string> and execute it multiple times, why is it even a function then? Yet again, better only evaluate it once and use a variable...
var unwrapped = value();
That would solve the issue, that Roberto Vázquez' answer adresses.
Then you are misusing NullReferenceException, instead rather use a ArgumentException
Next issue, that valuePath is only used in the exception message, that is a poor design to my beliefs.
The generic T parameter isnt even used, so get rid of it.
Last but not least, that catch-block doing the exact thing that could possibily throw the exception again, i cant see any reason why you would do this.
Finnaly this whole thing becomes a little more clear but its still a mess.
public static void SetStringValue(IValidate data, string propertyName,
string valuePath, Func<string> value, bool required)
{
if(data == null)
throw new ArgumentNullException(nameof(data));
var property = data.GetType().GetProperty(propertyName);
if(property == null)
throw new ArgumentException($"In {data.GetType()} => SetStringValue. " +
$"Passed property {propertyName}, but property doesn't exist.");
var unwrapped = value();
try
{
if (string.IsNullOrEmpty(unwrapped))
{
if (required)
data.DataValidationErrors.Add($"{valuePath} can't be empty");
unwrapped = null; // this might be unecessary.
}
property.SetValue(data, unwrapped);
}
catch(Exception e)
{
// This is probably a bad idea.
property.SetValue(data, null);
if (required)
data.DataValidationErrors.Add(Atleast put a better message here. e.Message ...);
}
}
I try to create an extension method that tests whether a streamreader can read data and return a boolean value.
My extension method code:
using System.IO;
namespace ExtensionMethods
{
public static class StreamReaderExtension
{
public static object isReady(this StreamReader sr)
{
if ((sr.ReadLine()) != null)
{
return true;
} else
{
return false;
}
}
}
}
I would like to use it as shown below:
StreamReader sr = new StreamReader(tcpClient.GetStream(), Encoding.ASCII);
if (sr.isReady() == true)
{
//Do something
}
But Visual Studio tells me this error message: Operator '==' cannot be applied to operands of type 'object' and 'bool'
What did I miss?
Sorry for bad english.
Your method is dangerous - it has sideeffects, you discard your full first line of data.
Additionally, your method is absolutely superflous, you do not need it, it is as simple as:
var sr = new StreamReader(tcpClient.GetStream(), Encoding.ASCII);
if (sr.Peek() != -1)
{
//Do something
}
Read this Peek()
You have a few problems here. First, your method is returning type object, which you can't directly compare to type bool. As far as the compiler "knows," there's absolutely no reason to believe that a comparison is sensible - for all it knows, you could be doing something like "bird" == true, which makes no sense.
Secondly, your method won't do what you think it does even once it compiles:
public static object isReady(this StreamReader sr)
{
if ((sr.ReadLine()) != null)
{
return true;
} else
{
return false;
}
}
First, stylistically, if you have a Boolean expression, why not just return that "directly"? This returns true exactly when (sr.ReadLine()) != null is true and false exactly when the expression is false.
Secondly, as pointed out in the comments, this "consumes" a line without actually storing it anywhere, so you'll actually "lose" data by doing this. (You simply discard the line).
Third, what's the point of this method in the first place? All you're actually doing is a one-line comparison, so there really isn't a reason to have this method at all.
Finally, with this line:
if (sr.isReady() == true)
There's no reason to explicitly compare to true and false. You could just write
if (sr.isReady())
(although, as already pointed out, the method is kind of pointless in the first place).
You have your isReady() function defined as returning an object:
public static object isReady(this StreamReader sr)
Have it return a boolean instead:
public static bool isReady(this StreamReader sr)
I'm trying to write a function that returns a string that represents the type of object currently selected in Excel.
Right now, this is what I have:
public String GetExcelType(dynamic thing)
{
if(thing.GetType().GetProperty("ChartStyle") != null)
{
return "[CHART]";
}
else if (thing.GetType().GetProperty("Cells") != null)
{
return "[TABLE]";
}
return "[UNKNOWN]";
}
And then later called with:
GetExcelType(oExcelApp.ActiveWindow.Selection);
Problem is, it returns "[UNKNOWN]" every time.
Further confusing the issue, popping open a debug session we can clearly see that the object has the property in question (in this case "Cells"):
I pulled the dynamic.GetType().GetProperty("foo") bit from several other questions (everyone seems to agree this should work) but it seems to flop, here. What am I doing wrong?
You might find this function useful for finding the type of a COM object:
Microsoft.VisualBasic.Information.TypeName(oExcelApp.ActiveWindow.Selection)
This seems to be what you need:
http://fernandof.wordpress.com/2008/02/05/how-to-check-the-type-of-a-com-object-system__comobject-with-visual-c-net/
Then you could do something like:
public String GetExcelType(dynamic thing)
{
Type type = GetExcelTypeForComObject(thing)
if(type == typeof(Microsoft.Office.Interop.Excel.Chart))
{
return "[CHART]";
}
else if (type == typeof(Microsoft.Office.Interop.Excel.Range))
{
return "[TABLE]";
}
return "[UNKNOWN]";
}
Here I can use either of these 2 methods. What are the differences and which one should I use?
Method 1:
string srUserIp = "";
try
{
srUserIp = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"].ToString();
}
catch
{
}
Method 2:
string srUserIp = "";
try
{
srUserIp = Request.UserHostAddress.ToString();
}
catch
{
}
Short answer: The two are identical.
Long answer: To determine the difference between the two use Reflector (or whatever disassembler you prefer).
The code for the HttpRequest.UserHostAddress property follows:
public string UserHostAddress
{
get
{
if (this._wr != null)
{
return this._wr.GetRemoteAddress();
}
return null;
}
}
Note that it returns _wr.GetRemoteAddress(). The _wr variable is an instance of an HttpWorkerRequest object. There are different classes derived from HttpWorkerRequest and which one is used depends on whether you are using IIS 6, IIS 7 or beyond, and some other factors, but all of the ones you would be using in a web application have the same code for GetRemoteAddress(), namely:
public override string GetRemoteAddress()
{
return this.GetServerVariable("REMOTE_ADDR");
}
As you can see, GetRemoteAddress() simply returns the server variable REMOTE_ADDR.
As far as which one to use, I'd suggest the UserHostAddress property since is doesn't rely on "magic strings."
Happy Programming
There is no difference. They return exactly the same value. However, one is IntelliSense-friendly whereas the other is not.
I have some production code like
private bool IsTypeEqual(object theFirstObject, object theSecondObject)
{
if(theFirstObject.GetType()==theSecondObject.GetType())
{
return true;
}
else
{
return false;
}
}
Now i have to write the unit test case for this code. I am using NMock to create the
object. So when i am passing the object of two different classes it should go to else part.
But actually as i am mocking both the objects, so GetType() returning the MockObject type for both of the object. How can i solve this problem.
You dont need to mock "theFirstObject" or "theSecondObject". You really dont care what happens to these classes, you just need to assert the result is correct.
If I were you I would pass in different type and assert whether it is true/false:
Assert.AreEqual(false, IsTypeEqual("HelloWorld", 192));
Assert.AreEqual(true, IsTypeEqual("Hello", "World"));
I hope this code will help you.
private bool IsTypeEqual<TMockedType>(object theFirstObject, object theSecondObject)
{
Matcher matcher = Is.TypeOf(typeof(TMockedType));
return matcher.Matches(theFirstObject) && matcher.Matches(theSecondObject);
}