Why are the results different in int and string cases? [duplicate] - c#

This question already has answers here:
C# difference between == and Equals()
(20 answers)
Closed 1 year ago.
im learning c# and i cant underestand that why are the results different in the following code:
public class Thing
{
public object Data = default(object);
public string Process(object input)
{
if (Data == input)
{
return "Data and input are the same.";
}
else
{
return "Data and input are NOT the same.";
}
}
}
and inside main method:
var t1 = new Thing();
t1.Data = 42;
Console.WriteLine($"Thing with an integer: {t1.Process(42)}");
var t2 = new Thing();
t2.Data = "apple";
Console.WriteLine($"Thing with a string: {t2.Process("apple")}");
and the output is:
Thing with an integer: Data and input are NOT the same.
Thing with a string: Data and input are the same.

The root of this behaviour is boxing. This is when assigning a .net value type, like an integer, to an object reference requires the creation of an object to hold the value. Because you do this twice - firstly when assigning 42 to Data and then by passing 42 as an object parameter, they are boxed into different objects which obey reference equality.
Strings are already objects but they are a special type in .net which overrides equality - see the rules.

See discussion which contains answer by #AFract!
He basically says that if (Data == input)
has to be replaced by if (Data.Equals(input))
then the problem is solved.
Please upvote his comment!
I tried this to test input type:
using System;
public class Thing
{
public object Data = default(object);
public string Process(object input)
{
if (Data.Equals(input))
{
return "Data and input are the same.";
}
else
{
return "Data and input are NOT the same.";
}
}
public dynamic Input(object myinput)
{
return myinput;
}
}
public class Program
{
public static void Main()
{
var t1 = new Thing();
t1.Data = 42;
Console.WriteLine($"Thing with an integer: {t1.Process(42)}");
var t2 = new Thing();
t2.Data = "apple";
Console.WriteLine($"Thing with a string: {t2.Process("apple")}");
Console.WriteLine($"{t1.Input(42).GetType()}");
}
}
Output is:
Thing with an integer: Data and input are the same.
Thing with a string: Data and input are the same.
System.Int32

Related

Calling class object's function from string in c# [duplicate]

This question already has answers here:
Calling a function from a string in C#
(5 answers)
Closed 4 years ago.
I'm using WPF mvvm pattern anyway if some method got string parameter is this possible calling like
SomeClass1 sc = new SomeClass();
DummyClass2 dc = new DummyClass2();
public void SomeMethod(string param) //param = "SomeMethodName"
{
sc.'param'(dc);
}
The key is calling class object's fuction via param without branch or Data structure mapping.
maybe using reflection.. any good idea?
Yes that's possible via reflection. You can use the Invoke method.
It would look something like this:
MethodInfo method = type.GetMethod(name);
object result = method.Invoke(objectToCallTheMethodOn);
Having said that, in normal circumstances you shouldn't use reflection to call methods in c#. It's only for really special cases.
Here's a full example:
class A
{
public int MyMethod(string name) {
Console.WriteLine( $"Hi {name}!" );
return 7;
}
}
public static void Main()
{
var a = new A();
var ret = CallByName(a, "MyMethod", new object[] { "Taekyung Lee" } );
Console.WriteLine(ret);
}
private static object CallByName(A a, string name, object[] paramsToPass )
{
//Search public methods
MethodInfo method = a.GetType().GetMethod(name);
if( method == null )
{
throw new Exception($"Method {name} not found on type {a.GetType()}, is the method public?");
}
object result = method.Invoke(a, paramsToPass);
return result;
}
This prints:
Hi Taekyung Lee!
7

Operator Overloading- concatenating two strings

In the following code, I am getting the error that One of the parameters of a binary operator must be the containing type
Whats wrong with the code?
public class Nest
{
public string a = "Test";
public string b = "Code";
}
class OperatorOverload
{
public static void Main(string[] args)
{
Nest n = new Nest();
Console.WriteLine("Enter first string");
n.a = Console.ReadLine();
Console.WriteLine("Enter second string");
n.b = Console.ReadLine();
Console.WriteLine(n.a + n.b);
}
public static string operator + (string a, string b)
{
a = string.Concat(b);
a = string.Concat(a);
return a;
}
}
Well if if was me I'd override ToString() on Nest, to return String.Concat(a,b).
Saves a lot of bogging about , when you add a c property to it.
From MSDN
Use the operator keyword to overload a built-in operator or to provide a user-defined conversion in a class or struct declaration.
what are you doing it's wrong you should define it in class like in msdn example documentation

