C# how to create the following syntax Method(param => { params.xxx })? - c#

In a code example I've seen the following code:
SomeClass.Columns(columns => {
columns.Add()
.Text("Product")
.Value("123");
columns.Add()
.Text("Amount")
.Value("456");
})
Now I was wondering what the requirements are to create this kind of structure
Where columns is a collection of Column objects and
.Text and .Value are methods on the Column object that return the Object again (to create the fluent syntax).
The columns.Add() would return a new Column() object
What would be the parameter(s) in the method in the SomeClass.Columns(???)?
Does this syntax have a specific name that I can research?
Thank you.
EDIT:
Yes there is fluent syntax in my example but that was not my question, sorry that I was not clear.
The question is howI make to following:
SomeClass.Columns(columns => { ... })
So how does the parameter in the method Columns look?
Thank you.

In this case, Columns is accepting something like Action<ColumnCollection>. That is, you pass it a delegate/lambda, it promises to call that lambda, passing in whatever columns is going to be, and then within your lambda/delegate you can manipulate the collection.

You first need a collection type that creates a new instance and returns it when called "Add":
interface IList<T>
{
T Add();
}
Then there is the fluent Column class:
class Column
{
public Column Text(string text)
{
// Do stuff
return this;
}
public Column Value(string value)
{
// Do stuff
return this;
}
}
Then there is SomeClass which allows the user to give an action to perform on the "collection":
class SomeClass
{
private static IList<Column> localList;
public static void Columns(Action<IList<Column>> action)
{
// Perform action using localList as parameter
action(localList);
}
}
This would satisfy the syntax of:
SomeClass.Columns(columns =>
{
columns.Add()
.Text("Product")
.Value("123");
columns.Add()
.Text("Amount")
.Value("456");
});

public static class SomeClass
{
public object void Columns(Func<Foo,object> action)
{
throw new Exception();
}
}
public class Foo
{
public Foo Add()
{
return this;
}
public Foo Value(object value)
{
return this;
}
public Foo Text(string text)
{
return this;
}
}
use like this:
SomeClass.Columns(columns =>
{
columns.Add().Text("SomeText");
columns.Add().Value("SomeValue");
return columns;
});

It's called a Fluent interface or a Fluent method. The way it works is that .Add(), .Text() and .Value() all return the same object afterwards that they're performing operations on as their return value. This is what allows operations to be chained in this way. Columns is simply returning an enumerable of these exact same objects.

It's a Higher-order functions. In c# language it is present like Action and Func classes.
The answer to your question and semantic of Columns method something like this:
public ColumnCollection Columns(Func<ColumnCollection,ColumnCollection> columnCollectionFunc)
=> columnCollectionFunc(_someInternalColumnCollection);

Related

How to simulate method overloading based on generic return type in c#

I have a read model as IQueryable<CustomType>, I use this inside my Web application. A lot of time I need to extract from this read model different View Model.
I use to write extension method like:
public static ViewModelA AsViewModelA(this IQueryable<CustomType> query)
{
var vm = view
.Select(x => new ViewModelA
{
Something = x.Something
}).FirstOrDefault();
return vm;
}
public static ViewModelB AsViewModelB(this IQueryable<CustomType> query)
{
var vm = view
.Select(x => new ViewModelB
{
SomethingElse = x.SomethingElse
}).FirstOrDefault();
return vm;
}
This do the job but I don't like the mess generated with method names; a more generic way, something like this would be preferable:
query.AsViewModel<ViewModelA>()
I know that return type is not intended as method signature (so no overload applies) and I know that generic type is not sufficient to make an overload.
What I would is a mechanism to just simulate overloading based on generic type. This mechanism should avoid a main method with cascading if/then/else. There is a way? Maybe with dynamics?
One option is to have a map from the type to a conversion of CustomType to that type. So it would look something like:
private static readonly Dictionary<Type, Expression> Mappings =
new Dictionary<Type, Expression>
{
{ typeof(ViewModelA),
Helper<ViewModelA>(x => new ViewModelA { Something = x.Something }) },
{ typeof(ViewModelB),
Helper<ViewModelB>(x => new ViewModelB { SomethingElse = x.SomethingElse }) },
...
}
// This method just helps avoid casting all over the place.
// In C# 6 you could use an expression-bodied member - or add a
private static Expression<Func<CustomType, T>> Helper<T>
(Expression<Func<CustomType, T>> expression)
{
return expression;
}
public static T AsViewModel<T>(this IQueryable<CustomType> query)
{
Expression rawMapping;
if (!Mappings.TryGetValue(typeof(T), out rawMapping))
{
throw new InvalidOperationException("Or another exception...");
}
// This will always be valid if we've set up the dictionary properly
var mapping = (Expression<Func<CustomType, T>>) rawMapping;
return view.Select(mapping).FirstOrDefault();
}
You can make the dictionary construction a bit cleaner with a bit more up-front code.
Well, yes, you can use dynamic:
private static ViewModelA AsViewModelInternal(this IQueryable<CustomType> query,
ViewModelA dummy) { ... }
private static ViewModelB AsViewModelInternal(this IQueryable<CustomType> query,
ViewModelB dummy) { ... }
public static T AsViewModel<T>(this IQueryable<CustomType> query)
{
return (T)query.AsViewModelInternal(default(T));
}
Make sure to handle a non-existing overload, of course :) The easiest way is to add an overload that takes object as the last argument, so that you basically have a "fallback overload".
However, I wouldn't recommend that. One of the great benefits of generics is you get great compile-time checks. This generic method pretends to accept all possible T's, but it actually doesn't. It's the equivalent of taking object instead of ViewModelA/ViewModelB.
It's not like there's a world's difference between
query.AsViewModelB()
and
query.AsViewModel<ViewModelB>()
I'd only use the alternative if you often find yourself having to use a generic type argument when calling AsViewModel, i.e. when you don¨t know the specific 'type in advance.

