konto usunięte

Temat: Wywołanie metody obiektu zawartego w kolekcji

Witam!

Posiadam ArrayList pełen obiektów (zmodyfikowanej przez siebie klasy timer). Chciałbym wywołać metodę jednego konkretnego timera. Jak to zrobić?

Przepraszam, jeśli narażam się na śmieszność, ale nie mam już pomysłów jak to znaleźć przez google...

Z góry dziękuję i pozdrawiam :)
Rafał Pietraszewski

Rafał Pietraszewski Pasjonat technologii
Microsoft

Temat: Wywołanie metody obiektu zawartego w kolekcji

a jak zdecydujesz który konkretnie timer z tej kolekcji Cię interesuje - daj trochę wiecej szczegółów (może kawałek kodu) bo opis zbyt ogólny by coś konkretnie doradzić

Pozdr

konto usunięte

Temat: Wywołanie metody obiektu zawartego w kolekcji


(mojArrayList[0] as JakisMojTyp).JakasMetodaTypu();


Cos takiego?
Maciej Hehl

Maciej Hehl w teorii Automatyk i
Robotyk (po wydziale
mechanicznym), ...

Temat: Wywołanie metody obiektu zawartego w kolekcji

Sergiusz B.:

(mojArrayList[0] as JakisMojTyp).JakasMetodaTypu();


Czy jest jakaś wyższość NullReferenceException nad InvalidCastException?

konto usunięte

Temat: Wywołanie metody obiektu zawartego w kolekcji


var timer = arrayList.OfType<Timer>()
.Where(x => x.SomeProperty == 1)
.FirstOrDefault();
if (timer == null)
{
throw new MyException("There is no timer.")
}
Console.WriteLine(timer.SomeProperty);
Jarek D. edytował(a) ten post dnia 25.05.10 o godzinie 20:56

konto usunięte

Temat: Wywołanie metody obiektu zawartego w kolekcji

Maciej Hehl:
Sergiusz B.:

(mojArrayList[0] as JakisMojTyp).JakasMetodaTypu();


Czy jest jakaś wyższość NullReferenceException nad InvalidCastException?

"Kto pierwszy ten lepszy". :)Jarek D. edytował(a) ten post dnia 25.05.10 o godzinie 21:01

konto usunięte

Temat: Wywołanie metody obiektu zawartego w kolekcji

pewnie składnia nie ta ale tak może być

if(mojArrayList != null)
if(mojArrayList.Count -1 >= myIndex)
if (mojArrayList[myIndex] is JakisMojTyp)
(mojArrayList[myIndex] as JakisMojTyp).JakasMetodaTypu();


ewentualnie jeśli metoda zwraca jakiś wynik to można zrobić to tak:


TypeOfMethodResult result = (mojArrayList != null)?
((mojArrayList.Count -1 >= myIndex)?
((mojArrayList[myIndex] is JakisMojTyp) ? (mojArrayList[myIndex] as JakisMojTyp).JakasMetodaTypu() : null)
:null)
:null;

if(result == null)
throw new Exception("Something wrong :)");
Łukasz Machowski edytował(a) ten post dnia 26.05.10 o godzinie 09:11
Norbert M.

Norbert M. Nobody's perfect.
Call me Nobody ;)

Temat: Wywołanie metody obiektu zawartego w kolekcji

A może tak:

private object ZwrocWartosc(int myIndex)
{
if (mojArrayList != null)
{
if (mojArrayList.Count - 1 >= myIndex)
{
if (mojArrayList[myIndex] is JakisMojTyp)
{
// jezeli metoda coś zwraca:
return (mojArrayList[myIndex] as JakisMojTyp).JakasMetodaTypu();

// jeżeli nie zwraca:
//(mojArrayList[myIndex] as JakisMojTyp).JakasMetodaTypu();
//u góry void oczywicie
}
else { throw new InvalidCastException(); }
}
else
{ throw new IndexOutOfRangeException(); }
}
else
{ throw new NullReferenceException(); }
}


[Edit]
ZwrocWartosc - Niezbyt fortunna nazwa, jeżeli metoda nic nie zwraca.Norbert Maziarz edytował(a) ten post dnia 26.05.10 o godzinie 09:51

konto usunięte

Temat: Wywołanie metody obiektu zawartego w kolekcji

Maciej Hehl:
Sergiusz B.:

(mojArrayList[0] as JakisMojTyp).JakasMetodaTypu();


Czy jest jakaś wyższość NullReferenceException nad InvalidCastException?

Exception to exception :)

Co do weryfikacji dlugosci kolekcji czy prawidlowego typu to oczywiscie mozna to robic w momencie wywolania metody timera z kolekcji jesli metoda ta nie jest wywolywana czesto. Jesli zas jest to jakis krytyczny kawalek kodu to samo wywolanie nalezy trzymac jak najprostsze, vide moj przyklad ;) natomiast zapewnic zgodnosc elementow kolekcji wczesniej, np. na etapie dodawania tych elemento do kolekcji sprawdzac czy nie sa nulami i maja wlasciwy typ.

konto usunięte

Temat: Wywołanie metody obiektu zawartego w kolekcji

