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; };
Related
How do I iterate over the anonymous type that is passed in as an object below (first, second, third) => new { One = first, Two = second, Three = third }
If I interrogate the type of message and print it, it says:<>f__AnonymousType0 3[MtApi.MtQuote,MtApi.MtQuote,MtApi.MtQuote]
//**How do I convert an object to the anonymous type?**
static void ShowAnonymousTypeMessage(object message)
{
foreach(var quote in message)
Console.WriteLine(
quote.Instrument + ": " + quote.Bid.ToString() + quote.Ask.ToString());
}
...
var pattern = observable1.And(observable2).And(observable3);
var plan = pattern.Then((first, second, third) => new { One = first, Two = second, Three = third });
var zippedSequence = Observable.When(plan);
zippedSequence.Subscribe(
ShowAnonymousTypeMessage
);
This is working for me:
static void Main()
{
var anon = new { Name = "Terry", Age = 34 };
test(anon);
}
static void test(dynamic t)
{
Console.WriteLine(t.Age);
Console.WriteLine(t.Name);
}
Anonymous types aren't intended to be passed around and you should only use object when absolutely necessary. Also you can't iterate over an anonymous type - you should use an Array.
var pattern = observable1.And(observable2).And(observable3);
var plan = pattern.Then((first, second, third) => new[] { first, second, third });
var zippedSequence = Observable.When(plan);
zippedSequence.Subscribe(
ShowAnonymousTypeMessage
);
Anonymous types aren't meant to be passed around, for the same reason we have strong typing in C# at all: The compiler doesn't make careless errors or forget things, and we often do. If your anonymous class instances are leaving the scope where they were created, it's time for them to grow up and be a real class.
Usually I'd say you should write a quickie class with appropriate properties (guessing at the property types here):
public class Thing {
public String One { get; set; }
public String Two { get; set; }
public String Three { get; set; }
}
But a Tuple<T1,T2,T3> is just as good really, if you've got property names like One, Two, and Three anyway:
public static void Main()
{
var x = Enumerable.Range(0, 10).Select(n => new Tuple<int, string>(n, $"Item {n + 1}"));
Test(x);
}
private static void Test(IEnumerable<Tuple<int, string>> stuff)
{
foreach (var item in stuff)
{
Console.Write($"{item.Item1}: {item.Item2}");
}
}
dynamic works, but dynamic is like the Vise-Grip: "Always the Wrong Tool for Every Job, Since 1921". dynamic has a legitimate but small role in the typesystem. It's not there so we can turn the whole language into JavaScript.
public static Main()
{
var x = Enumerable.Range(0, 10).Select(n => new { ID = n, Value = $"Item {n + 1}" });
Test(x);
}
private static void Test(dynamic message)
{
foreach (dynamic item in message)
{
Console.Write($"{item.ID}: {item.Value}");
}
}
OK, the Vise-Grip isn't always the wrong tool either. But it's rare there isn't a better one.
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);
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;
}
}
My code as below
public void DownloadConcurrent(Action<string> Methord)
{
Action<string>[] methordList = new Action<string>[Concurent_Downloads];
for (int i = 0; i < Concurent_Downloads; i++)
{
methordList[i] = Methord;
}
Parallel.Invoke(methordList);
}
Parallel.Invoke is giving error:
"cannot convert from 'System.Action<string>[]' to 'System.Action[]'"
The Method it is calling is
public void DownloadLinks(string Term)
{
}
check Parallel.ForEach like the following
static void Main(string[] args)
{
List<string> p = new List<string>() { "Test", "Test2", "Test3"};
Parallel.ForEach(p, Test);
}
public static void Test(string test)
{
Debug.WriteLine(test);
}
This should do the trick for you
HTH
Dominik
In your case it is easier if you use
Parallel.ForEach
over your string list instead of using
Parallel.Invoke
with additional parameter. Let me know if you want to stick to Parallel.Invoke.
Parallel.Invoke accepts Action array while your code is passing it an Action<string> array. What you can do is :
public void DownloadConcurrent(Action<string> Methord)
{
Action<string>[] methordList = new Action<string>[Concurent_Downloads];
var r = methordList.Select(a => (Action)(() => a("some_str"))).ToArray();
Parallel.Invoke(r);
}
You need to replace some_str with proper value for each action
How do I build an Action action in a loop? to explain (sorry it's so lengthy)
I have the following:
public interface ISomeInterface {
void MethodOne();
void MethodTwo(string folder);
}
public class SomeFinder : ISomeInterface
{ // elided
}
and a class which uses the above:
public Map Builder.BuildMap(Action<ISomeInterface> action,
string usedByISomeInterfaceMethods)
{
var finder = new SomeFinder();
action(finder);
}
I can call it with either of these and it works great:
var builder = new Builder();
var map = builder.BuildMap(z => z.MethodOne(), "IAnInterfaceName");
var map2 = builder(z =>
{
z.MethodOne();
z.MethodTwo("relativeFolderName");
}, "IAnotherInterfaceName");
How can I build the second implementation programmatically? i.e.,
List<string> folders = new { "folder1", "folder2", "folder3" };
folders.ForEach(folder =>
{
/* do something here to add current folder to an expression
so that at the end I end up with a single object that would
look like:
builder.BuildMap(z => {
z.MethodTwo("folder1");
z.MethodTwo("folder2");
z.MethodTwo("folder3");
}, "IYetAnotherInterfaceName");
*/
});
I've been thinking I need an
Expression<Action<ISomeInterface>> x
or something similar, but for the life of me, I'm not seeing how to construct what I want. Any thoughts would be greatly appreciated!
It's really easy, because delegates are already multicast:
Action<ISomeInterface> action1 = z => z.MethodOne();
Action<ISomeInterface> action2 = z => z.MethodTwo("relativeFolderName");
builder.BuildMap(action1 + action2, "IAnotherInterfaceName");
Or if you've got a collection of them for some reason:
IEnumerable<Action<ISomeInterface>> actions = GetActions();
Action<ISomeInterface> action = null;
foreach (Action<ISomeInterface> singleAction in actions)
{
action += singleAction;
}
Or even:
IEnumerable<Action<ISomeInterface>> actions = GetActions();
Action<ISomeInterface> action = (Action<ISomeInterface>)
Delegate.Combine(actions.ToArray());