Jak zwrócić obiekt nieznanego typu?

0

Witam,
Czy wie ktoś jak można w metodzie zwrócić obiekt nieznanego typu? Czy jest to mozliwe w C#?
Chodzi mi mniej więcej o coś takiego jak mam np:

// to sie znajduje w aplikacji konsolowej (serwer)
using Biblioteka;

public class Klasa : MarshalByRefObject, IKlasa
{
   public MojObiekt ReturnObiekt()
   {
     return new MojObiekt();
   }
}

[Serializable]
public class MojObiekt
{
   public void Metoda()
   {
      ...
   }
}
// a to jest interfejs w dołączonej bibliotece Biblioteka
public interface IKlasa
{
   MojObiekt ReturnObiekt();
}

ale niestety to nie działa ponieważ w bibliotece z interfejsem nie rozpoznaje typu MojObiekt, do tego nie moge w żaden sposób do biblioteki dodać referencji do projektu aplikacji konsolowej(serwera). Próbowałem zamienić w:

MojObiekt ReturnObiekt();

typ MojObiekt na Object, to samo w definicji:

public Object ReturnObiekt()
   {
     return new MojObiekt();
   }

i to sie kompiluje ale pożniej i tak są błędy więc nie działa poza tym tam gdzie to zwraca już jest nierozpoznawane jako MojObiekt. Tak więc czy istnieje w C# jakieś słowo kluczowe lub jakaś klasa która umożliwia takie przesyłanie obiektów z jednej aplikacji do drugiej?
Próbowałem jeszcze z ObjectHandle ale to chyba nie to bo też jakieś błędy były.

Z góry dziekuje za odp
Pozdrawiam

0

Problemem jest to, że jeśli używasz [Serializable] to musisz mieć całą definicję obiektu jak i również podobiektów w programie klienckim.

W zależności od tego co zamierzasz:

  1. Gdy chcesz zdalnie korzystać z obiektu, to po prostu usuń linijkę [Serializable] i wszystko powinno działać

  2. Gdy chcesz utworzyć kopie obiektu w programie klienckim (przesłać), to musisz całą definicję przenieść do pliku dll:

// a to jest interfejs w dołączonej bibliotece Biblioteka
public interface IKlasa
{
   MojObiekt ReturnObiekt();
}
[Serializable]
public class MojObiekt
{
   public void Metoda()
   {
      ...
   }
}

Tylko mając pełną definicję program kliencki będzie mógł odbudować obiekt.

0
Remote napisał(a)

Witam,
Czy wie ktoś jak można w metodzie zwrócić obiekt nieznanego typu? Czy jest to mozliwe w C#?

Wszystkie klasy dziedziczą po System.Object.

Remote napisał(a)

ale niestety to nie działa ponieważ w bibliotece z interfejsem nie rozpoznaje typu MojObiekt, do tego nie moge w żaden sposób do biblioteki dodać referencji do projektu aplikacji konsolowej(serwera).

To może jednak "MojObiekt" powinien być zdefiniowany w tej bibliotece? Tak na logikę...

Remote napisał(a)

i to sie kompiluje ale pożniej i tak są błędy więc nie działa poza tym tam gdzie to zwraca już jest nierozpoznawane jako MojObiekt.

Rzutowanie? Operator as?

...
object ReturnObject()
...
MojObiekt pupa = (MojObiekt) cośtam.ReturnObject();
MojObiekt kupa = cośtam.ReturnObject() as MojObiekt;
0

Może tak:

public T ReturnAnyObiekt<T>() where T:new(){
    return new T();
}

Wywołanie:

MojObiekt mo = ReturnAnyObiekt<MojObiekt>();
0

Jest to dobre rozwiązanie, ale nie zapominajcie tego co napisałem, program po rzutowaniu będzie musiał obiekt odbudować, więc jeśli używasz serializacji, to musisz posiadać w kliencie również pełną definicję obiektu. Miałem też podobny problem kiedyś, to wiem. Musiałem przesłać zrobiony przez siebie obiekt zawierający kilka stringów i inta, no i konieczne było umieszczenie go w pliku dll.

0

wielkie dzięki sprawdze wszystkie mozliwości, Hubert jak zwraca int i stringa to nie ma najmniejszego problemu żeby przesłać do klienta tak jak pisałem i wykonać lokalnie i nie trzeba umieszczać wówczas w pliku dll, wystarczy sam interfejs ale z własna klasą juz jest problem, tak czy inaczej jak widze że klient zaczyna laczyc sie z localhostem przy odbiorze danej klasy to juz jest dobrze ^^

0

sry że sie pod postem dopisuje ale zapomnialem dodać , właśnie zależy mi na tym aby nie dołączać mojego obiektu w pliku dll, w przypadku w którym mam swoj obiekt w pliku dll (który posiada zarówno klient i serwer) nie ma problemu z przesłaniem a właściwie nawet nie trzeba przesyłać obiektu żeby go uzyc w kliencie a ja chce aby osoba posiadająca klienta nie znała implementacji danego obiektu dopoki nie polaczy sie z serwerem

