How can I have conditional out parameters - c#

The method DoSomething() does Create an Instance of MyClass but not everyone wants to know the MyClass-Object sometimes it also fits if you simply know if the action was successful.
This doesn't compile
public bool DoSomething(out Myclass myclass = null)
{
// Do something
}
A ref or out parameter cannot have a default value
Sure I could simply remove the out-Keyword but then I needed to assign any variable first, which is not my intention.
This could be a workaround, but i want bool to be the return type
public Myclass DoSomething() //returns null if not successful
{
// Do something
}
Does anyone know a nice Workaround for that?

Just by overloading:
public bool DoSomething()
{
myClass i;
return DoSomething(out i);
}
public bool DoSomething(out myClass myclass)
{
myclass = whatever;
return true;
}
And then call DoSomething()

You could wrap the parameter in a class.
class Arguments
{
public Argument () { Arg = null; }
public Myclass Arg { get; set; }
}
and then use it like:
Arguments args;
if (DoSomething (args))
{
// args.Arg is something
}
and define the function like:
bool DoSomething (Arguments args)
{
bool success = false;
if (someaction)
{
args.Arg = new Myclass;
success = true;
}
return success;
}
Alternative, and this is making me feel a bit dirty, use exceptions:-
Myclass DoSomething ()
{
if (someactionhasfailed)
{
throw new Exception ("Help");
}
return new Myclass;
}

If you do not want to overload the method, you can always create a new class like:
public class Response
{
public bool Success{get;set;}
public Myclass MyclassInstance {get;set;}
}
And the use it as a return parameter of your DoSomething() method with the following signature:
public Response DoSomething()
{
// Do something
}

Related

Im trying to return a new class from a property getter, but I dont understand why one syntax works and another one with ternary operator does not

This is probably a simple C# question for somebody, who has been working in it for long enough.
Can I do something like this
class MyClass
{
public string Name { get; set; }
public void SetName(string name)
{
Name = name;
}
}
Then inside some other class I have something like this
MyClass myClass;
public MyClass MyProperty { get { return myClass ?? new MyClass().SetName("myName"); } }
So when I call Myproperty if it is null I want to just create a new one with a property set this way, I cannot use constructor on MyClass, instead I have few overloaded methods, that I call when MyClass is constructed.
This works
public MyClass MyProperty
{
get
{
myClass = myClass ?? new MyClass();
myClass.SetName("myName");
return myClass;
}
}
But I’m just curious why this does not, what is the difference because I don’t see any
public MyClass MyProperty
{
get
{
return myClass ?? new MyClass().SetName("myName");
}
}
EDIT:
I just did this instead based on the opinions
public MyClass MyProperty
{
get
{
if (myClass == null)
{
myClass = new MyClass();
myClass.SetName("myName);
}
return repository;
}
}
Another approach is to change MyClass to
class MyClass
{
public string Name { get; set; }
public MyClass SetName(string name)
{
Name = name;
return this;
}
}
and then use it like this
MyClass myClass;
public MyClass MyProperty
{
get
{
return myClass ?? new MyClass().SetName("myName");
}
}
And Im going with it :0
Thanks for all answers :)
Return type of SetName is void.
So new MyClass().SetName("myName") is void, not instance of MyClass.
UPDATE
To achieve your desired behaviour, you can change SetName to return this, and rewrite your MyProperty setter for example, to return myClass ?? new MyClass().SetName("myName");

Delegate for any method type - C#

I want to have a class that will execute any external method, like this:
class CrazyClass
{
//other stuff
public AnyReturnType Execute(AnyKindOfMethod Method, object[] ParametersForMethod)
{
//more stuff
return Method(ParametersForMethod) //or something like that
}
}
Is this possible? Is there a delegate that takes any method signature?
You can do this a different way by Func<T> and closures:
public T Execute<T>(Func<T> method)
{
// stuff
return method();
}
The caller can then use closures to implement it:
var result = yourClassInstance.Execute(() => SomeMethod(arg1, arg2, arg3));
The advantage here is that you allow the compiler to do the hard work for you, and the method calls and return value are all type safe, provide intellisense, etc.
I think you are better off using reflections in this case, as you will get exactly what you asked for in the question - any method (static or instance), any parameters:
public object Execute(MethodInfo mi, object instance = null, object[] parameters = null)
{
return mi.Invoke(instance, parameters);
}
It's System.Reflection.MethodInfo class.
Kinda depends on why you want to do this in the first place...I would do this using the Func generic so that the CrazyClass can still be ignorant of the parameters.
class CrazyClass
{
//other stuff
public T Execute<T>(Func<T> Method)
{
//more stuff
return Method();//or something like that
}
}
class Program
{
public static int Foo(int a, int b)
{
return a + b;
}
static void Main(string[] args)
{
CrazyClass cc = new CrazyClass();
int someargs1 = 20;
int someargs2 = 10;
Func<int> method = new Func<int>(()=>Foo(someargs1,someargs2));
cc.Execute(method);
//which begs the question why the user wouldn't just do this:
Foo(someargs1, someargs2);
}
}
public static void AnyFuncExecutor(Action a)
{
try
{
a();
}
catch (Exception exception)
{
throw;
}
}

