Closures and reference setting - c#

I think I have a fundamental misunderstanding here. Why does the test fail?
public static class ObjectExtensions
{
public static Action To<T>(this T newValue, T oldValue) where T : class
{
return () => oldValue = newValue;
}
}
public static class Assign
{
public static T TheValue<T>(T theValue)
{
return theValue;
}
}
public class Tests
{
public void Test()
{
var a = new TestType { Name = "a" };
var b = "b";
Assign.TheValue(b).To(a.Name)();
Assert.That(a.Name == "b"); //fails (a.Name == "a")
}
}
public class TestType { public string Name {get;set;} }

It fails because the arguments to To are passed by value.
Just because oldValue is set to "b" doesn't mean that a.Name will be changed at all. In the call To(a.Name), the expression a.Name is evaluated to a string reference, and that reference is passed to the method by value.
That's basic parameter passing in C#. Just using a closure doesn't change that.
What you can do is change the To method like this:
public static Action To<T>(this T newValue, Action<T> setter) where T : class
{
return () => setter(newValue);
}
then change the call to:
Assign.TheValue(b).To(x => a.Name = x)();

Put another way,
var a = new TestType { Name = "a" };
Assign.TheValue(b).To(a.Name)();
is equivalent to
Assign.TheValue(b).To("a")();
just like
int x = 5;
Convert.ToDecimal(x);
is equivalent to
Convert.ToDecimal(5);

Related

Delegates to generic operations where the generic type is unknown. How to create something like that?

