Cannot implicit convert a type - c#

I am running into a road block when I am trying to do some testing on delegate. My goal is to create instances of MyStates class that have the ability to call some predefined functions that I defined in MyFunctions class. In the class, I have a dictionary that will refer the functions by name and have a function that retrieve the address of the function and put it in MyState instance so that I could refer it at run time. The idea appears to be simple but the compiler is not happy about it. I think I may have an idea of what is wrong but I am not sure how to get rid of the compiler error. Please advise how to fix this compiler error.
MyFunctions class is defined as below:
public sealed class MyFunctions
{
public delegate int myFunction(object o);
private static Dictionary<string, myFunction> funcRouter
= new Dictionary<string, myFunction>();
#region Singleton
private static readonly MyFunctions _functionInstance = new MyFunctions();
static MyFunctions()
{
}
private MyFunctions()
{
funcRouter.Add("Test2", Test2);
}
public static MyFunctions functionInstance
{
get
{
return _functionInstance;
}
}
#endregion
#region Definition and implementation of all the functions
public int Test2(object o)
{
System.Diagnostics.Debug.WriteLine("Testing 2, object received {0}", (int)o);
return 112;
}
#endregion
public myFunction Get(string s)
{
return (myFunction)funcRouter[s];
}
}
MyStates class is defined below:
public delegate int myFunction(object o);
public class MyState
{
private int _ID;
private myFunction _func;
public myFunction func
{
get { return _func; }
}
public int ID
{
get { return _ID; }
}
public MyState(int myID, myFunction f = null)
{
_ID = myID;
_func = f;
}
}
My main program:
public delegate int myFunction(object o);
class Program
{
static void Main(string[] args)
{
myFunction f = null;
//f = MyFunctions.functionInstance.Test2;
f = MyFunctions.functionInstance.Get("Test2");
MyState s = new MyState(123,f);
Console.ReadLine();
}
}
Note: The code above will generate the compiling error. However, if I use the statement
f = MyFunctions.functionInstance.Test2;
The program will compile fine and execute correctly. I think the issue resides in the use of dictionary to retrieve the address of the function. It is possible to possible to do that in C++, I would think C# should allow me to do the same thing. I just did not do it correctly.
Please advise.

You are defining public delegate int myFunction(object o); in two places. The compiler error error says you can't convert one to the other. This is because in the case of f = MyFunctions.functionInstance.Get("Test2"); you are assigning a return value of one type to a variable of a different type, but with f = MyFunctions.functionInstance.Test2; the compiler just looks for a method signature that matches the delegate.
One fix is to declare f as MyDelegates.MyFunctions.myFunction.
MyDelegates.MyFunctions.myFunction f;
f = MyDelegates.MyFunctions.functionInstance.Get("Test2");
Another way is to wrap it in your local delegate (because then the signature-match is used again):
myFunction f;
f = new myFunction(MyDelegates.MyFunctions.functionInstance.Get("Test2"));
The same applies to using it in the MyState-call later.
Another way to work around this is to just use Func<object, int> everywhere instead of the myFunction delegate.

Related

How to return a named tuple with only one field

