I want to overload operator +(f,s) for a generic class. It should return +(f,s) if f and s have plus operator and null otherwise. How can I do it?
public class param<T> : TDefault
{
public string param_name;
public T cnt;
public param(T _cnt)
{
cnt=_cnt;
}
public static param<T> operator +(param<T> f, param<T> s)
{
if(T ? has_operator("+"))
return param<T>(((f.cnt as ?)+(s.cnt as ?)) as T);
return null;
}
}
For checking operator existence I tried
public static bool has_method(this object target,string method_name)
{
return target.GetType().GetMethod(method_name)!=null;
}
but
int x;
print (x.has_method("+="));
prints 'false'
Try this:
public class Param<T>
{
private static readonly Func<T, T, T> addMethod;
static Param()
{
try
{
ParameterExpression left = Expression.Parameter(typeof (T), "left");
ParameterExpression right = Expression.Parameter(typeof (T), "right");
addMethod = Expression.Lambda<Func<T, T, T>>(Expression.Add(left, right), left, right).Compile();
}
catch (InvalidOperationException)
{
//Eat the exception, no + operator defined :(
}
}
public string param_name;
public T cnt;
public Param(T _cnt)
{
cnt = _cnt;
}
public static Param<T> operator +(Param<T> leftOperand, Param<T> rightOperand)
{
if (addMethod != null)
{
return new Param<T>(addMethod(leftOperand.cnt, rightOperand.cnt));
}
return null;
}
}
private static void Main(string[] args)
{
var pi = new Param<int>(5);
var pi2 = new Param<int>(6);
var pi3 = pi + pi2;
var pi4 = new Param<ooject>(5);//Wont work
var pi5 = new Param<object>(6);
var pi6 = pi4 + pi5;
}
Credit goes to JonSkeet and Marc
Related
I have a list public List<ArticleWarehouseLocations> ArticleWarehouseLocationsList. In this list I have a property called Position.
`Swap<long>(ref ArticleWarehouseLocationsList[currentIndex].Position, ref ArticleWarehouseLocationsList[currentIndex - 1].Position);`
public void Swap<T>(ref T lhs, ref T rhs)
{
T temp = lhs;
lhs = rhs;
rhs = temp;
}
I'm trying to do something like this. It's giving me an error property or index may not be passed as ref or out.
I can use a local variable and assign it the value and use it but I'm looking for a global solution.
What you can do is make the property return by reference:
class Obj {
private long pos;
public ref long Position { get { return ref pos; } }
}
static void Main(string[] args)
{
Obj[] arr = new Obj[2] { new Obj(), new Obj() };
arr[0].Position = 10;
arr[1].Position = 20;
int index = 0;
WriteLine($"{arr[index].Position}, {arr[index+1].Position}");
Swap<long>(ref arr[index].Position, ref arr[index+1].Position);
WriteLine($"{arr[index].Position}, {arr[index+1].Position}");
}
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/ref-returns
I believe the tuple swap (x, y) = (y, x) proposed in comments is the way to go, but wanted to share yet another aproach with LINQ Expressions (a bit too long for a comment, so posting as an answer)
public static void SwapProperties<T>(T lhs, T rhs, Expression<Func<T, object>> propExpression)
{
var prop = GetPropertyInfo(propExpression);
var lhsValue = prop.GetValue(lhs);
var rhsValue = prop.GetValue(rhs);
prop.SetValue(lhs, rhsValue);
prop.SetValue(rhs, lhsValue);
}
private static PropertyInfo GetPropertyInfo<T>(Expression<Func<T, object>> propExpression)
{
PropertyInfo prop;
if (propExpression.Body is MemberExpression memberExpression)
{
prop = (PropertyInfo) memberExpression.Member;
}
else
{
var op = ((UnaryExpression) propExpression.Body).Operand;
prop = (PropertyInfo) ((MemberExpression) op).Member;
}
return prop;
}
class Obj
{
public long Position { get; set; }
public string Name { get; set; }
}
public static void Main(string[] args)
{
var a1 = new Obj()
{
Position = 10,
Name = "a1"
};
var a2 = new Obj()
{
Position = 20,
Name = "a2"
};
SwapProperties(a1, a2, obj => obj.Position);
SwapProperties(a1, a2, obj => obj.Name);
Console.WriteLine(a1.Position);
Console.WriteLine(a2.Position);
Console.WriteLine(a1.Name);
Console.WriteLine(a2.Name);
}
Ok, here is the problem:
int a = 111;
int b = 222;
Expression<Func<int>> expr = ()=> someClass.SomeWork(a) + b + 1;
As you see, there is 3 different arguments: someClass, a, b. They are all from another scope of execution, but one isn't. How I can get them? I mean, in general, I want only variables of outter scope.
For example, I want to use it like this:
var result = InvokeAndLog(expr);//this will invoke expression and print out everything I need from these arguments.
Ok, folks, I found answer myself. And here it is:
internal class Program
{
public static int Method1()
{
return new Random(0).Next(10000);
}
public class MyClass
{
private int var = 11111;
public int GetSome(int val)
{
return var * val;
}
}
private static void Main()
{
var clas = new MyClass();
int a = 111;
int b = 222;
Expression<Func<int>> expr = () => a * 2 - clas.GetSome(b) + b + 1 - Method1();
var result = InvokeAndLog(expr);
}
private static T InvokeAndLog<T>(Expression<Func<T>> expr)
{
var visitor = new ArgumentsVisitor();
visitor.Visit(expr);
Console.WriteLine("Inputs: {0}", string.Join(", ", visitor.Arguments));
return expr.Compile()();
}
}
The main class here is ExpressionVisitor descendant. I just overrided its member visitor and aggregated all members into single set:
public class ArgumentsVisitor : ExpressionVisitor
{
private readonly HashSet<MemberInfo> _all = new HashSet<MemberInfo>();
public IEnumerable<MemberInfo> Arguments
{
get { return _all; }
}
protected override Expression VisitMember(MemberExpression node)
{
_all.Add(node.Member);
return base.VisitMember(node);
}
}
Then I applyed visitor to expression and printed out all variables! Thanks, microsoft =)
I have been playing around with LINQ to Z3 for fun (not production use).
I've ended up with this syntax as a start:
var i = 123;
var test2 = from t in TheormProver.NewTheorm()
let f = TheormProver.Func<int, bool>()
let a = TheormProver.Int
let g = TheormProver.Func<bool, int>()
where !f(a * 2) && g(f(g(f(4)))) == i * a && a < g(f(a))
select new { f = f.ToString(), g = g.ToString(), a, asd = "Test extra property" };
var solution = test2.Solve(); // Edited in for clarification
// note that test2 is a TheormProver<T> which has a "T Solve()" method defined.
The static TheromProver.Int and TheormProver.Func methods/properties simply return a basic type (as per their name) currently.
Moving forwards I want to make a sort of Variable<T> type that contains more information than just a value.
TL;DR: The problem I'm having is that I want f and g variables to be a custom type that I can add fields and properties to, but I still want to be able to use them with the syntax I've got in the where clause (i.e. as a method/Func).
So, How do I create a custom type that can be used in method syntax while adding/having my own properties?
Note that I don't care if calling the method does nothing, or doesn't work as I'll be manipulating the where clause so they'll never get invoked/executed.
Example:
var test2 = from t in TheormProver.NewTheorm()
let f = TheormProver.Func<int, bool>()
let a = TheormProver.Int
where !f(a * 2) && a > 3 // f is used to create a method call expression
select new { f , a };
var testSolution = test2.Solve();
var fSolution = testSolution.f; // F is its own type with unique properties/fields.
var fConstraints = fSolution.Constraints;
var fSomeProperty = fSolution.SomeProperty;
foreach(var constraint in fConstraints)
{
//.....
}
I've mocked up a quick example of the work in progress syntax I have so far:
http://liveworkspace.org/code/3Fm6JM$0
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
namespace ConsoleApplication1
{
class TheormProver
{
public static int Int { get { return default(int); } } // Really this would return my Variable<int>
public static Func<T, TResult> Func<T, TResult>() { return default(Func<T, TResult>); } // Really this would return my Variable<Func<T, TResult>>
protected List<Expression> Constraints; // Holds constraints / where clauses that get translated into the Z3 language
//This gets called when we do the first "let" and gets us into the correctly typed world with a generic parameter
public virtual TheormProver<T> Select<T>(Func<TheormProver, T> sel)
{
return new TheormProver<T>(Constraints);
}
}
// This is what the user of the library sees and is returned by a from t in new TheormProver(). T will be the anonymous type from the last let
class TheormProver<T> : TheormProver
{
public TheormProver(List<Expression> Constraints)
{
}
// This gets called on subsequent "let"s, going from the anonymous type with one property "f" to one with 2, "f, g". Chaining this way allows as many lets as we want
public virtual TheormProver<U> Select<U>(Expression<Func<T, U>> sel)
{
return new TheormProver<T, U>(sel, Constraints.ToList());
}
public virtual TheormProver<T> Where(Expression<Func<T, bool>> constraint)
{
var result = (TheormProver<T>)this; // This should be a clone to allow composable queries
result.Constraints.Add(constraint);
return result;
}
public virtual T Solve(out bool foundSolution)
{
// TODO: Call Z3 and get a solution
foundSolution = false;
return default(T);
}
}
internal class TheormProver<T, U> : TheormProver<U>
{
private LambdaExpression Selector;
private TheormProver<T> InternalTheorumProver;
public TheormProver(Expression<Func<T, U>> selector, List<Expression> constraints)
: base(constraints)
{
Selector = selector;
InternalTheorumProver = new TheormProver<T>(constraints);
}
}
class Program
{
static void Main(string[] args)
{
var test = from t in new TheormProver()
let f = TheormProver.Func<int, bool>()
let g = TheormProver.Func<bool, int>()
let a = TheormProver.Int
where g(f(a)) == 0
select new { f, g, a };
bool foundSolution;
var testSolution = test.Solve(out foundSolution);
}
}
}
I've created a simple 'testbed' for your original code: http://liveworkspace.org/code/3Bl7wC$0.
With, a bit of dynamic magic, you can have the following class as a drop-in replacement for Func<T1, T2>:
public class MyCallable<T1, T2> : DynamicObject
{
private readonly Expression<Func<T1, T2> > _wrapped;
private readonly Func<T1, T2> _compiled;
public MyCallable(Expression<Func<T1, T2>> towrap)
{
_wrapped = towrap; _compiled = _wrapped.Compile();
}
public override bool TryInvoke(InvokeBinder binder, object[] args, out object result)
{
if ( (args.Length == 1) &&
(args[0].GetType() == typeof(T1)))
{
Console.WriteLine(#"Invoking ""{0}"" on {1}", _wrapped, args[0]);
result = _compiled((T1) args[0]);
return true;
}
else
{
//throw new ArgumentException("Cannot invoke " + _wrapped + " with the arguments passed");
result = null;
return false;
}
}
}
As you can see, it defines you class as being "dynamic" and allows you to try and invoke it as if it were a delegate/function/... a general callable:
// in "TheormProver"
public static dynamic Func<T1, T2>() { return new MyCallable<T1, T2>(arg1 => default(T2)); }
Here's proof it works: http://liveworkspace.org/code/4kBypd$0
Output:
Invoking "arg1 => False" on 0
Invoking "arg1 => False" on 4
Invoking "arg1 => 0" on False
Invoking "arg1 => False" on 0
Invoking "arg1 => 0" on False
Invoking "arg1 => False" on 0
Invoking "arg1 => 0" on False
Full code for reference:
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Dynamic;
public class Program
{
public class MyCallable<T1, T2> : DynamicObject
{
private readonly Expression<Func<T1, T2> > _wrapped;
private readonly Func<T1, T2> _compiled;
public MyCallable(Expression<Func<T1, T2>> towrap)
{
_wrapped = towrap; _compiled = _wrapped.Compile();
}
public override bool TryInvoke(InvokeBinder binder, object[] args, out object result)
{
if ( (args.Length == 1) &&
(args[0].GetType() == typeof(T1)))
{
Console.WriteLine(#"Invoking ""{0}"" on {1}", _wrapped, args[0]);
result = _compiled((T1) args[0]);
return true;
}
else
{
//throw new ArgumentException("Cannot invoke " + _wrapped + " with the arguments passed");
result = null;
return false;
}
}
}
public static class TheormProver
{
public static object[] NewTheorm() { return new object[] { 1 }; }
public static dynamic Func<T1, T2>() { return new MyCallable<T1, T2>(arg1 => default(T2)); }
public static int Int { get; set; }
}
public static void Main(string[] args)
{
var i = 123;
var test2 = from t in TheormProver.NewTheorm()
let f = TheormProver.Func<int, bool>()
let a = TheormProver.Int
let g = TheormProver.Func<bool, int>()
where !f(a * 2) && g(f(g(f(4)))) == i * a && a < g(f(a))
select new { f = f.ToString(), g = g.ToString(), a, asd = "Test extra property" };
test2.ToList().ForEach(Console.WriteLine);
}
}
You can't add custom members to delegate types and you cannot overload operator () in C#. That leaves you with extension methods.
Now, you don't want to add extensions to very general delegate types like Func<int, int> because that pollutes the namespace. I suggest you create custom delegates like this:
delegate TResult Z3Func<T1, TResult>(T1 arg1);
Then you can add extensions to Z3Func.
The extension calls will end up as static method calls in the expression tree you are analyzing.
Consider the following setup:
class A { public int x; }
class B { public int y; }
static class Helper
{
public static Expression<Func<B>> BindInput(
Expression<Func<A, B>> expression,
A input)
{
//TODO
}
}
static void Main(string[] args)
{
Expression<Func<B>> e = Helper.BindInput(
(A a) => new B { y = a.x + 3 },
new A { x = 4 });
Func<B> f = e.Compile();
Debug.Assert(f().y == 7);
}
What I want to do in the method BindInput is transform the expression to have input embedded into it. In the example usage in Main, the resulting expression e would be
() => new B { y = input.x + 3 }
where input is the second value that was passed into BindInput.
How would I go about doing this?
Edit:
I should add that the following expression e is not what I'm looking for:
((A a) => new B { y = a.x + 3 })(input)
This would be fairly trivial to obtain because it just involves adding a layer on top of the existing expression.
After lots of searching I stumbled across the magic ExpressionVisitor class. The following seems to be working perfectly:
class MyExpressionVisitor : ExpressionVisitor
{
public ParameterExpression TargetParameterExpression { get; private set; }
public object TargetParameterValue { get; private set; }
public MyExpressionVisitor(ParameterExpression targetParameterExpression, object targetParameterValue)
{
this.TargetParameterExpression = targetParameterExpression;
this.TargetParameterValue = targetParameterValue;
}
protected override Expression VisitParameter(ParameterExpression node)
{
if (node == TargetParameterExpression)
return Expression.Constant(TargetParameterValue);
return base.VisitParameter(node);
}
}
static class Helper
{
public static Expression<Func<B>> BindInput(Expression<Func<A, B>> expression, A input)
{
var parameter = expression.Parameters.Single();
var visitor = new MyExpressionVisitor(parameter, input);
return Expression.Lambda<Func<B>>(visitor.Visit(expression.Body));
}
}
I have a c++ class that is very simple:
struct Pt_t
{
T x, y;
template <class T2> operator Pt_t<T2>() { Pt_t<T2> pt = {x, y}; return pt; }
};
That allows me to create a pt that has T as any type I want. I can also do Pt_t<s8> = Pt_t<u64>; without a problem. How do I do the same in C#? I tried the below and got an error:
class Pt<T>
{
public T x, y;
//between operator and <T2>, error CS1031: Type expected
public static implicit operator<T2> Pt<T>(Pt<T2> v) {
Pt<T> r = new Pt<T>();
r.x = v.x;
r.y = v.y;
return r;
}
}
No, I don't think that is possible. You may have to add a method, such as To<T>.
The next problem will be "how to get from T2 to T - you can't just assign them. One option might be a conversion delegate:
public Pt<TDestination> To<TDestination>(
Converter<T, TDestination> converter)
{
if (converter == null) throw new ArgumentNullException("converter");
Pt<TDestination> t = new Pt<TDestination>();
t.x = converter(x);
t.y = converter(y);
return t;
}
...
var p = new Pt<int> { x = 1, y = 2 };
var p2 = p.To(t => t.ToString()); // a Pt<string>
You can use Nemerle: ( http://github.com/rsdn/nemerle ) :
using System.Console;
class A[T]
{
public static #:[From](x : A[From]) : A[T]
{
A()
}
}
class Base{}
class Derived{}
def a = A.[Derived]();
def b : A[Base] = a;
WriteLine($"$a $b");
Output:
A`1[Derived] A`1[Base]
Reflector for code:
internal class A<T>
{
public static implicit operator A<T><From>(A<From> x)
{
return new A<T>();
}
}
public class a
{
public static void Main()
{
A<Derived> a = new A<Derived>();
A<Base> a2 = (A<Base>) a;
Console.WriteLine(Convert.ToString(a) + " " + Convert.ToString(a2));
}
}