|
There's the ?? operator, I assume it would work when you call a method. But, in C# all classes are references. And, you can pass null through that function anyhow, so you can't do that in C#.
You have the ref keyword but it only works on value types. You can put 'ref' on a class param, but it makes no difference, it was a reference to start with
Christian Graus
Please read this if you don't understand the answer I've given you
"also I don't think "TranslateOneToTwoBillion OneHundredAndFortySevenMillion FourHundredAndEightyThreeThousand SixHundredAndFortySeven()" is a very good choice for a function name" - SpacixOne ( offering help to someone who really needed it ) ( spaces added for the benefit of people running at < 1280x1024 )
|
|
|
|
|
Christian Graus wrote: You have the ref keyword but it only works on value types
Can you explain? String is a predefined reference type, but when passed as a parameter, it is passed by value. To change the string, you have to explicitly mark it as ref in the signature
namespace RefChecker
{
class Program
{
static void changeMyString1(string myString)
{
myString += " worked";
}
static void changeMyString2(ref string myString)
{
myString += " worked";
}
static void Main(string[] args)
{
string string1 = "has it";
string string2 = "has it";
changeMyString1(string1);
changeMyString2(ref string2);
Console.WriteLine(string1);
Console.WriteLine(string2);
}
}
}
Knowledge is hereditary, it will find its way up or down.
Luc Pattyn
and since what every time when i want to add button to this control one add two times
posted in C# forum
|
|
|
|
|
The string class is a special case in a number of ways. Any other class, is passed by ref, always.
Christian Graus
Please read this if you don't understand the answer I've given you
"also I don't think "TranslateOneToTwoBillion OneHundredAndFortySevenMillion FourHundredAndEightyThreeThousand SixHundredAndFortySeven()" is a very good choice for a function name" - SpacixOne ( offering help to someone who really needed it ) ( spaces added for the benefit of people running at < 1280x1024 )
|
|
|
|
|
Christian Graus wrote: You have the ref keyword but it only works on value types. You can put 'ref' on a class param, but it makes no difference, it was a reference to start with
No, it does make a difference. If you pass a reference type with "ref", you are essentially passing a reference to the reference (something like a pointer to a pointer in C++). For example.
class A
{
public int x;
}
void Method()
{
A a = new A();
M1(ref a);
Console.WriteLine(a.x);
a = new A();
M2(a);
Console.WriteLine(a.x);
}
void M1(ref A a)
{
a = new A();
a.x = 1;
}
void M2(A a)
{
a = new A();
a.x = 2;
}
M1 takes a by ref and therefore assigning to a changes the reference itself. M2 takes a by value, so changing a doesn't change the a in Method.
|
|
|
|
|
:applause:
I can't believe how few people know about this. And I'm far from being a guru myself.
Cheers,
Vikram.
The hands that help are holier than the lips that pray.
|
|
|
|
|
You are actually assigned a new reference here, not changing the object the reference refers to. Try this...
class Program
{
class MyClass
{
public int x;
}
static void changeMyClass1(MyClass myClass )
{
myClass.x = 100;
}
static void changeMyClass2(ref MyClass myClass )
{
myClass.x = 100;
}
static void Main(string[] args)
{
MyClass instance1 = new MyClass();
MyClass instance2 = new MyClass();
instance1.x = 0;
instance2.x = 0;
changeMyClass1(instance1);
changeMyClass2(ref instance2);
Console.WriteLine(instance1.x);
Console.WriteLine(instance2.x);
}
}
Like CG said, they are by ref, by default. Both instances will change. Strings behave differently, which, in my opinion is bad.
Knowledge is hereditary, it will find its way up or down.
Luc Pattyn
and since what every time when i want to add button to this control one add two times
posted in C# forum
|
|
|
|
|
Malcolm Smart wrote: Like CG said, they are by ref, by default. Both instances will change.
Yes, but as you pointed out, passing the parameter with "ref" allows you to change the reference itself - which is different from changing the object being referenced. In your example, both methods only change the object being referenced, and there is no difference in that case.
My point was passing reference types for "ref" has a different meaning than passing them without "ref".
And strings don't behave differently - strings are immutable reference types. In your example,
static void changeMyString1(string myString)
{
myString = mystring + " worked";
}
static void changeMyString2(ref string myString)
{
myString = mystring + " worked";
}
the second method takes myString by ref, and therefore changes the reference itself. After both methods have executed, mystring will be referring to a new string object with " worked" concatentated. By passing myString as ref in the second method, the "original" myString that was passed to changeMyString2 changes to refer to the new string object. The first method doesn't take myString by ref, and therefore the original myString passed doesn't change.
If you know C++, the following piece of code demonstrates the difference.
int global = 10;
void Test()
{
int val = 0;
int *p = &val;
Method2(p);
Method1(&p);
}
void Method1(int **p)
{
*p = &g;
}
void Method2(int *p)
{
p = &g;
}
You can consider p to be equivalent to a reference type. Method2 is equivalent to not passing with "ref", and Method1 is equivalent to passing with "ref". Changing p inside Method2 doesn't affect p in Test, but changing *p in Method1 does.
|
|
|
|
|
Christian Graus wrote: You have the ref keyword but it only works on value types. You can put 'ref' on a class param, but it makes no difference, it was a reference to start with
In addition to what Senthil said, it helps to think of it like this: if you pass an object as you would regularly do, it gets passed by reference, but that reference is passed by value; if you pass an object by ref , the reference is passed by reference.
That's how my Java friend taught me (it's the same in magical Javaland). It looks like codswallop, but it really works wonders once you get the hang of it.
Cheers,
Vikram.
The hands that help are holier than the lips that pray.
|
|
|
|
|
As mentioned, that won't even work in C++.
However, this[^] article is my attempt to accomplish that in C#. See the comments for other ideas.
|
|
|
|
|
I have a multi-service service application that implements multiple services. Some of the settings in the app.config file are used by each service, some are "overridden" for these services, and yet more are completely unique to a given service.
I've come up with (what I think) is a relatively simple method for supporting this kind of app.config usage (and I'm writing an article about it), but I'm sure there is at least one more .Net-centric approach to the problem.
I googled this problem and found at least one method that requires writing setting-specific classes that access sections and sectiongroups within the app.config file. I decided that this requires WAY too much effort on the part of the programmer because not only do you need to heavily modify the app.config by hand, but you have to write what I think is an exorbitant amount of code just to support this method.
Am I missing something, or is it really expected to be so convoluted?
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
|
|
|
|
I'm actually doing something similar at the moment, so I know where you're coming from. I have a service that hosts four different tasks, and each one has its own config section.
I have organized the app.config file like this (Only showing 2 services for brevity and with names changed to protect the innocent):
<configuration>
<configSections>
<section name="ClassMap" type="System.Configuration.SingleTagSectionHandler" />
<section name="service1" type="System.Configuration.NameValueSectionHandler" />
<section name="service2" type="System.Configuration.NameValueSectionHandler" />
</configSections>
<ClassMap
service1="Service.Service1"
service2="Service.Service2" />
<!-- Service 1 -->
<Service1>
<!-- settings -->
</Service1>
<!-- Service 2 -->
<Service2>
<!-- settings -->
</Service2>
<!-- Global Application Settings -->
<appSettings>
<!-- settings -->
</appSettings>
</configuration> The classmap section is basically just a list of internal class names that get constructed by a class factory. Each service class derives from the same base class, which contains a few useful methods/properties.
The most useful of these is a private aggregated NameValueCollection class that reads from the given configuration section and exposes the settings to the correct service, where processorName is the name of the configuration section and is passed to the service by the class factory during construction from the ClassMap section:
Base class property
protected NameValueCollection config;
Base class constuctor
public BaseProcessor( string serviceName )<br />
{<br />
config = (NameValueCollection)ConfigurationManager.GetSection(serviceName);<br />
}
Derived classes can then read their own settings by simply doing something like this:
string userName = config["UserName"]
To construct each service, I do something like this:
Hashtable ClassMap = (Hashtable)ConfigurationManager.GetSection("ClassMap");<br />
foreach (string key in ClassMap.Keys)<br />
{<br />
BaseProcessor proc = (BaseProcessor)ClassFactory.Create(ClassMap[key].ToString(), key);<br />
}<br />
<br /> I hope this helps and isn't too confusing. It really is much easier to use than it is to describe!
|
|
|
|
|
In mine, I have something like this:
<appSettings>
<!-- =============================================================================
The following values are common among all services. Applicable settings might
be an smtp server address, and things like that.
============================================================================== -->
<add key="SmtpServer" value="12.345.678.9"/>
<add key="FromAddress" value="my.address@mydomain.com"/>
<add key="NotifyAddress" value="notified@notifydomain.com"/>
<add key="FfmpegPath" value="c:\program files\ffmpeg\ffmpeg.exe"/>
<add key="DeferValidation" value="false"/>
<add key="AllowDebugLaunch" value="false"/>
<!-- =============================================================================
The following values are unique among all services. Each service might have it's
own value for Test1. Values you might want to include here are things like the
event log name, a timeout value, service-specific folders, and things like that.
============================================================================== -->
<add key="Service1_EventLogName" value="Service1_Log"/>
<add key="Service1_UploadPath" value="C:\Upload\Service1"/>
<add key="Service1_AllowDebugLaunch" value="true"/>
<add key="Service2_EventLogName" value="Service2_Log"/>
<add key="Service2_UploadPath" value="C:\Upload\Service2"/>
<add key="Service2_DeferValidation" value="true"/>
<add key="Service2_UniqueSetting" value="12345"/>
</appSettings>
Then I have a base class (called AppConfigBase ) that allows me to set a key "prefix", and contains the following functions:
protected string KeyName(string name)
{
return (IgnoreConfigPrefix) ? name : string.Format("{0}{1}", ConfigPrefix, name);
}
protected string GetValue(string key)
{
string value = "";
if (ConfigurationManager.AppSettings[KeyName(key)] != null)
{
value = ConfigurationManager.AppSettings[KeyName(key)].ToString().Trim();
}
else
{
bool m_oldIgnore = m_ignoreConfigPrefix;
m_ignoreConfigPrefix = true;
if (ConfigurationManager.AppSettings[KeyName(key)] != null)
{
value = ConfigurationManager.AppSettings[KeyName(key)].ToString().Trim();
}
m_ignoreConfigPrefix = m_oldIgnore;
}
return value;
}
I then derive a class from AppConfigBase that loads/validates all of the common settings, and derive new service-specific classes from AppConfig that load service-specific settings (based on the specified prefix). So, when I want to add a service, I only have to write the class that derives from AppConfig. Everything else is already done for me.
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
|
|
|
|
Both approaches seem to be doing essentially the same thing. We both have a base class that worries about reading the correct values and supplying them to the derived class that does the actual work.
New derived classes can be added to either one just as easily once all the appropriate plumbing is taken care of (class factory, suitable base class etc). In my case, I have to add an additional entry to the app.config to tell it the name of the class so the class factory can find and create it, but other than that, both methods are very similar.
The biggest difference that I can see is that I've given each service its own section, while you have given each service its own prefix (I keep global settings in the <appSettings> section). The end result is functionally the same so I guess it all comes down to whether you prefer swings or roundabouts
|
|
|
|
|
Alrightie. I was just concerned that there was something fundamental I was missing out on, while in essence, it's a matter of personal preference. I have an idea - why don't you post an article about how you do it, and I'll post an article about how I do it, and we'll link to each other's article.
BTW, I'm interested in your class mapping deal too.
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
|
|
|
|
I just might write an article about it... I can't promise when I'll get to it though as I never seem to have enough time to get anything finished at the moment!
I'll certainly add it to my list of things to do though.
|
|
|
|
|
How do you guys handle exceptions that are caught in your custom data classes. For instance, I have a business class and if an exception is thrown during one of it's methods..I don't really want to pop up a messagebox (since this class could be used in something other than a windows form app). A lot of methods are void (return nothing) so returning the exception to the caller is not an option either ( and is probably bad practice).
|
|
|
|
|
I think I figured it out..I was having a brain fart. I simply re-throw the exception to the caller.
|
|
|
|
|
Hi, i got my menu like this
File | Staff | Catalogue | Inventory | etc etc etc
For example, when i click Staff, i have Register staff, modify staff, delete staff, search staff
Lets say i click Search staff, the below code is executed. But when i click search staff again, 2 of the same form appear. How do i prevent that, if one of the search staff is open, cannot open again
private void mnuSearchStaff_Click(object sender, EventArgs e)
{
FrmSearchStaff childSearchStaff = new FrmSearchStaff();
childSearchStaff.MdiParent = this;
childSearchStaff.Show();
}
|
|
|
|
|
benjamin yap,
Set a bool to be true when you open the form and false when the form is closed. And just add:
If (_isOpened)
return;
Above when you create the form.
Regards,
Gareth.
Regards,
Gareth.
(FKA gareth111)
|
|
|
|
|
Hmm where do i declare the bool. and why have to use _ for isOpen?
|
|
|
|
|
|
Where do i create a private variable.. I got more then 1 child form .. so i have to create individual _isOpen attribute for each childform? wat if a few differnt child form is open...
|
|
|
|
|
Go through the collection of forms in the parent's MDIChildren (IIRC) and check if the form type exist in the collection. If it doesn't exist, make a new one and display it. If it does exist, activate the existing form.
You may want to have a flag or attribute to mark forms that can be opened multiple times and forms that can only be opened once.
|
|
|
|
|
can you give me some example? i just started c# few days back. Please pardon me
|
|
|
|
|
It's a copy and paste code so the code may not compile. This is just to show you how to do it.
public class FormManager
{
private MainForm mainForm;
public FormManager(MainForm mainForm)
{
this.mainForm = mainForm;
}
public virtual System.Windows.Forms.Form GetForm(Type type, object[] args)
{
return GetMDIForm(type, args);
}
private ChildForm GetChildMDIForm(Type type)
{
for (int i = 0; i < mainForm.MdiChildren.Length; i++)
{
if (mainForm.MdiChildren[i].GetType().Equals(type))
{
return (ChildForm)mainForm.MdiChildren[i];
}
}
return null;
}
public virtual ChildForm GetMDIForm(Type type, object[] args)
{
ChildForm form = null;
bool allowMultiple = false;
object[] attributes = type.GetCustomAttributes(typeof(ChildFormAttribute), false);
if (attributes.Length > 0)
{
allowMultiple = ((ChildFormAttribute)attributes[0]).AllowMulti;
}
if (!allowMultiple)
{
form = GetChildMDIForm(type);
}
if (form == null)
{
form = CreateChildMDIForm(type, args);
if (form != null)
{
form.MdiParent = mainForm;
form.WindowState = FormWindowState.Maximized;
form.Show()
}
else
{
throw new Exception(string.Format("Unable to create form of type '{0}'", type.ToString()));
}
}
else
{
form.BringToFront();
}
return form;
}
private ChildForm CreateChildMDIForm(Type type, object[] args)
{
ConstructorInfo ci = type.GetConstructor(System.Type.EmptyTypes);
ChildForm form = (ChildForm)ci.Invoke(args);
return form;
}
public void ShowRole()
{
Wine.Global.FormManager.Instance.GetForm(typeof(Wine.UI.Role), null);
}
}
[ChildFormAttribute(false)]
public partial class Role : ChildForm
{
public Role()
: base()
{
InitializeComponent();
}
}
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class ChildFormAttribute : System.Attribute
{
private bool allowMulti;
public bool AllowMulti
{
get
{
return allowMulti;
}
}
public ChildFormAttribute(bool allowMulti)
{
this.allowMulti = allowMulti;
}
}
|
|
|
|
|