What is the best way to replace Tuple<T1,T2> with C# 2 - c#-2.0

I want to use a Tuple but in C# 2, it does not exist. I think to replace it by KeyValuePair.
Is it the best way to do this ?

A simple class holding two generic members is probably the best option. This is essentially what Tuple<T1,T2> is.
If you know the types you are using, it is better to create a class with members of those types - this way you can use good naming for the class and members to ensure good readability (which a generic type like Tuple obscures).
From you comment, I would suggest that creating a small wrapper class (or possibly struct) to hold the int values will be the best choice.
Untested:
public class Point
{
public Point(int xPos, int yPos)
{
this.xPos = xPos;
this.yPos = yPos;
}
int xPos;
int yPos;
public int XPos { get { return xPos;} set { xPos = value;} }
public int YPos { get { return yPos;} set { yPos = value;} }
}

If you use your Tuple always like Tuple<T1,T2> then you can switch easily to KeyValuePair<T1,T2> with no problems.
The only difference is that you have to use the Key and Value properties instead of the ItemN property of the Tuple.

Related

Equivalent of tuples in Dart [duplicate]

Is there a way to return several values in a function return statement (other than returning an object) like we can do in Go (or some other languages)?
For example, in Go we can do:
func vals() (int, int) {
return 3, 7
}
Can this be done in Dart? Something like this:
int, String foo() {
return 42, "foobar";
}
Dart doesn't support multiple return values.
You can return an array,
List foo() {
return [42, "foobar"];
}
or if you want the values be typed use a Tuple class like the package https://pub.dartlang.org/packages/tuple provides.
See also either for a way to return a value or an error.
I'd like to add that one of the main use-cases for multiple return values in Go is error handling which Dart handle's in its own way with Exceptions and failed promises.
Of course this leaves a few other use-cases, so let's see how code looks when using explicit tuples:
import 'package:tuple/tuple.dart';
Tuple2<int, String> demo() {
return new Tuple2(42, "life is good");
}
void main() {
final result = demo();
if (result.item1 > 20) {
print(result.item2);
}
}
Not quite as concise, but it's clean and expressive code. What I like most about it is that it doesn't need to change much once your quick experimental project really takes off and you start adding features and need to add more structure to keep on top of things.
class FormatResult {
bool changed;
String result;
FormatResult(this.changed, this.result);
}
FormatResult powerFormatter(String text) {
bool changed = false;
String result = text;
// secret implementation magic
// ...
return new FormatResult(changed, result);
}
void main() {
String draftCode = "print('Hello World.');";
final reformatted = powerFormatter(draftCode);
if (reformatted.changed) {
// some expensive operation involving servers in the cloud.
}
}
So, yes, it's not much of an improvement over Java, but it works, it is clear, and reasonably efficient for building UIs. And I really like how I can quickly hack things together (sometimes starting on DartPad in a break at work) and then add structure later when I know that the project will live on and grow.
Create a class:
import 'dart:core';
class Tuple<T1, T2> {
final T1 item1;
final T2 item2;
Tuple({
this.item1,
this.item2,
});
factory Tuple.fromJson(Map<String, dynamic> json) {
return Tuple(
item1: json['item1'],
item2: json['item2'],
);
}
}
Call it however you want!
Tuple<double, double>(i1, i2);
or
Tuple<double, double>.fromJson(jsonData);
You can create a class to return multiple values
Ej:
class NewClass {
final int number;
final String text;
NewClass(this.number, this.text);
}
Function that generates the values:
NewClass buildValues() {
return NewClass(42, 'foobar');
}
Print:
void printValues() {
print('${this.buildValues().number} ${this.buildValues().text}');
// 42 foobar
}
The proper way to return multiple values would be to store those values in a class, whether your own custom class or a Tuple. However, defining a separate class for every function is very inconvenient, and using Tuples can be error-prone since the members won't have meaningful names.
Another (admittedly gross and not very Dart-istic) approach is try to mimic the output-parameter approach typically used by C and C++. For example:
class OutputParameter<T> {
T value;
OutputParameter(this.value);
}
void foo(
OutputParameter<int> intOut,
OutputParameter<String>? optionalStringOut,
) {
intOut.value = 42;
optionalStringOut?.value = 'foobar';
}
void main() {
var theInt = OutputParameter(0);
var theString = OutputParameter('');
foo(theInt, theString);
print(theInt.value); // Prints: 42
print(theString.value); // Prints: foobar
}
It certainly can be a bit inconvenient for callers to have to use variable.value everywhere, but in some cases it might be worth the trade-off.
you can use dartz package for Returning multiple data types
https://www.youtube.com/watch?v=8yMXUC4W1cc&t=110s
Dart is finalizing records, a fancier tuple essentially.
Should be in a stable release a month from the time of writing.
I'll try to update, it's already available with experiments flags.
you can use Set<Object> for returning multiple values,
Set<object> foo() {
return {'my string',0}
}
print(foo().first) //prints 'my string'
print(foo().last) //prints 0
In this type of situation in Dart, an easy solution could return a list then accessing the returned list as per your requirement. You can access the specific value by the index or the whole list by a simple for loop.
List func() {
return [false, 30, "Ashraful"];
}
void main() {
final list = func();
// to access specific list item
var item = list[2];
// to check runtime type
print(item.runtimeType);
// to access the whole list
for(int i=0; i<list.length; i++) {
print(list[i]);
}
}

