Top level delegate reference cannot be resolved - c#

I have a test like this:
delegate int Mapper(string str);
public class MappingTests
{
[Fact]
public void MapFromStringToInt()
{
Mapper stringToIntMapper = (string text) => { return int.Parse(text); };
var x = stringToIntMapper("1");
Assert.Equal(1, x);
}
}
I can move the declaration of stringToIntMapper outside the test class like this:
delegate int Mapper(string str);
Mapper stringToIntMapper = (string text) => { return int.Parse(text); };
public class MappingTests
{
[Fact]
public void MapFromStringToInt()
{
var x = stringToIntMapper("1");
Assert.Equal(1, x);
}
}
How can I access stringToIntMapper in my test (or any other class/method)? Now the compiler says it cannot be resolved.

You can't declare variables outside of a class. If you want your variable to be globally accessable, you can put it into a static class:
public static class DelegateCollection
{
public static readonly Mapper stringToIntMapper = (string text) => { return int.Parse(text); };
}
You can access it via
DelegateCollection.stringToIntMapper
But you should make sure that your static class is stateless, e.g. by making everything inside this class readonly. Otherwise, your code becomes hard to test and you might get bugs which are hard to find.

Just make it a method:
static int StringToIntMapper(string text) {
return int.Parse(text);
}

Related

C# constructors sharing code and then referencing properties already set [duplicate]

