LINQ allows to elegantly transform the collection returned by a method to a different collection, i.e.
var x = SomeMethod().Select(t => new { ... });
Now, is there a concise way in C# to transform the return value of a method without introducing an intermediary variable? Declaring and invoking a lambda seems to work but is quite ugly:
var x = new Func<T, object>(t => { return new { ... }; })(SomeMethod());
Am I missing something obvious or is this the best one can do with C# today?
You can apply Select followed by Single to sequence of one item created from the result of calling SomeMethod, as follows:
var x = Enumerable.Repeat(SomeMethod(), 1).Select(r => new {...}).Single();
If you do it a lot, you can make a generic extension method for this:
static class MyExtensions {
public static TRes Transform<TSrc,TRes>(this TSrc src, Func<TSrc,TRes> selector) {
return selector(src);
}
}
Now the syntax becomes very simple:
var res = SomeMethod().Transform(x => new { ... });
I just figured that a generic extension method could fill the gap:
public static class TransformExtension
{
public static T2 Transform<T1, T2>(this T1 t1, Func<T1, T2> transform)
{
return transform(t1);
}
}
Sample usage:
public class A { };
public class B { };
void Foo()
{
var a = new A();
var b = a.Transform(x => new B());
}
Happy to hear why that's possibly a terrible idea.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I know this topic (memoization) has been discussed quite a bit (like here), but no answer I could find satisfies the DRY principle as much as I would like, so please, read this whole question and the three points I want to address.
I have a simple support class like this:
public class Memoized<T1, TResult>
{
private readonly Func<T1, TResult> _f;
private readonly Dictionary<T1, TResult> _cache = new Dictionary<T1, TResult>();
public Memoized(Func<T1, TResult> f)
{
_f = f;
}
public TResult Invoke(T1 p1)
{
if (p1 == null) throw new ArgumentNullException(nameof(p1));
if (_cache.TryGetValue(p1, out var res)) return res;
return _cache[p1] = _f(p1);
}
public static Func<T1, TResult> Of(Func<T1, TResult> f)
{
var memo = new Memoized<T1, TResult>(f);
return x => memo.Invoke(x);
}
}
Nothing especially fancy, but it allows me to do this:
public class MyClass
{
public Func<int, bool> MemoizedMethod { get; }
private bool UncachedMethod(int v)
{
return v > 0;
}
public MyClass()
{
MemoizedMethod = Memoized<int, bool>.Of(UncachedMethod);
}
}
Now, even if the resulting code is not terribly noisy, I'm trying to figure out if the implementation could be more elegant, because currently I need:
an invokable property that acts as a Method.
a true method that should not be called directly.
a line in the constructor (cannot be an inline initialization) that links the two (with a third repetition of the function signature!).
Any suggestion for a strategy that allows to remove one (or two!) of the above points would be great.
In my struggle for elegance, I finally found what I think is the best syntax I saw anywhere:
private class MemoizedTest
{
private int _counter = 0;
public int Method(int p) => this.Memoized(p, x =>
{
return _counter += x;
});
}
Implementation (one pretty small extension class):
namespace System
{
public static class MemoizerExtension
{
internal static ConditionalWeakTable<object, ConcurrentDictionary<string, object>> _weakCache =
new ConditionalWeakTable<object, ConcurrentDictionary<string, object>>();
public static TResult Memoized<T1, TResult>(
this object context,
T1 arg,
Func<T1, TResult> f,
[CallerMemberName] string? cacheKey = null)
where T1 : notnull
{
if (context == null) throw new ArgumentNullException(nameof(context));
if (cacheKey == null) throw new ArgumentNullException(nameof(cacheKey));
var objCache = _weakCache.GetOrCreateValue(context);
var methodCache = (ConcurrentDictionary<T1, TResult>) objCache
.GetOrAdd(cacheKey, _ => new ConcurrentDictionary<T1, TResult>());
return methodCache.GetOrAdd(arg, f);
}
}
}
Explanation
In the implementation I'm using a ConditionalWeakTable for caching, effectively extending the internal structure of the object invoking the memoization. As an additional key, the CallerMemberName is used, acting as a second key (this allows more memoizations for instance, and optionally more memoizations per method, if passing the cacheKey parameter explicitly).
The third key is the parameter of the invocation.
So, we have 3 runtime dictionary-like searches instead of 1, but a syntax that is a lot cleaner, IMO.
Is it worth it? I dunno, but my desire for elegance is satiated.
If someone else is interested, I'm including the tests for reference:
[TestFixture]
public class MemoizerTest
{
[Test]
public void MemoizationWorksOnFuncs()
{
int counter = 0;
Func<int, int> f = x => counter += x;
Assert.That(this.Memoized(1, f), Is.EqualTo(1));
Assert.That(this.Memoized(2, f), Is.EqualTo(3));
Assert.That(this.Memoized(2, f), Is.EqualTo(3));
Assert.That(this.Memoized(1, f), Is.EqualTo(1));
}
private class MemoizedTest
{
private int _counter = 0;
public int Method(int p)
=> this.Memoized(p, x => { return _counter += x; });
}
[Test]
public void MemoizationWorksOnInstances()
{
var obj1 = new MemoizedTest();
Assert.That(obj1.Method(5), Is.EqualTo(5));
Assert.That(obj1.Method(4), Is.EqualTo(9));
Assert.That(obj1.Method(5), Is.EqualTo(5));
Assert.That(obj1.Method(1), Is.EqualTo(10));
Assert.That(obj1.Method(4), Is.EqualTo(9));
obj1 = new MemoizedTest();
Assert.That(obj1.Method(5), Is.EqualTo(5));
Assert.That(obj1.Method(4), Is.EqualTo(9));
Assert.That(obj1.Method(5), Is.EqualTo(5));
Assert.That(obj1.Method(1), Is.EqualTo(10));
Assert.That(obj1.Method(4), Is.EqualTo(9));
}
[Test]
[Ignore("This test passes only when compiled in Release mode")]
public void WeakMemoizationCacheIsCleared()
{
var obj1 = new MemoizedTest();
var r1 = obj1.Method(5);
MemoizerExtension._weakCache.TryGetValue(obj1, out var cache);
var weakRefToCache = new WeakReference(cache);
cache = null;
GC.Collect(2);
obj1 = null;
GC.Collect();
GC.Collect();
var msg = weakRefToCache.TrackResurrection;
Assert.That(weakRefToCache.IsAlive, Is.False, "The weak reference should be dead.");
Assert.That(r1, Is.EqualTo(5));
}
}
If you capture the dictionary in the lambda, your state will be maintained implicitly.
public class Memoized
{
// Example with a single parameter. That parameter becomes the key to the dictionary.
public static Func<T1, TRet> Of<T1, TRet>(Func<T1, TRet> f)
{
ConcurrentDictionary<T1, TRet> cache = new ConcurrentDictionary<T1, TRet>();
return (arg1) => cache.GetOrAdd(arg1, xarg=>f(xarg));
}
// Example with two parameters. The key is a tuple, and it must be unpacked before calling func.
// Three or more parameters generalize from this
public static Func<T1, T2, TRet> Of<T1, T2, TRet>(Func<T1, T2, TRet> f)
{
ConcurrentDictionary<Tuple<T1,T2>, TRet> cache = new ConcurrentDictionary<Tuple<T1, T2>, TRet>();
return (arg1, arg2) => cache.GetOrAdd(new Tuple<T1,T2>(arg1, arg2),
(xarg)=>f(xarg.Item1, xarg.Item2)
);
}
}
Usage example:
class Test
{
public int Method(String s, String s2)
{
return 99;
}
}
class Program
{
static bool UncachedMethod(int x) { return x > 0; }
static void Main(string[] args)
{
var cached = Memoized.Of<int,bool>(UncachedMethod);
var exampleCall = cached(44);
var exampleCall2 = cached(44);
// Capture a non-static member function
var x = new Test();
var cachedX = Memoized.Of<String, String,int>(x.Method);
var exampleCall3 = cachedX("a","b");
}
}
Please tell me what is wrong and how to write annonymous method with return for this impementation
public class Test
{
public string Implisity { get; set; }
}
class Program
{
static void Main(string[] args)
{
/*Here is a problem */
var variable = Method(delegate(IList<string> i, List<string> j){ return new Test(){Implisity = i[j.IndexOf("Implisity")]}; });
}
public static List<T> Method<T>(Func<IList<string>, IList<string>, T> staff) { return new List<T>(){staff(new List<string>() {"1","2"}, new List<string>(){"Explisity","Implisity"})}; }
}
this is a flat method what as me need to make annonymous
public static Test Annonymous(IList<string> i, List<string> j)
{
var obj = new Test() { Implisity = i[j.IndexOf("Implisity")] };
return obj;
}
The problem is that the Method(...) method expects a Func<...> with different parameter types: it expects a method that takes two IList<string> objects, while you are making a delegate that takes an IList<string> and a List<string>
var variable = Method(
delegate(IList<string> i, IList<string> j) {
// ^
return new Test() {
Implisity = i[j.IndexOf("Implisity")]
};
}
);
To avoid issues like this in the future, use implicit typing, like this:
var variable = Method( (i, j) => new Test { Implisity = i[j.IndexOf("Implisity")] } );
In this example, the compiler knows what the parameter types of the function must be from the signature of the Method(...) method, so it implicitly assigns the types to i and j.
Try this:
var variable = Method((i, j) => new Test() { Implisity = i[j.IndexOf("Implisity")] });
A lambda expression is an unnamed method written in place of a delegate instance.
The compiler immediately converts the lambda expression to either:
A delegate instance.
An expression tree, of type Expression<TDelegate>, representing the
code inside the lambda expression in a traversable object model. This
allows the lambda expression to be interpreted later at runtime
I have an NUnit unit test which I have two collections of different types which I want to assert are equivalent.
class A { public int x; }
class B { public string y; }
[Test]
public void MyUnitTest()
{
var a = GetABunchOfAs(); // returns IEnumerable<A>
var b = GetABunchOfBs(); // returns IEnumerable<B>
Assert.IsPrettySimilar(a, b, (argA, argB) => argA.ToString() == argB);
}
where Assert.IsPrettySimilar is defined like such
public static void IsPrettySimilar<T1, T2>(
IEnumerable<T1> left,
IEnumerable<T2> right,
Func<T1, T2, bool> predicate)
{
using (var leftEnumerator = left.GetEnumerator())
using (var rightEnumerator = right.GetEnumerator())
{
while (true)
{
var leftMoved = leftEnumerator.MoveNext();
if (leftMoved != rightEnumerator.MoveNext())
{
Assert.Fail("Enumerators not of equal size");
}
if (!leftMoved)
{
break;
}
var isMatch = predicate(leftEnumerator.Current,
rightEnumerator.Current);
Assert.IsTrue(isMatch);
}
}
}
My question is, is there a more idiomatic way of doing the above with the existing methods in NUnit? I already looked at CollectionAssert and there's nothing matching what I want to do.
My description of "equivalent" in this case is:
1) Collections must be of same size
2) Collections must be in same logical order
3) Some predicate must be used to determine equivalence between matching items.
Let's think what you are trying to test. You are not trying to test that objects from first sequence are same as objects from second sequence. They can be very different. So, word similar is very vague here. What you really trying to test here, is that some projection of first sequence is equal to other projection of second sequence. And NUnit already have such functionality:
CollectionAssert.AreEqual(bunchOfAs.Select(a => a.ToString()),
bunchOfBs.Select(b => b));
Thus you are projecting both sequences to get particular data, then you can give nice names for these two projections, which will make your test readable to others. You have some hidden business logic here, which does not have explanation in code - you don't explain why you making such projections. So, nice names of projection results will explain your intent. E.g:
var expectedNames = employees.Select(u => u.Login);
var actualNames = customers.Select(c => c.Name);
CollectionAssert.AreEqual(expectedNames, actualNames);
That is much cleaner for me than
Assert.IsPrettySimilar(employees, customers, (e, c) => u.Login == c.Name);
I know you looked into CollectionAssert, however, I have found a strategy like this very useful in my own tests.
Overriding ToString and Equals on the objects makes this test pass.
[TestFixture]
public class Class1
{
[Test]
public void MyUnitTest()
{
var a = GetABunchOfAs(); // returns IEnumerable<A>
var b = GetABunchOfBs(); // returns IEnumerable<B>
CollectionAssert.AreEqual(a, b.OrderBy(x => x.y));
}
public List<A> GetABunchOfAs()
{
return new List<A>
{
new A() {x = 1},
new A() {x = 2},
new A() {x = 3},
new A() {x = 4}
};
}
public List<B> GetABunchOfBs()
{
return new List<B>
{
new B() {y = "4"},
new B() {y = "1"},
new B() {y = "2"},
new B() {y = "3"},
};
}
}
public class A
{
public int x;
public override bool Equals(object obj)
{
return obj.ToString().Equals(x.ToString());
}
public override string ToString()
{
return x.ToString();
}
}
public class B
{
public string y;
public override string ToString()
{
return y;
}
public override bool Equals(object obj)
{
return obj.ToString().Equals(y);
}
}
I deliberately left GetABunchOfBs out of order, however the test still passes.
It looks like Sergey's answer is the one I'm looking for (which was to see whether NUnit already has a facility to do what I want). However, this is the solution I ended up with, which is closer to the implementation I want.
public static class EnumerableAssert
{
public static void AreEquivilent<TExpected, TActual>(IEnumerable<TExpected> expected, IEnumerable<TActual> actual, Func<TExpected, TActual, bool> predicate)
{
if (ReferenceEquals(expected, actual))
{
return;
}
using (var expectedEnumerator = expected.GetEnumerator())
using (var actualEnumerator = actual.GetEnumerator())
{
while (true)
{
var expectedMoved = expectedEnumerator.MoveNext();
if (expectedMoved != actualEnumerator.MoveNext())
{
Assert.Fail("Expected and Actual collections are of different size");
}
if (!expectedMoved)
{
return;
}
Assert.IsTrue(predicate(expectedEnumerator.Current, actualEnumerator.Current));
}
}
}
}
This question is related to this other question.
I have the following method:
public static T GetNewData<T>(params Action<dynamic>[] actions) where T : class, new()
{
dynamic dynamicData = new DeepObject();
foreach (var action in actions)
{
action(dynamicData);
}
return Converter.Convert<T>(dynamicData);
}
The users of this method will include less technical people, even non-developers and as such the easier writing calls to this method is the better. My sticking point right now is that by using Action<dynamic> as the parameter type there is no intellisense provided to the user. In the context I know that the intellisense should be acting as if the dynamic was in fact T.
So is their a way I could either: Tell Visual Studio to use type T for the intellisense or change the parameter to be Action<T> and somehow programmatically change it to be Action<dynamic> or Action<DeepObject> so that the call to it will succeed?
EDIT: To clarify, the types that I am using for T are not of type DeepObject and they do not inherit any standard interface, the use of DeepObject is to allow setting up nested types without the user needing to explicitly instantiate at each level. This was the original usage before adding the dynamic and DeepObject code:
ExampleDataFactory.GetNewData<ServicesAndFeaturesInfo>(
x => x.Property1 = ExampleDataFactory.GetNewData<Property1Type>(),
x => x.Property1.Property2 = ExampleDataFactory.GetNewData<Property2Type>(),
x => x.Property1.Property2.Property3 = ExampleDataFactory.GetNewData<Property3Type>(),
x => x.Property1.Property2.Property3.Property4 = true);
Here is what it looks like now:
ExampleDataFactory.GetNewData<ServicesAndFeaturesInfo>(
x => x.Property1.Property2.Property3.Property4 = true);
EDIT: Here is the fully implemented solution based on nmclean's answer
public static DataBuilder<T> GetNewData<T>() where T : class, new()
{
return new DataBuilder<T>();
}
The DataBuilder Class:
public class DataBuilder<T>
{
public readonly T data;
public DataBuilder()
{
data = Activator.CreateInstance<T>();
}
public DataBuilder(T data)
{
this.data = data;
}
public DataBuilder<T> SetValue<T2>(Expression<Func<T, T2>> expression, T2 value)
{
var mExpr = GetMemberExpression(expression);
var obj = Recurse(mExpr);
var p = (PropertyInfo)mExpr.Member;
p.SetValue(obj, value);
return this;
}
public T Build()
{
return data;
}
public object Recurse(MemberExpression expr)
{
if (expr.Expression.Type != typeof(T))
{
var pExpr = GetMemberExpression(expr.Expression);
var parent = Recurse(pExpr);
var pInfo = (PropertyInfo) pExpr.Member;
var obj = pInfo.GetValue(parent);
if (obj == null)
{
obj = Activator.CreateInstance(pInfo.PropertyType);
pInfo.SetValue(parent, obj);
}
return obj;
}
return data;
}
private static MemberExpression GetMemberExpression(Expression expr)
{
var member = expr as MemberExpression;
var unary = expr as UnaryExpression;
return member ?? (unary != null ? unary.Operand as MemberExpression : null);
}
private static MemberExpression GetMemberExpression<T2>(Expression<Func<T, T2>> expr)
{
return GetMemberExpression(expr.Body);
}
}
The Usage:
ExampleDataFactory.GetNewData<ServicesAndFeaturesInfo>()
.SetValue(x=> x.Property1.EnumProperty, EnumType.Own)
.SetValue(x=> x.Property2.Property3.Property4.BoolProperty, true)
.Build();
Do not use Action<dynamic>, use Action<T>with method's constraint where T:DeepObject. Users will get intellisence and ability to use strongly typed objects:
public static DeepObject GetNewData<T>(params Action<T>[] actions)
where T : DeepObject, //restrict user only inheritors of DeepObject
new() //and require constructor
{
var data = new T();
foreach (var action in actions)
{
action(data);
}
return data;
}
Does the user need to access unknown properties or add new ones? If not, using dynamic objects seems like a step backwards. If your desired syntax does compile as an Action<T>, I think you should just declare it that way and then go with your first instinct of using the LINQ Expression API to decide how to interpret the code.
Unfortunately, although statements, such as an assignment, are part of the API, C# doesn't support converting them to expression trees. This is not allowed:
public static T GetNewData<T>(params Expression<Action<T>>[] actions)
where T : class, new() {
...
}
...
ExampleDataFactory.GetNewData<ServicesAndFeaturesInfo>(
x => x.Property1.Property2.Property3.Property4 = true);
Only single-line expressions that would have a return a value are supported. So I think the best you could do is something like this:
public class Assignment<T> {
public readonly Expression Expression;
public readonly object Value;
public Assignment(Expression<Func<T, object>> expression, object value) {
Expression = expression;
Value = value;
}
}
...
public static T GetNewData<T>(params Assignment<T>[] assignments)
where T : class, new() {
var data = Activator.CreateInstance<T>();
foreach (var assignment in assignments) {
// todo:
// - pull property names from assignment.Expression
// - initialize nested properties / assign to assignment.Value
}
return data;
}
...
ExampleDataFactory.GetNewData<ServicesAndFeaturesInfo>(
new Assignment<ServicesAndFeaturesInfo>(
x => x.Property1.Property2.Property3.Property4, true));
Getting the property names from an expression tree of chained property access is not too complicated. Here is one implementation.
Of course, the new Assignment<ServicesAndFeaturesInfo>(...) is ugly and repetitive, so maybe it could be restructured to something like this:
var newData = ExampleDataFactory.NewData<ServicesAndFeaturesInfo>();
newData.Add(x => x.Property1.Property2.Property3.Property4, true);
newData.Add(...);
...
newData.Get();
I am working on a generic utility method that takes a generic argument and returns a generic type--I hope that makes sense!--but I want the return type to be a different type from the argument.
Here's what I'm thinking this should look like if I mock it up in pseudo code:
public static IEnumerable<R> DoSomethingAwesome<T>(T thing)
{
var results = new List<R>();
for (int xx = 0; xx < 5; xx++)
{
results.Add(thing.ToRType(xx));
}
return results;
}
With generics not being able to infer the return type how would I go about doing something like this? So far, my Google-Fu has failed me.
// You need this to constrain T in your method and call ToRType()
public interface IConvertableToTReturn
{
object ToRType(int someInt);
}
public static IEnumerable<TReturn> DoSomethingAwesome<T, TReturn>(T thing)
where T : IConvertableToTReturn
{
Enumerable.Range(0, 5).Select(xx => thing.ToRType(xx));
}
You can pass the return class as an output parameter:
public static void DoSomethingAwesome<T,R>(T thing, out IEnumerable<R> output)
This can then be inferred.
static IEnumerable<R> Function<T,R> (T h)
{
for (int xx = 0; xx < 5; xx++)
{
yield return h.ToRType(xx);
}
yield return break;
}
IEnumerable<class2> res = Function<class1, class2>(class1Object);
You need to explicitly specify the return generic type as a type parameter to the method.
Something like:
public static IEnumerable<R> DoSomething<T,R>(IEnumerable<T> things, Func<T,R> map)
{
foreach (var t in things) { yield return map(t); }
}
This is essentially what the Linq IEnumerable extension method "Select" does..
Generics can be awesome and a pretty awesome pain. As other have stated you can use a variety of ways to have multiple in put parameters the real trick is in doing something usefully with the passed in types.
in Your example
public static IEnumerable<Ret> Fn<Ret,Parm>(IList<Parm> P)
{
var Results = new List<Ret>();
foreach(Parm p in P)
{
Results.Add(p.ToType());
}
return Results;
}
Will not complie since the complier doesn't know what to do with P.ToType()
So you say well I can just add the function needed to my param type But that doesn't work either since the complier again doesn't know what the concrete version or Ret will be and your return list is of type Ret not of type returnType
public class RetunType
{
public int a;
}
public class Input
{
public int x;
public RetunType TotoAReturnType()
{
return new RetunType() { a = this.x };
}
}
public static IEnumerable<Ret> Fn<Ret, Parm>(IList<Parm> P) where Parm : Input where Ret:RetunType
{
var Results = new List<Ret>();
foreach (Parm p in P)
{
Results.Add(p.TotoAReturnType());
}
return Results;
}
To solve this issue you can add a generic interface so that your function can work if any type supports the generic interface
Like this
public interface ToType<R>
{
R ToType();
}
public class B
{
public int x;
}
public class A : ToType<B>
{
string x = "5";
public B ToType()
{
B aB = new B();
aB.x = int.Parse(x);
return aB;
}
}
public static IEnumerable<Ret> Fn<Ret,Parm>(IList<Parm> P) where Parm : ToType<Ret>
{
var Results = new List<Ret>();
foreach(Parm p in P)
{
Results.Add(p.ToType());
}
return Results;
}
static void Main(string[] args)
{
List<A> inLst = new List<A>() { new A()};
var lst = Fn<B, A>(inLst);
}
Generics are awesome but I would strongly suggest looking to using interfaces to support you actions in those functions.