How could I achieve JQuery style method calls on IEnumerables in C#?

In JQuery you can write $('.my-class').hide() and it will call hide() on all the results. There's no for loop, no iterating, no LINQ extensions and lambdas etc. and it makes dealing with lists super fun. I want to be able to have this functionality on IEnumerables in C#. I think Matlab has a similarly concise syntax when operating on arrays/matrices.
Long story short, I want the following code (or similar) to work:
class Program
{
static List<MyClass> MyList = new List<MyClass>();
static void Main(string[] args)
{
for (int i = 0; i < 100; i++)
MyList.Add(new MyClass());
MyList.MyMethod();
// should be exactly equivalent to:
MyList.Select(n => n.MyMethod());
}
}
class MyClass
{
public int MyMethod() { return 123; }
}
I'm aware this is possible on a case-by-case basis using extension methods:
public static IEnumerable<int> MyMethod(this IEnumerable<MyClass> lst)
{
return lst.Select(n => n.MyMethod());
}
But we'd have to create one extension method for every single method on every single type that you wanted this behaviour on.
Ideally this would be possible for all types and all methods and still be type-safe at compile time. I suspect I'm asking too much from the C# language here, but how would we do this or something similar in a as-generic-as-possible way?
Possible solutions:
Auto-generate extension methods for particular types. If we only intend to use this notation for a few types, we could just generate the extension methods once automatically. This would achieve the exact syntax and full type safety but generating code would be a pain.
A single extension method that returns a dynamic object built using reflection on the supplied type. The idea is that we'd use reflection to iterate through the type's methods and build up a dynamic object that would have all the methods like .MyMethod() that would behind the scenes call Select(...) on the IEnumerable. The syntax would end up being something like MyList.Selector().MyMethod(). But now we've lost the syntax and type safety. Clever, maybe. Useful, probably not.
Intercepting method calls? Is it possible to decide how to react to a method call at runtime? I don't know. Again you'd lose type safety.
The most simple solution is using dynamic objects. If you are willing to throw away type safety, you can make a IEnumerable type that behaves statically when needed and dynamically otherwise, here's a sample prototype:
public class DynamicIEnumerable<T> : DynamicObject, IEnumerable<T>
{
public IEnumerable<T> _enumerable;
public DynamicIEnumerable(IEnumerable<T> enumerable)
{
this._enumerable = enumerable;
}
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
result = new DynamicIEnumerable<T>(_enumerable.Select(x => (T)typeof(T).InvokeMember(binder.Name, BindingFlags.InvokeMethod, null, x, null)));
return true;
}
public IEnumerator<T> GetEnumerator()
{
return _enumerable.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return _enumerable.GetEnumerator();
}
}
In TryInvokeMember, the invoked member on IENumerable is applied on all items using reflection. The only constraints on this approach is that you have to return this in invoked method. Here's a sample of how to use this approach:
public class SomeClass
{
public int Value {get;set;}
public SomeClass(int value)
{
this.Value = x;
}
public SomeClass Plus10()
{
Value += 10;
return this;
}
}
static void Main()
{
dynamic d = new DynamicIEnumerable<X>(Enumerable.Range(0, 10).Select(x => new SomeClass(x)));
foreach (var res in d.Plus10().Plus10())
Console.WriteLine(res.Value);
}
how would we do this or something similar in a as-generic-as-possible way?
This isn't a pretty solution but it does work:
public class MyClass
{
public void MyMethod()
{
}
public void MyMethod2()
{
}
}
Extension Method:
public static class WeirdExtensions
{
public static IEnumerable<T> CallOnAll<T>(this IEnumerable<T> instance ,
Action<T> call)
{
foreach(var item in instance)
{
call(item);
}
return instance;
}
}
Usage (chaining/fluent):
var blah = new List<MyClass>();
blah.CallOnAll(b => b.MyMethod())
.CallOnAll(b => b.MyMethod2());
Notes
This isn't quite possible due to a the underlying assumption that you'd have to every single method on every single type. In jQuery/Html there is only one underlying type of an Html Element. All elements are exposed to the same methods (whether or not the type supports it). In jQuery, you can call $('head').hide() but it won't do anything visually, but because it is an element, it will be inline styled. If you need a new method, you do have a build one, but for only one type because there is only one type.
In contrast with C# you build your types (many many types) and they all have different methods (sure there could be overlap).