I have two constructors which feed values to readonly fields.
public class Sample
{
public Sample(string theIntAsString)
{
int i = int.Parse(theIntAsString);
_intField = i;
}
public Sample(int theInt) => _intField = theInt;
public int IntProperty => _intField;
private readonly int _intField;
}
One constructor receives the values directly, and the other does some calculation and obtains the values, then sets the fields.
Now here's the catch:
I don't want to duplicate the
setting code. In this case, just one
field is set but of course there may
well be more than one.
To make the fields readonly, I need
to set them from the constructor, so
I can't "extract" the shared code to
a utility function.
I don't know how to call one
constructor from another.
Any ideas?
Like this:
public Sample(string str) : this(int.Parse(str)) { }
If what you want can't be achieved satisfactorily without having the initialization in its own method (e.g. because you want to do too much before the initialization code, or wrap it in a try-finally, or whatever) you can have any or all constructors pass the readonly variables by reference to an initialization routine, which will then be able to manipulate them at will.
public class Sample
{
private readonly int _intField;
public int IntProperty => _intField;
private void setupStuff(ref int intField, int newValue) => intField = newValue;
public Sample(string theIntAsString)
{
int i = int.Parse(theIntAsString);
setupStuff(ref _intField,i);
}
public Sample(int theInt) => setupStuff(ref _intField, theInt);
}
Before the body of the constructor, use either:
: base (parameters)
: this (parameters)
Example:
public class People: User
{
public People (int EmpID) : base (EmpID)
{
// Add more statements here.
}
}
I am improving upon supercat's answer. I guess the following can also be done:
class Sample
{
private readonly int _intField;
public int IntProperty
{
get { return _intField; }
}
void setupStuff(ref int intField, int newValue)
{
//Do some stuff here based upon the necessary initialized variables.
intField = newValue;
}
public Sample(string theIntAsString, bool? doStuff = true)
{
//Initialization of some necessary variables.
//==========================================
int i = int.Parse(theIntAsString);
// ................
// .......................
//==========================================
if (!doStuff.HasValue || doStuff.Value == true)
setupStuff(ref _intField,i);
}
public Sample(int theInt): this(theInt, false) //"false" param to avoid setupStuff() being called two times
{
setupStuff(ref _intField, theInt);
}
}
Here is an example that calls another constructor, then checks on the property it has set.
public SomeClass(int i)
{
I = i;
}
public SomeClass(SomeOtherClass soc)
: this(soc.J)
{
if (I==0)
{
I = DoSomethingHere();
}
}
Yeah, you can call other method before of the call base or this!
public class MyException : Exception
{
public MyException(int number) : base(ConvertToString(number))
{
}
private static string ConvertToString(int number)
{
return number.toString()
}
}
Constructor chaining i.e you can use "Base" for Is a relationship and "This" you can use for same class, when you want call multiple Constructor in single call.
class BaseClass
{
public BaseClass():this(10)
{
}
public BaseClass(int val)
{
}
}
class Program
{
static void Main(string[] args)
{
new BaseClass();
ReadLine();
}
}
When you inherit a class from a base class, you can invoke the base class constructor by instantiating the derived class
class sample
{
public int x;
public sample(int value)
{
x = value;
}
}
class der : sample
{
public int a;
public int b;
public der(int value1,int value2) : base(50)
{
a = value1;
b = value2;
}
}
class run
{
public static void Main(string[] args)
{
der obj = new der(10,20);
System.Console.WriteLine(obj.x);
System.Console.WriteLine(obj.a);
System.Console.WriteLine(obj.b);
}
}
Output of the sample program is
50 10 20
You can also use this keyword to invoke a constructor from another constructor
class sample
{
public int x;
public sample(int value)
{
x = value;
}
public sample(sample obj) : this(obj.x)
{
}
}
class run
{
public static void Main(string[] args)
{
sample s = new sample(20);
sample ss = new sample(s);
System.Console.WriteLine(ss.x);
}
}
The output of this sample program is
20
Error handling and making your code reusable is key. I added string to int validation and it is possible to add other types if needed. Solving this problem with a more reusable solution could be this:
public class Sample
{
public Sample(object inputToInt)
{
_intField = objectToInt(inputToInt);
}
public int IntProperty => _intField;
private readonly int _intField;
}
public static int objectToInt(object inputToInt)
{
switch (inputToInt)
{
case int inputInt:
return inputInt;
break;
case string inputString:
if (!int.TryParse(inputString, out int parsedInt))
{
throw new InvalidParameterException($"The input {inputString} could not be parsed to int");
}
return parsedInt;
default:
throw new InvalidParameterException($"Constructor do not support {inputToInt.GetType().Name}");
break;
}
}
Please, please, and pretty please do not try this at home, or work, or anywhere really.
This is a way solve to a very very specific problem, and I hope you will not have that.
I'm posting this since it is technically an answer, and another perspective to look at it.
I repeat, do not use it under any condition. Code is to run with LINQPad.
void Main()
{
(new A(1)).Dump();
(new B(2, -1)).Dump();
var b2 = new B(2, -1);
b2.Increment();
b2.Dump();
}
class A
{
public readonly int I = 0;
public A(int i)
{
I = i;
}
}
class B: A
{
public int J;
public B(int i, int j): base(i)
{
J = j;
}
public B(int i, bool wtf): base(i)
{
}
public void Increment()
{
int i = I + 1;
var t = typeof(B).BaseType;
var ctor = t.GetConstructors().First();
ctor.Invoke(this, new object[] { i });
}
}
Since constructor is a method, you can call it with reflection. Now you either think with portals, or visualize a picture of a can of worms. sorry about this.
In my case, I had a main constructor that used an OracleDataReader as an argument, but I wanted to use different query to create the instance:
I had this code:
public Subscriber(OracleDataReader contractReader)
{
this.contract = Convert.ToString(contractReader["contract"]);
this.customerGroup = Convert.ToString(contractReader["customerGroup"]);
this.subGroup = Convert.ToString(contractReader["customerSubGroup"]);
this.pricingPlan= Convert.ToString(contractReader["pricingPlan"]);
this.items = new Dictionary<string, Member>();
this.status = 0;
}
So I created the following constructor:
public Subscriber(string contract, string customerGroup) : this(getSubReader(contract, customerGroup))
{ }
and this method:
private static OracleDataReader getSubReader(string contract, string customerGroup)
{
cmdSubscriber.Parameters[":contract"].Value = contract + "%";
cmdSubscriber.Parameters[":customerGroup"].Value = customerGroup+ "%";
return cmdSubscriber.ExecuteReader();
}
notes: a statically defined cmdSubscriber is defined elsewhere in the code; My main constructor has been simplified for this illustration.
In case you need to run something before calling another constructor not after.
public class Sample
{
static int preprocess(string theIntAsString)
{
return preprocess(int.Parse(theIntAsString));
}
static int preprocess(int theIntNeedRounding)
{
return theIntNeedRounding/100;
}
public Sample(string theIntAsString)
{
_intField = preprocess(theIntAsString)
}
public Sample(int theIntNeedRounding)
{
_intField = preprocess(theIntNeedRounding)
}
public int IntProperty => _intField;
private readonly int _intField;
}
And ValueTuple can be very helpful if you need to set more than one field.
NOTE: most of the solutions above does not work for structs.
Unfortunately initializing struct fields in a method called by a constructor is not recognized by the compiler and will lead to 2 errors:
in the constructor: Field xxxx must be fully assigned...
in the method, if you have readonly fields: a read-only field cannot be assigned except in a constructor.
These can be really frustrating for example when you just need to do simple check to decide on which constructor to orient your call to.

