1

I have a constructor for a class that looks like this:

public class Class
{
 private Func<string, IThirdField, IFourthField, IResultField> resultField;

 public Class(
      IFirstField firstField,
      ISecondField secondField,
      Func<string, IThirdField, IFourthField, IResultField> resultField,
      ISomeOtherField someOtherField)
}

I am trying to initialize this class like this:

var classObject = new Class (firstField, secondField, 
Func<string, IThirdField, IFourthField, IResultField>
 resultField, someOtherField );

I am getting the following errors:

  • Using the generic type 'Func' requires 1 type arguments.

  • Invalid expression term "string".

  • "IThirdField" is a type, which is not valid in the given context.

What am I doing wrong?

M.Tach
  • 143
  • 1
  • 1
  • 8
  • Do you already have a method with the needed signature? Something like: `IResultField doStuff(string value, IThirdField thirdField, IFourthField fourthField) { /* ... */ }`? Or do you want to pass in an anonymous method "on the fly"? – Corak Aug 15 '16 at 13:40
  • @M.Tach - did any of the answers below help you solve the problem? – Gilad Green Aug 18 '16 at 06:23
  • No, I ended up hard-coding a helper method to return an IResultField type object. – M.Tach Aug 18 '16 at 12:27

3 Answers3

2

You need to pass an instance that answers that signature of the Func so:

var obj = new Class (firstField, 
                     secondField, 
                     (stringVal, thirdFieldVal, fourthFieldVal) => default(IResultField), 
                     someOtherField);

Or if you have a named function then:

var obj= new Class (firstField, 
                    secondField, 
                    /*your named function*/), 
                    someOtherField);
Gilad Green
  • 36,708
  • 7
  • 61
  • 95
  • 1
    As far as I can tell, both of these options pass five arguments to the constructor, which only takes four arguments. How does it compile? – Mark Seemann Aug 15 '16 at 13:42
1

You'll need to pass a delegate. There are various ways to do that, but passing an anonymous function may be the easiest:

var classObject =
    new Class(
        firstField,
        secondField, 
        (str, thrd, frth) => new ResultFieldImp()),
        someOtherField);

Here, I'm assuming that ResultFieldImp implements IResultField. You probably need to tweak this step to do whatever is actually required.

Mark Seemann
  • 225,310
  • 48
  • 427
  • 736
  • Hi @Mark. Please do you think you could take at look a this question? http://stackoverflow.com/questions/40198294/how-to-configure-ninject-so-that-it-creates-a-single-instance-per-controller?noredirect=1#comment67673663_40198294 – eddy Oct 23 '16 at 18:27
  • @eddy I've never used NInject, so I can't help you. Sorry. – Mark Seemann Oct 23 '16 at 18:49
  • No problem @Mark. Thanks anyway. – eddy Oct 23 '16 at 20:02
0

You need to pass it the Func<>

var classObject = new Class (firstField, secondField, 
(stringVal, thirdFieldVal, fourthFieldVal) => {
   // do something here

   return something;// where something is of type IResultField
},
someOtherField);

Passing Func<> is a good way to define what you want to happen with the particular input, but not at the time you give it that method definition and if you want different results using different implementations.

So a good example is Linq. You can use Where<T>(Func<T, bool> predicate) and give it a definition of what you would like to execute at the time Where needs to use it (i.e. in the different iterations). So this makes the function execution deferred (although this is left to you).

It seems like to me, that you are passing in the parameters to this Func<> in the constructor and also giving a definition of the method you want to execute using those parameters. This to me wouldn't seem like the best solution.

In your example, it would be better off just to define the interface with a method signature, and then define several implementations. It does seem like to me that you're trying to achieve this through the use of a Func<>

Callum Linington
  • 14,213
  • 12
  • 75
  • 154
  • +1 You don't have to pass a lambda, if you have a method that matches the signature you could pass that method either (just the name, don't call the method). – Binary Worrier Aug 15 '16 at 13:40
  • As far as I can tell, this passes five arguments to the constructor, which only takes four arguments. How does it compile? – Mark Seemann Aug 15 '16 at 13:43
  • @MarkSeemann yeah fixed that. It seems more like a contrived example of what the user is doing, which doesn't totally make sense to me – Callum Linington Aug 15 '16 at 13:45