no to jeśli komuś chce się pobawić to można to zrobic tak;)

Testowa klasa MyType, z której chcemy wykonać metody:

public class MyType
{
public bool Test1()
{ return false;}
public void Test2()
{}
public void Test3(int x, string f)
{}
}


Teraz w jakimś tam miejscu piszemy sobie metodę do wykonywania metod z list :

public X ReturnSomthOrNoth<T, X>(IList list,int index, string methodName, object[] userParameters)
{
X instance = (X)Activator.CreateInstance(typeof(X));
try
{
Type thisType = typeof(T);
MethodInfo theMethod = thisType.GetMethod(methodName);
object t = null;
if (list != null)
{
if (list.Count - 1 >= index)
{
if (list[index] is T)
{
t = theMethod.Invoke((T)list[index], userParameters);
}
else
throw new InvalidCastException();
}
else
throw new IndexOutOfRangeException();
}
else
throw new NullReferenceException();

if (t != null)
if (t is X)
instance = (X)t;
else
throw new InvalidCastException();
}
catch (TargetParameterCountException arEx)
{
throw new Exception("Wrong number or type of parameters");
}

return instance;
}


No i teraz testowe użycie metod, w jakimś dogodnym dla nas miejscu:

//Test
ArrayList myArrayList = new ArrayList();
myArrayList.Add(new MyType());
//return some type
bool resTest = ReturnSomthOrNoth<MyType, bool>(myArrayList, 0, "Test1", null);
//void without parameters
ReturnSomthOrNoth<MyType,object>(myArrayList, 0, "Test2", null);
//with parameters
ReturnSomthOrNoth<MyType,object>(myArrayList, 0, "Test3", new object[] { 2, "4" });


Pewnie można by zrobić jeszcze parę fajnych rzeczy, ale póki co i tak sprawdza się:)
Jeśli metoda jest typu void to wystrczy w typie X wpisać object :)

Ewentualnie metoda która bezpośrednio wykona metodę obiektu:

public X ReturnSomthOrNoth<T, X>(T objectToUse, int index, string methodName, object[] userParameters)
{
X instance = (X)Activator.CreateInstance(typeof(X));
try
{
Type thisType = typeof(T);
MethodInfo theMethod = thisType.GetMethod(methodName);
object t = null;
t = theMethod.Invoke(objectToUse, userParameters);

if (t != null)
if (t is X)
instance = (X)t;
else
throw new InvalidCastException();

}
catch (TargetParameterCountException arEx)
{
throw new Exception("Wrong number or type of parameters");
}

return instance;
}


Testowe użycie, tutaj już z try i catch na zewnątrz, ale za to bardziej uniwersalnie:)

//object of MyType
try
{
ReturnSomthOrNoth<MyType, object>((MyType)myArrayList[0], 0, "Test3", new object[] { 2, "4" });
}
catch (NullReferenceException ex)
{ }
catch (IndexOutOfRangeException ex)
{ }
catch (InvalidCastException ex)
{ }
Łukasz Machowski edytował(a) ten post dnia 26.05.10 o godzinie 13:29

konto usunięte

Temat: Wywołanie metody obiektu zawartego w kolekcji

Norbert Maziarz:
A może tak:
[Code]
private object ZwrocWartosc(int myIndex)
{
if (mojArrayList != null)
{
if (mojArrayList.Count - 1 >= myIndex)
{
if (mojArrayList[myIndex] is JakisMojTyp)
....

Za taką ilość zagnieżdzonych if'ow idzie się do piekła :)

konto usunięte

Temat: Wywołanie metody obiektu zawartego w kolekcji

nie przesadzaj:)
bardzo ładnie się czyta taki kod... oczywiście jeśli liczba ich jest skończona:)

ale zawsze oczywiście można zrobić tak(odwrócić wyrażenia):

if(mojArrayList == null)
throw new NullReferenceException();
if(mojArrayList-1 < myIndex)
throw new IndexOutOfRangeExcedption();
if(mojArrayList is JakisMojTyp)
throw new InvalidCastException();
//i teraz dopiero nasz kod robiący wszystko :)
Łukasz Machowski edytował(a) ten post dnia 26.05.10 o godzinie 21:12
Norbert M.

Norbert M. Nobody's perfect.
Call me Nobody ;)

Temat: Wywołanie metody obiektu zawartego w kolekcji