C# How to treat static class as a variable

I have a static Class and within it I have multiple public static attributes. I treat this class as my global class.
However now I need to treat this class as a variable so that I can pass it to a method of another class for processing..
I can't instantiate this class.. So in effect I can only assign the variables inside this class.
Is my understanding correct or am I missing something?
public static class Global
{
public const int RobotMax = 2;
// GUI sync context
public static MainForm mainForm;
public static SynchronizationContext UIContext;
// Database
public static Database DB = null;
public static string localDBName = "local.db";
public static Database localDB = null;
public static Database ChangeLogDB = null;
public static string changeLogDBName = "ChangeLog.db";
}
Let say I have a class like this, and I need to somehow keep a copy of this in another class maybe
public static class Global_bk
{
public const int RobotMax = 2;
// GUI sync context
public static MainForm mainForm;
public static SynchronizationContext UIContext;
// Database
public static Database DB = null;
public static string localDBName = "local.db";
public static Database localDB = null;
public static Database ChangeLogDB = null;
public static string changeLogDBName = "ChangeLog.db";
}
I need to copy the contents from Global to Global_bk.
And after that I need to compare the contents of the two classes in a method like
static class extentions
{
public static List<Variance> DetailedCompare<T>(T val1, T val2)
{
List<Variance> variances = new List<Variance>();
FieldInfo[] fi = val1.GetType().GetFields();
foreach (FieldInfo f in fi)
{
Variance v = new Variance();
v.Prop = f.Name;
v.valA = f.GetValue(val1);
v.valB = f.GetValue(val2);
if (!v.valA.Equals(v.valB))
variances.Add(v);
}
return variances;
}
}
class Variance
{
string _prop;
public string Prop
{
get { return _prop; }
set { _prop = value; }
}
object _valA;
public object valA
{
get { return _valA; }
set { _valA = value; }
}
object _valB;
public object valB
{
get { return _valB; }
set { _valB = value; }
}
}
So on my main form, how do I go about calling the compare method and passing the static Global class inside?
example: extentions.DetailedCompare(Global, Global_bk) ? Of course this would give me an error because I cant pass a type as a variable.
Please help me, this is driving me nuts...
How about the singleton pattern ? You can pass reference to shared interface (IDoable in exable below) and still have just one instance.
I.E.:
public interface IDoable {
int Value { get; set; }
void Foo();
}
public static class DoableWrapper {
private MyDoable : IDoable {
public int Value { get;set; }
public void Foo() {
}
}
private static IDoable s_Doable = new MyDoable();
public static IDoable Instance {
get { return s_Doable; }
}
}
Singleton is the way to go here. You can do it like this:
internal class SomeClass
{
private static SomeClass singleton;
private SomeClass(){} //yes: private constructor
public static SomeClass GetInstance()
{
return singleton ?? new SomeClass();
}
public int SomeProperty {get;set;}
public void SomeMethod()
{
//do something
}
}
The GetInstance Method will return you a SomeClass object that you can edit and pass into whatever you need.
You can access the members with classname.membername.
internal static class SomeClass
{
public static int SomeProperty {get;set;}
public static void SomeMethod()
{
//do something
}
}
static void main()
{
SomeClass.SomeProperty = 15;
SomeClass.SomeMethod();
}
The only way you are going to obtain a variable with the "class" information is using reflection. You can get a Type object for the class.
namespace Foo {
public class Bar
{
}
}
Type type = Type.GetType("Foo.Bar");
Otherwise, if you are really describing a class "instance" then use an object and simply instantiate one.
C# offers no other notation for class variables.

