1
 List<DynamicBusinessObject> dbo = SearchController.Instance.GetSearchResultList(search, null, "date", startRow - 1, ucDataPager1.PageSize, state); 

The above line of code is calling the GetSearchResultList method which up until now had 5 arguments.

I added a 6th argument but wanted to make this argument optional so that all the other pages that call this function don't need to be updated just yet.

So i changed the function to look like this:

 [System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select, true)] public List<DynamicBusinessObject> GetSearchResultList(Search search, List<CategoryAttribute> listCatAttrib, string sortBy, int startRow, int pageSize, [Optional, DefaultParameterValue("")] string state) { StorageQuery qry = new QrySearchResult( search.ID, (listCatAttrib != null && listCatAttrib.Count > 0) ? listCatAttrib[0].Attribute.ID : -1, (listCatAttrib != null && listCatAttrib.Count > 1) ? listCatAttrib[1].Attribute.ID : -1, (listCatAttrib != null && listCatAttrib.Count > 2) ? listCatAttrib[2].Attribute.ID : -1, 1, sortBy, startRow, pageSize, state); List<DynamicBusinessObject> list = BusinessObject.Search(qry); return list; } 

However, when i try to build, it gives me the error that GetSearchResultList has no overload method and takes 5 arguments. I also tried doing string state = "" instead of using [Optional]

Anyone got any ideas why it's complaining about me not passing 6 arguments when i make the call if the 6th argument is optional?

2 Answers 2

2

Those attributes are not how you define an optional parameter in c#.

Rather, the syntax is just the parameter plus = <value>.

So your method signature becomes:

public List<DynamicBusinessObject> GetSearchResultList( Search search, List<CategoryAttribute> listCatAttrib, string sortBy, int startRow, int pageSize, string state = "") 

Although I'd recommend using null instead of an empty string, the default types are more natural fits if these signatures are consumed by external libraries.

Optional parameters are like constants, they are baked into referencing assemblies at compile-time.

Let's say you have another library which calls this method using the optional parameter, like so:

myObj.GetSearchListResult(search, listCatAttrib, sortBy, startRow, pageSize); 

At the time you compile this library, the call will actually be written in your library as:

myObj.GetSearchListResult(search, listCatAttrib, sortBy, startRow, pageSize, ""); 

Then, if you change the declaration of your method to be:

public List<DynamicBusinessObject> GetSearchResultList( Search search, List<CategoryAttribute> listCatAttrib, string sortBy, int startRow, int pageSize, string state = "some value") 

The call in the first library will still pass an empty string, not the new value. You have to recompile the all callers of your method to make sure the new value takes.

That said, this is why if you are exposing this method outside of your assembly, you use overloads instead of default values; if you change the value passed to the method in the overload, you only have to distribute the assembly where the method is defined, you don't have to distribute and have all the callers against that method recompiled.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the explanation - turns out I needed to tweak the web.config so that it would run under 4.0. I upvoted your answer though.
1

You should be able to use:

..., string state = "") { 

One possible issue is that your project is targeting an older version of .NET. Check the project properties to make sure it is pointing at the correct version.

1 Comment

Hmm, i found the compilers section in the web.config it was set to use 3.5. I changed it to 4.0 and added a targetframework=4.0 in the compilation section, that seems to have fixed it. Thanks for the suggestion.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.