How to handle a dynamic class differently based on expected return value

Which method of DynamicObject do I have to override in order to get a different behavior (in the dynamic class) based on the context in which the instance is used?
Here is an example of what I am trying to accomplish:
class DynamicTest : DynamicObject
{
public DynamicTest(string xyz)
{
_xyz = xyz;
}
private string _xyz;
//TODO: what do I need to implement to get required behaviour?
}
class Program
{
static void Main(string[] args)
{
dynamic foo = new DynamicTest("test);
if (foo) // treat foo as boolean
{ // jump in here when _xyz of foo has a value
System.Console.WriteLine(foo); //treat foo as string
}
else
{ // jump in here when _xyz of foo is null
System.Console.WriteLine("No Value In Object");
}
}
}
I don't know why are you trying to do this and I will definitely NOT will recommend doing this, but you can override TryConvert method on DynamicObject like:
class DynamicTest : DynamicObject
{
public DynamicTest(string xyz)
{
_xyz = xyz;
}
private string _xyz;
public override bool TryConvert(ConvertBinder binder, out Object result)
{
Console.WriteLine ("TryConvert was called");
Console.WriteLine ("Is explicit: "+binder.Explicit);
if(binder.Type == typeof(bool))
{
result = true;
return true;
}
else if(binder.Type == typeof(string))
{
result = _xyz;
return true;
}
result = null;
return false;
}
public override string ToString()
{
return _xyz;
}
}
Now there are some issues: ToString is required for Console.WriteLine, it doesn't try to convert if no implicit convertions exist (because WriteLine is overloaded), so it calls ToString. Implicit and explicit conversions to bool pass, but if you use foo inside if - you will get RuntimeBinderException: Cannot implicitly convert type 'DynamicTest' to 'bool'.
Examples:
dynamic foo = new DynamicTest("test:");
bool boolFoo = foo; //passes, TryConvert is called with `binder.Explicit` == false
bool boolFoo1 = (bool)foo; //passes, TryConvert is called with `binder.Explicit` == true
if(foo) //throws RuntimeBinderException
I think implicit operator can help you
Example code:
class DynamicTest : DynamicObject
{
public DynamicTest(string xyz)
{
_xyz = xyz;
}
private string _xyz;
public static implicit operator bool(DynamicTest rhs)
{
return rhs._xyz != null;
}
public static implicit operator string(DynamicTest rhs)
{
return rhs._xyz;
}
//TODO: what to override to get required behaviour
}
class Program
{
static void Main(string[] args)
{
dynamic foo = new DynamicTest("test");
if (foo) // treat foo as boolean
{ // jump in here when _xyz of foo has a value
System.Console.WriteLine((string)foo); //treat foo as string //Importat: (string)foo to go operatorstring
}
else
{ // jump in here when _xyz of foo is null
System.Console.WriteLine("No Value In Object");
}
}
}

Testing delegates for equality

I'm building a hierarchical collection class that orders magnetic resonance images spatially and arranges them into groupings based on the various acquisition parameters that were used to generate them. The specific method used to perform the grouping is provided by the user of the class. I've abstracted out the relevant features in the sample code below. For the IEquatable<MyClass> implementation, I'd like to be able to compare the _myHelperDelegate attributes of two MyClass instances to determine if both delegates point to the same piece of code. The (_myHelperDelegate == other._myHelperDelegate) clause in the if statement below is clearly the wrong way to go about doing this (it fails to compile, giving the error "Method name expected"). My question is, is there a way to compare two delegates to determine if they reference the same piece of code? If so, how do you do that?
public class MyClass : IEquatable<MyClass>
{
public delegate object HelperDelegate(args);
protected internal HelperDelegate _myHelperDelegate;
public MyClass(HelperDelegate helper)
{
...
_myHelperDelegate = helper;
}
public bool Equals(MyClass other)
{
if (
(_myHelperDelegate == other._myHelperDelegate) &&
(... various other comparison criteria for equality of two class instances... )
)
return true;
return false;
}
}
The following compiles and works as expected.
private void Form1_Load(object sender, EventArgs e)
{
var helper1 = new TestDelegates.Form1.MyClass.HelperDelegate(Testing);
var helper2 = new TestDelegates.Form1.MyClass.HelperDelegate(Testing2);
var myClass1 = new MyClass(helper1);
var myClass2 = new MyClass(helper1);
System.Diagnostics.Debug.Print(myClass1.Equals(myClass2).ToString()); //true
myClass2 = new MyClass(helper2);
System.Diagnostics.Debug.Print(myClass1.Equals(myClass2).ToString()); //false
}
private object Testing()
{
return new object();
}
private object Testing2()
{
return new object();
}
public class MyClass : IEquatable<MyClass>
{
public delegate object HelperDelegate();
protected internal HelperDelegate _myHelperDelegate;
public MyClass(HelperDelegate helper)
{
_myHelperDelegate = helper;
}
public bool Equals(MyClass other)
{
if (_myHelperDelegate == other._myHelperDelegate)
{
return true;
}
return false;
}
}
Per msdn, Delegate.Equals method returns:
true if obj and the current delegate have the same targets, methods, and invocation list; otherwise, false.
Have you tried this?
Old question, but I wrote a simple example program to demonstrate comparing delegates with Delegate.Equals -
public delegate int test1(int t);
public static int asdf(int t)
{
return t + 5;
}
public static int asdf2(int x)
{
return x + 7;
}
public static void CompareDelegates(test1 test1, test1 test2)
{
Console.WriteLine(test1 == test2);
}
public static void Main(string[] args)
{
test1 test1 = asdf;
test1 test2 = asdf2;
test1 test3 = asdf;
CompareDelegates(test1, test1);
CompareDelegates(test1, test2);
CompareDelegates(test2, test3);
CompareDelegates(test1, test3);
}
// Outputs:
//
// True
// False
// False
// True

Can a method be overriden with a lambda function

Is there any way to override a class method with a lambda function?
For example with a class definition of
class MyClass {
public virtual void MyMethod(int x) {
throw new NotImplementedException();
}
}
Is there anyway to do:
MyClass myObj = new MyClass();
myObj.MyMethod = (x) => { Console.WriteLine(x); };
Chris is right that methods cannot be used like variables. However, you could do something like this:
class MyClass {
public Action<int> MyAction = x => { throw new NotImplementedException() };
}
To allow the action to be overridden:
MyClass myObj = new MyClass();
myObj.MyAction = (x) => { Console.WriteLine(x); };
No. However if you declare the method as a lambda in the first place, you can set it, though I would try to do that at initialization time.
class MyClass {
public MyClass(Action<int> myMethod)
{
this.MyMethod = myMethod ?? x => { };
}
public readonly Action<int> MyMethod;
}
This however cannot implement an interface that has a MyMethod declared, unless the interface specifies a lambda property.
F# has object expressions, which allow you to compose an object out of lambdas. I hope at some point this is part of c#.
No. Methods cannot be used like variables.
If you were using JavaScript, then yes, you could do that.
You can write this code:
MyClass myObj = new MyClass();
myObj.TheAction = x => Console.WriteLine(x);
myObj.DoAction(3);
If you define MyClass in this way:
class MyClass
{
public Action<int> TheAction {get;set;}
public void DoAction(int x)
{
if (TheAction != null)
{
TheAction(x);
}
}
}
But that shouldn't be too surprising.
Not directly, but with a little code it's doable.
public class MyBase
{
public virtual int Convert(string s)
{
return System.Convert.ToInt32(s);
}
}
public class Derived : MyBase
{
public Func<string, int> ConvertFunc { get; set; }
public override int Convert(string s)
{
if (ConvertFunc != null)
return ConvertFunc(s);
return base.Convert(s);
}
}
then you could have code
Derived d = new Derived();
int resultBase = d.Convert("1234");
d.ConvertFunc = (o) => { return -1 * Convert.ToInt32(o); };
int resultCustom = d.Convert("1234");
Depending on what you want to do, there are many ways to solve this problem.
A good starting point is to make a delegate (e.g. Action) property that is gettable and settable. You can then have a method which delegates to that action property, or simply call it directly in client code. This opens up a lot of other options, such as making the action property private settable (perhaps providing a constructor to set it), etc.
E.g.
class Program
{
static void Main(string[] args)
{
Foo myfoo = new Foo();
myfoo.MethodCall();
myfoo.DelegateAction = () => Console.WriteLine("Do something.");
myfoo.MethodCall();
myfoo.DelegateAction();
}
}
public class Foo
{
public void MethodCall()
{
if (this.DelegateAction != null)
{
this.DelegateAction();
}
}
public Action DelegateAction { get; set; }
}

Categories

Resources