C# Using Assignment Lists which Reference the Assigned Variable - c#

Does anyone know a trick that would allow me to do something like this (where Function is a Func<bool>:
UnaryNode<bool> compliment = new UnaryNode<bool>()
{ Function = () => !compliment.Right.Value };
The following works in place, but is not as nice.
UnaryNode<bool> compliment = new UnaryNode<bool>();
compliment.Function = () => !compliment.Right.Value;

This is not allowed, as documented in the langauge specification. Section 7.6.10.2:
It is not possible for the object initializer to refer to the newly
created object it is initializing.
Nor do I find your second version in any way not "nice." As for a "trick," it would be something even more "ugly." You would need to create a temporary throwaway, and then rely upon lambdas closing over the variable instead of the value. For example, given:
class Foo
{
public Func<bool> Function;
public Bar Bar;
}
class Bar
{
public bool Value;
}
You could then have
// DO NOT try this at home
Foo foo = null;
Foo temp = new Foo { Function = () => !foo.Bar.Value };
foo = temp;
bool result1 = foo.Function(); // true
foo.Bar.Value = true;
bool result2 = foo.Function(); // false
Is that more or less "nice" than what you already have?

Perhaps you can create a new class.
class ComplimentUnaryNode : UnaryNode<bool>
{
public ComplimentUnaryNode()
{
Function = () => !Right.Value;
}
}

Related

Maintaining a reference inside a Task?

I've put together a simple demo class that looks like this:
public class HelloWorld
{
public string Name { get; set; }
}
public Main()
{
var h = new HelloWorld() { Name = "A" };
Task.Factory.StartNew(() => { Console.WriteLine(h.Name); });
h = new HelloWorld() { Name = "B" };
}
The following code prints:
B
Which is perfectly logical, but not what I want (I want to print A).
I would expect to be able to call StartNew() with an argument, which would preserve the first reference to h inside the delegate, but I can't see this option.
Am I missing something?
Edit: I can see that I can use
Task.Factory.StartNew(new Action<object>((obj) => { Console.WriteLine((obj as Hello).Name); }),h);
Being forced to pass in a type of object seems a bit .NET 1.1 / pre-generics to me though, so hoping for a better option.
What you've encountered is called a closure and it's not unique to tasks. Every time you use a variable in a lambda, it gets captured by the compiler in a special class it builds just for this purpose. The compiler generates roughly something like:
public void Main()
{
var closure = new Main_Closure();
closure.h = new HelloWorld() { Name = "A" };
Task.Factory.StartNew(closure.M1);
closure.h = new HelloWorld() { Name = "B" };
}
class Main_Closure
{
public HelloWorld h;
public void M1()
{
Console.WriteLine(h.Name);
}
}
And since closure.h could be assigned again before the task starts, you get the result you're seeing.
In this case, you can simply use another variable to store your new object. Or use another variable just before invoking the lambda, e.g.
var h1 = h;
Task.Factory.StartNew(() => { Console.WriteLine(h1.Name); });
Wrap task creation in a method to prevent closure.
static Task DoAsync<T>(Action<T> action, T arg)
{
return Task.Run(() => action(arg));
}
static void Main(string[] args)
{
Action<HelloWorld> hello = (HelloWorld h2) => { Console.WriteLine(h2.Name); };
var h = new HelloWorld() { Name = "A" };
Task task = DoAsync(hello, h);
var h = new HelloWorld() { Name = "B" };
}
What you are experiencing is a very powerful mechanism called a closure. Its extremely useful in a miriad of circumstances. Take a more in depth on how closures work at: http://csharpindepth.com/Articles/Chapter5/Closures.aspx
The problem in your case is that h changes before the Task had a chance to run. Notice that this is mere luck, some time the task might run first some others it might not.
One thing you could possibly do in your case to fix this is to simply await the Task.
If your code is on a main method you can achieve this by simply adding .Wait() at the end of your line:
var h = new HelloWorld() { Name = "A" };
Task.Factory.StartNew(() => { Console.WriteLine(h.Name); }).Wait();
h = new HelloWorld() { Name = "B" };
If you are on any other method you can simply await the task with the await keyword and making the method async:
public async Task MyMethod()
{
var h = new HelloWorld() { Name = "A" };
await Task.Factory.StartNew(() => { Console.WriteLine(h.Name); });
h = new HelloWorld() { Name = "B" };
}
Also bear in mind that using Task.Factory.StartNew is not the best option in most circumstances. Try to favour the use of Task.Run instead.

Making passed reference available to methods

Currently I'm writing a wizard (using MBG SimpleWizard library). I have several pages. and as a way of sharing data between them, they are passed a class out DBManip DBController. I need to use this DBController in a method, but the call is handled by the library and so I can't easily pass DBController by reference to the method. How can I make the passed reference into a property that the method can modify, and preserve the reference.
Class Initialization:
WizardHost host = new WizardHost();
using (host)
{
host.Text = Migration.Properties.Resources.AppName;
host.ShowFirstButton = false;
host.ShowLastButton = false;
host.WizardCompleted += new WizardHost.WizardCompletedEventHandler(this.Host_WizardCompleted);
DBManip DBController;
host.WizardPages.Add(1, new Page1());
host.WizardPages.Add(2, new Page2(out DBController));
host.WizardPages.Add(3, new Page3(out DBController));
host.WizardPages.Add(4, new Page4(out DBController));
host.LoadWizard();
host.ShowDialog();
}
Constructor:
public Page2(out DBManip DBController)
{
this.InitializeComponent();
this.label1.Text = Migration.Properties.Resources.ExportDirectoryMessage;
this.exportDirTextbox.Text = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
}
Method:
private bool SetExportDirectory ()
{
string exportDirectory = this.exportDirTextbox.Text;
// If a path is given, check if it's valid
// and set the pathExists boolean
if (!Directory.Exists(exportDirectory))
{
MessageBox.Show(Migration.Properties.Resources.InvalidPath);
return false;
}
// Initializing the object to manipulate the databases
exportDirectory = new DBManip(exportDirectory);
return true;
}
Property which will call method:
public bool PageValid
{
get { return SetExportDirectory(); }
}
Sorry if I'm missing something simple, I'm fairly new to C#
It's not clear what your pages are doing with DBManip, but you'll need to have it as a property of any Page class that uses it.
To do that, you'd ordinarily create an instance of DBManip first before creating the pages, and pass it to each constructor that wants it. Each of those classes will have a property where it stores the reference so it can use it later. Each class will need to declare that property for itself, since you're not easily going to be able to give them a common base class of your own.
But you're creating it later. Since you need the different classes to share a reference to an object that's created after their constructors exit, we'll add a quickie "reference" generic class, and they'll all share a reference to that. Then we can change its properties, and they'll all have the new property values on the existing instance of this little "handle" class.
Reference.cs
// Semantically, this is basically a pointer to a pointer, without the asterisks.
public class Reference<T>
{
public Reference() { }
public Reference(T t) { Value = t; }
public T Value;
}
Main C#
WizardHost host = new WizardHost();
using (host)
{
host.Text = Migration.Properties.Resources.AppName;
host.ShowFirstButton = false;
host.ShowLastButton = false;
host.WizardCompleted += new WizardHost.WizardCompletedEventHandler(this.Host_WizardCompleted);
// ************************
// Create shared "reference" instance
// ************************
Reference<DBManip> dbControllerRef = new Reference<DBManip>();
host.WizardPages.Add(1, new Page1());
host.WizardPages.Add(2, new Page2(dbControllerRef));
host.WizardPages.Add(3, new Page3(dbControllerRef));
host.WizardPages.Add(4, new Page4(dbControllerRef));
host.LoadWizard();
host.ShowDialog();
}
Page2.cs
// It's not an out parameter so don't make it one.
public Page2(Reference<DBManip> dbControllerRef)
{
this.InitializeComponent();
this.DBControllerRef = dbControllerRef;
this.label1.Text =
Migration.Properties.Resources.ExportDirectoryMessage;
this.exportDirTextbox.Text =
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
}
public Reference<DBManip> DBControllerRef {
get; private set;
}
private bool SetExportDirectory ()
{
string exportDirectory = this.exportDirTextbox.Text;
// If a path is given, check if it's valid
// and set the pathExists boolean
if (!Directory.Exists(exportDirectory))
{
MessageBox.Show(Migration.Properties.Resources.InvalidPath);
return false;
}
// Everybody has the same Refernece<DBManip>
this.DBControllerRef.Value = new DBManip(exportDirectory);
return true;
}

Using reflection to get rid of the first two parameters in the function?

I have the following code. Is it possible to use reflection to get rid of the first two parameters since the information can be found in the Action assign (Or Expression), which will always have the form of b.P... = a.P...?
class A { .... }; var a = new A { P1 = .... } // class A and B are totally different clas
class B { .... }; var b = new B { P1 = .... } // But they have some properties with the same names
....
AssignAndDoSth(a.P1, b.P1, () => b.P1 = a.P1);
private void AssignAndDoSth<T>(T curr, T prev, Action assign) // assign can be Expression
{
if (!EqualityComparer<T>.Default.Equals(curr, prev))
{
assign();
Do(prev);
....
}
}
The short answer would be "I strongly advise against it"; in reality, this is actually an instance method of a compiler-generated capture class; so you would need to deconstruct the IL of the target method, and evaluate that IL against the fields of the target instance. Not good. What that actually looks like is something like:
var ctx = new SomeType();
ctx.a = new A { P1 = .... };
ctx.b = new B { P1 = .... };
AssignAndDoSth(a.P1, b.P1, new Action(ctx.SomeMethod));
...
class SomeType {
public A a;
public B b;
public void SomeMethod()
{
b.P1 = a.P1;
}
}
The other approach would be to refactor to an Expression<Action> - but that doesn't change the work involved much - it just presents a more friendly API (relatively speaking).
Either way, all that inspection will have a non-trivial performance cost.
An expression tree may not contain an assignment operator, but can contain operator ==
static void AssignAndDoSomething<T>(T curr, T prev, Expression<Func<bool>> assign)
{
var logExpr = assign.Body as System.Linq.Expressions.BinaryExpression;
//output rid of the first parameter
Console.WriteLine(logExpr.Left);
//output rid of the second parameter
Console.WriteLine(logExpr.Right);
//assign first parameter
Expression.Lambda<Action>(Expression.Assign(logExpr.Left, Expression.Constant(curr))).Compile()();
//assign second parameter
Expression.Lambda<Action>(Expression.Assign(logExpr.Right, Expression.Constant(prev))).Compile()();
}
class A
{
public int P1;
}
class B
{
public int P1;
}
var a = new A();
var b = new B();
AssignAndDoSomething(a.P1, b.P1, () => b.P1 == a.P1);

Returning anonymous type in C#

I have a query that returns an anonymous type and the query is in a method. How do you write this:
public "TheAnonymousType" TheMethod(SomeParameter)
{
using (MyDC TheDC = new MyDC())
{
var TheQueryFromDB = (....
select new { SomeVariable = ....,
AnotherVariable = ....}
).ToList();
return "TheAnonymousType";
}
}
You can't.
You can only return object, or container of objects, e.g. IEnumerable<object>, IList<object>, etc.
You can return dynamic which will give you a runtime checked version of the anonymous type but only in .NET 4+
public dynamic Get() {
return new { Message = "Success" };
}
In C# 7 we can use tuples to accomplish this:
public List<(int SomeVariable, string AnotherVariable)> TheMethod(SomeParameter)
{
using (MyDC TheDC = new MyDC())
{
var TheQueryFromDB = (....
select new { SomeVariable = ....,
AnotherVariable = ....}
).ToList();
return TheQueryFromDB
.Select(s => (
SomeVariable = s.SomeVariable,
AnotherVariable = s.AnotherVariable))
.ToList();
}
}
You might need to install System.ValueTuple nuget package though.
You cannot return anonymous types. Can you create a model that can be returned? Otherwise, you must use an object.
Here is an article written by Jon Skeet on the subject
Code from the article:
using System;
static class GrottyHacks
{
internal static T Cast<T>(object target, T example)
{
return (T) target;
}
}
class CheesecakeFactory
{
static object CreateCheesecake()
{
return new { Fruit="Strawberry", Topping="Chocolate" };
}
static void Main()
{
object weaklyTyped = CreateCheesecake();
var stronglyTyped = GrottyHacks.Cast(weaklyTyped,
new { Fruit="", Topping="" });
Console.WriteLine("Cheesecake: {0} ({1})",
stronglyTyped.Fruit, stronglyTyped.Topping);
}
}
Or, here is another similar article
Or, as others are commenting, you could use dynamic
You can use the Tuple class as a substitute for an anonymous types when returning is necessary:
Note: Tuple can have up to 8 parameters.
return Tuple.Create(variable1, variable2);
Or, for the example from the original post:
public List<Tuple<SomeType, AnotherType>> TheMethod(SomeParameter)
{
using (MyDC TheDC = new MyDC())
{
var TheQueryFromDB = (....
select Tuple.Create(..., ...)
).ToList();
return TheQueryFromDB.ToList();
}
}
http://msdn.microsoft.com/en-us/library/system.tuple(v=vs.110).aspx
C# compiler is a two phase compiler. In the first phase it just checks namespaces, class hierarchies, Method signatures etc. Method bodies are compiled only during the second phase.
Anonymous types are not determined until the method body is compiled.
So the compiler has no way of determining the return type of the method during the first phase.
That is the reason why anonymous types can not be used as return type.
As others have suggested if you are using .net 4.0 or grater, you can use Dynamic.
If I were you I would probably create a type and return that type from the method. That way it is easy for the future programmers who maintains your code and more readable.
Three options:
Option1:
public class TheRepresentativeType {
public ... SomeVariable {get;set;}
public ... AnotherVariable {get;set;}
}
public IEnumerable<TheRepresentativeType> TheMethod(SomeParameter)
{
using (MyDC TheDC = new MyDC())
{
var TheQueryFromDB = (....
select new TheRepresentativeType{ SomeVariable = ....,
AnotherVariable = ....}
).ToList();
return TheQueryFromDB;
}
}
Option 2:
public IEnumerable TheMethod(SomeParameter)
{
using (MyDC TheDC = new MyDC())
{
var TheQueryFromDB = (....
select new TheRepresentativeType{ SomeVariable = ....,
AnotherVariable = ....}
).ToList();
return TheQueryFromDB;
}
}
you can iterate it as object
Option 3:
public IEnumerable<dynamic> TheMethod(SomeParameter)
{
using (MyDC TheDC = new MyDC())
{
var TheQueryFromDB = (....
select new TheRepresentativeType{ SomeVariable = ....,
AnotherVariable = ....}
).ToList();
return TheQueryFromDB; //You may need to call .Cast<dynamic>(), but I'm not sure
}
}
and you will be able to iterate it as a dynamic object and access their properties directly
Using C# 7.0 we still can't return anonymous types but we have a support of tuple types and thus we can return a collection of tuple (System.ValueTuple<T1,T2> in this case). Currently Tuple types are not supported in expression trees and you need to load data into memory.
The shortest version of the code you want may look like this:
public IEnumerable<(int SomeVariable, object AnotherVariable)> TheMethod()
{
...
return (from data in TheDC.Data
select new { data.SomeInt, data.SomeObject }).ToList()
.Select(data => (SomeVariable: data.SomeInt, AnotherVariable: data.SomeObject))
}
Or using the fluent Linq syntax:
return TheDC.Data
.Select(data => new {SomeVariable: data.SomeInt, AnotherVariable: data.SomeObject})
.ToList();
.Select(data => (SomeVariable: data.SomeInt, AnotherVariable: data.SomeObject))
Using C# 7.1 we can omit properties names of tuple and they will be inferred from tuple initialization like it works with anonymous types:
select (data.SomeInt, data.SomeObject)
// or
Select(data => (data.SomeInt, data.SomeObject))
You can return list of objects in this case.
public List<object> TheMethod(SomeParameter)
{
using (MyDC TheDC = new MyDC())
{
var TheQueryFromDB = (....
select new { SomeVariable = ....,
AnotherVariable = ....}
).ToList();
return TheQueryFromDB ;
}
}
public List<SomeClass> TheMethod(SomeParameter)
{
using (MyDC TheDC = new MyDC())
{
var TheQueryFromDB = (....
select new SomeClass{ SomeVariable = ....,
AnotherVariable = ....}
).ToList();
return TheQueryFromDB.ToList();
}
}
public class SomeClass{
public string SomeVariable{get;set}
public string AnotherVariable{get;set;}
}
Creating your own class and querying for it is the best solution I know.As much as I know you can not use anonymous type return values in another method, because it won't just be recognized.However, they can be used in the same method.
I used to return them as IQueryable or IEnumerable, though it still does not let you see what is inside of the anonymous type variable.
I run into something like this before while I was trying to refactor some code, you can check it here : Refactoring and creating separate methods
You can only use dynamic keyword,
dynamic obj = GetAnonymousType();
Console.WriteLine(obj.Name);
Console.WriteLine(obj.LastName);
Console.WriteLine(obj.Age);
public static dynamic GetAnonymousType()
{
return new { Name = "John", LastName = "Smith", Age=42};
}
But with dynamic type keyword you will loose compile time safety, IDE IntelliSense etc...
With reflection.
public object tst() {
var a = new {
prop1 = "test1",
prop2 = "test2"
};
return a;
}
public string tst2(object anonymousObject, string propName) {
return anonymousObject.GetType().GetProperties()
.Where(w => w.Name == propName)
.Select(s => s.GetValue(anonymousObject))
.FirstOrDefault().ToString();
}
Sample:
object a = tst();
var val = tst2(a, "prop2");
Output:
test2
It is actually possible to return an anonymous type from a method in a particular use-case. Let's have a look!
With C# 7 it is possible to return anonymous types from a method, although it comes with a slight constraint. We are going to use a new language feature called local function together with an indirection trick (another layer of indirection can solve any programming challenge, right?).
Here's a use-case I recently identified. I want to log all configuration values after I have loaded them from AppSettings. Why? Because there's some logic around missing values that revert to default values, some parsing and so on. An easy way to log the values after applying the logic is to put them all in a class and serialize it to a logfile (using log4net). I also want to encapsulate the complex logic of dealing with settings and separate that from whatever I need to do with them. All without creating a named class that exists just for a single use!
Let's see how to solve this using a local function that creates an anonymous type.
public static HttpClient CreateHttpClient()
{
// I deal with configuration values in this slightly convoluted way.
// The benefit is encapsulation of logic and we do not need to
// create a class, as we can use an anonymous class.
// The result resembles an expression statement that
// returns a value (similar to expressions in F#)
var config = Invoke(() =>
{
// slightly complex logic with default value
// in case of missing configuration value
// (this is what I want to encapsulate)
int? acquireTokenTimeoutSeconds = null;
if (int.TryParse(ConfigurationManager.AppSettings["AcquireTokenTimeoutSeconds"], out int i))
{
acquireTokenTimeoutSeconds = i;
}
// more complex logic surrounding configuration values ...
// construct the aggregate configuration class as an anonymous type!
var c = new
{
AcquireTokenTimeoutSeconds =
acquireTokenTimeoutSeconds ?? DefaultAcquireTokenTimeoutSeconds,
// ... more properties
};
// log the whole object for monitoring purposes
// (this is also a reason I want encapsulation)
Log.InfoFormat("Config={0}", c);
return c;
});
// use this configuration in any way necessary...
// the rest of the method concerns only the factory,
// i.e. creating the HttpClient with whatever configuration
// in my case this:
return new HttpClient(...);
// local function that enables the above expression
T Invoke<T>(Func<T> func) => func.Invoke();
}
I have succeeded in constructing an anonymous class and also encapsulated the logic of dealing with complex settings management, all inside CreateHttpClient and within its own "expression". This might not be exactly what the OP wanted but it is a lightweight approach with anonymous types that is currently possible in modern C#.
Another option could be using automapper: You will be converting to any type from your anonymous returned object as long public properties matches.
The key points are, returning object, use linq and autommaper.
(or use similar idea returning serialized json, etc. or use reflection..)
using System.Linq;
using System.Reflection;
using AutoMapper;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json;
namespace UnitTestProject1
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var data = GetData();
var firts = data.First();
var info = firts.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public).First(p => p.Name == "Name");
var value = info.GetValue(firts);
Assert.AreEqual(value, "One");
}
[TestMethod]
public void TestMethod2()
{
var data = GetData();
var config = new MapperConfiguration(cfg => cfg.CreateMissingTypeMaps = true);
var mapper = config.CreateMapper();
var users = data.Select(mapper.Map<User>).ToArray();
var firts = users.First();
Assert.AreEqual(firts.Name, "One");
}
[TestMethod]
public void TestMethod3()
{
var data = GetJData();
var users = JsonConvert.DeserializeObject<User[]>(data);
var firts = users.First();
Assert.AreEqual(firts.Name, "One");
}
private object[] GetData()
{
return new[] { new { Id = 1, Name = "One" }, new { Id = 2, Name = "Two" } };
}
private string GetJData()
{
return JsonConvert.SerializeObject(new []{ new { Id = 1, Name = "One" }, new { Id = 2, Name = "Two" } }, Formatting.None);
}
public class User
{
public int Id { get; set; }
public string Name { get; set; }
}
}
}
Now with local functions especially, but you could always do it by passing a delegate that makes the anonymous type.
So if your goal was to run different logic on the same sources, and be able to combine the results into a single list. Not sure what nuance this is missing to meet the stated goal, but as long as you return a T and pass a delegate to make T, you can return an anonymous type from a function.
// returning an anonymous type
// look mom no casting
void LookMyChildReturnsAnAnonICanConsume()
{
// if C# had first class functions you could do
// var anonyFunc = (name:string,id:int) => new {Name=name,Id=id};
var items = new[] { new { Item1 = "hello", Item2 = 3 } };
var itemsProjection =items.Select(x => SomeLogic(x.Item1, x.Item2, (y, i) => new { Word = y, Count = i} ));
// same projection = same type
var otherSourceProjection = SomeOtherSource((y,i) => new {Word=y,Count=i});
var q =
from anony1 in itemsProjection
join anony2 in otherSourceProjection
on anony1.Word equals anony2.Word
select new {anony1.Word,Source1Count=anony1.Count,Source2Count=anony2.Count};
var togetherForever = itemsProjection.Concat(otherSourceProjection).ToList();
}
T SomeLogic<T>(string item1, int item2, Func<string,int,T> f){
return f(item1,item2);
}
IEnumerable<T> SomeOtherSource<T>(Func<string,int,T> f){
var dbValues = new []{Tuple.Create("hello",1), Tuple.Create("bye",2)};
foreach(var x in dbValues)
yield return f(x.Item1,x.Item2);
}
I am not sure of the name of this construct, I thought this was called an anonymous type but I might be wrong. Anyway I was looking for this:
private (bool start, bool end) InInterval(int lower, int upper)
{
return (5 < lower && lower < 10, 5 < upper && upper < 10);
}
private string Test()
{
var response = InInterval(2, 6);
if (!response.start && !response.end)
return "The interval did not start nor end inside the target";
else if (!response.start)
return "The interval did not start inside the target";
else if (!response.end)
return "The interval did not end inside the target";
else
return "The interval is inside the target";
}
Another style to call this could be:
var (start, end) = InInterval(2, 6);