I wrote a function in c# which initially returned a named tuple.
But now, I only need one field of this tuple and I would like to keep the name because it helps me to understand my code.
private static (bool informationAboutTheExecution, bool field2thatIdontNeedAnymore) doSomething() {
// do something
return (true, false);
}
This function compile. But It's the following function that I want
private static (bool informationAboutTheExecution) doSomething() {
// do something
return (true);
}
the error messages:
Tuple must containt at least two elements
cannot implcitly convvert type 'bool' to '(informationAboutTheExecution,?)
Has somebody a solution to keep the name of the returned value?
I just want to add another option, althought he out is the easiest workaround and Marc explained already why it's not possible. I would simply create a class for it:
public class ExecutionResult
{
public bool InformationAboutTheExecution { get; set; }
}
private static ExecutionResult DoSomething()
{
// do something
return new ExecutionResult{ InformationAboutTheExecution = true };
}
The class can be extended easily and you could also ensure that it's never null and can be created with factory methods like these for example:
public class SuccessfulExecution: ExecutionResult
{
public static ExecutionResult Create() => new ExecutionResult{ InformationAboutTheExecution = true };
}
public class FailedExecution : ExecutionResult
{
public static ExecutionResult Create() => new ExecutionResult { InformationAboutTheExecution = false };
}
Now you can write code like this:
private static ExecutionResult DoSomething()
{
// do something
return SuccessfulExecution.Create();
}
and in case of an error(for example) you can add a ErrorMesage property:
private static ExecutionResult DoSomething()
{
try
{
// do something
return SuccessfulExecution.Create();
}
catch(Exception ex)
{
// build your error-message here and log it also
return FailedExecution.Create(errorMessage);
}
}
You cannot, basically. You can return a ValueTuple<bool>, but that doesn't have names. You can't add [return:TupleElementNamesAttribute] manually, as the compiler explicitly does not let you (CS8138). You could just return bool. You can do the following, but it isn't any more helpful than just returning bool:
private static ValueTuple<bool> doSomething()
=> new ValueTuple<bool>(true);
Part of the problem is that ({some expression}) is already a valid expression before value-tuple syntax was introduced, which is why
private static ValueTuple<bool> doSomething()
=> (true);
is not allowed.
If you must name your return, you can do this:
private static void doSomething(out bool information) {
// do something
information = true;
}
then call it with
bool result;
doSomething(out result);

How to write universal manipulator using generics?

I have interface that defines value and few operations:
public interface IValue<T>
{
T Value { get; }
void InteractionA(IValue<T> target);
void InteractionB(IValue<T> target);
bool Check(IValue<T> target);
}
Then i implement class based on that interface
public class DoubleValue : IValue<double>
{
public double Value { get; private set; }
public bool Check(IValue<double> target)
{
// ...
return false;
}
public void InteractionA(IValue<double> target)
{
// ...
}
public void InteractionB(IValue<double> target)
{
// ...
}
}
Now i want to make universal manipulator that operates on pool of values and uses generics (so i only write it once). Because of the way i want to use this class in the future it cannot be declared static. Moving generic type into methods also doesn't do any good.
The closest i could get is:
public class ValueManipulator<T>
{
public IEnumerable<IValue<T>> Pool { get; private set; }
public ValueManipulator(IEnumerable<IValue<T>> pool)
{
Pool = pool;
}
public void ManipulateA()
{
foreach (int i in Enumerable.Range(0, Pool.Count()))
{
IValue<T> firstValue = Pool.ElementAt(i);
foreach (IValue<T> secondValue in Pool.Skip(i))
{
if (firstValue.Check(secondValue))
firstValue.InteractionA(secondValue);
else
firstValue.InteractionB(secondValue);
}
}
}
public void ManipulateB()
{
// ...
}
}
Main problem with this ValueManipulator class is that i need to know T of IValue used in DoubleValue (in this case double). So it looks like this:
static void Main(string[] args)
{
ValueManipulator<double> doubleManipulator = new ValueManipulator<double>();
doubleManipulator.Manipulate(ProvideDoubles());
}
private static IEnumerable<DoubleValue> ProvideDoubles()
{
yield return new DoubleValue();
yield return new DoubleValue();
yield return new DoubleValue();
}
How do i make ValueManipulator so user does not need to know what type was used in value implementation?
Well, if your ValueManipulator<T> has no state, as appears to be your case according to your code snippets, then simply make the methods generic instead of the class, that way you can leverage type inference.
public class ValueManipulator
{
public void Manipulate<T>(IEnumerable<IValue<T>> pool)
{
foreach (int i in Enumerable.Range(0, pool.Count()))
{
IValue<T> firstValue = pool.ElementAt(i);
foreach (IValue<T> secondValue in pool.Skip(i))
{
if (firstValue.Check(secondValue))
firstValue.InteractionA(secondValue);
else
firstValue.InteractionB(secondValue);
}
}
}
}
Now you can simply do:
ValueManipulator myManipulator = new ValueManipulator();
myManipulator.Manipulate(ProvideDoubles()); //type inference will figure out T is double
If this is a valid solution then consider making ValueManipulator a static class:
ValueManipulator.Manipulate(ProvideDoubles());
P.D. Please follow advice in commentaries and change ValueType to some other name thats less confusing.
UPDATE After your latest edit to your question, where you clearly state that ValueManipulator<T> does have state, the solution seems to be implementing a static factory class:
public static class ValueManipulator
{
public static ValueManipulator<T> Create<T>(IEnumerable<IValue<T>> pool)
=> new ValueManipulator<T>(pool);
}
public class ValueManipulator<T> { ... }
And again you let type inference do its job:
var doubleManipulator = ValueManipulator.Create(ProvideDoubles());

