C# Beginner problems - c#

I have a "Debug" class, which simply prints information to the console etc. From the rest of the code I want to be able to call the methods within it, but so far it's only partly working.
Calling dc.Print() works fine, but as soon as I call dc.Print(dc.GetEventsLogged()) I get a red line with the message
"The best overloaded method match has some invalid arguments" as well as Argument 1: cannot convert from 'int' to 'string'.
Basically: Why are my arguments to dc.Print wrong? Also, what can I do about "cannot convert from int to string? I tried .ToString but that didn't work either.
This is my "Debug.cs" class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Test
{
public class Debug
{
private int events_logged;
public Debug()
{
events_logged = 0;
}
public void Print(string Message)
{
Console.WriteLine("[" + DateTime.UtcNow + "] " + Message);
events_logged++;
}
public int GetEventsLogged()
{
return events_logged;
}
}
}
And in my "Program.cs" class I have:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Test
{
class Program
{
static void Main(string[] args)
{
Debug dc = new Debug();
dc.Print("Test");
}
}
}

The reason you are seeing the error is because GetEventsLogged() returns an int whereas Print() expects you to pass in a string. Therefore you need to the return from int to string and you were on the right track with ToString(). This will do what you want to achieve:
dc.Print(dc.GetEventsLogged().ToString());

dc.Print() wants a string argument and dc.GetEventsLogged() returns an int. You need to ToString() the int so that the types match.
int numberOfEventsLogged = dc.GetEventsLogged();
string numberOfEventsLoggedAsString = numberOfEventsLogged.ToString();
dc.Print(numberOfEventsLoggedAsString)

try dc.Print(dc.GetEventsLogged().toString()) because GetEventsLogged() is of int type and Print(string Message) looking for string input.

Your method Print expects an argument of type String. When you call dc.Print(dc.GetEventsLogged()), your actually give an int because your method GetEventsLogged() returns an int.

public string GetEventsLogged()
{
return events_logged.ToString();
}

Related

Confused about C#'s extension method overload resolution

Consider the following code:
using System;
using System.Linq;
using System.Collections.Generic;
public static class Ex
{
public static IEnumerable<T> Take<T>(this IEnumerable<T> source, long cnt)
{
return source;
}
}
public class C
{
public static void Main()
{
foreach(var e in Enumerable.Range(0, 10).Take(5).ToArray())
Console.Write(e + " ");
}
}
I have an extension on IEnumerable<T> for Take(long), which isn't provided by the framework. The framework only provides Take(int). And since I'm calling it with an int parameter (Take(5)), I would have expected it to use the framework version, but it's calling my extension.
Am I missing something? The closest match would obviously be the one that takes int as a parameter, and System.Linq is included so it should be in the pool of valid overloads. In fact if I delete my extension, the correct framework function is called.
For reference
Edit: Moving them to different namespaces shows the same problem:
using System;
using System.Linq;
using System.Collections.Generic;
namespace N1
{
public static class Ex
{
public static IEnumerable<T> Take<T>(this IEnumerable<T> source, long cnt)
{
return source;
}
}
}
namespace N2
{
using N1;
public class C
{
public static void Main()
{
foreach(var e in Enumerable.Range(0, 10).Take(5).ToArray())
Console.Write(e + " ");
}
}
}
For reference
Because as Eric Lippert puts it:
the fundamental rule by which one potential overload is judged to be
better than another for a given call site: closer is always better
than farther away.
Closer is better
Try System.Linq.Enumerable.Take(source, 5) instead of just Take(source, 5) to force using the original "Take" function or rename your own "Take" into somthing else "Takef" for example to avoid this kind of problems.

Why I have to write the namespace to access to this extension method?

I have a project that has class to implement extension methods for some type. For example I have this class for ObservableCollection:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
namespace MyProject.Collections.Utils
{
public static class ObservableCollection
{
public static void RemoveAll<T>(this ObservableCollection<T> collection, Func<T, bool> condition)
{
for (int i = collection.Count - 1; i >= 0; i--)
{
if (condition(collection[i]))
{
collection.RemoveAt(i);
}
}
}//RemoveAll
}
}
With this class, in my main project I can use this library with the using:
using MyProject.Collections.Utils
And when I want to use the extension methods I can do:
ObservableCollection<MyType> myOC = new ObservableCollection<MyType>();
myOC.RemoveAll(x=>x.MyProperty == "123");
So I have access to my extension method.
However, I have another class for Decimal, is this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MyProject.Decimal.Utils
{
public static class Decimal
{
public static decimal? Parse(this string paramString)
{
try
{
myCode
}
catch
{
throw;
}
}//Parse
}
}
But in this case, although in my main prject I import the class:
using MyProject.Decimal.Utils;
If I do this:
decimal? myDecimalParsed= Decimal.Utils.Decimal.Parse("123");
Why in this case I can't do this?:
decimal? myDecimalParsed= decimal.Parse("123");
thank so much.
Two problems:
You can't use extension methods as if they were static methods of the extended type
System.Decimal already has a Parse method, and the compiler always looks for "real" methods before extension methods.
In fact, you can write
decimal? miTiempoEstimadoParseado = decimal.Parse("123");
... but that will just call the normal method and then convert the decimal to decimal? implicitly in the normal way.
Note that you're not really using your method as an extension method at the moment anyway - to do so you'd write something like:
decimal? miTiempoEstimadoParseado = "123".Parse();
... but personally I'd view that as pretty ugly, partly as the method name doesn't indicate the target type at all, and partly because by convention Parse methods throw an exception instead of returning a null value on failure. You probably want to come up with a different name.