With Delphi/Pascal there are internal methods - isn't there a way of doing that in C# [duplicate]

I am creating a C# library with some reusable code and was trying to create a method inside a method. I have a method like this:
public static void Method1()
{
// Code
}
What I would like to do is this:
public static void Method1()
{
public static void Method2()
{
}
public static void Method3()
{
}
}
Then I could choose either Method1.Method2 or Method1.Method3. Obviously the compiler isn't happy about this, any help is much appreciated. Thanks.
If by nested method, you mean a method that is only callable within that method (like in Delphi) you could use delegates.
public static void Method1()
{
var method2 = new Action(() => { /* action body */ } );
var method3 = new Action(() => { /* action body */ } );
//call them like normal methods
method2();
method3();
//if you want an argument
var actionWithArgument = new Action<int>(i => { Console.WriteLine(i); });
actionWithArgument(5);
//if you want to return something
var function = new Func<int, int>(i => { return i++; });
int test = function(6);
}
Yes, when C# 7.0 is released, Local Functions will allow you to do that. You will be able to have a method, inside a method as:
public int GetName(int userId)
{
int GetFamilyName(int id)
{
return User.FamilyName;
}
string firstName = User.FirstName;
var fullName = firstName + GetFamilyName(userId);
return fullName;
}
Note that public (and similar modifiers) are not supported C# programming guide:
Because all local functions are private, including an access modifier, such as the private keyword, generates compiler error CS0106, "
This answer was written before C# 7 came out. With C# 7 you can write local methods.
No, you can't do that. You could create a nested class:
public class ContainingClass
{
public static class NestedClass
{
public static void Method2()
{
}
public static void Method3()
{
}
}
}
You'd then call:
ContainingClass.NestedClass.Method2();
or
ContainingClass.NestedClass.Method3();
I wouldn't recommend this though. Usually it's a bad idea to have public nested types.
Can you tell us more about what you're trying to achieve? There may well be a better approach.
You can define delegates within your method with complete code and call them if you want.
public class MyMethods
{
public void Method1()
{
// defining your methods
Action method1 = new Action( () =>
{
Console.WriteLine("I am method 1");
Thread.Sleep(100);
var b = 3.14;
Console.WriteLine(b);
}
);
Action<int> method2 = new Action<int>( a =>
{
Console.WriteLine("I am method 2");
Console.WriteLine(a);
}
);
Func<int, bool> method3 = new Func<int, bool>( a =>
{
Console.WriteLine("I am a function");
return a > 10;
}
);
// calling your methods
method1.Invoke();
method2.Invoke(10);
method3.Invoke(5);
}
}
There is always an alternative of using a nested class within a class that will not be visible from outside and calling its methods, like:
public class SuperClass
{
internal static class HelperClass
{
internal static void Method2() {}
}
public void Method1 ()
{
HelperClass.Method2();
}
}
As of C# 7.0 you can do that:
public static void SlimShady()
{
void Hi([CallerMemberName] string name = null)
{
Console.WriteLine($"Hi! My name is {name}");
}
Hi();
}
This is called local functions, that is just what you were looking for.
I took the example from here, but further informatin can be found here and here.
Why you don't use classes?
public static class Helper
{
public static string MethodA()
{
return "A";
}
public static string MethodA()
{
return "A";
}
}
Now you can acces MethodA via
Helper.MethodA();
Older thread, but C# does have the concept of nested functions
Func<int> getCalcFunction(int total, bool useAddition)
{
int overallValue = 0;
if (useAddition)
{
Func<int> incrementer = new Func<int>(() =>
{
overallValue += total;
return overallValue;
});
return incrementer;
}
else
{
Func<int> decrementer = new Func<int>(() =>
{
overallValue -= total;
return overallValue;
});
return decrementer;
}
}
private void CalcTotals()
{
Func<int> decrem = getCalcFunction(30, false);
int a = decrem(); //result = -30
a = decrem(); //result = -60
Func<int> increm = getCalcFunction(30, true);
int b = increm(); //result = 30
b = increm(); //result = 60
}
Your nearly there
public static void Method1()
should be
public static class Method1{}
Don't you want to use nested class instead?
That's said, you seem to not respect the Single Responsibility Principle because you want a single method do more than one thing at a time.
Why don't you just Run a method within another
public void M1()
{
DO STUFF
}
public void M1()
{
DO STUFF
M1();
}