Get name of generic class without tilde [duplicate]

This question already has answers here:
Get GenericType-Name in good format using Reflection on C#
(7 answers)
Closed 7 years ago.
I am trying to get the type name of T using this:
typeof(T).Name
The name of the class is ConfigSettings
Instead of returning ConfigSettings it is returning ConfigSettings`1.
Is there any specific reason why? How can I return the actual name without `1?
Here is an extension method that will get the "real" name of a generic type along with the names of the generic type parameters. It will properly handle nested generic types.
public static class MyExtensionMethods
{
public static string GetRealTypeName(this Type t)
{
if (!t.IsGenericType)
return t.Name;
StringBuilder sb = new StringBuilder();
sb.Append(t.Name.Substring(0, t.Name.IndexOf('`')));
sb.Append('<');
bool appendComma = false;
foreach (Type arg in t.GetGenericArguments())
{
if (appendComma) sb.Append(',');
sb.Append(GetRealTypeName(arg));
appendComma = true;
}
sb.Append('>');
return sb.ToString();
}
}
Here is a sample program showing its usage:
static void Main(string[] args)
{
Console.WriteLine(typeof(int).GetRealTypeName());
Console.WriteLine(typeof(List<string>).GetRealTypeName());
Console.WriteLine(typeof(long?).GetRealTypeName());
Console.WriteLine(typeof(Dictionary<int, List<string>>).GetRealTypeName());
Console.WriteLine(typeof(Func<List<Dictionary<string, object>>, bool>).GetRealTypeName());
}
And here is the output of the above program:
Int32
List<String>
Nullable<Int64>
Dictionary<Int32,List<String>>
Func<List<Dictionary<String,Object>>,Boolean>
The back-tick is indicative that the class is a generic type. Probably the easiest thing is to just lop off anything from the back-tick forward:
string typeName = typeof(T).Name;
if (typeName.Contains('`')) typeName = typeName.Substring(0, typeName.IndexOf("`"));
Is there any specific reason why?
It means that the type has one generic type argument.
How can I return the actual name without "`1"?
You can just find the index of ` (if it exists) and return the substring of the type name up to that character.

Anyone know how I can get FCL style initialisation syntax for c# types?

Instead of writing
int i = new int();
i = 7;
One can write
int i = 7;
Is there a way I can get that style of initialisation for my own types?
MyType mt = xyz;
The closest you can come is by creating implicit conversions on your type. For example:
public class Unit
{
public static implicit operator Unit( string val )
{
return Unit.Parse( val );
}
public static Unit Parse( string unitString )
{
// parsing magic goes here
}
}
This would enable you to do something like this:
Unit width = "150px";
var width = Unit.Parse("150px"); // equivalent to previous line
Note that you cannot introduce new syntax; this would be impossible to implement:
Unit width = 150px;
since 150px does not represent a valid value type.
Note that implicit casting can get you into trouble in weird ways so don't over do it. Support implicit casting only to and from types that you're really going to need.
Alternatively, if you're using C# compiler 3.5 or up you can also use inline initialization which is more verbose but also more explicit:
Unit with = new { Value=150, UnitType=Units.Pixel };
For the specific example in your comment you could add an implicit conversion operator to the type.
Note that doing this is generally not recommended because it makes your code less readable. For example, something like String2 s2 = new String2("yo") is completely explicit about what is happening; not so with something like String2 s2 = "yo".
String2 s2 = "yo";
// ...
public sealed class String2
{
public readonly string _value;
public string Value { get { return _value; } }
public String2(string value)
{
_value = value;
}
public override string ToString()
{
return Value;
}
public static implicit operator String2(string value)
{
return new String2(value);
}
}
You can do it through implicit cast operators.
Here's an article that describes the concept:
http://www.codeproject.com/KB/cs/Csharp_implicit_operator.aspx
short answer is "no you can't". You're always going to hide a new somewhere.
In your specific case you could do some trick with implicit conversions like this:
class String2 {
private readonly string WrappedString;
public String2(string wrappedString) {
this.WrappedString = "my modified " + wrappedString ;
}
public override string ToString() {
return this.WrappedString;
}
// the "magic" is here: the string you assign to String2 gets implicitly
// converted to a String2
public static implicit operator String2(string wrappedString) {
return new String2(wrappedString);
}
}
that enables you to do:
String2 test = "test";
Console.WriteLine(test.ToString()); // writes: "my modified test" to the Console
but you get the "new" hidden in the implicit conversion anyway.
Another approach which may be more general and lands you not too far from the syntax you want is through extension methods:
static class StringExtensions {
public static String2 ToString2(this string that) {return new String2(that);}
}
with that in scope, you can do this:
var test2="anothertest".ToString2();

Is possible return more than one return type in a Method?

I use asp.net 4 and c#.
I would like to know if could be possible return more than one return type in a Method.
As example in this method I return only a single bool type.
protected bool IsFilePresent()
{
return File.Exists(Server.MapPath("/myFile.txt"));
}
But lets imagine I would like return also a string type using in the same method like:
string lineBase = File.ReadAllText(Server.MapPath("/myFile.txt"));
Is possible to do it?
I would appreciate some code example. Many Thanks.
No, it's not possible to return multiple, different values. You have a few alternatives:
One is to make a class or struct that has each of the things you want to return as properties or fields.
Another is to use out parameters, where you pass in a variable to a method, which the method then assigns a value to.
You could also use ref parameters (pass by reference), which is similar to out, but the variable you pass in needs to have been assigned before you call the method (i.e. the method changes the value).
In your case, as cjk points out, you could just have the method return a string with the file contents, or null to indicate that the file didn't exist.
For this example, you have 3 choices.
Add an out parameter to your method and set it in the body (code below)
Create a custom class that contains a Booelan and a String and return that
Just return the string, but return null when the file does not exist
protected bool IsFilePresent(out String allText)
{
Boolean fileExists = File.Exists(Server.MapPath("/myFile.txt"));
if (fileExists)
{
allText = File.ReadAllText(Server.MapPath("/myFile.txt"));
}
return fileExists;
}
Yes you can only if your using framework 4. Look into tuple
http://sankarsan.wordpress.com/2009/11/29/tuple-in-c-4-0/
No, you could use out parameter instead.
http://msdn.microsoft.com/en-us/library/t3c3bfhx(v=vs.80).aspx
http://msdn.microsoft.com/en-us/library/aa645764(v=vs.71).aspx
You can return a class with different types in it :
class TestFile
{
private bool isFilePresent;
private string lineBase;
}
Yes, you can create a wrapper class called (for instance) "Pair" parametrized with two types, put two values in the object of that class and return it as a result. In your case it would be something like Pair
I'm not a C# programmer, so I won't give you exact code.
You might want to use out-parameters.
protected bool IsFilePresent(out string fileContents) {
string filePath = Server.MapPath("/myFile.txt");
try {
fileContents = File.ReadAllText(filePath);
return true;
} catch {
fileContents = null;
return false;
}
}
You have two options.
First one, more C-ish: out parameters:
void test(out bool p1, out bool p2) {
p1 = true;
p2 = false;
}
Second one, more OO, use a struct or class to contain your results:
class Result {
public bool Part1 {get;set;}
public bool Part2 {get;set;}
}
Result test() {
return new Result {Part1 = true, Part2 = false};
}
In C# 4 you can use the Tuple class instead of creating your own result class.
I did not look at your specific requirement but you can combine the methods if you need, but keep in mind that the out parameters are discouraged in object oriented programming at least as per microsoft guidelines.
Yes you can use output parameters.
public bool GetData(string filename, out string data)
{
if (File.Exists(filename))
{
data = File.ReadAllText(filename);
return true;
}
data = string.Empty;
return false;
}
string data;
if (GetData(Server.MapPath("/myFile.txt"), out data))
{
// do something with data
}
Yes, we can. dotNet 4 support dynamic type, so you can return more than one type
public dynamic GetSomething()
{
if (!File.Exists(Server.MapPath("/myFile.txt")))
return false;
else
return File.ReadAllText(Server.MapPath("/myFile.txt"));
}
var result = GetSomething();
if(result is bool && result == false)
{
//doSomething();
}
This way is hard to read your code.
It's very easy nowadays... use Tuple
public (string,int) MyMethod(){
return ("text", 3);
}
string text;
int number;
(text, number) = MyMethod();
//OR
(var text, var number) = MyMethod();

Categories