Implement VB With statement in C#

How would you create an extension method which enables me to do the following (warning: exteme pseudo-code)...
class FooBar
{
Int32 Foo { get; set; }
String Bar { get; set; }
}
new FooBar().With(fb => new Func<FooBar, Object>(instance =>
{
// VB With magic
// NOTE: The instance parameter HAS to be by reference
instance.Foo = 10;
instance.Bar;
return new Object();
}));
If you could specify anonymous functions without a return type (void), the above would look much cleaner...
new FooBar().With(fb => new Func<FooBar, void>(instance =>
{
instance.Foo = 10;
instance.Bar;
}));
This is pseudo-code of the worst kind. But I hope you get the idea.
To specify anonymous methods without return type, use Action<T> instead of Func<T, TResult>:
new FooBar().With(new Action<FooBar>(instance =>
{
instance.Foo = 10;
instance.Bar;
}));
(I don't quite see the point in this particular case, but I take your word on the pseudo code part...)
Update
Full example for being complete:
The extension method:
public static void With<T>(this T input, Action<T> action)
{
action(input);
}
Sample usage
new FooBar().With(fb =>
{
fb.Foo = 10;
fb.Bar = "some string";
});
Note that you don't need to explicitly declare the Action<FooBar>, the compiler figures that out. Should you wish to, for clarity, the call would look like this:
new FooBar().With<FooBar>(new Action<FooBar>(fb =>
{
fb.Foo = 10;
fb.Bar = "some string";
}));
Maybe this will help:
new FooBar().With( fb=> {
fb.Foo = 10;
fb.Bar = fb.Foo.ToString();
} );
// ... somewhere else ...
public static void With<T>( this T target, Action<T> action ) {
action( target );
}
As you asked how to write the extension, here goes
public static void With<T>(this T target, Action<T> action) where T : class
{
action(target);
}
Personally dont see what benefit this has, but fill yer boots!
How about just
return new FooBar{ Foo=10; };

Categories