Better way to write common function with parameter is different class - list

In my project, I have some functions like that:
func 1 (with 2 class: class1 and classs1_1):
List<class1> GetData1(class1_1 cls)
{
List<class1> list = new List<class1>();
cls = new cls();
//do something for cls, like cls.GetSpecialCase();
//fill data from cls to list, as using foreach to fill data to list
return list;
}
func 2 (with 2 class: class2 and classs2_2):
List<class2> GetData2(class2_2 cls)
{
List<class2> list = new List<class2>();
cls = new cls();
//do something for cls, like cls.GetSpecialCase();
//fill data from cls to list, as using foreach to fill data to list
return list;
}
How could I write a function like that (because I don't want to use a lot of functions as above):
common func (with T is class1, object cls is class1_1):
List<T> GetData(object cls)
{
List<T> list = new List<T>();
//how to recognize which class of cls
if(cls == class1_1) class1_1 other_cls = cls as class1_1;
if(cls == class2_2) class2_2 other_cls = cls as class2_2;
//do something for other_cls
//fill data from other_cls to list
return list;
}
I just want to pass parameter as object, and in the common function, I want to know which class I'm passing to so that I can treat to right class, and call right function.
Anyone helps me to solve this problem.
Thank you very much.

It sounds like you need:
An interface or abstract base class with the GetSpecialCase method
A generic method (with type parameters for both input and output) of
List<TResult> GetData<T, TResult>(T item) where T : ISpecialCase<TResult>
{
List<TResult> list = new List<TResult>();
var other = item.GetSpecialCase();
// Fill list via other
return list;
}
If you can't introduce an interface or base class, you could use dynamic typing, but I'd strongly recommend that you use polymorphism to express what the different classes have in common (GetSpecialCase here) if you possibly can.

you can use generics also for the input type.
your code could be something like:
List<T> GetData<T>(T cls)
{
List<T> list = new List<T>();
//no need to recognize which class of cls
//do something for other_cls
//fill data from other_cls to list
return list;
}
and both classes needs to implement the same interface so you wouldn't need to know which type it is...

Related

Dot notation for list of object in class

I have a "fixed list" in a class, I know all the objects that are in that list and I can refer to the objects through the names. The list is immutable, except for the parameters of every object contained in this list.
Something like this
class Object {
String name; // Know prior to build time
String color; // Can change
Object(this.name, this.color);
}
class MyClass {
List<Object> myList = [Object('apple', 'red'),
Object('banana', 'yellow'),
Object('mango', 'orange')];
}
I would like to access the members of the list like
final test = MyClass();
test.myList.apple.color = 'green'
Is there some "special list" that consent this type of access?
I tried using ENUM but they are not suitable for this problem.
A Map<String, String> would be better suited for what you are trying to do.
final colors = HashMap<String, String>();
colors['apple'] = 'green';

Create a list of objects from a list of String in groovy

I am having a list of string as follows.
List l = ["1","2","3"]
And I have a class like as follows.
class person {
String name
}
I want to create a list of person object from List l.
I have tried using groovy list collect but I am not able to do so.
Here is my code.
class testJsonSlurper {
static void main(String[] args) {
List l = ["1","2","3"]
def l2 = l.collect { new person(it) }
println(l2)
}
}
But I getting following error.
Exception in thread "main" groovy.lang.GroovyRuntimeException: Could not find matching constructor for: testJsonSlurper$person(java.lang.String)
In your class testJsonSlurper, you have to change this line
def l2 = l.collect { new person(it) }
into
def l2 = l.collect { new person(name:it) }
This is what we call Named argument constructor. You can find more about Named argument constructor here.
If you do not want to make this change, then you need to add constructor in class person yourself.
The class person should look like this after adding constructor.
​class person {
String name
person(name){
this.name = name
}
}

Is it possible to overload a constructor that accepts a list in scala?

I am trying to overload the constructor to a class so that it can accept lists of two different types of objects:
class myClass(){
var someStrings: List[String]=List[String]()
println("hello!")
def this(strings : List[String])={
this()
this.someStrings=strings
}
def this(ints: List[Int])={
this()
this.someStrings=ints.map(x => x.toString)
}
}
In this case, accept a list of ints or strings, and save a list of strings to the variable someStrings. The code above doesn't work:
error: double definition:
constructor myClass: (strings: List[String])myClass at line 12 and
constructor myClass: (ints: List[Int])myClass at line 17
have same type after erasure: (strings: List)myClass
def this(ints: List[Int])={
^
Is there a better way of doing this in scala? (Other than taking List[Any] and testing the elements)
Thanks!
create functions on a companion object which do the construction for you in a typesafe way that can be checked at compile time:
class myClass(){
var someStrings: List[String]=List[String]()
println("hello!")
}
object myClass {
def fromStrings(strings: List[String]) = {
val c = new myClass
c.someStrings = strings
}
def fromInts(ints: List[Int]) = {
val c = new myClass
c.someStrings = ints.map(_.toString)
}
}
object Usage {
val c1 = myClass.fromStrings(List("a","b","c"))
val c2 = myClass.fromInts(List(1,2,3))
}
I would urge you to avoid overloading in general, or checking types at runtime, when you could be checking types at compile-time instead
That's what DummyImplicit is for:
def this(strings: List[String])={
this()
this.someStrings=strings
}
def this(ints: List[Int])(implicit d: DummyImplicit)={
this()
this.someStrings=ints.map(x => x.toString)
}
This makes the erased signatures of constructors (i.e. the ones JVM sees) MyClass(List) and MyClass(List, DummyImplicit), so the overloading is allowed.
However, as #stew says, it could be a better idea to avoid overloading in this case.
In addition to the other answer, another thing you can do is use Arrays. The type information on an array is kept at runtime, so you can do overloading based on the type parameter.
class myClass() {
var someStrings: Array[String] = Array[String]()
println("hello!")
def this(strings: Array[String]) = {
this()
this.someStrings = strings
}
def this(ints: Array[Int])={
this()
this.someStrings = ints.map(x => x.toString)
}
}
Arrays are much underused in my opinion

Error to instantiate one class in form c++

I need insert one object in the linked list when i clicked a button
but when i make instantiate the class List this shows me one error
public ref class Boletos : public System::Windows::Forms::Form
{
public:
Boletos(void)
{
Lista *List=new Lista;
InitializeComponent();
//
//TODO: Add the constructor code here
//
}
//*****************Click_event**********************//
...
if (count==4){
Capacidad=Convert::ToInt32(line);
capc=Capacidad;
//sala->set_capacidad(Capacidad);
Sala *sala=new Sala();
List->insertAlFinal(newSala(numSala,HPeli,capc,"",2000,nombrePelicula));//Here the error List undefined
count=0;
}
u are placing your code at the wrong position, its so to say out of scope. Btw. this is not really c++, looks like c# ...
Try something like
Boletos(void)
{
Lista* list = new Lista();
InitializeComponent();
}
What u need is a class member.
public ref class Boletos ...
{
public:
....
void InitializeComponent()
{
m_lista = new Lista();
}
private:
Lista* m_lista;
}
now u can use m_lista in all the classes member functions. What u need to understand is the concept of scope. If u declare and intialize a variable only in the scope of one function this variable is so to say lost after the program leaves the scope of this function. In the case of c++ the dynamich alloaction new Lista() without a matching call to delete would even be a memory leak.

Spark List in Actionscript: Passing Layout & itemRenderer in construtctor

I am trying to create a generic List, where I can pass the layout & item renderer as parameters.
Since it is not possible to pass parameters to a MXML component's Constructor, I figured I should create my List in Actionscript.
I figured it would go something like this:
public class GenericList extends List {
public function GenericList(iR:ItemRenderer, ac:ArrayCollection, layout:LayoutBase) {
super();
this.dataProvider = ac;
this.layout = ... // don't even have access to this.layout
this.itemRenderer = iR // Cannot pass itemRender
}
I would prefer to have the List in MXML (because It will be easier using states later), but If I am forced to use pure Actionscript so I can instantiate it and pass in parameters, any help would go a long way.
You cannot set the itemRenderer property of a list must implement IClassFactory. So your assignment would look like this:
public function GenericList(cf:ClassFactory, ac:ArrayCollection, layout:LayoutBase) {
And the instantiation would be:
var myList:GenericList = new GenericList( new ClassFactory( com.company.renderers.MyItemRenderer, ....);
Regarding the layout:
List essentially wraps DataGroup, so it is the datagroup's layout that you need to access. However, dataGroup will not necessarily be instantiated yet. So you might have to create a private property that you then utilize in commitProperties.
private var _myLayout:LayoutBase; (populate in constructor via getter/setter)
protected var layoutInvalidated:Boolean;
public function set myLayout( layout:LayoutBase):void {
_myLayout = layout;
layoutInvalidated = true;
}
override protected function commitProperties():void {
super.commitProperties();
if( layoutInvalidated && dataGroup && dataGroup.layout ) {
layoutInvalidated = false;
dataGroup.layout = _myLayout;
}
}