How to know the calling Class Name?

Is there a way know which class has called a function in another class.
Eg:
public class A
{
public static string Aa = "test";
public void test()
{
B.testB();
}
}
public class B
{
public static void testB()
{
string Bb = A.Aa;
}
}
In the above example, i know the class A function has called the function in class B. But if there are many classes which will call the function in class B and all of those classes will have variable Aa in common, so how can i read its value and assign it to Bb. So in simple
string Bb = CalledClassName.Aa;
You could use the CallerMemberNameAttribute that was added with .NET 4.5. This will only get you the member name though:
public void SomeMethod ()
{
OtherMethod();
}
public void OtherMethod ([CallerMemberName] string memberName = null)
{
Console.WriteLine(memberName);
}
The attribute will fill the optional parameter at compile time, so it will actually call OtherMethod("SomeMethod").
You could also use a combination of accessing the stack trace and using reflection to read the Aa property of the type of the calling method. Note that this accesses debugging information, and is very vulnerable to changes in your code. It also has a bad performance, so you should avoid it. But just to show you how to use it:
public static void testB()
{
StackTrace stackTrace = new StackTrace();
Type callingType = stackTrace.GetFrame(1).GetMethod().DeclaringType;
FieldInfo field = callingType.GetField("Aa", BindingFlags.Public | BindingFlags.Static);
string Bb = (string) field.GetValue(null);
Console.WriteLine(Bb);
}
Use an interface, pass that in:
public interface AaInterface {
public string GetAa();
}
public class A : AaInterface
{
public static string Aa = "test";
public GetAa() { return Aa; }
public void test()
{
B.testB(this);
}
}
public class B
{
public static void testB(AaInterface pAa)
{
string Bb = pAa.GetAa();
}
}
I guess you are looking for something different than you are asking.
You should pass the instance of A to your method. All calling methods should pass the instance based on an interface. In that interface you put the properties and methods you want to share. In that way you can call the 'same' method for every passed instance.
public interface ISomeInterface
{
string Aa {get;}
}
public class A : ISomeInterface
{
public string Aa {get { return "a"; } }
}
Then you can pass it to this method:
public static void testB(ISomeInterface something)
{
string Bb = something.Aa;
}
Note that in this case, Aa is not allowed to be static. You could wrap that static in an instance property though.
If i understood your question correctly then you can pass a reference to a class instance in method as parameter then use 'is' operator to check its type:
public class A
{
public static string Aa = "test";
public void test(object calledClass)
{
if(calledClass is B) Aa = calledClass.Bb;
}
}
When you call this static method from class B just put :
A.Test(this)
P.S.
This is just an example of logic that you can use to achieve what you want
I geuss you can do something like this:
public class A {
public void test() {
B.testB(this);
}
}
public class B {
public static void testB(object sender) {
String className = sender.GetType().Name;
}
}
//To call
A a = new A();
a.test();