Suppose I have the following code.
static class Store<T> {
public static T A;
public static T B;
public static T C;
}
public static class Store {
public static Value A = new Value(<T>(v) => Store<T>.A = v); //just an example of what I want
public static Value B = new Value(<T>(v) => Store<T>.B = v); //just an example of what I want
public static Value C = new Value(SetC<T>); //just an example of what I want
public static void SetA<T>(T value) { Store<T>.A = value; }
public static void SetB<T>(T value) { Store<T>.B = value; }
public static void SetC<T>(T value) { Store<T>.C = value; }
}
public class Value {
Action<T><T> _valueChanger; //just an example of what I want
public Value(Action<T><T> valueChanger) { //just an example of what I want
_valueChanger = valueChanger;
}
public void SetValue<T> (T value) {
_valueChanger<T>(value); //just an example of what I want
}
}
I want to write Store.A.SetValue(42) so that the value is saved to Store<int>.A. What can I write instead of the lines marked by "just an example of what I want" to make that happen? (I want to explore a solution that doesn't involve dictionaries or something similar)
Rephrasing the question:
I want to modify class Value (define some fields, write a constructor and write the method Value.SetValue(T value) ), then construct three different variables of type Value (A, B, C) in such a way that when I call Store.A.SetValue(42) the value Store<int>.A is changed to 42.
Another variation of the classes:
static class Holder<T> {
T Value { get; set; }
}
static class Store2<T> {
public static Holder<T> A = new Holder<T>();
public static Holder<T> B = new Holder<T>();
public static Holder<T> C = new Holder<T>();
}
public static class Store2 {
public static Value A = new Value2(Store2<>.A); //just an example of what I want
public static Value B = new Value2(Store2<>.B); //passing non-specific generic expression
public static Value C = new Value3({TFree}() => Store2<TFree>.C); //just an example of what I want
}
public class Value2 { //Non-generic class!
Holder{TFree}<TFree> _holder; //just an example of what I want
public Value(Holder{TFree}<TFree> holder) { //just an example of what I want
_holder = holder;
}
public void SetValue<T> (T value) {
_holder{T}.Value = value; //just an example of what I want
}
}
public class Value3 { //Non-generic class! (Another variation)
Func{TFree}<Holder<TFree>> _holderFactory; //just an example of what I want
public Value(Func{TFree}<Holder<TFree>> holderFactory) { //just an example of what I want
_holderFactory = holderFactory;
}
public void SetValue<T> (T value) {
Holder<T> holder = _holderFactory{T}(); //just an example of what I want
holder.Value = value;
}
}
Solution:
An easy reflection-free and collection-free solution was found using the answers to another question ( Emulating delegates with free generic type parameters in C# and Emulating delegates with free generic type parameters in C#). The solution is Delegates to generic operations where the generic type is unknown. How to create something like that?.
Use an array to store the values and access them through a property using an index
public static class Store<T>
{
public static readonly T[] Values = new T[3];
public static T A { get { return Values[0]; } set { Values[0] = value; } }
public static T B { get { return Values[1]; } set { Values[1] = value; } }
public static T C { get { return Values[2]; } set { Values[2] = value; } }
}
public static class Store
{
public static readonly Value A = new Value(0);
public static readonly Value B = new Value(1);
public static readonly Value C = new Value(2);
}
public class Value
{
private int _index;
public Value(int index)
{
_index = index;
}
public void SetValue<T>(T value)
{
Store<T>.Values[_index] = value;
}
public T GetValue<T>()
{
return Store<T>.Values[_index];
}
}
Since the constructor of Value is not aware of any generic type parameter, you cannot have any reference to a specific Store<T>.
UPDATE
Be aware of the fact that a copy of Store<T> will be created for every distinct type argument that you supplied for T. See this example
Store.A.SetValue(42);
Store.A.SetValue("Douglas Adams");
Store.A.SetValue(new DirectoryInfo(#"C:\"));
Store.A.SetValue(new List<int>());
var x1 = Store.A.GetValue<int>(); // --> 42
var x2 = Store.A.GetValue<string>(); // --> "Douglas Adams"
var x3 = Store.A.GetValue<DirectoryInfo>(); // --> DirectoryInfo{ C:\ }
var x4 = Store.A.GetValue<List<int>>(); // --> List<int>{ Count = 0 }
By using the debugger, you will see that four different values are stored in A at the same time! Of cause these are four differents A's that exist in four diffferent Store<T>.
The problem turned out to be solvable. Mike-z gave me a nearly right solution for the delegate-to-generic-method problem ( Emulating delegates with free generic type parameters in C#) which I modified to be a full solution: ( Emulating delegates with free generic type parameters in C#).
The solution this question becomes easy too. Interfaces can contain generic methods and we can use the interface-valued variables to store links to generic methods without specifying concrete type arguments. The following code utilizes the Store<T> class without modifications and uses the ISetter interface and ASetter/BSetter/CSetter "closures" to hold references to different generic members. The Value class stores the references in a ISetter-typed variable and uses the generic member which the _setter links to once the type argument T becomes available.
public interface ISetter {
void SetValue<T>(T value);
}
public static class Store {
public static Value A = new Value(new ASetter());
public static Value B = new Value(new BSetter());
public static Value C = new Value(new CSetter());
class ASetter : ISetter {
public void SetValue<T>(T value) { Store<T>.A = value; }
}
class BSetter : ISetter {
public void SetValue<T>(T value) { Store<T>.B = value; }
}
class CSetter : ISetter {
public void SetValue<T>(T value) { Store<T>.C = value; }
}
}
public class Value {
ISetter _setter;
public Value(ISetter setter) {
_setter = setter;
}
public void SetValue<T> (T value) {
_setter.SetValue<T>(value);
}
}

C#: how to define an extension method as "with" in F#?

F# has a convenient feature "with", example:
type Product = { Name:string; Price:int };;
let p = { Name="Test"; Price=42; };;
let p2 = { p with Name="Test2" };;
F# created keyword "with" as the record types are by default immutable.
Now, is it possible to define a similar extension in C#?
seems it's a bit tricky, as in C# i'm not sure how to convert a string
Name="Test2"
to a delegate or expression?
public static T With<T, U>(this T obj, Expression<Func<T, U>> property, U value)
where T : ICloneable {
if (obj == null)
throw new ArgumentNullException("obj");
if (property == null)
throw new ArgumentNullException("property");
var memExpr = property.Body as MemberExpression;
if (memExpr == null || !(memExpr.Member is PropertyInfo))
throw new ArgumentException("Must refer to a property", "property");
var copy = (T)obj.Clone();
var propInfo = (PropertyInfo)memExpr.Member;
propInfo.SetValue(copy, value, null);
return copy;
}
public class Foo : ICloneable {
public int Id { get; set; }
public string Bar { get; set; }
object ICloneable.Clone() {
return new Foo { Id = this.Id, Bar = this.Bar };
}
}
public static void Test() {
var foo = new Foo { Id = 1, Bar = "blah" };
var newFoo = foo.With(x => x.Bar, "boo-ya");
Console.WriteLine(newFoo.Bar); //boo-ya
}
Or, using a copy constructor:
public class Foo {
public Foo(Foo other) {
this.Id = other.Id;
this.Bar = other.Bar;
}
public Foo() { }
public int Id { get; set; }
public string Bar { get; set; }
}
public static void Test() {
var foo = new Foo { Id = 1, Bar = "blah" };
var newFoo = new Foo(foo) { Bar = "boo-ya" };
Console.WriteLine(newFoo.Bar);
}
And a slight variation on George's excellent suggestion, that allows for multiple assignments:
public static T With<T>(this T obj, params Action<T>[] assignments)
where T : ICloneable {
if (obj == null)
throw new ArgumentNullException("obj");
if (assignments == null)
throw new ArgumentNullException("assignments");
var copy = (T)obj.Clone();
foreach (var a in assignments) {
a(copy);
}
return copy;
}
public static void Test() {
var foo = new Foo { Id = 1, Bar = "blah" };
var newFoo = foo.With(x => x.Id = 2, x => x.Bar = "boo-ya");
Console.WriteLine(newFoo.Bar);
}
I would probably use the second one since (1) any general purpose solution is going to be unnecessarily slow and convoluted; (2) it has the closest syntax to what you want (and the syntax does what you expect); (3) F# copy-and-update expressions are implemented similarly.
Maybe something like this:
void Main()
{
var NewProduct = ExistingProduct.With(P => P.Name = "Test2");
}
// Define other methods and classes here
public static class Extensions
{
public T With<T>(this T Instance, Action<T> Act) where T : ICloneable
{
var Result = Instance.Clone();
Act(Result);
return Result;
}
}
As an alternative to lambda function, you can use parameters with default values. The only minor issue is that you have to pick some default value that means do not change this parameter (for reference types), but null should be a safe choice:
class Product {
public string Name { get; private set; }
public int Price { get; private set; }
public Product(string name, int price) {
Name = name; Price = price;
}
// Creates a new product using the current values and changing
// the values of the specified arguments to a new value
public Product With(string name = null, int? price = null) {
return new Product(name ?? Name, price ?? Price);
}
}
// Then you can write:
var prod2 = prod1.With(name = "New product");
You have to define the method yourself, but that's always the case (unless you're going to use reflection, which less efficient). I think the syntax is reasonably nice too. If you want to make it as nice as in F#, then you'll have to use F# :-)
There is no native ability to do this in C# short of an extension method, but at what cost? a and b are reference types and any suggestion that b is based ("with") on a causes immediate confusion as to how many objects we are working with. Is there only one? Is b a copy of a ? Does b point to a ?
C# is not F#.
Please see a previous SO question of mine as answered by Eric Lippert:
"Amongst my rules of thumb for writing clear code is: put all side effects in statements; non-statement expressions should have no side effects."
More fluent C# / .NET

How to convert chained static class names and a property value to a string?

Context:
Suppose one has the following class structure:
public static class SomeStaticClass
{
public static class SomeInnerStaticClass
{
public static readonly string SomeProperty = "someStringValue";
}
}
Question:
Is there an easy way to convert the reference SomeStaticClass.SomeInnerStaticClass.SomeProperty to string value of "SomeStaticClass.SomeInnerStaticClass.someStringValue"?
the first thing I posted was wrong because they were static types I wrote a little code and this works.
public static class A
{
public static class B
{
public static string c
{
get
{
return "hi";
}
}
}
}
class Program
{
static void Main( string[] args )
{
Console.WriteLine(typeof(A.B).FullName.Replace("+",".") + "." + A.B.c ) ;
}
}
Don't you just want:
public static class SClass
{
public static class SInner
{
public static string Property =
(typeof(SInner)).DeclaringType.Name+ "."
+ typeof(SInner).Name + "."
+ "value";
}
}
Which would output SClass.SInner.Property.value
If you wanted to automated it, you could put it in a while loop and exit once the parent type propertyIsNested is false.
You could use an expression:
namespace ConsoleApplication2
{
using System;
using System.Linq.Expressions;
class Program
{
static void Main(string[] args)
{
string fullName = GetExpression(() => SomeClass.SomeProperty);
Console.WriteLine(fullName);
}
public static string GetExpression<TProperty>(Expression<Func<TProperty>> expr)
{
string name = expr.Body.ToString();
string value = expr.Compile().Invoke().ToString();
name = name.Substring(0, name.LastIndexOf(".") + 1) + value;
return name;
}
}
public static class SomeClass
{
public static string SomeProperty = "Hello";
}
}
Here's one more elaborate solution. The method accepts a lambda expression denoting a property or a field. It the computes the value of the property or field and prepends it with names of all encapsulating classes.
I guess you want to have a type-safe method of producing some kind of structured / hierarchical identifiers encoded as a hierarchy of classes and properties or fields. I've been using this approach for a few years and it helps prevent many hard-to-catch bugs caused by simple typos.
Code:
public string GetStructuredName(Expression<Func<object>> nameObject)
{
if (nameObject == null) throw new ArgumentNullException("nameObject");
// find the expression denoting a property or a field
MemberExpression member = null;
switch (nameObject.Body.NodeType)
{
case ExpressionType.MemberAccess:
member = (MemberExpression)nameObject.Body;
break;
case ExpressionType.Convert:
case ExpressionType.ConvertChecked:
member = ((UnaryExpression)nameObject.Body).Operand as MemberExpression;
break;
}
if (member == null) throw new ArgumentNullException("nameObject");
StringBuilder sb = new StringBuilder();
// use the value of the member as the final component of the resulting name
sb.Append(nameObject.Compile().DynamicInvoke());
// use short names of embedded type names as components of the resulting name
Type type = member.Member.DeclaringType;
while (type != null && type != typeof(Object))
{
sb.Insert(0, ".");
sb.Insert(0, type.Name);
type = type.DeclaringType;
}
return sb.ToString();
}
Example:
public class OuterContainer
{
public class InnerContainer
{
public static string Property
{
get { return "value"; }
}
public static int Field = 10;
}
}
GetStructuredName(() => OuterContainer.InnerContainer.Property)
GetStructuredName(() => OuterContainer.InnerContainer.Field)
The output will be:
"OuterContainer.InnerContainer.value"
"OuterContainer.InnerContainer.10"
I don't know about the nature of your input format, but you can do this with System.Linq.Expressions:
Expression<Func<string>> expr = () =>
SomeStaticClass.SomeInnerStaticClass.SomeProperty;
var myResult = String.Concat(expr.Body, ".", expr.Compile().Invoke());

calling trygetmember on chained null references

Is it possible to have a DynamicObject implementation that can be called in chain keeping a null reference to end if anywhere in the path a null reference is encountered, without throwing any exceptions?
a.b.c.e
for example: if a is null then a.b.c.e is null, or if c is null c.e is null etc.?
Very much like the Maybe monad from Haskell.
You can do something like that, but not for the outermost object, i.e. if a is null, you can't access a.b.
You can make an empty instance of the A class, that returns empty instances for all it's properties. Then a.b would return an empty instance of B, which for the c property would return an empty instance of C, which for the e property would return an empty instance of E.
You would not get a null value, but you would get an empty instance, which you could check with:
E e = a.b.c.e;
if (e != E.Empty) { ... }
If any of the properties along the way returns an empty instance, the end result would be E.Empty.
public class A {
public B b;
public A(B newB) { b = newB; }
private static A _empty = new A(B.Empty);
public static A Empty { get { return _empty; }}
}
public class B {
public C c;
public B(C newC) { c = newC; }
private static B _empty = new B(C.Empty);
public static B Empty { get { return _empty; } }
}
public class C {
public E e;
public C(E newE) { e = newE; }
private static C _empty = new C(E.Empty);
public static C Empty { get { return _empty; } }
}
public class E {
public string name;
public E(string newName) { name = newName; }
private static E _empty = new E(null);
public static E Empty { get { return _empty; } }
}
Example:
A a1 = new A(new B(new C(new E("Hello world!"))));
A a2 = new A(new B(new C(E.Empty)));
A a3 = new A(B.Empty);
E e1 = a1.b.c.e; // e1.name returns "Hello world!"
E e2 = a2.b.c.e; // e2 == E.Empty
E e3 = a3.b.c.e; // e3 == E.Empty
Check this great article: Chained null checks and the Maybe monad
A great many programmers have met a situation where, while accessing a nested object property (e.g., person.Address.PostCode), they have to do several null checks. This requirement frequently pops up in XML parsing where missing elements and attributes can return null when you attempt to access them (and subsequently trying to access Value throws a NullReferenceException). In this article, I’ll show how a take on the Maybe monad in C#, coupled with use of extension methods, can be used to improve readability.
Here is a poor man's safe navigation extension method that just wraps an expression in a try catch looking for a nullref.
https://gist.github.com/1030887
public static class Extensions
{
public static TResult SafeInvoke<TModel, TResult>(this TModel model, Func<TModel, TResult> expression, TResult nullValue = default(TResult))
{
try
{
return expression(model);
}
catch (NullReferenceException)
{
return nullValue;
}
}
}
You can invoke the code fairly easily.
public class MyModel
{
public Name Name { get; set; }
}
public class Name
{
public string First { get; set; }
public string Last { get; set; }
}
var model = new MyModel();
var firstName = model.SafeInvoke(x => x.Name.First, "john");
var lastName = model.SafeInvoke(x => x.Name.Last, "doe");
Console.WriteLine("{0}, {1}", lastName, firstName)
// prints: "doe, john"

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