I use this getter to make a list:
List<CabModel> get cabs() => cabsList.value;
and works. But now I need to pass a parameter to filter a list. Something like
List<CabModel> get cabs(String value) => cabsList.value;
I know, I can't pass parameter in getters, but how do it?
The getter only sends back copy of data, but cannot make any changes/filter stuff. You'd have to create a function that takes in the required parameters and returns the required value.
If you also want to filter and overwrite the existing data, make a setter as well.
List FilteredList(...){
.../required filtering
return list
}
Related
What is the reason of using custom getters and setters in an application.
That's fairly very simple
First let me show you a sample of how getters and setters in Dart look like, which is essentially the language behind Flutter
class Foo {
// Creating a field/instance variable
String _fooName; //Keeping it private always
// Using the getter
String get foo_name {
//We can do something else here, like saving the variable somewhere and then returning it to the caller function
return _fooName;// private variable return for use in outside class
}
// Using the setter method
set foo_name (String name) {
// We can do something else, like update another variable based on fooName
this._fooName = name;//private variable being assigned new value
}
}
From the name, setters are involved in setting the values to an instance variable in an object oriented programming paradigm whereas getters are involved in getting the value of an instance variable
Now you would ask why not return the instance variable directly and why having such a roundabout approach to setting and getting the value
Well the answer is while getting as well as setting, we might want to do some other operation too other than just setting or getting the value and it's always better not to give admin access to the variables and that's why they are private so as to promote consistency within the objects accessing the field
It's a matter of preference, but you really shouldn't needlessly create one for a single field
https://dart.dev/guides/language/effective-dart/usage#dont-wrap-a-field-in-a-getter-and-setter-unnecessarily
One use case for creating a setter would be to perform some type of validation
For a getter, it'd be useful for a calculated field based on other properties, rather than a single property alone
I have a variable which I want to give the option to call the setter with multiple types, but I would set the variable with one type of course. For example, if I have a variable called list, I want to be able to call the setter using a single list item i.e. a string and then in the setter method I would add the string to the end of the list. Another way to set the variable would be through an actual list, and the setter, I would just set the list to the list passed in.
Here's an example of what I would like to do, but the second time I call the list setter method, I get an error saying The name 'list' is already defined:
List<String> _list = [];
List<String> get list => list;
set list(List<String> newList) {
_list = newList;
}
set list(String newListItem) {
_list = [..._list, newListItem];
}
As Remi mentioned, it is not possible to do so. I would argue that it would be best not to do so because it changes the expectation of the contract of the setter. That is, you expect a setter to replace the value of a variable. Having a setter that appends to it is counter-intuitive and will lead to confusion for other developers.
Generally, for the maintainability of a code base, it's better to have an explicit interface to your class's behavior than to provide terse shortcuts.
That is not possible.
In Dart you can have only one setter per variable.
You will need to rename one of your setters to use a different name.
Let’s say we have a factory trait
trait Factory {
def createObject(paramA, paramB)
}
And now we have implementations of this Factory - FactoryV1 and FactoryV2 which are selected at runtime. While FactoryV2 uses both params to create object, FactoryV1 uses only paramA. So, when we call FactoryV1’s createObject method we pass an unnecessary parameter in paramB. How bad is passing an extra parameter? Some alternatives:
One way to improve upon it is to have paramB as a Scala Option, and depending on the factory being used, we pass None for FactoryV1.createObject and Some for FactoryV2.createObject.
Another alternative would be to have two methods in the base trait, one with just paramA and another with both parameters. Depending on the factory being used (V1 or V2), we call the appropriate method with 1/2 parameters (I don’t see a very clean way of doing this though).
What are other alternatives? I am inclined towards having a single factory method with Option parameters for those params that are not needed in all implementations of the factory.
Essentially what do we do when Factory implementations don't need all parameters of the Factory method?
I'd say it all depends on how you want to handle the absence of second parameter where you require one.
val factory: Factory = new FactoryV2 // this is the one that needs both params to create an object
// Assuming signature createObject(param1, param2 = default)
// if you use default parameter, is it ok to create an object with default value? THis may be difficult to notice.
factory.createObject(param1)
// Assuming signature createObject(param1, Option[param2])
// Is it ok to fail when second param not supplied?
factory.createObject(param1, None)
Choose your solution based on desired semantics.
I wondering how to get object property value given name of property in string in Scala? I saw examples when you get all fields of object using Reflection and iterate over it. But is it possible to call it without iteration? Or may be there is a way to pass object.field to another function without evaluation and evaluate it there and return result?
Kolmar comment give me right direction to call by name function.
1.First I defined an extension method for the IEnumerable.Add() like the code below
public static IEnumerable<T> Add<T, TKey>(this IEnumerable<T> enumerable, T value, Func<T, TKey> orderBy)
{
if (enumerable == null)
return null;
if (enumerable is IList<T>)
{
var list = enumerable as IList<T>;
if (!enumerable.Contains(value))
{
list.Add(value);
enumerable = enumerable.OrderBy(orderBy);
}
}
}
2.Then,I raised the extension method like this to sort the itemlist according to the "Date" property when a new item was added to the list:
itemList.Add(item, o => o.Date);
3.After all,it appears that the "itemList" was not sorted.
4.I followed the extension method and found that "enumerable" was a new instance after "enumerable = enumerable.OrderBy(orderBy)" and it was sorted,but the "list" was not.
5.Then I tried to cast the sorted enumerable to list like "list=enumerable.ToList()",both of them("enumerable" and "list") were sorted.
6.After that ,when the call stack went back to the "itemList.Add(item, o => o.Date);",the "itemList" was not sorted at all!!!
Anyone can give me some advices?Thanks a looooooooooooooooooooooooooooooooot!!
I believe your problem is that the reference to enumerable is being passed by value rather than by reference. See Jon Skeet's article about passing parameters by value or reference for more information about what that means. In short, C# passes a copy of the parameter's reference so assigning a new value to parameter does not change the reference of the object that was passed in. To pass a parameter by reference you specify the ref keyword, but I don't think that will work with an extension method. If you're dead set on making this work I would suggest inserting the items into your List in sorted order, probably requiring that T implement IComparable.
Update:
First off, see the Skeet's article it's really quite informative and I will probably only be half as clear as he is. Second, when you pass an object as a parameter to a method you are passing a copy of the reference. This means you can still access members of the object but, the same way that a value type is passed by copy, if you modify the reference (ie assign it a new value) you wont modify the original reference. Specifying ref means that you are passing a reference to the reference and changing the reference (assigning a value to it) will affect the original object.
Neither OrderBy or ToList will affect the source list. When you did this: list=enumerable.ToList() you changed your variable to point to a whole new list instance.
It appears to me that this method does too much. I would keep adding and sorting as separate operations. The fact that this extends IEnumerable but silently does nothing if the target is not an IList is a code smell.