Ref in async Task

How I can to pass a reference as a parameter to Async method in Windows Store App ? I'm looking for something like this:
var a = DoThis(ref obj.value);
public async Task DoThis(ref int value)
{
value = 10;
}
But error:
Async methods cannot have ref or out parameters
Has any another way?
Note:I need to pass exactly obj.value. This method would be used by different types of objects, by same type of objects, by one object, but I will pass obj.val_1, obj.val_2 or obj.val_10. All values will be same type (for ex string)
If you don't care about a little overhead and possibly prolonged lifetime of your objects, you could emulate the ref behavior by passing a setter and a getter method to the function, like this:
public async Task DoStuff(Func<int> getter, Action<int> setter)
{
var value1 = getter();
await DoSomeOtherAsyncStuff();
setter(value1 * value1);
}
And call it like this:
await DoStuff(() => obj.Value, x => obj.Value = x);
You could directly pass the object itself and set the value of the corresponding property inside the method:
var a = DoThis(obj);
public async Task DoThis(SomeObject o)
{
o.value = 10;
}
And if you do not have such object simply write one and have the async method take that object as parameter:
public class SomeObject
{
public int Value { get; set; }
}
You can always use the Task<> class and return the desired value. Then Your code would look something like:
var a = DoThis(obj.value);
obj.value = a.Result;
public async Task<int> DoThis(int value)
{
int result = value + 10; //compute the resulting value
return result;
}
EDIT
Ok, the other way to go with this that I can think of is encapsulating the update of the given object's member in a method and then passing an action invoking this method as the task's argument, like so:
var a = DoThis(() => ChangeValue(ref obj.value));
public void ChangeValue(ref int val)
{
val = 10;
}
public async Task DoThis(Action act)
{
var t = new Task(act);
t.Start();
await t;
}
As far as I tested it the change was made in the child thread, but still it's effect was visible in the parent thread. Hope this helps You.
You can't do this as you have it (as you know). So, a few work arounds:
You can do this by passing the initial object since it will be a reference type
var a = DoThis(obj);
public async Task DoThis(object obj) //replace the object with the actual object type
{
obj.value = 10;
}
EDIT
Based upon your comments, create an interface and have your classes implement it (providing it's always the same type you want to pass). Then you can pass the interface which is shared (maybe over kill, depends on your needs, or even unrealistic amount of work).
Or, provide a base class with the property! (I don't like this suggestion but since you're asking for something which can't be done it may suffice although I don't recommend it).
An example of the interface is here (not using what you have, but close enough using a Colsone App)
using System;
namespace InterfacesReferenceTypes
{
class Program
{
static void Main(string[] args)
{
MyClass mc = new MyClass();
DoThis(mc);
Console.WriteLine(mc.Number);
Console.ReadKey();
}
static void DoThis(IDemo id)
{
id.Number = 10;
}
}
class MyClass : IDemo
{
//other props and methods etc
public int Number { get; set; }
}
interface IDemo
{
int Number { get; set; }
}
}
EDIT2
After next comments, you will have to still use an interface, but re assign the value afterwards. I'm sure there is a better way to do this, but this works:
using System.Text;
namespace InterfacesRerefenceTypes
{
class Program
{
static void Main(string[] args)
{
MyClass mc = new MyClass();
Console.WriteLine(mc.Number);
mc.val1 = 3;
mc.val2 = 5;
mc.Number = mc.val2;
DoThis(mc);
mc.val2 = mc.Number;
Console.WriteLine(mc.val2);
Console.ReadKey();
}
static void DoThis(IDemo id)
{
id.Number = 15;
}
}
class MyClass : IDemo
{
public int val1 { get; set; }
public int val2 { get; set; }
public int Number { get; set; }
}
interface IDemo
{
int Number { get; set; }
}
}

Call one constructor from another

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.

Categories

Resources