Func<T> as class member, access other members of instance - c#

I have a question wheater or not it is possible (and if it is, how) to access class members from inside a Func<T, TResult> delegate.
For example, I have the following class:
class NinjaTurtle
{
public string Sound { get; set; }
public Func<string, string> DoNinjaMove { get; set; }
}
Now I'd like to do this
NinjaTurtle leonardo = new NinjaTurtle();
leonardo.Sound = "swiishhh!";
leonardo.DoNinjaMove = (move) => {
if(move == "katana slash") return leonardo.Sound;
return "zirp zirp zirp";
}
The problem is, how do I correctly access the property Sound, when I define the callback function? Is it OK to just use the reference to the instance from outside the function? Would this still work when I pass the object to another method, or even when this would be part of a dll, and I would return the object leonardo from a function in the dll? Would it "survive" serialization / deserialization?
(Thanks Vladimir and Lee, the question is now more specific to what I would like to know).

You can use closures. A closure will be an anonymous delegate or lambda expression which may reference variables, methods, properties, events or anything from an outer scope (oops, it's your case!).
leonardo.DoNinjaMove = (move) => {
// THIS IS VALID! IT'S A CLOSURE! You can access leonardo reference within
// the closure!!
if(move == "katana slash") return leonardo.Sound;
return "zirp zirp zirp";
}
Anyway, DoNinjaMove is Func<string, bool>. If you want to return Sound value, it should be refactored to Func<string, string>.
Further details about how closures work and why you can safely use outer scope's references within them can be found on this other Q&A here in StackOverflow:
How do closures work behind the scenes? (C#)
About if using closures would work when working with satellite assemblies and so...
Yes, there's no problem with that. Closures are a very interesting feature that most modern languages own and it's a must-have feature for languages that have incorporated functional programming. Anyway, it's a must-have feature! :)

If you came here from Google specifically wanting to code a Lambda function as a class member declared inside the class body, read on...
I found this post through google, because I was looking for a way to declare the Lambda Func as a member method of the class itself. You can declare a Func inside of a class but you can't directly assign to it in the same line. Example:
public class myClass {
public Func<string,string> DoNinjaMove; //Can't declare method body here.
}
The solution is to assign the Lambda function body inside the Constructor of the class like this:
public class myClass {
public Func<string,string> DoNinjaMove; //Can't declare method body here.
public myClass()
{
DoNinjaMove = (someString) =>
{
//Do something here
return anotherString;
}
}
}
Now DoNinjaMove is a member of myClass and it's body is also declared inside myClass. DoNinjaMove has access to all members of myClass, and you get the ability to pass DoNinjaMove to other classes/objects for them to call it.
I probably wouldn't recommend this design pattern unless you absolutely know what you're doing. In my case, another library I was using demanded I pass it a Lambda function with a specific input and return type, but I needed the function to be a member of my own class where it had access to class data for the sake of elegance and encapsulation. This is the solution I came up with.

This will capture the variable leonardo in a closure and will work but I don't think this is a good design but it is hard to suggest something different without context.
var leonardo = new NinjaTurtle();
leonardo.Sound = "swiishhh!";
leonardo.DoNinjaMove = (move) =>
{
if (move == "katana slash")
{
return leonardo.Sound;
}
else
{
return "zirp zirp zirp";
}
}
You may want to consider using Func<NinjaTurtle, String, String> and pass the turtle in explicitly.
leonardo.DoNinjaMove = (turtle, move) =>
{
if (move == "katana slash")
{
return turtle.Sound;
}
else
{
return "zirp zirp zirp";
}
}
But this does still not look like a convincing design to me.

Related

Calling static method without passing parameters

I have this code (its just part, entire code works just fine):
internal static Rule<IWorkflowModel> Get()
{
var rule = new Rule<IWorkflowModel>("Argument Naming Rule", RuleId, Inspect)
{
DefaultErrorLevel = System.Diagnostics.TraceLevel.Warning,
RecommendationMessage = Recommendation
};
return rule;
}
private static InspectionResult Inspect(IWorkflowModel workflowModel, Rule ruleInstance)
{
I am trying to understand, how can we pass Inspect static method as parameter in line 3, without adding parameters to itself (like Inspect(paramA, paramB)?
I can guess it takes both Rule and IWorkflowModel objects from the rule created itself (line 3). But trying to figure out some logic/rule behind it.
Edit
This is Rule<T> class from metadata
namespace UiPath.Studio.Activities.Api.Analyzer.Rules
{
public sealed class Rule<T> : Rule where T : IInspectionObject
{
public Rule(string ruleName, string ruleId, Func<T, Rule, InspectionResult> inspectionFunction);
public Func<T, Rule, InspectionResult> Inspect { get; }
}
}
You're passing the function, not invoking it. This allows a different piece of code to invoke the function later, supplying the arguments.
The way this is done in C# is through delegates (since about .NET 3.5, instead of using custom delegate types, you will probably want to use Action and Func respectively). You can think of a delegate as a single-method interface - it's basically a bridge between object-oriented and true functional programming.
In older code, this was mainly used in events and callbacks. Today, as C# gets more and more functional, it's getting rather common for abstract functions to accept functions as arguments; LINQ was probably the first big example. You supply your own behaviour to other functions. You want to filter a collection? Just pass a function that does the filtering (col.Where(i => i.Name.Length > 3)).
To show you a possible way of implementing what you're seeing in your code:
public class Rule<T> : Rule
{
private readonly Func<T, Rule, InspectionResult> _inspect;
public Rule(string name, string ruleId, Func<T, Rule, InspectionResult> inspect)
: base(name, ruleId)
{
_inspect = inspect;
}
public InspectionResult Inspect(T model) => _inspect(this, model);
}
Note that when Rule<T> calls the delegate, it must supply all of the arguments.
Of course, the actual behaviour of the caller can be essentially arbitrary. The point is that you're passing a behaviour to someone else. Delegates are a very simple and quick way of doing that, especially combined with anonymous functions and all that.

C# Dictionary of generic classes

I am new to C#. I am trying to implement a Dictionary in C# whose Java-equivalent is:
HashMap<string, Variable<?>> dictionary
Here is the detailed Java version of what I'm trying to do: Java how to manage user-defined variables
In C# so far I have something like this:
interface IVariable { }
public class Variable<T> : IVariable
{
public T myValue { get; set; }
}
Dictionary<string, IVariable> vars = new Dictionary<string, IVariable>();
Then I try to do this:
Variable<int> age = new Variable<int>();
age.myValue = 12;
vars.Add("age", age);
IVariable theVar;
if (vars.TryGetValue("age", out theVar) {
Console.WriteLine("fetched age is " + theVar.myValue);
}
I run into trouble in the last line because the compiler doesn't recognize the myValue member of a theVar because it is an IVariable.
In this simple example maybe I could declare theVar to be a Variable<int> instead of an IVariable but I haven't tried it because it would require a priori knowledge about what kind of variable I'm fetching from the dictionary and I might not always have that knowledge.
I wouldn't mind if myValue were an inherited/abstract property (if there is such a thing), since every Variable will have a property named myValue (each will differ in type but not in name). In that case I guess I could make IVariable an abstract class rather than an interface, but then I still run into trouble as far as what to put for the type of myValue.
Could I do a cast of theVar into something using as by first checking its type with is? I'm not sure if that would work or is even possible.
I've looked at these posts for guidance (especially the second one):
Wildcard equivalent in C# generics
C# Generics: wildcards
However, my situation is still slightly different than the second example above because that example has an abstract method that is returning a void whereas I wish to have my variables return non-void generic values.
Thanks for any help.
C# has dynamic. You can create Dictionary<string, dynamic>
Or you can use object (boxing/unboxing) Dictionary<string, object>
Or you can get generic type from class
class MyClass<TDicValue>
{
Dictionary<strint, TDicValue> myDictionary;
}
I had this same problem where I had 20 slightly different types and I had to keep dictionaries on. I wanted to organize them in a list.
The problem was the same, selecting the right kind from the list with reflection or strings lacked the ability to provide a type to return to. #skrilmps answer is correct, but packing and and unpacking was at best unreliable without a lot (metric ton) of ugly messy code.
While unity does support dynamics in 2020, this doesn't exactly work with what i am doing unless I make like everything dynamic safe and that's shamble coding, not extensible or maintainable, and just sounds like a general nightmare.
I personally feel that I am an inadequate programmer after years of trying to learn and still not having my efforts provide a productive return or product of note, so i cannot claim the answer being mine, but in my research on the proper solution to this problem i found this: https://www.youtube.com/watch?v=A7qwuFnyIpM
In here he says basically if you add an interface to your similar classes that are intended for use in a variety of different lists, that you can instead make a list of that type of interface. I would assume dictionary as well, and then you can add any kind of class implementing this interface to this singular interface type defined list.
I tried using boxing/unboxing and came up with this solution. It appears to work... so far. But it doesn't seem very safe.
public interface Variable
{
object getValue();
void setValue(object value);
Type myType();
}
public class Variable<T>: Variable
{
private T myValue;
public object getValue()
{
return myValue;
}
public void setValue(object value)
{
myValue = (T)value;
}
public Type myType() { return myValue.GetType(); }
}
Dictionary<string, Variable> vars = new Dictionary<string, Variable>();
Variable<int> age = new Variable<int>();
age.setValue(21);
vars.Add("age", age);
Variable theAgeVar;
vars.TryGetValue("age", out theAgeVar);
Console.WriteLine("age = " + theAgeVar.getValue());
Variable<double> height = new Variable<double>();
height.setValue(5.9);
Variable theHeightVar;
vars.TryGetValue("age", out theHeightVar);
Debug.Log("height = " + theHeightVar.getValue());
This prints:
age = 21
height = 5.9
One thing I do not like is that I had to make the return type of getValue() be an object. If I wanted myValue (which is of type T) to implement IComparable, for instance, then this information is lost when the boxing happens and the caller receives an object.
// The following should resolve the boxing problem and now is totally generic:
public interface IVariable<T>
{
T GetContent();
void SetContent(T value);
Type GetDataType();
}
public class Variable<T> : IVariable
{
private T content;
public T GetContent()
{
return content;
}
public void SetContent(T value)
{
content = value;
}
public Type GetDataType() { return GetType(); }
}
Dictionary<string, Variable<T>> variables = new Dictionary<string, Variable<T>>();

C# simpler run time generics

Is there a way to invoke a generic function with a type known only at run time?
I'm trying to do something like:
static void bar()
{
object b = 6;
string c = foo<typeof(b)>();
}
static string foo<T>()
{
return typeof (T).Name;
}
Basically I want to decide on the type parameter only at run time, but the function I'm calling depends on the type parameter.
Also I know this can be done with reflections... but it's not the nicest solution to the problem...
I'm sort of looking for dynamic features in C#...
I'm writhing a bridge between two classes the first one is basically a big tree with different types of of objects (composite by interface) the other is a sort of a "super visitor".
the supper visitor accepts key-value dictioneries that map types to object it looks like:
dic.Add(object value)
and T is not necessarily the type of the value... a lot of times it isn't...
I know it's written poorly, but i can't fix it...
I can work around it, but only at runtime...
I already did it with reflections, but if there's a better way to do it without them i would be happy to learn...
Thank you
This is a bit of a hack but you can get dynamic to do the reflection work for you by something like,
class Program
{
static void Main(string[] args)
{
var b = 6;
var t = (dynamic)new T();
var n = t.Foo(b);
}
class T
{
public string Foo<T>(T a)
{
return typeof(T).Name;
}
}
}
Here the dynamic call will extract the type of b and use it as a type parameter for Foo().
You can use dynamic keyword if you're using .NET 4. In a word, the type of the variable will be resolved at run time so it is a super generic type ;) You can read a article here or read the MSDN documentation
Saly refelction is THE solution to the problem, whether it is nice or not is irrelevant here. It is the runtime designed mechanism to achieve exactly this. As there is no parameter or generics to use as input, this is the only way to do it - it is also senseless. As in: your example is bad. Because in the example the type is hardcoded.
If the method where b exists has b as generic parameter, the type is available for passing to foo. If not - reflection is THE way to go, albeit the syntax looks clumsy. Only one time, though.
This I believe is the only way:
var foo = typeof(Foo<>).MakeGenericType(typeof (bar));
You can set up a class which takes a type parameter at run time which can be used in the methods in that class.
public class GenericClass<T>()
{
ICommonInterface TheObject;
public GenericClass(T theObject)
{
TheObject = theObject;
}
public string GetName()
{
return TheObject.Name;
}
}
But this is only really useful if the Types being passed in share interfaces so have common properties between them. In your example it seems that relection is the answer as depending on the type you want to access specific properties.

Expose Action<T> as Action<object>

I'm creating a framework that contains a wrapper around a library (specifically SharpBrake) that performs all interaction with SharpBrake via reflection so there's no hard dependency on the library to 3rd parties of my framework.
If 3rd parties of my framework wants to use SharpBrake, they can just stuff the SharpBrake.dll into the bin folder, but if they don't, they can just forget about it. If my framework had explicit references to SharpBrake types, users of my framework would get exceptions during runtime of SharpBrake.dll missing, which I don't want.
So, my wrapper first loads SharpBrake.dll from disk, finds the AirbrakeClient type, and stores a delegate pointing to the AirbrakeClient.Send(AirbrakeNotice) method in a private field. My problem, however, is that since the Send() method takes an AirbrakeNotice object and I can't reference the AirbrakeNotice object directly, I need to somehow convert the Send() method to an Action<object>.
I have a strong feeling this isn't possible, but I want to explore all options before settling on exposing Delegate and using DynamicInvoke(), which I assume is far from optimal, performance-wise. What I would love to do is the following:
Type clientType = exportedTypes.FirstOrDefault(type => type.Name == "AirbrakeClient");
Type noticeType = exportedTypes.FirstOrDefault(type => type.Name == "AirbrakeNotice");
MethodInfo sendMethod = clientType.GetMethod("Send", new[] { noticeType });
object client = Activator.CreateInstance(clientType);
Type actionType = Expression.GetActionType(noticeType);
Delegate sendMethodDelegate = Delegate.CreateDelegate(actionType, client, sendMethod);
// This fails with an InvalidCastException:
Action<object> sendAction = (Action<object>)sendMethodDelegate;
However, this fails with the following exception:
System.InvalidCastException: Unable to cast object of type 'System.Action`1[SharpBrake.Serialization.AirbrakeNotice]' to type 'System.Action`1[System.Object]'.
Obviously, because sendMethodDelegate is an Action<AirbrakeNotice> and not an Action<object>. Since I can't mention AirbrakeNotice in my code, I'm forced to do this:
Action<object> sendAction = x => sendMethodDelegate.DynamicInvoke(x);
or just exposing the Delegate sendMethodDelegate directly. Is this possible? I know that there's chance of getting into situations where the object can be of a different type than AirbrakeNotice which would be bad, but seeing how much you can mess up with reflection anyway, I'm hoping there's a loophole somewhere.
If you're happy to use expression trees, it's reasonably simple:
ConstantExpression target = Expression.Constant(client, clientType);
ParameterExpression parameter = Expression.Parameter(typeof(object), "x");
Expression converted = Expression.Convert(parameter, noticeType);
Expression call = Expression.Call(target, sendMethod, converted);
Action<object> action = Expression.Lambda<Action<object>>(call, parameter)
.Compile();
I think that's what you want...
If you don't need below C# 4 support you can get much greater performance using the dynamic vs DynamicInvoke.
Action<dynamic> sendAction = x => sendMethodDelegate(x);
Actually I guess you wouldn't even need the above if you can use dynamic, because it would increase performance and simplify everything if you just did:
Type clientType = exportedTypes.FirstOrDefault(type => type.Name == "AirbrakeClient");
dynamic client = Activator.CreateInstance(clientType);
...
client.Send(anAirbrakeNotice);
But if you need to support .net 3.5 jon skeets answer with expression trees is definitely the way to go.
From my comment on the OP:
I'd avoid extended use of reflections if you are concerned about performance. If you can come up with an interface for the class(es) you are using, then I'd create one. Then write a wrapper that implements the interface by calling into the SharpBreak code, and stuff it in a separate DLL. Then dynamically load just your wrapper assembly and concrete wrapper type(s), and call into that interface. Then you don't have to do reflections at a method level.
I'm not sure all the classes you'd need, but here's a simple example of how you can hook into that library with loose coupling based on interfaces.
In your program's assembly:
public IExtensions
{
void SendToAirbrake(Exception exception);
}
public static AirbreakExtensions
{
private static IExtensions _impl;
static()
{
impl = new NullExtensions();
// Todo: Load if available here
}
public static void SendToAirbrake(this Exception exception)
{
_impl.SendToAirbrake(exception);
}
}
internal class NullExtensions : IExtensions // no-op fake
{
void SendToAirbrake(Exception exception)
{
}
}
In a load-if-available (via reflections) assembly
public ExtensionsAdapter : IExtensions
{
void SendToAirbrake(Exception exception)
{
SharpBrake.Extensions.SendToAirbrake(exception);
}
}
The advantage of this approach is that you only use reflections once (on load), and never touch it again. It is also simple to modify to use dependency injection, or mock objects (for testing).
Edit:
For other types it will take a bit more work.
You might need to use the Abstract Factory pattern to instantiate an AirbrakeNoticeBuilder, since you need to deal directly with the interface, and can't put constructors in interfaces.
public interface IAirbrakeNoticeBuilderFactory
{
IAirbrakeNoticeBuilder Create();
IAirbrakeNoticeBuilder Create(AirbrakeConfiguration configuration);
}
If you're dealing with custom Airbreak structures, you'll have even more work.
E.g. for the AirbrakeNoticeBuilder you will have to create duplicate POCO types for any related classes that you use.
public interface IAirbrakeNoticeBuilder
{
AirbrakeNotice Notice(Exception exception);
}
Since you're returning AirbrakeNotice, you might have to pull in nearly every POCO under the Serialization folder, depending on how much you use, and how much you pass back to the framework.
If you decide to copy the POCO code, including the whole object tree, you could look into using AutoMapper to convert to and from your POCO copies.
Alternately, if you don't use the values in the classes you're getting back, and just pass them back to the SharpBreak code, you could come up with some sort of opaque reference scheme that will use a dictionary of your opaque reference type to the actual POCO type. Then you don't have to copy the whole POCO object tree into your code, and you don't need to take as much runtime overhead to map the object trees back and forth:
public class AirbrakeNotice
{
// Note there is no implementation
}
internal class AirbreakNoticeMap
{
static AirbreakNoticeMap()
{
Map = new Dictionary<AirbreakNotice, SharpBreak.AirbreakNotice>();
}
public static Dictionary<AirbreakNotice, SharpBreak.AirbreakNotice> Map { get; }
}
public interface IAirbrakeClient
{
void Send(AirbrakeNotice notice);
// ...
}
internal class AirbrakeClientWrapper : IAirbrakeClient
{
private AirbrakeClient _airbrakeClient;
public void Send(AirbrakeNotice notice)
{
SharpBreak.AirbrakeNotice actualNotice = AirbreakNoticeMap.Map[notice];
_airbrakeClient.Send(actualNotice);
}
// ...
}
internal class AirbrakeNoticeBuilderWrapper : IAirbrakeNoticeBuilder
{
AirbrakeNoticeBuilder _airbrakeNoticeBuilder;
public AirbrakeNotice Notice(Exception exception)
{
SharpBreak.AirbrakeNotice actualNotice =
_airbrakeNoticeBuilder.Notice(exception);
AirbrakeNotice result = new AirbrakeNotice();
AirbreakNoticeMap.Map[result] = actualNotice;
return result;
}
// ...
}
Keep in mind that you only need to wrap the classes and parts of the public interface that you're going to use. The object will still behave the same internally, even if you don't wrap its entire public interface. This might mean you have to do less work, so think hard and try to wrap only what you need now, and what you know you're going to need in the future. Keep YAGNI in mind.
The programming style I have come to really like for problems like this is to write as much strongly-typed code as possible, and then hand off the logic from the dynamically-typed code to the strongly-typed code. So I would write your code like this:
//your code which gets types
Type clientType = exportedTypes.FirstOrDefault(type => type.Name == "AirbrakeClient");
Type noticeType = exportedTypes.FirstOrDefault(type => type.Name == "AirbrakeNotice");
//construct my helper object
var makeDelegateHelperType=typeof(MakeDelegateHelper<,>).MakeGenericType(clientType, noticeType);
var makeDelegateHelper=(MakeDelegateHelper)Activator.CreateInstance(makeDelegateHelperType);
//now I am in strongly-typed world again
var sendAction=makeDelegateHelper.MakeSendAction();
And this is the definition of the helper object, which is able to get away with fewer reflectiony calls.
public abstract class MakeDelegateHelper {
public abstract Action<object> MakeSendAction();
}
public class MakeDelegateHelper<TClient,TNotice> : MakeDelegateHelper where TClient : new() {
public override Action<object> MakeSendAction() {
var sendMethod = typeof(TClient).GetMethod("Send", new[] { typeof(TNotice) });
var client=new TClient();
var action=(Action<TNotice>)Delegate.CreateDelegate(typeof(Action<TNotice>), client, sendMethod);
return o => action((TNotice)o);
}
}

Are parentheses mandatory to include in C# methods?

I have seen multiple tutorials that show C# method creation with parentheses containing parameters or simple empty. I have also seen a C# method written with out parentheses.
public int Value {
get{ return _Value; }
set{ _Value = value; }
}
I haven't tested out that code but is this allowed? Is it considered bad form?
That is a Property and not a method. If you create a Method then it requires ().
As in Philip's answer, your example code is actually a Property,
But you perhaps have hit on something that many actually miss and that is that Properties are implemented using one or two methods. They get created for you by the compiler and contain the contents of each of the get and/or set blocks.
So, a property of:
public string Name {
get {
return "Fred";
}
}
Is a nicer way of writing:
public string GetName() {
return "Fred";
}
Parentheses are mandatory when declaring or invoking a method.
As others have said, what you've shown there is a property, which is implemented as one or two methods behind the scenes (one for each of the "getter" and "setter").
However, you will sometimes see method names without parentheses - these are called method groups and are used to construct instances of delegate types.
For example:
public void Foo(string x)
{
...
}
...
Action<string> action = Foo;
Here Action<string> is a delegate type representing a call with a single string parameter and a void return type. This assignment creates an instance of that delegate type which will call the Foo method when it's invoked, e.g.
action("Test");
will call Foo with an argument of "Test".
That is a property, not a method. A method requires parenthesis.
Bad form depends on context, there are a few design considerations to take into account when deciding to use a property or not.
MSDN has a nice list here: http://msdn.microsoft.com/en-us/library/ms229006.aspx

Categories