Generic type's causing issue C#.net

I have class called GroupItem, i can store any type here say int, string, decimal, datetime etc.., Then, i have GroupItems which will store any groupItem. I'm using an arraylist to store all the groupItem.
public class GroupItem<T>
{
private string heading;
private List<T> items = new List<T>();
public GroupItem() { }
public string Heading
{
get { return heading; }
set { heading = value; }
}
public List<T> Items
{
get { return items; }
set { items = value; }
}
public void Add(T value)
{
this.items.Add(value);
}
public T this[int index]
{
get
{
return this.items[index];
}
}
}
public class GroupItems
{
private string groupName;
private List<object> items = new List<object>();
public string GroupName
{
get { return groupName; }
set { groupName = value; }
}
public GroupItems() { }
public void Add(object value)
{
this.items.Add(value);
}
public object this[int index]
{
get
{
return this.items[index];
}
}
}
I want to retrieve from GroupItems. How i can get generic item's values in groupItems?
I'm now inserting two items, datetime and int to groupitems. Now i want to retrieve groupitems[2] value but how i can convert this to groupItem without knowing what it is. Even we may get its genericarguments by getType().getGenericarguments()[0]. But how i can create an instance based upon that.
If the list is storing heterogeneous items, then I would suggest you need a common non-generic interface or base-class. So, say we have
interface IGroupItem {
// the non-generic members, and maybe
// "object Value {get;}" etc, and maybe
// "Type ItemTypr {get;}"
}
You would then have:
class GroupItem<T> : IGroupItem {...}
an you would then use
List<IGroupItem> ...
instead of ArrayList, or, franky, in place of GroupItems {...}
What I'd do is create a generic collection such as:
public class GroupItems<T> : List<GroupItem<T>>
{
}
If you need to extend the basic functionality of a list, you could also extend Collection<T> and override the methods you need:
public class GroupItems<T> : Collection<GroupItem<T>>
{
protected override void InsertItem(int index, T item)
{
// your custom code here
// ...
// and the actual insertion
base.InsertItem(index, item);
}
}
How about just replacing your GroupItems class with List<GroupItem<T>> ?
Depending on what you do with GroupItem you should either inherit from List/Collection as was offered by other or use a generic collection inside your class
e.g.
class GroupItem<T>
{
private List<T> items = new List<T>();
public void Add(T value)
{
items.Add(value);
}
public T Get()
{
//replace with some logic to detemine what to get
return items.First();
}
}
There are two situations that could be covered by your question:
You want to simply store a collection of GroupItem's of type T in the class GroupItems.
You want to store a collection of generic GroupItem's of any type in the class GroupItems. To better clarify, I mean that you could store GroupItem<DateTime> or GroupItem<int> in the same GroupItems class.
Here are some ways of going about storing and retrieving for both scenarios:
Same Type
public class GroupItem<T>
{
// ... Code for GroupItem<T>
}
public class GroupItems<T>
{
private List<GroupItem<T>> mItems = new List<GroupItem<T>>();
public void Add(T item)
{
mItems.Add(item);
}
public T GetItem(int index)
{
return mItems[index];
}
}
Here you will build a collections that contain GroupItem's of the same time, so a collection of GroupItem<DateTime> for example. All the items will be of the same type.
Generic Type
public interface IGroupItem
{
// ... Common GroupItem properties and methods
}
public class GroupItem<T>
{
// ... Code for GroupItem<T>
}
public class GroupItems
{
private List<IGroupItem> mItems = new List<IGroupItem>();
public void Add(IGroupItem item)
{
mItems.Add(item);
}
// This is a generic method to retrieve just any group item.
public IGroupItem GetItem(int index)
{
return mItems[index];
}
// This is a method that will get a group item at the specified index
// and then cast it to the specific group item type container.
public GroupItem<T> GetItem<T>(int index)
{
return (GroupItem<T>)mItems[index];
}
}
Here you will be able to build and maintain a single collection that can contain any GroupItem with any Type. So you could have a GroupItems collection that contains items of GroupItem<DateTime>, GroupItem<int>, etc.
Please note that none of these code examples take into account any erroneous circumstances.
Consider: you have a collection of items; the items may have any runtime type (string, int, etc.). Because of this, the static type of the collections items must be object.
It seems that you want to be able to retrieve items from the list with strong static typing. That's not possible without a lot of conditional logic (or reflection). For example:
object item = collection[0];
if (item is int)
//do something with an int
else if (item is string)
//do something with a string
Now suppose instead of "doing something" with the value of collection[0], we assign the value to a variable. We can do one of two things:
use the same variable for both cases, in which case the static type must be object.
use separate variables, in which case the static type will be string or int, but outside of the conditional logic, we can't know which variable holds the value of collection[0].
Neither option really solves the problem.
By creating GroupItem<T>, you add a level of indirection to this problem, but the underlying problem is still there. As an exercise, try reworking the example, but starting from "Consider: you have a collection of items; the items are of type GroupItem<T> where T may be any runtime type (string, int, etc.)."
Thanks for your inputs.
I have resolved it myself using multiple overloading methods to resolve this.
for example:
private void Print(GroupItem<string> items)
{
///custom coding
}
private void Print(GroupItem<int> items)
{
///custom coding
}
Though its not efficient enough, i want to do in this way as it was .net 2.0.
I'm now improving this in .Net 4.0 with new algorithm.
Thanks a lot for all of your helps.

