Method doesn't work when I use ? after int - asp.net-mvc

I have this Action method :
public ActionResult Index(int? mid)
{
IList<SubGroup> SubGroupLit = (mid != null) ? _subGroupService.GetAllWithGroupId(mid) : _subGroupService.GetAll();
return View(SubGroupLit);
}
I getting this ERROR:
he best overloaded method match for 'ServiceLayer.Interfaces.ISubGroupService.GetAllWithGroupId(int)' has some invalid arguments
But when I remove the ? after the int (in Index parameters), it works fine .
What is wrong?

The ? means it's nullable. Your GetAllWithGroupId method, however, only accepts int. If mid just happens to come through as null, then it can't be passed into that method because null is not an int. Hence the error. What you'll have to do is make mid just an int, which, as you noted already, works. Or you'll need to check mid has a value and then pass the value into the method. It looks like you were already attempting to do this with the ternary, but you made a few mistakes. The following code should work:
IList<SubGroup> SubGroupLit = mid.HasValue ? _subGroupService.GetAllWithGroupId(mid.Value) : _subGroupService.GetAll();

Related

Create nullable object based on nullable value

i have to create a domain class object which has a nullable attribute. This Creating is in an extansion of a primitive class.
For example: Domainclass
Meeting({required String id, required Datetime date, Example? example})
behind Example is an class like so: Example(String value)
MeetingPrimitive.dart:
extension MeetingPrimitiveX on Meeting {
Meeting toDomain() {
return Meeting(
id: id,
date: date,
example: example == null ? null : Example(example)
}
}
My question is, how can i simplify this:
example == null ? null : Example(example)
'''
thanks in advance
You generally can't.
You can change it in various ways, but nothing is more direct than what you have here.
One variant would be:
extension DoWith<T> on T {
R doWith<R>(R Function(T) action) => action(this);
}
With that, you can write:
example?.doWith(Example.new)
to conditionally call the Example.new constructor (tear-off of the unnamed constructor) if example is non-null.
Slightly shorter, requires a helper function, and ... isn't actually more readable IMO.

Calling a function with two same arguments, but setting the second while calling

I am calling a function that expects two arguments. I use the same variable, but at the second argument I set this variable to another thing.
See below:
https://dartpad.dartlang.org/2156442de07f56d90b430bc67f3461ac
void main() {
String s = 'oi';
aa(s, s = 'oi2');
}
void aa(String buf, String buf2){
print('$buf, $buf2');
}
This will print "oi, oi2".
I want this to happen. I am using a modified notification within properties, like:
set title(String n) {
this.modified('title', _title, _title = n);
}
However, I wonder if this can be seen as a bug or it is expected.
thanks, Joe
s is a String which are passed by value, not by reference.
aa(s, s = 'oi2');
evaluates the first parameter s, which is 'oi'
next s = 'oi2' is evaluated, which means s gets 'oi2' assigned
then the result of s = 'oi2' (which is 'oi2') is passed as 2nd parameter.
After aa(s, s = 'oi2'); s has the value oi2.
See also https://gist.github.com/floitschG/b278ada0316dca96e78c1498d15a2bb9
Evaluation order of arguments is left-to-right, so you can rely on the first argument's value being found by evaluation s to "ii", and then second argument's value is the value of the assignment s = 'oi2 - which evaluates to "oi2" (and not, technically, by reading the variable, it just happens that the variable is written to with the same value before the function is called).
It is expected - if any implementation does something else, it's broken.

Using a query in an Adapter for listview

I have a listview that I fill from an Adapter. My original code the data was being returned from a table, but now I need to get the code from a query with a join so the examples I used will no longer work and I haven't been able to find out how to use a query for this. I'm using an ORMrepository.
In my ORMrepository I have this function
public IList<Coe> GetmyCoe()
{
using (var database = new SQLiteConnection(_helper.WritableDatabase.Path))
{
string query = "SELECT Coe.Id, Adult.LName + ', ' + Adult.MName AS Name, Coe.Createdt FROM Adult INNER JOIN Coe ON Adult.CoeMID = Coe.Id";
return database.Query<Coe>(query);
}
}
which actually returns the data I want.
then in my Activity page I have this.
_list = FindViewById<ListView>(Resource.Id.List);
FindViewById<ListView>(Resource.Id.List).ItemClick += new System.EventHandler<ItemEventArgs>(CoeList_ItemClick);
var Coe = ((OmsisMobileApplication)Application).OmsisRepository.GetmyCoe();
_list.Adapter = new CoeListAdapter(this, Coe);
My Adapter page is where I have the problem, I know it is set up to to looking at a table which I'm not doing anymore. But I don't know how to change it for what I'm passing into it now. Current CoeListAdapter is:
public class CoeListAdapter : BaseAdapter
{
private IEnumerable<Coe> _Coe;
private Activity _context;
public CoeListAdapter(Activity context, IEnumerable<Coe> Coe)
{
_context = context;
_Coe = Coe;
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
var view = (convertView
?? _context.LayoutInflater.Inflate(
Resource.Layout.CoeListItem, parent, false)
) as LinearLayout;
var Coe = _Coe.ElementAt(position);
view.FindViewById<TextView>(Resource.Id.CoeMID).Text = Coe.Id.ToString();
//view.FindViewById<TextView>(Resource.Id.GrdnMaleName).Text = Coe.Name;
view.FindViewById<TextView>(Resource.Id.CreateDt).Text = Coe.CreateDt;
return view;
}
public override int Count
{
get { return _Coe.Count(); }
}
public Coe GetCoe(int position)
{
return _Coe.ElementAt(position);
}
public override Java.Lang.Object GetItem(int position)
{
return null;
}
public override long GetItemId(int position)
{
return position;
}
}
How do I set up the CoeListAdapter.cs page so that it can use the passed in data. As you can see I have a commented out lines where I fill a TextView which error because Coe.Name is not in the table model for Coe. but it is returned in the query. I believe my problem is IEnumerable but what do I change it to. I'm new to Mobile developement and suing VS2010 for Mono
The problem probably lies with the binding/mapping of the object not the creation of the view.
Or probably more specifically, the query.
Adult.LName + ', ' + Adult.MName AS Name
this should be:
Adult.LName || ', ' || Adult.MName AS Name
See also: String concatenation does not work in SQLite
From the sqlite docs: http://www.sqlite.org/lang_expr.html under the Operators heading:
The unary operator + is a no-op. It can be applied to strings,
numbers, blobs or NULL and it always returns a result with the same
value as the operand.
Note that there are two variations of the equals and not equals
operators. Equals can be either = or ==. The non-equals operator can
be either != or <>. The || operator is "concatenate" - it joins
together the two strings of its operands. The operator % outputs the
value of its left operand modulo its right operand.
The result of any binary operator is either a numeric value or NULL,
except for the || concatenation operator which always evaluates to
either NULL or a text value.
This shows that the + will evaluate to zero. If you use ||, the value will either be the correct value or NULL (if either of Adult.LName or Adult.MName is NULL).
This can be fixed by:
coalesce(first, '') || ', ' || coalesce(second, '')
but this may result in , LastName or FirstName,.
Another way would be to create another two properties in Coe called LName and MName.
Then bind the values to those properties and use the Name property like this:
public string Name
{
get { return string.Join(", ", LName, MName); }
}
This will probably be better as you can change how the Name appears especially if there are different combinations of First, Middle and Last names in different places.
And off topic:
I believe my problem is IEnumerable...
This is probably not too true as it returns the correct values. A better way would be to use IList as IEnumerable will iterate through the list each time to get the item as it does not know that the collection is actually a list. (I think)
thanks for the help on the concantination, I did find that was wrong, I did fix my problem, I was using an example by Greg Shackles on how to set up using a data base. what I had to do was create a new model with the elements I was wanting. So I created a new Model and called it CoeList, then everywhere I had List or IEnumerable I changed it to List or IEnumerable and it worked.

RedirectToAction() vs. View() and the ternary operators?

when deciding on which ActionResult to return from a Controller Action I decided to use the ternary operators as opposed to the lengthier if-else. Here is my issue...
this code works
return
ModelState.IsValid ?
(ActionResult) RedirectToAction("Edit", new { id = id }) :
View(new EditViewModel(updatedCategory));
but this doesn't
return
ModelState.IsValid ?
RedirectToAction("Edit", new { id = id }) :
View(new EditViewModel(updatedCategory));
I would not have to do the explicit casting if using an if-else. Plus both RedirectToAction() and View() return an ActionResult derivative.
I like the terseness of this code but that casting doesn't seem right. Can anyone enlighten me?
Though I'm sure this is obvious, the EditViewModel is a view model for my Edit action and updatedCategory is an EF4 object. But I don't think this is relevant to the issue.
ok... I just realized what I was doing is unnecessary because regardless I am going back to the Edit action with the updatedCategory, so I don't need to make sure the Model is valid. I am still curious to know the answer to the question if anyone can help.
I believe it's because the arguments when using the ?: operator have to be convertable between themselves, e.g. in condition ? x : y you need to be able to convert x to y or y to x. Then the type of the result is the least specific of the two. So if x was an object and y a string then you can cast a string to an object and the result would be of type object.
In your example x is a RedirectToRouteResult and y is a ViewResult. You cannot convert a RedirectToRouteResult to a ViewResult or vice versa. You can convert them both to an ActionResult however, which is why if you cast to an ActionResult it works - the type of x is then an ActionResult,y can be converted to an ActionResult and the overall result is of type ActionResult.
Hope I've explained myself correctly there... Afraid I don't know the exact semantics of the ?: operator as I rarely use it myself...
The data types have to be exactly the same on the assignment variable and both return types here is the most simple example I can think of:
int originalValue = 10;
int? value = (originalValue != 10) ? null : originalValue;
//Which is very easily fixed with type casting as you have done
int? value = (originalValue != 10) ? null : (int?)originalValue;

Using __arglist with a varying set of named parameters

in my application I have 2 layers. The first layer is a C legacy exposing cdecl functions that use the "..." syntax for a varying parameter list. The only way I found to call these functions from my .Net layer (the second one) is using the DllImport technics. For example the C function below:
int myFunc(char* name, ...);
looks like that in C#:
[DllImport("MyDll.dll"),
CharSet = CharSet.Ansi,
CallingConvention = CallingConvention.Cdecl]
int myFunc(string name, __arglist);
My problem is that sometimes I want to call this function with 2 extra parameters but if one of them is NULL it won't be included in the argument list (my legacy code fails on NULL values). For example I want this call:
int foo(string name, string a, string b)
{
myFunc(name, __arglist(a, b));
}
{
foo("john", "arg1", null);
}
to be interpreted by C as
myFunc("john", "arg1");
Unfortunately doing something like that:
int foo(string name, string a, string b)
{
List<string> args = new List<string>();
if(a != null) args.Add(a);
if(b != null) args.Add(b);
myFunc(name, __arglist(args));
}
{
foo("john", "arg1", null);
}
is interpreted by C like that:
myFunc(name, args);
and not:
myFunc(name, args[0]);
Does anybody have any idea?
How does the C function know which one is the last parameter? It cannot know a priori how many parameters there are. It needs additional information. One common way for functions get the information they need is by parsing the included string parameter to count format specifiers, as in printf. In that case, if the format string only indicates that there is one extra parameter, then the function doesn't know the difference between a call that really had just one extra parameter and a call that had two or a call that had 20. The function should have the self-discipline to only read one parameter, since that's all the format string said there was. Reading more would lead to undefined behavior.
If what I've described is not the way your function works, then there's not much you can do on the calling end to solve it. But if it is how your function works, then there's nothing to do on the calling end, because there's no problem.
Another option, since you indicate that your "legacy code fails on null values," is to fix your legacy code so it doesn't fail anymore.
A third option is to simply write all four possibilities:
if (a != null) {
if (b != null)
return myFunc(name, a, b);
else
return myFunc(name, a);
} else {
if (b != null)
return myFunc(names, b);
else
return myFunc(names);
}
More than two optional parameters, though, and the code starts getting unwieldy.
Try converting your System.List ToArray() before wrapping it in __arglist
myFunc(name, __arglist(args.ToArray()));

Resources