Method Within A Method

I am creating a C# library with some reusable code and was trying to create a method inside a method. I have a method like this:
public static void Method1()
{
// Code
}
What I would like to do is this:
public static void Method1()
{
public static void Method2()
{
}
public static void Method3()
{
}
}
Then I could choose either Method1.Method2 or Method1.Method3. Obviously the compiler isn't happy about this, any help is much appreciated. Thanks.
If by nested method, you mean a method that is only callable within that method (like in Delphi) you could use delegates.
public static void Method1()
{
var method2 = new Action(() => { /* action body */ } );
var method3 = new Action(() => { /* action body */ } );
//call them like normal methods
method2();
method3();
//if you want an argument
var actionWithArgument = new Action<int>(i => { Console.WriteLine(i); });
actionWithArgument(5);
//if you want to return something
var function = new Func<int, int>(i => { return i++; });
int test = function(6);
}
Yes, when C# 7.0 is released, Local Functions will allow you to do that. You will be able to have a method, inside a method as:
public int GetName(int userId)
{
int GetFamilyName(int id)
{
return User.FamilyName;
}
string firstName = User.FirstName;
var fullName = firstName + GetFamilyName(userId);
return fullName;
}
Note that public (and similar modifiers) are not supported C# programming guide:
Because all local functions are private, including an access modifier, such as the private keyword, generates compiler error CS0106, "
This answer was written before C# 7 came out. With C# 7 you can write local methods.
No, you can't do that. You could create a nested class:
public class ContainingClass
{
public static class NestedClass
{
public static void Method2()
{
}
public static void Method3()
{
}
}
}
You'd then call:
ContainingClass.NestedClass.Method2();
or
ContainingClass.NestedClass.Method3();
I wouldn't recommend this though. Usually it's a bad idea to have public nested types.
Can you tell us more about what you're trying to achieve? There may well be a better approach.
You can define delegates within your method with complete code and call them if you want.
public class MyMethods
{
public void Method1()
{
// defining your methods
Action method1 = new Action( () =>
{
Console.WriteLine("I am method 1");
Thread.Sleep(100);
var b = 3.14;
Console.WriteLine(b);
}
);
Action<int> method2 = new Action<int>( a =>
{
Console.WriteLine("I am method 2");
Console.WriteLine(a);
}
);
Func<int, bool> method3 = new Func<int, bool>( a =>
{
Console.WriteLine("I am a function");
return a > 10;
}
);
// calling your methods
method1.Invoke();
method2.Invoke(10);
method3.Invoke(5);
}
}
There is always an alternative of using a nested class within a class that will not be visible from outside and calling its methods, like:
public class SuperClass
{
internal static class HelperClass
{
internal static void Method2() {}
}
public void Method1 ()
{
HelperClass.Method2();
}
}
As of C# 7.0 you can do that:
public static void SlimShady()
{
void Hi([CallerMemberName] string name = null)
{
Console.WriteLine($"Hi! My name is {name}");
}
Hi();
}
This is called local functions, that is just what you were looking for.
I took the example from here, but further informatin can be found here and here.
Why you don't use classes?
public static class Helper
{
public static string MethodA()
{
return "A";
}
public static string MethodA()
{
return "A";
}
}
Now you can acces MethodA via
Helper.MethodA();
Older thread, but C# does have the concept of nested functions
Func<int> getCalcFunction(int total, bool useAddition)
{
int overallValue = 0;
if (useAddition)
{
Func<int> incrementer = new Func<int>(() =>
{
overallValue += total;
return overallValue;
});
return incrementer;
}
else
{
Func<int> decrementer = new Func<int>(() =>
{
overallValue -= total;
return overallValue;
});
return decrementer;
}
}
private void CalcTotals()
{
Func<int> decrem = getCalcFunction(30, false);
int a = decrem(); //result = -30
a = decrem(); //result = -60
Func<int> increm = getCalcFunction(30, true);
int b = increm(); //result = 30
b = increm(); //result = 60
}
Your nearly there
public static void Method1()
should be
public static class Method1{}
Don't you want to use nested class instead?
That's said, you seem to not respect the Single Responsibility Principle because you want a single method do more than one thing at a time.
Why don't you just Run a method within another
public void M1()
{
DO STUFF
}
public void M1()
{
DO STUFF
M1();
}

