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));
}
}
Related
Consider this example,
public class NumberAsIs
{
public NumberAsIs(double number) { _number = number; }
public double Value => _number;
private double _number;
}
public class Percentage
{
public Percentage(double number) { _number = number; }
public double Value => _number * 0.01;
private double _number;
}
class Program
{
static void Main(string[] args)
{
var a = new NumberAsIs(1);
var b = new Percentage(2);
var c = a.Value + b.Value; // Expect c = 1.02
}
}
Because the only purpose of NumberAsIs and Percentage is to call them for their Value method, is there a way to just call them as value types? For example,
class Program
{
static void Main(string[] args)
{
var a = new NumberAsIs(1);
var b = new Percentage(2);
double c = a + b; // Expect c = 1.02
}
}
I'm not looking to redefine the operator+, but to access the numeric value just by calling the object. If it's not possible just fine and say no, asking just in case there is a workaround/sugar syntax I'm not aware of.
The question is roughly related to this other: Value type class definition in C#?
You can try implementing implicit operator:
//TODO: better use struct, not class
public class NumberAsIs {
...
public static implicit operator double(NumberAsIs value) => value.Value;
}
//TODO: better use struct, not class
public class Percentage {
...
public static implicit operator double(Percentage value) => value.Value;
}
Now you can put
var a = new NumberAsIs(1);
var b = new Percentage(2);
// double c = 1.02 as expected
var c = a + b;
// 0.98
var c2 = a - b;
// 0.02
var c3 = a * b;
If you define both directions:
public class NumberAsIs
{
private readonly double _number;
private NumberAsIs(double d) => _number = d;
public static implicit operator double(NumberAsIs value) => value._number;
public static implicit operator NumberAsIs(double value) => new NumberAsIs(value);
}
public class Percentage
{
private readonly double _number;
private Percentage(double d) => _number = d/100.0;
public static implicit operator double(Percentage value) => value._number;
public static implicit operator Percentage(double value) => new Percentage(value);
}
It means you can do this:
NumberAsIs a = 1;
Percentage b = 2;
var c = a + b; // Expect c = 1.02
Console.WriteLine(c); //prints 1.02
I think what you want is to keep the value as defined, but convert it into a double using whatever conversion factor applies.
Here operations such as + etc are handled by invoking the implicit conversion to double.
public struct Number
{
public Number(double value) : this()
{
Value = value;
}
public static implicit operator double(Number number)=>number.Value;
public static implicit operator Number(double value) => new Number(value);
public double Value { get; }
public override string ToString() => $"{Value:g}";
}
public struct Percent
{
public Percent(double value) : this()
{
Value = value;
}
public static implicit operator double(Percent number) => number.Value/100;
public static implicit operator Percent(double value) => new Percent(value * 100);
public double Value { get; }
public override string ToString() => $"{Value:g}%";
}
static class Program
{
static void Main(string[] args)
{
Number a = new Number(1.0); // 1.0
Percent b = new Percent(2.0); // 2%
double c = a + b;
Console.WriteLine($"{a} + {b} = {c}");
// 1 + 2% = 1.02
}
}
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 =)
Please see the code:
class X
{
public string x;
}
class Y : X
{
public string y;
}
class A
{
string a;
public virtual X createX<T>()
where T : X, new()
{
return new T() { x = a };
}
}
class B : A
{
string b;
public override X createX<T>()
{
var x = base.createX<T>();
if (x is Y)
((Y)x).y = b; // Yak.
return y;
}
}
...
var c = new B();
var z = c.createX<Y>(); // Yak. I prefer to not needing to know the type Y
I dislike this code, trying to come up with the better way to refactor it. The general idea is quite simple, each class of the hierarchy has factory method to produce an instance of the counterpart class of mirror hierarchy. I get an instance of the root class or derivative class and need to return the instance of counterpart class or its derivative (as root counterpart class). Any ideas or design pattern I can implement instead?
This is what I have ended up with. All yacks removed. But it is a bit verbose.
class X
{
public string x;
}
class Y : X
{
public string y;
}
class A
{
string a;
protected void setX(X x)
{
x.x = a;
}
public virtual X createX()
{
var x = new X();
setX(x);
return x;
}
}
class B : A
{
string b;
protected void setY(Y y)
{
base.setX(y);
y.y = b;
}
public override X createX()
{
var y = new Y();
setY(y);
return y;
}
}
...
var c = new B();
var z = c.createX();
Could this be what you want ?
class BaseProduct
{
public string x;
}
class ChildProduct : BaseProduct
{
public string y;
}
class BaseFactory
{
string a;
public virtual BaseProduct buildProduct(BaseProduct product = null)
{
if (product == null)
product = new BaseProduct();
product.x = a;
return product;
}
}
class ChildFactory : BaseFactory
{
string b;
public override BaseProduct buildProduct(BaseProduct product = null)
{
if (product == null)
product = new ChildProduct();
//else if (!(product is ChildProduct))
// return null or throw exception
((ChildProduct)product).y = b;
return base.buildProduct(product); //build BaseProduct.x
}
}
...
var cFactory = new ChildFactory();
var cProduct = c.buildProduct(); //create a ChildProduct with x=a, y=b
buildProduct determine whether it has been requested to create a new
product of its own, or some derived-factory requesting it to build its
own part only
You should provide some safeguard mechanism of your own, like checking
whether the product is a derived class from ChildProduct in
ChildFactory.buildProduct. That'll avoid user from passing something like:
childFactory.buildProduct(new BaseProduct()); //yak
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
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));
}
}