I want to be able to assign functions from classes to variables
Ex:
namespace test
{
class init
{
static void Main(string[] args)
{
var toSingle = BitConverter.ToSingle;
}
}
}
ERROR The delegate type could not be inferred.
I rather think you might want using static (applied to the top of the file with your other using imports, or just inside your namespace):
using static BitConverter;
This will allow you to simply call ToSingle(...) anywhere in your class.
using static docs
Alternatively, if you really want to assign it to a variable, you could potentially assign it to a delegate (here I'll use Func):
Func<byte[], int, float> toSingle = BitConverter.ToSingle;
Though this won't work if you want to use the overload that takes a ReadOnlySpan<Bye> because it can't be a generic parameter.
Related
After saving an anonymous type into a variable of type "IEnumerable" using LINQ, I discovered that it is possible to use several methods that were defined inside of the class "Enumerable" over the aforementioned variable. How is this possible? It should also be noted that "IEnumerable" is an interface.
Here is a small code example:
class MyClass
{
public string Name;
}
class Program
{
static void Main(string[] args)
{
MyClass[] myArray =
{
new MyClass{Name = "Bill"},
new MyClass{Name = "Bill"},
new MyClass{Name = "Steve"}
};
IEnumerable<MyClass> variable = from myInstance in myArray
where myInstance.Name == "Bill"
select myInstance;
MyClass[] newArray = variable.ToArray<MyClass>(); // How is it possible for me to use "ToArray<T>()" on "varialble"?
}
}
This uses a C# feature called extension methods. The method is defined in a separate class (hence the name - it extends the functionality of the original class/interface). The first parameter is prefixed by the this keyword, and the method can be called as if it's a method on that parameter (i.e. on your IEnumerable<MyClass>).
In your example, you are using a library called LINQ, which is composed entirely of extension methods. You can see the source code for ToArray on github. Your code will have using System.Linq; at the top, which is what allows you to call the method in your code.
In C# language and .NET framework, could you help me with understanding delegates?
I was trying to check some code, and found that the results I received were unexpected for me. Here it is:
class Program
{
public static int I = 0;
static Func<string> del = new Func<string>(I.ToString);
static void Main(string[] args)
{
I = 10;
Console.WriteLine("{0}", del());
}
}
The answer was 0, but not 10. Why?
The reason is the following:
The way you declare the delegate it points directly to the ToString method of the static int instance. It is captured at the time of creation.
As flindeberg points out in the comments below, each delegate has a target and a method to be executed on the target.
In this case, the method to be executed is obviously the ToString method. The interesting part is the instance the method is executed on: It is the instance of I at the time of the creation, meaning that the delegate is not using I to get the instance to use but it stores the reference to the instance itself.
Later you change I to a different value, basically assigning it a new instance. This doesn't magically change the instance captured in your delegate, why should it?
To get the result you expect, you would need to change the delegate to this:
static Func<string> del = new Func<string>(() => I.ToString());
Like this, the delegate points to an anonymous method that executes ToString on the current I at the time of the execution of the delegate.
In this case, the method to be executed is an anonymous method created in the class in which the delegate is declared in. The instance is null as it is a static method.
Have a look at the code the compiler generates for the second version of the delegate:
private static Func<string> del = new Func<string>(UserQuery.<.cctor>b__0);
private static string cctor>b__0()
{
return UserQuery.I.ToString();
}
As you can see, it is a normal method that does something. In our case it returns the result of calling ToString on the current instance of I.
You need to pass in I to your function so that I.ToString() can be executed at the appropriate time (instead of at the time function is created).
class Program
{
public static int I = 0;
static Func<int, string> del = num => num.ToString();
static void Main(string[] args)
{
I = 10;
Console.WriteLine("{0}", del(I));
}
}
Here is how this should be done:
using System;
namespace ConsoleApplication1
{
class Program
{
public static int I = 0;
static Func<string> del = new Func<string>(() => {
return I.ToString();
});
static void Main(string[] args)
{
I = 10;
Console.WriteLine("{0}", del());
}
}
}
C# delegate enable encapsulate both an object and instance and a method. A delegate declaration defines a class that is derived from the class System.Delegate. A delegate instance encapsulates an invocations list, which is a list one or more method, each of which is referred to as callable entity.
learn more form
http://asp-net-by-parijat.blogspot.in/2015/08/what-is-delegates-in-c-how-to-declare.html
My guess is because int are passed by values not references, and for that reason when creating the delegate, it's a delegate to the method ToString of the current value of "I" (0).
Can I locally reference a class in C#, instead of an instance of a class? The following code won't compile but, as an example, something like:
void someFunc()
{
var a = System.Math;
var b = a.Abs(4);
}
edit: In the real program it's not the System.Math class and I'm wanting to construct the class and return the constructed value. I didn't think originally that the context in which I wanted to use the class would be relevent, and probably it shouldn't be.
Anastasiosyal has an interesting idea with using a local Delegate to do it.
You can reference a class:
Type math = typeof(System.Math);
But you cannot call static methods on it using regular dot syntax:
// Wont compile:
math.Abs(5);
If you just want to shorten (and IMHO obfuscate) your code, you can reference classes with aliases via a using directive:
// Untested, but should work
namespace MyUnreadableCode {
using m = System.Math;
class Foo {
public static Int32 Absolut(Int32 a) {
return m.Abs(a);
}
}
}
You cannot assign a variable a value of a static class. The question is why would you want to do this, there are probably other ways that you could tackle your problem
e.g. you could use delegates to assign the operation you want to perform:
Func<int,int> operation = Math.Abs;
// then you could use it like so:
int processedValue = operation(-1);
In c# they're called Types. And you can assign them like:
Type a = typeof(SomeClass);
However, you would have to instantiate it to use it. What I believe you want is a static import like in java, but unfortunately, they do not exist in c#.
Short answer: Not like what you have above.
In C# 6.0 they introduced a static import feature, which can solve the problem.
using static System.Math;
class MyProgram
{
static void Main(string[] args)
{
var b = Abs(4); // No need to specify the name of Math class
}
}
As I understand you need to refer to the class with short name? try this (on top of the file, inside using statements section):
using m = System.Math;
later in your code:
m.Abs(...)
Makes sense?
No. It's not possible to treat a Type as a value where instance methods bind to static methods on the original type. In order to do this you would need to construct a new type which forwards it's method calls to the original type.
class MyMath {
public int Abs(int i) {
return Math.Abs(i);
}
}
var x = new MyMath();
How do I explicitly refer to the parameter as opposed to the member variable?
static recursive{
public static List<string> output = new List<string>();
public static void Recursive(List<string> output){
...
}
}
An unqualified reference will always refer to the parameter because it is at a more local scope.
If you want to refer to the member variable, you need to qualify it with the name of the class (or this, for non-static member variables).
output = foo; // refers to the parameter
recursive.output = foo; // refers to a static member variable
this.output = foo; // refers to a non-static member variable
But you should probably change the name anyway. It makes your code much easier to read.
And you shouldn't have public static variables at all. All of the .NET coding style guidelines strongly recommend properties instead of exposing public fields. And since those are always camel-cased, this problem solves itself.
public static void Recursive(List<string> output){
...
}
The code in the block that refers to output will always be local & not the member variable.
If you wish to refer to member variable, you could use recursive.output.
When you are inside the Recursive static method output will point to the argument of the method. If you want to point to the static field use the name of the static class as prefix: recursive.output
Give your member variable another name.
The convention is to use Camelcasing on public static members.
public static List<string> Output = new List<string>();
public static void Recursive( List<string> output )
{
Output = output;
}
You can explicitly reference recursive.output to indicate the static member, but it would be cleaner to rename either the parameter or the member.
I know of no way to explicitly refer to a parameter. The way this is usually handled is to give member variables a special prefix such as _ or m_ so that parameters will never have exactly the same name. The other way is to refer to member variables using this.var.
public class MyClass {
public int number = 15;
public void DoSomething(int number) {
Console.WriteLine(this.number); // prints value of "MyClass.number"
Console.WriteLine(number); // prints value of "number" parameter
}
}
EDIT::
For static fields is required name of class instead of "this":
public class MyClass {
public static int number = 15;
public void DoSomething(int number) {
Console.WriteLine(this.number); // prints value of "MyClass.number"
Console.WriteLine(MyClass.number); // prints value of "number" parameter
}
}
I would like to overload a generic list's Add method so I can use collection initializations like:
var x = new List<Tuple<string>> { { "1", "2" }, { "1", "2" } };
(Where Tuple is a simple custom implementation of a binary tuple.)
However, I created an extension method, put a using directive in the cs file, and still get the "No overload for method 'Add' takes 2 arguments"-error.
Is it not possible to do (with an extension method)?
Extension method code:
namespace ExtensionMethods {
public static class Extensions{
public static void Add<T>(this List<Tuple<T>> self, T value1, T value2) {
self.Add(new Tuple<T> { value1, value2 });
}
}
}
It is not possible via extension methods. In order to make this syntax working you have to create your own collection class which will have void Add(T value1, T value2) signature.
P.S.: What you've done is not overload and there is no way to overload anything in existing class.
UPDATE: Looks like my first sentence should be: "It is not possible via extension methods in C#"
In C# 6.0[0] Microsoft allows the use of extensions methods in collection initializers. hurray :)
And since this isn't a .NET Framework or CLR change, but a compiler change, this feature can be used with .NET 4.0.
So the following is now valid C# code. (Tested in Visual Studio 2015 RC)
class Program
{
static void Main(string[] args)
{
var x = new List<Tuple<string,string>> { { "1", "2" }, { "1", "2" } };
}
}
public static class Extensions
{
public static void Add<T1,T2>(this List<Tuple<T1,T2>> self, T1 value1, T2 value2)
{
self.Add(Tuple.Create( value1, value2 ));
}
}
C# 6 Features [0]
You cannot implement constructors using extension methods.Extension method is nothing but a static method which takes in an instance of an object. Hence you need to have an instance first to be able to pass to it.
But you can just use AddRange() of the List to initialise your list.
Extension methods can't overload any method defined on their target type simply because they are not members of the target type. Extension methods do not ADD anything to their target types. They are just compiler magic that allow them to be called as if they were methods defined on their target type. In reality, they are defined in a separate static type, hence they can't overload any method on their target type.
Behind the scenes, the compiler replaces any calls to your extension method with a call to Extensions.
It looks like you are trying to make C# behave like Ruby and initialize an array of objects by passing a set of values, or at least imitate the behavior of dictionary initialization.
Unfortunately you can't do that without actually overloading List<>.
Collection initialization is just another bit of compiler magic that tries to find an Add method with as many arguments as there are items in the argument list. If it were otherwise you could define a conversion operator to convert a list to your Tuple type.
Why don't you just use the built-in object initializers? You'll just have to write a bit more code