1

We have an extension method that accepts an action to initialize an object. Is there some way to improve the syntax of such a call:

public static T NewRow<T>(this IUow uow, Action<T> action();

// this does internally call
public T NewRow<T>(Action<T> initializer) where T : IBo
{
    T bo = NewRow<T>();
    initializer.Invoke(bo);
    return bo;
}

uow.NewRow<ICustomer>(customer => { 
        customer.Name = "Zzz";
        customer.Info = "Abc"
);

I thought maybe I could use something similar to the object initializer syntax?

uow.NewRow<ICustomer>({ 
      Name: "Zzz",
      Info: "Abc"
});

The idea is to get rid of customer.* = ... in every line.

I would be happy for any tip.

INFO:

  • We are using the latest C# language version
  • The solution should support IntelliSense (e.g., Name and Info should be proposed to the user)

Edit:

  • I can't use a constructor because I only have an interface. No class/implementation. The framework behind creates the object to the given interface T bo = NewRow<T>();. Which actual object gets created is decided by the framework
  • Also initializers like { Name: myOtherVariable.FirstName } should be possible
4
  • Use a Func<T> and have something like () => new Customer { Name: "zzz", Info: "Abc" }? Commented Jan 26, 2022 at 7:06
  • 1
    Use constructor instead? Commented Jan 26, 2022 at 7:06
  • Name: "Zzz", here you are hardcoding the value. maybe your real use case is using values from somewhere else? Commented Jan 26, 2022 at 7:08
  • an Action could be everything, not just a simple assignment. So if a client chosed to make a function-call instead, there literally is nothing to shortcut here. So no, what you want isn't possible. Commented Jan 26, 2022 at 7:48

1 Answer 1

2

an Action could be everything, not just a simple assignment. So if a client chosed to make a function-call instead, there literally is nothing to shortcut here. See this for example:

uow.NewRow<IWhatever>(() => Console.WriteLine("tataaaa"););

So no, what you want isn't possible.

However you could create some kind of EventsArgs that hold your names and use those within your NewRow-method. There's no need for an action if all those callbacks should actually be just assignement-calls alltogether.

uow.NewRow<ICustomer>(new MyArgs { 
    Name = "Zzz",
    Info = "Abc"
});

And within NewRow:

public T NewRow<T>(MyArgs args) where T : IBo 
{
    customer.Name = args.Name;
    customer.Info = args.Info;
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the hint. The problem is that ICustomer can be any type containing any number of different properties. So it is not possible to create a MyArgs type. But I will think about it and maybe I can use code generators to create such a function for each Type T : IBo that I can find in my solution.
@ManuelKroiß if all those types have different properties, a common ICustomer-interface is pretty pointless, and a client has no chance to set the properties, as it only knows that interface. Either your types all have something in common, or they don't, in which case an interface is pointless.
Not really. They have something in Common. E.g. ModificationDate and ModificationUser. Nevertheless, those are internal framework specific questions that do not belong to the original question. I think you already answered my question. What I want to achieve is propably not possible. Thank you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.