How can I initialize a mixin's immutable data in Dart?

I am programming in Flutter using Dart 2.1.0, and come across this situation:
mixin Salt {
final int pinches; // Immutable, and I want to delay initialization.
// Cannot declare constructors for mixin
}
class Meat with Salt {
Meat(int pinches) ... // How to initialize it?
}
Salt has no constructor, so I cannot use initializer list. pinches is final, so I cannot set it in Meat's constructor.
I don't want to make Salt a class because Meat may need to extend from something else.
And I want to keep pinches immutable.
Any way to do it? Thanks in advance.
You can change the declaration of your mixin to:
mixin Salt {
int get pitches;
}
And then define the field inside the implementation class
class Meat with Salt {
final int pitches;
Meat(this.pitches);
}
By design it is not possible to declare a final member into a mixin because it is not possible to declare a constructor for initializing the final member,
citing the docs:
However, in this proposal, a mixin may only be extracted from a class that has no declared constructors. This restriction avoids complications that arise due to the need to pass constructor parameters up the inheritance chain.
A compromise may be to declare a private member and implement only a getter.
_pinches is visible only inside the library, it is read-only for library users.
mixin Salt {
int _pinches;
get pinches => _pinches;
}
class Meat with Salt {
Meat(int pinches) {
_pinches = pinches;
}
}
Note: the above pattern, because of the visibility rules, works only if the mixin and the mixed classes reside in the same library.
I offer my take on a solution to this. By marking the variable late you can make it final. No warning will appear if you fail to initialize it so use with caution.
mixin Salt {
late final int pinches;
}
class Vegetable with Salt {
Vegetable(int pinches) {
this.pinches = pinches;
}
}
Similar to attdona's suggestion, but a little bit closer to what you really wanted, you could do it like
mixin Salt {
int _pinches;
int get pinches => _pinches;
void initSalt(int pinches) {
assert(_pinches == null);
_pinches = pinches;
}
}
class Meat with Salt {
Meat(int pinches) {
initSalt(pinches);
}
}
It's still not strictly final, but (so long as the mixin's in a different library so you can't change the private member directly) it's immutable at runtime. Not as good as if it could be properly final, but maybe close enough.
The following method allows you to set the data at a later time, and gets rid of the warning:
This class (or a class that this class inherits from) is marked as '#immutable', but one or more of its instance fields aren't final
mixin Salt {
final SaltData _saltData = SaltData();
int get pinches => _saltData.pinches;
set pinches(int extraData) {
_saltData.pinches = extraData;
}
}
class SaltData {
int pinches = 0;
}
So what I did is create a class SaltData. This will store all the variables you need.
The private _saltData variable is final, this will stop the warning.
Then use a getter and setter to retrieve and update the data.
int get pinches => _saltData.pinches;
set pinches(int extraData) {
_saltData.pinches = extraData;
}
If you want you can could expose the entire saltData object as well:
SaltData get saltData => _saltData;

How to point to the field in dart without dart:mirrors?