Returning a function pointer

I'm trying to create a url builder similar to the one in asp mvc except our methods are frequently changing parameters and breaking pages.
Does anyone know if it's possible to coerce c# into allowing event like syntax to be returned from a delegate like this:
new UrlBuilder2<FakeController>(x => { return x.ActionWithInt; });
The class would be similar to this:
public class UrlBuilder<TController>
{
public UrlBuilder2(Func<TController, TType> action)
{
}
}
Basically I want to know what Type to use for TType. Or if it's at all possible.
Edit -
I would (if possible) like to use just the method, similar to how you would assign an event ( clickEvent =+ myMethod;)
Not exactly sure what you want to achieve, but assuming you want to generate link simlar to this:
MyForm/MyMethod.aspx
based on WebForm (or any other class) like this:
public class MyForm {
public void MyMethod() {
// Something here
}
public void MethodWithParams(int i, string str) {
// Something here
}
}
You can use this builder (test included):
class UrlBuilder2<T> {
private readonly Expression<Func<T, object>> callExpression;
public UrlBuilder2(Expression<Func<T,object>> callExpression) {
this.callExpression = callExpression;
}
public override string ToString() {
MethodCallExpression call = (MethodCallExpression) callExpression.Body;
StringBuilder sb = new StringBuilder();
sb.AppendFormat("{0}/{1}.aspx", call.Object.Type.Name, call.Method.Name);
var delimiter = "?";
var formalParams = call.Method.GetParameters();
for (int i = 0; i < formalParams.Length; i++) {
var actual = call.Arguments[i];
if (actual == null)
continue; // Do not put NULL to QueryString
var formal = formalParams[i].Name;
sb.AppendFormat("{0}{1}={2}", delimiter, formal, HttpUtility.HtmlEncode(actual.ToString()));
}
return sb.ToString();
}
}
[Test]
public void CanBuildUrlByClassAndMethodName() {
var str = new UrlBuilder2<MyForm>(c => c.MyMethod()).ToString();
str.Should().Be.EqualTo("MyForm/MyMethod.aspx");
}
[Test]
public void CanBuildUrlByMethodWithParams() {
var str = new UrlBuilder2<MyForm>(c => c.MethodWithParams(2, "hello")).ToString();
str.Should().Be.EqualTo("MyForm/MyMethod.aspx?i=2&str=hello");
}
All this will allow you to keep the links type-safe and refactoring advantages will be leveraged.
You will probably need to enhance the UrlBuilder2 but this should get you started.
If you just want to use name of a method to generate links you can do something like this:
class MyClass {
public void MyMethod() {}
}
class UrlBuilder3<T> {
Expression<Func<T, Action>> info;
public UrlBuilder3(Expression<Func<T, Action>> info) {
this.info = info;
}
public override string ToString() {
UnaryExpression exp = (UnaryExpression)info.Body;
MethodCallExpression createDelegate = (MethodCallExpression)exp.Operand;
// 0-Action,1-x,2-Delegate as Constant
ConstantExpression methodArgument = (ConstantExpression)createDelegate.Arguments[2];
MethodInfo method = (MethodInfo)methodArgument.Value;
return string.Format("{0}/{1}.aspx", typeof(T).Name, method.Name);
}
}
[Test]
public void UrlByDelegate() {
new UrlBuilder3<MyClass>(x => x.MyMethod).ToString()
.Should().Be.EqualTo("MyClass/MyMethod.aspx");
}
The tricky thing is correctly resolving the Expression tree. The code above works for this particular sample, but you will need to check it works for all your cases.
You can return a function pointer aka a delegate in c# as below.
public delegate int mydelegate(string s);
public class Test
{
mydelegate MyFunc(string s)
{
return (astring => astring.Length + s.Length);
}
}
This would allow you to attach the output of the function to an event.
var test = new Test();
someevent += test.MyFunc("this is a test");
Assuming that someevent took a function with the same signature as the delegate.

Categories