0

W takim przypadku pozostaje tylko usunąć serializację zwracanego obiektu i odziedziczyć go po MarshalByRefObject, tka jak napisałeś to w przypadku klasy Klasa:

// to sie znajduje w aplikacji konsolowej (serwer)
using Biblioteka;

public class Klasa : MarshalByRefObject, IKlasa
{
   public MojObiekt ReturnObiekt()
   {
     return new MojObiekt();
   }
}

//[Serializable] - to usuwasz
public class MojObiekt: MarshalByRefObject, IMojObiekt // to dopisujesz
{
   public void Metoda()
   {
      ...
   }
}

wtedy udostępnić musisz w bibliotece tylko interfejs IMojObiekt

0

Przepraszam zapomnieałem dodac że metoda musi wykonać sie lokalnie dla klienta, w przypadku w którym zdejmuje serializacje i dziedzicze MBR wszytko wykona sie po stronie serwera a ja chce serwer odciązyć w ten sposób czyli zwracając MojObiekt do klienta i odbierajac go w kliencie var obiekt .... dlatego zapytalem na poczatku czy to jest w ogóle mozliwe zeby po prostu przekopiować z jednej domeny aplikacyjnej do drugiej majać w zdalnej bibliotece jedynie interfejs z funkcja zwracającą dany obiekt

0

Nie, to nie jest możliwe, no chyba, że byś się pobawił w refleksję, ale nie wiem, czy to zadziała.

0

Wielkie dzieki na pewno sprawdze, własnie chciałem sie upewnić czy to możliwe bo remoting dopiero zaczynam sie uczyć jeżeli to nie zadziała to juz sobie dam z tym spokój bo juz pare dni próbuje znaleźć jakieś rozwiązanie
Pozdrawiam

0
Remote napisał(a)

sry że sie pod postem dopisuje ale zapomnialem dodać , właśnie zależy mi na tym aby nie dołączać mojego obiektu w pliku dll, w przypadku w którym mam swoj obiekt w pliku dll (który posiada zarówno klient i serwer) nie ma problemu z przesłaniem a właściwie nawet nie trzeba przesyłać obiektu żeby go uzyc w kliencie a ja chce aby osoba posiadająca klienta nie znała implementacji danego obiektu dopoki nie polaczy sie z serwerem

mozesz wiec napisac klienta tak, zeby laczyl sie z serwerem, ściągał z niego DLL'kę w postaci tablicy bajtow, NIE zapisywal jej nigdzie na dysku, tylko potraktowal ja Assembly.Load et voil'a, juz masz DLL'ke zaladowana i wszystkie jej typy "znane". W runtime'ie. Czyli od momentu zaladowania jej, wszystkie deserializacje obiektow ktore w tej DLL sa zdefiniowane sie powioda.

A co to da..?

Wydziel ze swojego fragmentu serwera definicje tych serializowanych obiektow do oddzielnego classlibrary. Jesli rzeczywiscie byly napisane pod serializacje poprawnie - nie powinno byc z tym problemow, bo beda mialy referencje tylko do typow/interfejsow znanych klientowi. I juz masz DLL'ke do wyslania klientowi na w/w rozruchowe żądanie - a serwer niech sobie ja "linkuje statycznie"..

0

quetzalcoatl, dzieki że to napisałeś! [browar] dopiero teraz zobaczyłem ten post, właśnie o czyms takim myślałem ale nie wiedziałem za bardzo jak sie za to zabrać i czy to jest mozliwe(zastanawiałem się właśnie skąd by miałby byc znane podczas pisania kodu konkretne definicje poszczegolnych metod bez dodawania referencji) aby pobrac klientem dllke i wczytać dynamicznie w pamięci bez zapisywania na dysku, szukałem wcześniej w necie jakis przykładów jak załadować dllke dynamicznie ale dużo nie znalazłem, tak czy inaczej jeżeli tylko jest to mozliwe to postaram sie to napisać, nie znasz moze jakiś przykładów które by się przydały do tego?

0

Skoro poruszamy już temat dynamicznego ładowania DLLek, to mam pytanie. Czy istnieje sposób na takie zbudowanie biblioteki, aby program mógł ją załadować wiedząc jedynie, że zawiera klasę dziedzicząca po pewnym interfejsie i wczytywać dowolną ilość tego typu bibliotek. W skrócie mam na myśli coś w rodzaju folderu z pluginami.

0

A nie wystarczyło wklepać do szukajki "plugin"?
http://4programmers.net/Forum/505684#id505684
W moim przykładzie szukam klas, które dziedziczą po klasie abstrakcyjnej MailClient, ale z interfejsem również zadziała.

1 użytkowników online, w tym zalogowanych: 0, gości: 1