C# - Error on Skip - File.ReadLines(FileNameFinal).Skip.Take(1).First()

I have this error 'System.Linq.Queryable.Skip(System.Linq.IQueryable, int)' is a 'method', which is not valid in the given context.
It is just going to read a file and then read the 15th line but i get the error as above.
Please Help
using System;
using System.IO;
using System.Text;
using System.Collections.Generic;
using System.Linq;
namespace FileManager
{
public class OpenFile
{
public static string FileNameFinal;
public static string GetFileName(string FileName);
public static string line = File.ReadLines(FileNameFinal).Skip.Take(1).First();
}
}
The problem is in .Skip.
As the error specified Skip is a method, and therefor should be called as one: Skip(3) (the 3 is just en example for an argument)
You need to specify How many items you want to skip.
Try something like:
public static string line = File.ReadLines(FileNameFinal).Skip(3).Take(1).First();
for skipping the first 3 items.
You can take a look at the documentation for more details about the method.
Skip require int parameter.
SKIP : how many value it will skip
provide value to it like Skip(10) which will skip 10 values
public static string line = File.ReadLines(FileNameFinal).Skip(10).Take(1).First();

Beginner C#.NET error: If args doesn't have a length why is my book writing it as such?

I recently started learning C#.NET and have been using Visual Studios 2005 as my IDE. I copied this code straight out of the textbook and it gives me the the error below. The output I am suppose to receive is: Please enter a numeric argument: 1
Yet I get this error: Since ConsoleApplication1.Program.Main(string[])' returns void, a return keyword must not be followed by an object expression
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
if(args.Length == 0)
{
Console.WriteLine("Please enter a numeric argument: ");
return 1;
}
}
}
}
This is because you had Main marked as void. This means it would only expect you to call return. If you want to return an exit code, as in your example, then you need to change your Main method to return an int:
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
// Make this int instead of void
static int Main(string[] args)
{
if(args.Length == 0)
{
Console.WriteLine("Please enter a numeric argument: ");
return 1;
}
// Default return value
return 0;
}
}
}
You are returning some value to a method which return type is VOID.
As documented in official site http://msdn.microsoft.com/en-us/library/yah0tteb.aspx :-
When used as the return type for a method, void specifies that the
method doesn't return a value.
Make your method as below
static int Main(string[] args)
{
////Your code
return 1;
}
Reviews for this book can be found at http://www.amazon.com/visual-blueprint-building-applications-Software/dp/076453601X; it has an average rating of 1.9 out of 5, and comments include:
I thought it was a beginner book, maybe the pics are but the code [is bad]. Doesn't explain any of the examples very well. Not a very good book.
and
Wow!!! This book is really badly written.
Sadly, the code quoted is another example of this. A void method is one that doesn't return a value, so to have defined main as void and then returned a value is completely incorrect.
I would recommend recycling your current book into a set of firelighters, and then buying a decent book to replace it.
If you just want it to display the message and do nothing else then it should be:
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
if(args.Length == 0)
{
Console.WriteLine("Please enter a numeric argument: ");
return;
}
}
}
}
Remove "1" after return.

Argument Confusion Running a C# Method In IronPython

I am trying to run a c# method in the IronPython (2.7.3) console:
The c# (compiled to a dll) is:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PythonTest
{
public class PythonTest
{
public PythonTest(){}
public int GetOne()
{
return 1;
}
public double Sum(double d1, double d2)
{
return d1+d2;
}
public string HiPlanet()
{
return "Hi Planeta";
}
}
}
the python is
import sys
sys.path.append("Y:\\")
import clr
clr.AddReferenceToFile('./PythonTest')
import PythonTest
a = PythonTest.PythonTest.GetOne()
I get a TypeError in ironpython saying that the function takes one arguement (which it doesn't according to my c#!). I am confused and woudl appeciate help here, I'm just trying to call some c# functions provide the arguements and get the results, thanks in advance!
Since it's an instance method, you need to instantiate the object before calling GetOne method:
obj = PythonTest.PythonTest()
a = obj.GetOne()
or, in one-liner:
a = PythonTest.PythonTest().GetOne()

Categories

Resources