|
Members declared with new will not be visible to the base class. When code in the base class looks for the Data member, it will use its own member, not the "shadowed" member declared by the derived class.
Members which are meant to be overridden in a derived class must be marked as virtual , and overridden properly in the derived class.
Knowing When to Use Override and New Keywords - C# Programming Guide | Microsoft Docs[^]
However, a nested class cannot be marked as "virtual". Instead, you will need to inherit from it. You will also need to use a constructor to overwrite the default field values.
public class BaseClass
{
public class Data
{
public int data1 = 1;
public int data2 = 1;
public string data3 = "BaseString";
}
public Data Value { get; }
public BaseClass()
{
Value = new Data();
}
}
public class DerivedClass : BaseClass
{
public class DerivedData : BaseClass.Data
{
public int data4 = 2;
public DerivedData()
{
data1 = 2;
data2 = 2;
data3 = "DerivedString";
}
}
public DerivedClass()
{
Value = new DerivedData();
}
}
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Hllo,
Thank you very much for the answer, Richard.
Now everything is clear, and sound logic.
I will modify my code as for you suggestions.
Regards,
Giovanni
|
|
|
|
|
See if Richard's excellent response, and this code ... gives you some ideas:
using System;
using System.IO;
using System.Xml.Serialization;
namespace TextToClasses
{
public class BaseClass
{
public class Data
{
public int Data1;
public int Data2;
public string Data3;
public Data()
{
}
public Data(int data1, int data2, string data3)
{
Data1 = data1;
Data2 = data2;
Data3 = data3;
}
}
public Data TheData;
public bool Save(string Filename, Data data)
{
var xs = new XmlSerializer(data.GetType());
using (TextWriter sw = new StreamWriter(Filename))
{
xs.Serialize(sw, data);
}
return File.Exists(Filename);
}
public Data Load(string Filename, Type type)
{
Data rslt;
var xs = new XmlSerializer(type);
using (var sr = new StreamReader(Filename))
{
rslt = (Data) xs.Deserialize(sr);
}
return rslt;
}
}
public class DerivedClass : BaseClass
{
public class DerivedData : BaseClass.Data
{
public int Data4;
public DerivedData()
{
}
public DerivedData(int data4, int data1, int data2, string data3) : base(data1, data2, data3)
{
Data4 = data4;
}
}
}
} Sample usage:
BaseClass bc = new BaseClass();
bc.TheData = new BaseClass.Data(1,1,"BaseString");
bc.Save(@"C:\Users\test_user\Desktop\Basedata.xml", bc.TheData);
var bcdata = bc.Load(@"C:\Users\test_user\Desktop\Basedata.xml", bc.TheData.GetType());
DerivedClass dc = new DerivedClass();
dc.TheData = new DerivedClass.DerivedData(4, 2, 2, "DerivedString");
dc.Save(@"C:\Users\test_user\Desktop\Deriveddata.xml", dc.TheData);
var dcdata = dc.Load(@"C:\Users\test_user\Desktop\Deriveddata.xml", dc.TheData.GetType());
I am sure this can be improved
«One day it will have to be officially admitted that what we have christened reality is an even greater illusion than the world of dreams.» Salvador Dali
|
|
|
|
|
This is the scenario & I was able to make 1/2 of it work: Programmatically launch Outlook 365, send an message & quit Outlook; it must exit. The quitting is the problematic part-- it likes to keep running so I'm thinking I'm not releasing the resources fully forcing it to keep running.
Tons of samples to launch & send a simple message & this is not about that. Outlook 365 has to quit.
This works (simplified for this post though & should be accurate enough): Outlook launches, sends, quits---
using ol = Microsoft.Office.Interop.Outlook;
void Send(string Subject, string EmailBody, string BCC)
{
ol.Application olOutlook = null;
ol.MailItem olMsg = null;
olOutlook = new ol.Application();
olMsg = ( ol.MailItem )olOutlook.CreateItem( ol.OlItemType.olMailItem );
olMsg.BodyFormat = ol.OlBodyFormat.olFormatHTML;
olMsg.HTMLBody = EmailBody;
olMsg.Subject = Subject;
olMsg.Importance = Microsoft.Office.Interop.Outlook.OlImportance.olImportanceNormal;
olMsg.BCC = BCC;
olMsg.Send();
System.Runtime.InteropServices.Marshal.FinalReleaseComObject( olMsg );
olMsg = null;
System.Runtime.InteropServices.Marshal.FinalReleaseComObject( olOutlook.Session );
olOutlook.Quit();
System.Runtime.InteropServices.Marshal.FinalReleaseComObject( olOutlook.Application );
System.Runtime.InteropServices.Marshal.FinalReleaseComObject( olOutlook );
olOutlook = null;
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
Question part 1: Outlook does not quit whenever the EventHandler is subscribed to so the reminders window is suppressed. I'm adding & immediately removing the EventHandler because that's what I've narrowed it down to as the issue for not closing for me. Commenting out the 2 event lines is what's above btw.
using ol = Microsoft.Office.Interop.Outlook;
void Send(string Subject, string EmailBody, string BCC)
{
ol.Application olOutlook = null;
olOutlook.Reminders.BeforeReminderShow += Reminders_BeforeReminderShow;
olOutlook.Reminders.BeforeReminderShow -= Reminders_BeforeReminderShow;
ol.MailItem olMsg = null;
olOutlook = new ol.Application();
olMsg = ( ol.MailItem )olOutlook.CreateItem( ol.OlItemType.olMailItem );
olMsg.BodyFormat = ol.OlBodyFormat.olFormatHTML;
olMsg.HTMLBody = EmailBody;
olMsg.Subject = Subject;
olMsg.Importance = Microsoft.Office.Interop.Outlook.OlImportance.olImportanceNormal;
olMsg.BCC = BCC;
olMsg.Send();
System.Runtime.InteropServices.Marshal.FinalReleaseComObject( olMsg );
olMsg = null;
System.Runtime.InteropServices.Marshal.FinalReleaseComObject( olOutlook.Session );
olOutlook.Quit();
System.Runtime.InteropServices.Marshal.FinalReleaseComObject( olOutlook.Application );
System.Runtime.InteropServices.Marshal.FinalReleaseComObject( olOutlook );
olOutlook = null;
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
The EventHandler:
private void Reminders_BeforeReminderShow(ref bool Cancel)
{
Cancel = true;
}
Part 2 of this question is where I am right now: Once I add an attachment & send the message, Outlook again does not quit.
What am I missing with releasing these resources? Why is adding & then removing this EventHandler causing issues with quitting Outlook? This is tricky because there are a gazillion "how to send mail" posts but much fewer "how to send mail & quit Outlook" posts.
Also, anything related to killing a task is not being considered because that's a dirty shutdown & will only cause deeper issues with mailboxes etc. over time, so don't post it as a solution.
Thank you

|
|
|
|
|
|
Are you trying to use this is a service or web app (ASP.NET, MVC, ...)?
|
|
|
|
|
I would be surprised if this has anything to do with your code and resources, I suspect MS have organised Outlook to stay awake despite your .Quit - is there a .Exit?
I often find outlook remains running in the background after closing the app (not using code). So much so that I have to end the task to restart outlook.
Never underestimate the power of human stupidity -
RAH
I'm old. I know stuff - JSOP
|
|
|
|
|
Hi, I apologize if a solution for something like this has been posted somewhere in the forums already. I've looked.
I have a large string which will include text such as:
"..just random text 5:43 and more random text 9:25..and even more random text 3:00.."
I'd like to be able to store these times in an array or even just get each as an individual string. I've thought about searching the text for colons and just getting the two characters before and after each. Any help would be greatly appreciated. Thanks in advance.
|
|
|
|
|
|
Thank you Richard. I was able to put a regular expression together which was rather long and ugly but did exactly what I needed. Much appreciated.
|
|
|
|
|
Why is it long? A Regex to extract the times is pretty trivial:
[012]?\d:\d\d would work,or even
\d:\d\d if the time is midnight - ten AM (less one second)
For real accuracy it should be
[012]?\d:[0-5]\d to prevent 15:67 being accepted, but ...
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
|
Ah - you run on Mercury time: no problemo ... one alarm set for October ...
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
That's why I'd probably stick with [012]?\d:\d\d - then post process the Matches collection to eliminate bad times. Much simpler, cleaner and more obvious than the "full on" regex! (And a whole load easier to maintain when the requirement changes)
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Yep. The one I find a perpetual PITA is dotted decimal IPv4 addresses, particularly if you allow for all the corner cases. And as for IPv6, the less said the better.
Software rusts. Simon Stephenson, ca 1994. So does this signature. me, 2012
|
|
|
|
|
Thanks folks, really appreciate the responses.
OriginalGriff wrote: Why is it long? A Regex to extract the times is pretty trivial:
It was long because I am pretty new to regular expressions and really just needed to get it done, rather than work on the most efficient expression. But thanks to you guys, I now have a much more effective way to do it. Since last night I have read up on the topic more and have a better grasp.
Thanks again!
free-pizza
|
|
|
|
|
If you are going to use Regular Expressions - and it's a good idea sometimes - then get a copy of Expresso[^] - it's free, and it examines, tests, and generates Regular expressions.
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Got an odd one I could do with some advice on...
I have a base form all my decendent data entry forms are based on. The base form had some menus defined on it with icons on the various menu options. This means all the child data entry forms have them too. So far so good.
I decided to update the icons on the base form, thinking this change would automatically cascade down to all the child forms but no, they don't. When I open the resources file for each child form, they have a separate copy of the icons.
Why would this be - surely it defeats the whole point of visual inheritance?
Any suggestions on how I can update all the icons on the child forms to match? I can't go through them one by one and manually adjust as I have several hundred forms in the application.
Many thanks.
|
|
|
|
|
Did you do a rebuild? Or just recompile?
|
|
|
|
|
|
It's really strange - when I create a really simple project with just 2 forms - a parent and inherited child, it behaves correctly.
|
|
|
|
|
OK, I just tried it: A MainForm and a BaseForm from which it derives.
I add a small menu strip to the BaseForm, and assign Image properties to each menu item.
Derive the MainForm from BaseForm, and run it: MainForm has the menus, with the correct icons.
Check the Image for one of the BaseForm menu items, run it again: the menus are there, and are using the new images.
So what am I doing that is different from you?
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Thanks for the response. I don't know. On my simple test it also worked. But on my application that hundred of forms and a quite complex set of base forms it doesn't work. Really at a loss.
|
|
|
|
|
Are you running a single project solution, or are these mixed across assemblies?
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Running across multiple assemblies.
I think I may have got to the bottom it. I created a brand new inherited form from the base form and it behaved correctly. On comparing the designer.cs code of the new form with one of my original (problematic) inherited forms, it looks like a load of extra code has been inserted into the code behind the designers.
For Example:
//
// bsiAdd
//
this.bsiAdd.ImageOptions.Image = ((System.Drawing.Image)(resources.GetObject("bsiAdd.ImageOptions.Image")));
This seems to have also pushed the images into the resx file. If I remove all the bits of code for about 50 menu items then remove the images manually from the resx file then the inheritance seems to work properly.
The only thing I can think of which might have caused this is I put a DevExpress SharedImageCollection onto my main window form and I'm thinking that the nature of this control has perhaps caused this.
Issue I have now is I have to apply my manual fix to several hundred forms!
modified 27-Aug-20 10:07am.
|
|
|
|