I have model
class Model {
int counter;
}
now I get a Model object at runtime, so I mark it as dynamic.
dynamic model = new Model();
int counter = 3;
What would be possible way to do equivalent of
model['counter'] = counter;
one thing to mention is that counter from Model is used in the app somewhere, so tree shaking wont remove it.
I am looking for any solution.
class Model {
int counter;
var counterPath = "any way to reference counter field, so I can give the value to it";
}
open to any suggestion or hack :)
One way is to implement a mapping between string name and actual field like
class Model {
int counter;
// reading: print(model['counter']);
operator [](String name) {
switch(name) {
case 'counter':
return counter;
default: throw 'Field $name doesn't exist' in $runtimeType';
}
// writing: model['counter'] = counter;
operator []=(String name, dynamic value) {
switch(name) {
case 'counter':
counter = value;
break;
default: throw 'Field $name doesn't exist' in $runtimeType';
}
}
I'd not recommend this, as using model['string'] makes you loose a lot in maintainability.
But if you truly need it, the best way to achieve this is by using code generation.
In your case, json_serializable may be a good idea. As it will generate a toJson method and a MyClass.fromJson constructor ; without having to change your model in any way.
In the end you'd have
#JsonSerializable()
class Model extends Object with _$ModelSerializerMixin {
int couter;
Model();
factory Model.fromJson(Map<String, dynamic> json) => _$ModelFromJson(json);
}
Which allows you to run the following :
final model = new Model()
..counter = 42;
final modelJson = model.toJson();
modelJson['counter'] = 43;
final result = new Model.fromJson(modelJson); // counter = 43
This may not be the most optimal in term of performances. But it's far less likely to have a bug or require constant edit.
That was for the easy solution.
But that's ugly ; please don't do that.
If you have a real use case where you need reflection then instead of loosing all type check ; create a custom code generator.
There are a few awesome toolings for code generators in dart.
Starting with the lower layer source_gen followed by build to name a few.
Dart team created a lot of tools for code generation ; go take a look !

Get and Set on each field like in Java

I tried to look all over the internet to find out what is the best practice of encapsulating data in Swift. I only found some information about get and set method of an instance variables. They used to work pretty much like C#'s did set, but now they work as computed properties and one can't set them in their setters and can't get them in their getters. The question is: do people still create getter and setter for each property in the class in swift ? Like:
private var age: Int = 0
public func getAge() -> Int {
return age
}
public func setAge(newAge: Int) {
self.age = newAge
}
If not, then what is considered to be the best practice ?
Thank You.
I use this type of syntax with computed vars to expose the getter and setters when the internals are more complex than what is shown here:
internal var _age: Int = 0
var age: Int {
get {
return _age
}
set {
_age = newValue
}
}
Plenty of syntaxic sugar to make it easy to hide complexity in some expressions.
But most of the time I am happy with just exposing the plain var and be done with it:
var age: Int = 0
The advantage of this is that both ways are easily swappable when you want to do more work inside the getters and setters.
I don't think you need to create getX/setX methods, because you can always change from a stored to a computed property without having to change the source code of the clients. Just like you could change the bodies of your getAge & setAge methods, so I do not see what is gained in swift by not letting clients use age.
if you want to access the property (Age) itself, you can always get/set it directly.
let theGirlsAge = Age; // Get
Age = theBoysAge; // Set
Getters and Setters are used for define relationship between the property and other properties.
public func getAge() -> Int {
return theBoysAge
}
public func setAge(newAge: Int) {
theGirlsAge = newAge
}

Is there a way to pass a primitive parameter by reference in Dart?

I would like to pass a primitive (int, bool, ...) by reference. I found a discussion about it (paragraph "Passing value types by reference") here: value types in Dart, but I still wonder if there is a way to do it in Dart (except using an object wrapper) ? Any development ?
The Dart language does not support this and I doubt it ever will, but the future will tell.
Primitives will be passed by value, and as already mentioned here, the only way to 'pass primitives by reference' is by wrapping them like:
class PrimitiveWrapper {
var value;
PrimitiveWrapper(this.value);
}
void alter(PrimitiveWrapper data) {
data.value++;
}
main() {
var data = new PrimitiveWrapper(5);
print(data.value); // 5
alter(data);
print(data.value); // 6
}
If you don't want to do that, then you need to find another way around your problem.
One case where I see people needing to pass by reference is that they have some sort of value they want to pass to functions in a class:
class Foo {
void doFoo() {
var i = 0;
...
doBar(i); // We want to alter i in doBar().
...
i++;
}
void doBar(i) {
i++;
}
}
In this case you could just make i a class member instead.
No, wrappers are the only way.
They are passed by reference. It just doesn't matter because the "primitive" types don't have methods to change their internal value.
Correct me if I'm wrong, but maybe you are misunderstanding what "passing by reference" means? I'm assuming you want to do something like param1 = 10 and want this value to still be 10 when you return from your method. But references aren't pointers. When you assign the parameter a new value (with = operator), this change won't be reflected in the calling method. This is still true with non-primitive types (classes).
Example:
class Test {
int val;
Test(this.val);
}
void main() {
Test t = new Test(1);
fn1(t);
print(t.val); // 2
fn2(t);
print(t.val); // still 2, because "t" has been assigned a new instance in fn2()
}
void fn1(Test t) {
print(t.val); // 1
t.val = 2;
}
void fn2(Test t) {
t = new Test(10);
print(t.val); // 10
}
EDIT
I tried to make my answer more clear, based on the comments, but somehow I can't seem to phrase it right without causing more confusion. Basically, when someone coming from Java says "parameters are passed by reference", they mean what a C/C++ developer would mean by saying "parameters are passed as pointers".
As dart is compiled into JavaScript, I tried something that works for JS, and guess what!? It worked for dart!
Basically, what you can do is put your value inside an object, and then any changes made on that field value inside that function will change the value outside that function as well.
Code (You can run this on dartpad.dev)
main() {
var a = {"b": false};
print("Before passing: " + a["b"].toString());
trial(a);
print("After passing: " + a["b"].toString());
}
trial(param) {
param["b"] = true;
}
Output
Before passing: false
After passing: true
One of the way to pass the variables by reference by using the values in List. As arrays or lists are Pass by reference by default.
void main() {
List<String> name=['ali' ,'fana'];
updatename(name);
print(name);
}
updatename(List<String> name){
name[0]='gufran';
}
Try this one, This one of the simplest way to pass by reference.
You can use ValueNotifier
And, you can pass it as ValueListenable to classes or methods that needs to know up-to-date value, but should not edit it:
class Owner {
final theValue = ValueNotifier(true);
final user = User(theValue);
...
}
class User {
final ValueListeneble<bool> theValue;
User(this.theValue);
...
}
It provides more functionality than actually needed, but solves the problem.
If ValueNotifier + ValueListenable do not work for you (you want to make sure the client does not listen to every change of the value, or your package is pure Dart package and thus cannot reference Flutter libraries), use a function:
class Owner {
int _value = 0;
int getValue() => _value;
void increase() => _value++;
}
void main() {
final owner = Owner();
int Function() obtainer = owner.getValue;
print(obtainer());
owner.increase();
print(obtainer());
}
Output will be:
0
1
This approach has memory usage related downside: the obtainer will hold the reference to the owner, and this, even if owner is already not referenced, but obtainer is still reachable, owner will be also reachable
and thus will not be garbage collected.
If you do not want the downside, pass the smaller container than the entire owner:
import 'package:flutter/foundation.dart';
class ListenableAsObtainer<T> implements ValueObtainer<T> {
ListenableAsObtainer(this._listenable);
final ValueListenable<T> _listenable;
#override
T get value => _listenable.value;
}
class FunctionAsObtainer<T> implements ValueObtainer<T> {
FunctionAsObtainer(this._function);
final T Function() _function;
#override
T get value => _function();
}
class ValueAsObtainer<T> implements ValueObtainer<T> {
ValueAsObtainer(this.value);
#override
T value;
}
/// Use this interface when the client needs
/// access to the current value, but does not need the value to be listenable,
/// i.e. [ValueListenable] would be too strong requirement.
abstract class ValueObtainer<T> {
T get value;
}
The usage of FunctionAsObtainer will still result in holding the owner from garbage collection, but two other options will not.
Just to make it clear:
void main() {
var list1 = [0,1,2];
var modifiedList1 = addMutable(list1, 3);
var list2 = [0,1,2];
var modifiedList2 = addImmutable(list2, 3);
print(list1);
print(modifiedList1);
print(list2);
print(modifiedList2);
}
List<int> addMutable(List<int> list, int element){
return list..add(element);
}
List<int> addImmutable(List<int> list, int element){
return [...list, element];
}
Output:
[0, 1, 2, 3]
[0, 1, 2, 3]
[0, 1, 2]
[0, 1, 2, 3]
All variables are passed by value. If a variable contains a primitive (int, bool, etc.), that's it. You got its value. You can do with it whatever you want, it won't affect the source value. If a variable contains an object, what it really contains is a reference to that object.
The reference itself is also passed by value, but the object it references is not passed at all. It just stayed where it was. This means that you can actually make changes to this very object.
Therefore, if you pass a List and if you .add() something to it, you have internally changed it, like it is passed by reference. But if you use the spread operator [...list], you are creating a fresh new copy of it. In most cases that is what you really want to do.
Sounds complicated. Isn't really. Dart is cool.

Resources