Is there any way to infer an Action type, or a full Action?

I find myself (too) often using a construct like the following:
class MyClass
{
public TypeA ObjectA;
public TypeB ObjectB;
public TypeC ObjectC;
public List<TypeD> ListOfObjectD = new List<TypeD>();
public void DoSmth()
{
return SomeConstruct(
/*...*/
new Setter<TypeA>(a => ObjectA = a), // these are the
new Setter<TypeB>(b => ObjectB = b), // things I'm trying
new Setter<TypeC>(c => ObjectC = c), // to make shorter
new Setter<TypeD>(d => ListOfObjectD.Add(d)),
/*...*/
);
}
}
class Setter<T>
{
public Action<T> Action;
public Setter(Action<T> action)
{
Action = action;
}
}
Is there any way for the Setter class to infer the type of the Action and create the standard (T obj) => Member = obj Action by only passing the Member in some way? I'm thinking of something like:
new Setter(ObjectA)
which of course is not valid syntax, but should give you an idea what I'm trying to achieve. I'm using this construct literally hundreds of time in my code, so the code
saved by this small change would be tremendous.
Edit: Added the TypeD example. The part
new Setter<TypeD>(d => ListOfObjectD.Add(d))
can be simplified to
new Setter<TypeD>(ListOfObjectD.Add)
which is awesome because it cuts from the redundant code. If only <TypeD> could also be inferred it would be perfect. I'm looking for something like this for the others.
#Lazarus - basically the purpose is to return setters, so other objects can set certain members of the class (or it can do other stuff defined in the Action) without accessing the class itself, only the Setter object. The full list of reasons is long and convoluted, but the structuring of the program works like a charm and I doubt needs changing (the example of course is simplified and doesn't really make sense as is).
Edit 2: I found a good way to simplify things for List's:
static class SetterHelper
{
public static Setter<T> GetSetter<T>(this List<T> list)
{
return new Setter<T>(list.Add);
}
}
Now I can just use this:
ListOfObjectD.GetSetter()
which works perfectly! why can't I do the same for T directly? I tried this:
static class SetterHelper
{
public static Setter<T> GetSetter<T>(this T item)
{
return new Setter<T>(t => item = t); // THIS DOESN'T SET THE PASSED MEMBER
}
}
Of course it won't work as intended because it will set item, but not the passed member. I tried adding ref as (ref this T item) but it won't compile :(... It would have been perfect.
Best I can offer you is the following syntax:
Setter.For( () => ObjectA );
using this helper class
static class Setter
{
public static Setter<T> For<T>(Expression<Func<T>> e)
{
ParameterExpression[] args = { Expression.Parameter(((e.Body as MemberExpression).Member as FieldInfo).FieldType) };
Action<T> s = Expression.Lambda<Action<T>>(Expression.Assign(e.Body, args[0]), args).Compile();
return new Setter<T>(s);
}
}

C# Lambda Expressions or Delegates as a Properties or Arguments

I'm looking to create an ValidationRule class that validates properties on an entity type object. I'd really like to set the name of the property to inspect, and then give the class a delegate or a lambda expression that will be evaluated at runtime when the object runs its IsValid() method. Does anyone have a snippet of something like this, or any ideas on how to pass an anonymous method as an argument or property?
Also, I'm not sure if I'm explaining what I'm trying to accomplish so please ask questions if I'm not being clear.
Really, what you want to use is Func<T,bool> where T is the type of the item you want to validate. Then you would do something like this
validator.AddValidation(item => (item.HasEnoughInformation() || item.IsEmpty());
you could store them in a List<Func<T,bool>>.
class ValidationRule {
public delegate bool Validator();
private Validator _v;
public ValidationRule(Validator v) { _v = v; }
public Validator Validator {
get { return _v; }
set { _v = value; }
}
public bool IsValid { get { return _v(); } }
}
var alwaysPasses = new ValidationRule(() => true);
var alwaysFails = new ValidationRule(() => false);
var textBoxHasText = new ValidationRule(() => textBox1.Text.Length > 0);
That should get you started. But, really, inheritance is far more appropriate here. The problem is simply that the Validator doesn't have access to any state that it doesn't close over, this means that it isn't as reusable as say ValidationRules that contain their own state. Compare the following class to the previous definition of textBoxHasText.
interface IValidationRule {
bool IsValid { get; }
}
class BoxHasText : IValidationRule {
TextBox _c;
public BoxHasText(TextBox c) { _c = c; }
public bool IsValid {
get { return _c.Text.Length > 0; }
}
}
Well, simply, if you have an Entity class, and you want to use lambda expressions on that Entity to determine if something is valid (returning boolean), you could use a Func.
So, given an Entity:
class Entity
{
public string MyProperty { get; set; }
}
You could define a ValidationRule class for that like this:
class ValidationRule<T> where T : Entity
{
private Func<T, bool> _rule;
public ValidationRule(Func<T, bool> rule)
{
_rule = rule;
}
public bool IsValid(T entity)
{
return _rule(entity);
}
}
Then you could use it like this:
var myEntity = new Entity() { MyProperty = "Hello World" };
var rule = new ValidationRule<Entity>(entity => entity.MyProperty == "Hello World");
var valid = rule.IsValid(myEntity);
Of course, that's just one possible solution.
If you remove the generic constraint above ("where T : Entity"), you could make this a generic rules engine that could be used with any POCO. You wouldn't have to derive a class for every type of usage you need. So if I wanted to use this same class on a TextBox, I could use the following (after removing the generic constraint):
var rule = new ValidationRule<TextBox>(tb => tb.Text.Length > 0);
rule.IsValid(myTextBox);
It's pretty flexible this way. Using lambda expressions and generics together is very powerful. Instead of accepting Func or Action, you could accept an Expression> or Expression> and have direct access to the express tree to automatically investigate things like the name of a method or property, what type of expression it is, etc. And people using your class would not have to change a single line of code.
something like:
class ValidationRule
{
private Func<bool> validation;
public ValidationRule(Func<bool> validation)
{
this.validation = validation;
}
public bool IsValid()
{
return validation();
}
}
would be more C# 3 style but is compiled to the same code as #Frank Krueger's answer.
This is what you asked for, but doesn't feel right. Is there a good reason why the entity can't be extended to perform validation?
Would a rule definition syntax like this one work for you?
public static void Valid(Address address, IScope scope)
{
scope.Validate(() => address.Street1, StringIs.Limited(10, 256));
scope.Validate(() => address.Street2, StringIs.Limited(256));
scope.Validate(() => address.Country, Is.NotDefault);
scope.Validate(() => address.Zip, StringIs.Limited(10));
switch (address.Country)
{
case Country.USA:
scope.Validate(() => address.Zip, StringIs.Limited(5, 10));
break;
case Country.France:
break;
case Country.Russia:
scope.Validate(() => address.Zip, StringIs.Limited(6, 6));
break;
default:
scope.Validate(() => address.Zip, StringIs.Limited(1, 64));
break;
}
Check out DDD and Rule driven UI Validation in .NET for more information

Categories

Resources