Forum » Programiranje » c# base class, derived class, inheritance problem
c# base class, derived class, inheritance problem
Vapo1 ::
naredil sem derived class ker sem hotel dodati se neke svoje lastnosti(npr LastPingTime) classu TcpClient...
problem je potem ko bi rad uporabljal funkcije ki ti returnajo base class... in bi jaz rad ta base class assignal na moj derived class(kar ne gre.. obratno pa mislim da gre)
edina resitev ki jo jaz poznam je da ne naredim derived classa ampak da naredim svoj class obican class ki notir vsebuje "base class" in potem ta "base class" javno exposeam (in po tem ga lahko po mili volji assignam)...
ali pa da ta base class pustim private.. in javno exposeam vse metode od tega base classa ki jih hocem imeti javne
a ima kdo kaksno boljso idejo?..
poglejte kodo prosim.. in upam da bo jasno
(TcpListener.AcceptTcpClient je funkcija ki bi jo rad uporabil ampak mi returna class tipa TcpClient (ki je base class od mojega derived classa.. in ga zato ne morem assignat na moj derived class)
//*****************************KODA***********funkcija accepta cliente ki se hocejo connectat in jih doda v listo*************//
class MojDerivedTcpClient : TcpClient
{
public DateTime LastPingTime; //to je lastnost ki bi jo rad dodal ... zato sem sel delati derived class
}
FunkcijaGlavna()
{
List#MojDerivedTcpClient# ListaClientov = new List#MojDerivedTcpClient #();//nevem zakaj mi tukaj na slotech ni ratalo dati puščičastih oklepajov.. pa sem dal #
TcpListener TL = new TcpListener(6666);
TL.Start();
while(TL.Pending())
{
MojDerivedTcpClient MTC = (MojDerivedTcpClient)TL.AcceptTcpClient(); //TUKAJ V TEJ VRSTICI JE PROBLEM..(noce se assignat)
//...TcpListener.AcceptTcpClient returna TcpClient (ki je base class od MojDerivedTcpClient) !!!!
MTC.LastPingTime = DateTime.Now;
ListaClientov.Add(MTC);
}
}
//*****************************KONEC KODE***********//
probal sem razne fore npr narediti funkcijo ki bi assignala base class z zunanjim classom:
//*****************************KODA***********//
class MojDerivedTcpClient : TcpClient
{
public DateTime LastPingTime;
public AssignTcpClient(TcpClient TC)
{
base = TC;
}
}
//*****************************KONEC KODE***********//
valda ni delalo....
ena resitev ki jo vidim je da ne naredim derived classa.. ampak da "parent" class vsebuje TcpClient clas in da exposeam vsako funkcijo posebej:
//*****************************KODA***********//
class MojDerivedTcpClient //tokrat ni base classa(in class tokrat ni derived)
{
public DateTime LastPingTime;
private TcpClient TC_;
public AssignTcpClient(TcpClient TC_)
{
TC = TC_;
}
public Connect(IPEndPoint)
{
TC.Connect(IPEndPoint);
}
public Close()
{
TC.Close
}
..
..//in tako vse funkcije ki jih rabim
..
}
//*****************************KONEC KODE***********//
seveda to nikamor ne pelje... lazje je ce kar exposeam celoten TcpClient class:
//*****************************KODA***********//
class MojDerivedTcpClient //tokrat ni base classa(in class tokrat ni derived)
{
public DateTime LastPingTime;
public TcpClient TC;
}
FunkcijaGlavna()
{
List#MojDerivedTcpClient# ListaClientov = new List#MojDerivedTcpClient #();
TcpListener TL = new TcpListener(6666);
TL.Start();
while(TL.Pending())
{
MojDerivedTcpClient MTC = new MojDerivedTcpClient();
MTC.TC = TL.AcceptTcpClient();
MTC.LastPingTime = DateTime.Now;
ListaClientov.Add(MTC);
}
}
//*****************************KONEC KODE***********//
problem je potem ko bi rad uporabljal funkcije ki ti returnajo base class... in bi jaz rad ta base class assignal na moj derived class(kar ne gre.. obratno pa mislim da gre)
edina resitev ki jo jaz poznam je da ne naredim derived classa ampak da naredim svoj class obican class ki notir vsebuje "base class" in potem ta "base class" javno exposeam (in po tem ga lahko po mili volji assignam)...
ali pa da ta base class pustim private.. in javno exposeam vse metode od tega base classa ki jih hocem imeti javne
a ima kdo kaksno boljso idejo?..
poglejte kodo prosim.. in upam da bo jasno
(TcpListener.AcceptTcpClient je funkcija ki bi jo rad uporabil ampak mi returna class tipa TcpClient (ki je base class od mojega derived classa.. in ga zato ne morem assignat na moj derived class)
//*****************************KODA***********funkcija accepta cliente ki se hocejo connectat in jih doda v listo*************//
class MojDerivedTcpClient : TcpClient
{
public DateTime LastPingTime; //to je lastnost ki bi jo rad dodal ... zato sem sel delati derived class
}
FunkcijaGlavna()
{
List#MojDerivedTcpClient# ListaClientov = new List#MojDerivedTcpClient #();//nevem zakaj mi tukaj na slotech ni ratalo dati puščičastih oklepajov.. pa sem dal #
TcpListener TL = new TcpListener(6666);
TL.Start();
while(TL.Pending())
{
MojDerivedTcpClient MTC = (MojDerivedTcpClient)TL.AcceptTcpClient(); //TUKAJ V TEJ VRSTICI JE PROBLEM..(noce se assignat)
//...TcpListener.AcceptTcpClient returna TcpClient (ki je base class od MojDerivedTcpClient) !!!!
MTC.LastPingTime = DateTime.Now;
ListaClientov.Add(MTC);
}
}
//*****************************KONEC KODE***********//
probal sem razne fore npr narediti funkcijo ki bi assignala base class z zunanjim classom:
//*****************************KODA***********//
class MojDerivedTcpClient : TcpClient
{
public DateTime LastPingTime;
public AssignTcpClient(TcpClient TC)
{
base = TC;
}
}
//*****************************KONEC KODE***********//
valda ni delalo....
ena resitev ki jo vidim je da ne naredim derived classa.. ampak da "parent" class vsebuje TcpClient clas in da exposeam vsako funkcijo posebej:
//*****************************KODA***********//
class MojDerivedTcpClient //tokrat ni base classa(in class tokrat ni derived)
{
public DateTime LastPingTime;
private TcpClient TC_;
public AssignTcpClient(TcpClient TC_)
{
TC = TC_;
}
public Connect(IPEndPoint)
{
TC.Connect(IPEndPoint);
}
public Close()
{
TC.Close
}
..
..//in tako vse funkcije ki jih rabim
..
}
//*****************************KONEC KODE***********//
seveda to nikamor ne pelje... lazje je ce kar exposeam celoten TcpClient class:
//*****************************KODA***********//
class MojDerivedTcpClient //tokrat ni base classa(in class tokrat ni derived)
{
public DateTime LastPingTime;
public TcpClient TC;
}
FunkcijaGlavna()
{
List#MojDerivedTcpClient# ListaClientov = new List#MojDerivedTcpClient #();
TcpListener TL = new TcpListener(6666);
TL.Start();
while(TL.Pending())
{
MojDerivedTcpClient MTC = new MojDerivedTcpClient();
MTC.TC = TL.AcceptTcpClient();
MTC.LastPingTime = DateTime.Now;
ListaClientov.Add(MTC);
}
}
//*****************************KONEC KODE***********//
- spremenilo: Vapo1 ()
darkolord ::
Katero napako pa dobiš, ko narediš tole:
MojDerivedTcpClient MTC = (MojDerivedTcpClient)TL.AcceptTcpClient();
MojDerivedTcpClient MTC = (MojDerivedTcpClient)TL.AcceptTcpClient();
Vapo1 ::
hej darko... moj najljubši znalec na slotech... sem upal na tvoj insight...
ce ne naredim casta.. torej:
MojDerivedTcpClient MTC = TL.AcceptTcpClient();
mi ze pri compiletime pribije:
Cannot implicitly convert type 'System.Net.Sockets.TcpClient' to 'Test_NetKomunikacije_SingleThreadVse.MojDerivedTcpClient'. An explicit conversion exists (are you missing a cast?)
ce pa naredim cast.. torej:
MojDerivedTcpClient MTC = (MojDerivedTcpClient)TL.AcceptTcpClient();
se lepo scompila in mi v runtime pribije:
System.InvalidCastException was unhandled
Message="Unable to cast object of type 'System.Net.Sockets.TcpClient' to type 'Test_NetKomunikacije_SingleThreadVse.MojDerivedTcpClient'.
...
koda v tem primeru je derived class.. torej:
class MojDerivedTcpClient : TcpClient
{
public TimeSpan LastPingTime;
}
ce ne naredim casta.. torej:
MojDerivedTcpClient MTC = TL.AcceptTcpClient();
mi ze pri compiletime pribije:
Cannot implicitly convert type 'System.Net.Sockets.TcpClient' to 'Test_NetKomunikacije_SingleThreadVse.MojDerivedTcpClient'. An explicit conversion exists (are you missing a cast?)
ce pa naredim cast.. torej:
MojDerivedTcpClient MTC = (MojDerivedTcpClient)TL.AcceptTcpClient();
se lepo scompila in mi v runtime pribije:
System.InvalidCastException was unhandled
Message="Unable to cast object of type 'System.Net.Sockets.TcpClient' to type 'Test_NetKomunikacije_SingleThreadVse.MojDerivedTcpClient'.
...
koda v tem primeru je derived class.. torej:
class MojDerivedTcpClient : TcpClient
{
public TimeSpan LastPingTime;
}
Zgodovina sprememb…
- spremenilo: Vapo1 ()
Vapo1 ::
vbistvu je tole ista fora.. samo na malo bolj simple primeru...
class MojList : List#int#
{
public DateTime Time_LastElementAdded;
}
FunkcijaGlavna()
{
List#int# L = new List#int# { 1, 2, 3, 4, 5 };
MojList ML = (MojList)L;
}
in ista zgodba.. dobim runtime error... "unable to cast"
class MojList : List#int#
{
public DateTime Time_LastElementAdded;
}
FunkcijaGlavna()
{
List#int# L = new List#int# { 1, 2, 3, 4, 5 };
MojList ML = (MojList)L;
}
in ista zgodba.. dobim runtime error... "unable to cast"
Genetic ::
Namesto
List#int# L = new List#int# { 1, 2, 3, 4, 5 };
MojList ML = (MojList)L;
daj
List#int# L = new MojList { 1, 2, 3, 4, 5 };
MojList ML = (MojList)L;
List#int# L = new List#int# { 1, 2, 3, 4, 5 };
MojList ML = (MojList)L;
daj
List#int# L = new MojList { 1, 2, 3, 4, 5 };
MojList ML = (MojList)L;
d-mon ::
//base ima dober konstruktor, ki ga lahko uporabis tukaj
class MojList : List<int>
{
public MojList(IEnumerable<int> collection) : base(collection) { }
public DateTime Time_LastElementAdded { get; set; }
}
//TcpClient nima pametnega konstruktorja in je tudi inherit samo od IDisposable...kar pomeni, da ga ne mores kar tako prekopirat (razen property by property, pa se te samo public -- ce ne uporabis reflection). Zato najbolj da naredis takole. Tako imas vse podatke shranjene in kaj bi kompliciral z inheriti ce ni treba? Po moje itak nikol ne bos na dol castal. Ce hoces to raje uporabis instancaMojTcpClient.Client in je. Jako tezko :) Komplicirej tam kjer je treba.
class MojTcpClient
{
public MojTcpClient(TcpClient c, DateTime lpt)
{
Client = c;
LastPingTime = lpt;
}
public TcpClient Client { get; private set; }
public DateTime LastPingTime { get; private set; }
}
class Program
{
static void Main(string[] args)
{
List<int> L = new List<int> { 1, 2, 3, 4, 5 };
MojList l = new MojList(L);
TcpListener TL = new TcpListener(6666);
TL.Start();
while (TL.Pending())
{
MojTcpClient MTC = new MojTcpClient(TL.AcceptTcpClient(), DateTime.Now);
}
}
}
class MojList : List<int>
{
public MojList(IEnumerable<int> collection) : base(collection) { }
public DateTime Time_LastElementAdded { get; set; }
}
//TcpClient nima pametnega konstruktorja in je tudi inherit samo od IDisposable...kar pomeni, da ga ne mores kar tako prekopirat (razen property by property, pa se te samo public -- ce ne uporabis reflection). Zato najbolj da naredis takole. Tako imas vse podatke shranjene in kaj bi kompliciral z inheriti ce ni treba? Po moje itak nikol ne bos na dol castal. Ce hoces to raje uporabis instancaMojTcpClient.Client in je. Jako tezko :) Komplicirej tam kjer je treba.
class MojTcpClient
{
public MojTcpClient(TcpClient c, DateTime lpt)
{
Client = c;
LastPingTime = lpt;
}
public TcpClient Client { get; private set; }
public DateTime LastPingTime { get; private set; }
}
class Program
{
static void Main(string[] args)
{
List<int> L = new List<int> { 1, 2, 3, 4, 5 };
MojList l = new MojList(L);
TcpListener TL = new TcpListener(6666);
TL.Start();
while (TL.Pending())
{
MojTcpClient MTC = new MojTcpClient(TL.AcceptTcpClient(), DateTime.Now);
}
}
}
[D-mon]
Genetic ::
Metoda TcpListener.AcceptTcpClient vrne instanco TcpClienta. Le-tega generira system in ga ne mores downcastati na MojDerivedTcpClient, ker sploh ni takega tipa.
Naredi tako, da bo MojDerivedTcpClient vseboval argument tipa TcpClient, in ko ga metoda TcpListener.AcceptTcpClient ustvari, ustvari nov objekt tipa MojDerivedTcpClient (s pomocjo konstruktorja, ki sprejme kot vhodni argument TcpClient.
Potem pa se v classu MojDerivedTcpClient napises vse metode, preko katerih posredujes delo na vsebovani TcpClient.
Namesto
MojDerivedTcpClient MTC = (MojDerivedTcpClient)TL.AcceptTcpClient(); //TUKAJ V TEJ VRSTICI JE PROBLEM..(noce se assignat)
daj
MojDerivedTcpClient MTC = new MojDerivedTcpClient(TL.AcceptTcpClient());
Lahko se dodas implicitni cast operator na TcpClienta v MojDerivedTcpClient:
public static implicit operator TcpClient(MojDerivedTcpClient md) { return md.m_tcpClient; );
Naredi tako, da bo MojDerivedTcpClient vseboval argument tipa TcpClient, in ko ga metoda TcpListener.AcceptTcpClient ustvari, ustvari nov objekt tipa MojDerivedTcpClient (s pomocjo konstruktorja, ki sprejme kot vhodni argument TcpClient.
Potem pa se v classu MojDerivedTcpClient napises vse metode, preko katerih posredujes delo na vsebovani TcpClient.
Namesto
MojDerivedTcpClient MTC = (MojDerivedTcpClient)TL.AcceptTcpClient(); //TUKAJ V TEJ VRSTICI JE PROBLEM..(noce se assignat)
daj
MojDerivedTcpClient MTC = new MojDerivedTcpClient(TL.AcceptTcpClient());
Lahko se dodas implicitni cast operator na TcpClienta v MojDerivedTcpClient:
public static implicit operator TcpClient(MojDerivedTcpClient md) { return md.m_tcpClient; );
darkolord ::
Genetic: Nah, operatorja iz base classa ne morš met.
Vapo1: tko kot je reku d-mon, probaj samo nastavit property Client (s tem da lahko tudi kar direkt):
P.S. za kodo pastat lahko uporabis st.koda tag (v oglatih [ ] oklepajih)
Vapo1: tko kot je reku d-mon, probaj samo nastavit property Client (s tem da lahko tudi kar direkt):
MojDerivedTcpClient MTC = new MojDerivedTcpClient() MTC.Client = TL.AcceptTcpClient().Client;
P.S. za kodo pastat lahko uporabis st.koda tag (v oglatih [ ] oklepajih)
Zgodovina sprememb…
- spremenilo: darkolord ()
Genetic ::
Genetic: Nah, operatorja iz base classa ne morš met.
Saj MojDerivedTcpClient ne bo vec inherital iz TcpClienta ampak do vseboval instanco kot private argument.
(tako da je ime MojDerivedTcpClient sedaj nesmiselno, boljse je samo MojTcpClient)
Vapo1 ::
ok... hvala dragi ljudje...
ocitno ne bo nic z derived forami... in bom kar lepo naredil public TcpClient TC.. in je...
sem se pa nekaj naucil od vasih postov... o implicit operatorjih...
hvala
ocitno ne bo nic z derived forami... in bom kar lepo naredil public TcpClient TC.. in je...
sem se pa nekaj naucil od vasih postov... o implicit operatorjih...
hvala
Vredno ogleda ...
Tema | Ogledi | Zadnje sporočilo | |
---|---|---|---|
Tema | Ogledi | Zadnje sporočilo | |
» | OpenVPN na DD-WRTOddelek: Omrežja in internet | 956 (753) | ExSpirit |
» | Socket ServerOddelek: Programiranje | 2443 (1636) | fx |
» | [C#] Client -> Server komunikacija dela, kako je pa z Server -> Client?Oddelek: Programiranje | 1285 (1151) | Mitja Bonča |
» | [Visual C#] zaradi while zanke se ne pokaže oknoOddelek: Programiranje | 1002 (879) | Fresh-Grass |
» | [Delphi] client serverOddelek: Programiranje | 1277 (1136) | jvolk |