Jarek D.:
Norbert Maziarz:
A może tak:
[Code]
private object ZwrocWartosc(int myIndex)
{
if (mojArrayList != null)
{
if (mojArrayList.Count - 1 >= myIndex)
{
if (mojArrayList[myIndex] is JakisMojTyp)
....

Za taką ilość zagnieżdzonych if'ow idzie się do piekła :)

private object ZwrocWartosc(int myIndex)
Za polisz-inglisz też ;)
I co to zmienia...

konto usunięte

Temat: Wywołanie metody obiektu zawartego w kolekcji

Niektore rozwiazania wrecz przerazaja..... :(

konto usunięte

Temat: Wywołanie metody obiektu zawartego w kolekcji

To nie dobrze jak Cię przerażają :)
Są to różne wariacje na temat tylko. Nigdzie nie powiedziane, która najlepsza i że nadaje się dla pytającego...
To takie raczej popuszczenie fantazji i chwila wolnego czasu, który można było zagospodarować jakoś.
Bo jeśli chodzi o odpowiedź na pytanie to w zupełności wystarczyło to co napisał Sergiusz.Łukasz Machowski edytował(a) ten post dnia 27.05.10 o godzinie 10:33

konto usunięte

Temat: Wywołanie metody obiektu zawartego w kolekcji

Tak, wszystko sie zgadza, zalezy jakiego frameworka sie uzywa.

Probowalem cos samemu wymyslec i zaprezentowac, ale wyszlo mniej wiecej to samo co Jarkowi. Chcialem sie jeszcze jakos pozbyc tego nieprzyjemnego if(xxx==null) ale chyba LINQ nie posiada takich mozliwosci.

konto usunięte

Temat: Wywołanie metody obiektu zawartego w kolekcji

Pawel K.:
Probowalem cos samemu wymyslec i zaprezentowac, ale wyszlo mniej wiecej to samo co Jarkowi. Chcialem sie jeszcze jakos pozbyc tego nieprzyjemnego if(xxx==null) ale chyba LINQ nie posiada takich mozliwosci.

A gdzie dokładnie chcesz się tego if pozbyć? może pokaż kawałek kodu.

chodzi o ten kawłek kodu Jarka?:

if(timer == null)

bo jeśli tak to nie znam czegoś takie w linq.
Zawsze możesz wrzucić całoś w try-catch i tam łapać, ewentualnie nie sprawdzać i nie puszczać MyException, bo jeśli będzie null to i tak poleci wyjątek NullReferenceException :) A if wcale nie jest taki nieprzyjemny :)Łukasz Machowski edytował(a) ten post dnia 27.05.10 o godzinie 12:04

konto usunięte

Temat: Wywołanie metody obiektu zawartego w kolekcji

Mialem na mysli cos takiego:

class ExTimer : Timer
{
public int SomeProperty { get; set; }
}
static ArrayList list = new ArrayList();
static void Main(string[] args)
{
list.Add(2);
list.Add(new ExTimer() { SomeProperty = 23 });
list.Add(new ExTimer() { SomeProperty = 1 });

list.OfType<ExTimer>()
.Where(x => x.SomeProperty == 1)
.FirstOrDefault(p =>
{
Console.WriteLine(p.SomeProperty);
return true;
});
}


Przez to ze najpierw w Where() wyfiltrowalismy interesujace obiekty to pozniej w FirstOrDefault() mozna na nich operowac. To co jest parametrem w FirstOrDefault() nie bedzie nullem.

Podchodzi to pod hackowanie LINQ.....

konto usunięte

Temat: Wywołanie metody obiektu zawartego w kolekcji

Trochę chyba wszystkim nam popuszcza fantazja :)

I tak szczerze mówiąc to zastanawia mnie jedno.

Mariusz dlaczego używasz ArrayList ?
Składujesz tam tylko obiekty TwójTimer??

Bo jeśli tak to polecam używać List<TwójTimer>.
Pierwsze masz zapewnione, że w liście są same TwojeTimery :)
Drugie jest zdecydowanie mniej pamięciożerna niż ArrayList, co wręcz gigantycznie można odczuć na systemie 64 bitowym.
Trzecie możesz wtedy bardzo prosto wykonywać wszystkie metody itp. Ponieważ poprzez podanie indeksu masz od razu dostęp do obiektu.


List<MyTimer> timersList = new List<MyTimer>();


wywołanie:


if(timersList.Count -1 >= myIndex)
timersList[myIndex].SomeMethodToDo();


Dlatego moim zdaniem najpierw się zastanów czy ArrayList jest dobrym rozwiązaniem, ale chyba na tej liście masz obiekty tylko jednego typu, a wtedy zrezygnuj z Arraylist.Łukasz Machowski edytował(a) ten post dnia 27.05.10 o godzinie 13:21
Jakub Fila

Jakub Fila Inżynieria / finanse
/ zarządzanie

Temat: Wywołanie metody obiektu zawartego w kolekcji

+ w rozwiązaniu Łukasza pozbywasz się rzutowania. Developer nadmiaru rzutowań, przeszukiwań kolekcji nie zauważy, ale jeśli taka aplikacja ma obsługiwać kilkadziesiąt tysięcy użytkowników, w tym kilkuset z dostępem jednoczesnym, to przy milionach rzutowań, zbyt ciężkich transakcji, setek joinów w każdej procedurze składowanej jesteśmy w stanie przeciążyć każdy system...

Zachęcam do przeglądania starych kodów pisanych w Fortranie,C,Cobolu w latach 80tych i 90tych, nie celem powielania stylu, ale spojrzenia na to, jak programiści radzili sobie z potencjalnymi problemami wydajnościowymi.Jakub Fila edytował(a) ten post dnia 29.05.10 o godzinie 19:46

Następna dyskusja:

iteracja po parametrach met...




Wyślij zaproszenie do