|
Coder For Hire wrote: I'm not trying to change the struct, I'm try to change the departmentId. That's the problem. You can change the struct, but assigning to its fields (no matter if it's with a property or not) would do nothing (and is banned because it is always a bug).
Remember that properties are just syntactic sugar for get and set methods. You can see this in effect in a decompiler (you may have to mess with settings). Using TheDepartment in a context where it is read from (as you do here) then you're really calling a get-method that returns it. So it's a copy. You're making a copy, calling a set-method on it, then the copy disappears and really nothing has happened at all (unless the properties have side effects). At least, that's what you would be doing if it wasn't an error to write this. That's a sort of unofficial way to look at it though, properties and methods do act differently, for example if you emulate a property using your own getter and setter then you wouldn't get this compile error (you'd get the useless behaviour I described above).
This "weird difference" between fields and properties also exists between elements of an array and indexers (in particular this means changing an array of structs to List<T> does not always work).
To quote the spec,
ECMA 334, §14.5.4 Member access: ... if E is a property or indexer access, then the value of the property or indexer access is obtained
(§14.1.1) and E is reclassified as a value. This says that TheDepartment is a value, andECMA 334, §18.3.3 Assignment: When a property or indexer of a struct is the target of an assignment, the instance expression associated with
the property or indexer access shall be classified as a variable. If the instance expression is classified as a
value, a compile-time error occurs. This is described in further detail in §14.14.1. says that if the target of assignment is a property of a struct and the instance is a value, then it's an error. So, DepartmentId cannot be the target of assignment here.
|
|
|
|
|
Just to add to what Harold says, the problem is that Department is a struct, and thus a value type - so when you use a property to access the value what is returned is a copy of the value rather than a reference to the value itself - so when you change the value of a field or property within the copy, it will have no effect on the actual value in your class.
Try it: change the struct to a class and it will return a reference to the value instead - and it'll all compile fine.
Alternatively, manually implement the property in your Employee class and use the backing value directly:
public class Employee
{
private Department _TheDepartment;
public Department TheDepartment
{
get { return _TheDepartment; }
set { _TheDepartment = value; }
}
public Employee()
{
_TheDepartment.DepartmentId = 100;
}
}
public struct Department
{
public int DepartmentId { get; set; }
}
Because that way you are directly referring to the valuetype, instead of a copy.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
I am hesitant to add any words to the astute explanations offered by Harold, and Griff. However, I can't help providing you with a working example, created in Visual Studio 2013 using FrameWork 4.5, that may intrigue you:
namespace Sanebox2
{
public class Employee
{
public Department TheDepartment { get; set; }
public Employee(int departmentid = 100)
{
TheDepartment = new Department(departmentid);
}
}
public struct Department
{
public int DepartmentId { get; set; }
public Department(int id) : this()
{
DepartmentId = id;
}
}
}
«To kill an error's as good a service, sometimes better than, establishing new truth or fact.» Charles Darwin in "Prospero's Precepts"
modified 13-Apr-15 7:35am.
|
|
|
|
|
Or, without changing the Department structure:
TheDepartment = new Department { DepartmentId = departmentId };
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Interesting, Richard. I am em-bare-assed to say that I can't explain (satisfactorily, to myself) exactly why adding the call to the base initializer makes this work. I assume it has something to do with the "parametric constructor" mentioned in various places I've searched for an answer to this.
cheers, Bill
«To kill an error's as good a service, sometimes better than, establishing new truth or fact.» Charles Darwin in "Prospero's Precepts"
|
|
|
|
|
I guess it's due to compiler error CS0188[^] - all fields in a struct have to be assigned by a constructor before the constructor can call a method in the struct .
Setting a property counts as calling a method on the struct , which you can't do until all of the fields have been assigned. Since you're using an automatic property, you can't directly access the backing field to initialize it. Therefore, the only way to initialize it is to call the default parameterless constructor (which all struct s have), which initializes all of the fields to their default values.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
What does the ": this()" do?
I can't find an explanation anywhere.
Removing it doesn't seem to have any effect.
If it's not broken, fix it until it is
|
|
|
|
|
You shouldn't be able to compile the code without it - you'll get compiler error CS0188[^] - "The 'this' object cannot be used before all of its fields are assigned to".
- All fields in a struct have to be assigned by a constructor before the constructor can call a method in the struct.
- Setting a property counts as calling a method on the struct, which you can't do until all of the fields have been assigned.
- Since you're using an automatic property, you can't directly access the backing field to initialize it.
- Therefore, the only way to initialize the field is to call the default parameterless constructor first.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
I just saw this on SO:
In C#, these are some common memory leaks:
•Not removing event listeners. Any event listener that is created with an anonymous method or lambda expression that references an outside object will keep those objects alive. Remember to remove event listeners when they are no longer used.
Can someone show me an example of this in an anonymous method? I'd like to see how C# looks like that causes this.
Thanks
If it's not broken, fix it until it is
|
|
|
|
|
Following in google seems to work for me
C# anonymous event listener example
|
|
|
|
|
So the reason I asked is because I have this:
using (WebClient client = new WebClient())
{
client.DownloadProgressChanged += (sender, e) =>
{
double bytesIn = double.Parse(e.BytesReceived.ToString());
double totalBytes = double.Parse(e.TotalBytesToReceive.ToString());
double percentage = bytesIn / totalBytes * 100;
file.PercentDone = Math.Truncate(percentage);
};
client.DownloadFileCompleted += (sender, e) =>
{
Files.Remove(file);
};
await client.DownloadFileTaskAsync(new Uri(file.FileName), outputFile);
}
I've never dealt with leaks before, and I'm handling the events using lamdas. Isn't there a protential here for a memory leak?
If it's not broken, fix it until it is
|
|
|
|
|
Do not know why the above post was deleted
|
|
|
|
|
I have a piece of code in c++ and I want to know how it can be in C# :
int m_it[MAX_BC];
int m_iKe[MAX_ROUNDS][MAX_BC];
char const* a_pchIn;
int* pi = m_it;
for(i=0; i<8; i++)
{
*pi = ((unsigned char)*(a_pchIn++) << 24);
*pi |= ((unsigned char)*(a_pchIn++) << 16);
*pi |= ((unsigned char)*(a_pchIn++) << 8);
(*(pi++) |= (unsigned char)*(a_pchIn++)) ^= m_iKe[0][i];
}
In C# ?
Thank you
|
|
|
|
|
This answer might erk a few programmers here in Discussions, but I can recall having a moderate amount of success taking C++ code verbatim and pasting it as C# code in the C# code behind module I was working on, attempting a compile, THEN ACTUALLY working from the compiler error list to clear the syntax breaks while F2-ing the HELP tome.
'Might try this if you find no other solution ...
|
|
|
|
|
Code--- C#
strHTML = "<table id='table1'> <colgroup><col width='190'/></colgroup><tbody>";
for (int i = 0; i < objDs.Tables[0].Rows.Count; i++)
{
if (i <= 10)
{
strUniqueID = "a" + i;
strBGColor = "a" + i.ToString();
}
else
{
strUniqueID = "a" + i;
strBGColor = "a" + (i - 1);
}
strSubject = objDs.Tables[0].Rows[i]["SubjectName"].ToString();
iSubjectID = Convert.ToInt32(objDs.Tables[0].Rows[i]["Subjectid"]);
<pre>
strHTML = strHTML + "<tr><td class='dark'><div id='" + strUniqueID + "' class='drag clone " + strBGColor + "'>" + strSubject + "</div><input id='b_" + strUniqueID + "' class='" + strUniqueID + "' type='button' value='' onclick='report(" + strUniqueID + ")' title='Show only " + strSubject + "'/></td></tr>";
}
strHTML = strHTML + "<tr><td class='trash' title='Trash'>Trash</td></tr>";
strHTML = strHTML + "</tbody></table>";
left.InnerHtml = strHTML;</pre>
---OutPut
English Test P | Kunal | Kunwar | Maths | Maths Test | Raj | Trash |
|
|
|
|
|
And?
You didn't ask a question...
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
I'm underwater on this
I used this tutorial
A Pretty Good Splash Screen in C#[^]
In the CloseForm, the Splash screen doesn't fade out, or just close and go away
hmm? In VB, you just add it, and it works. I'm stumped here.
So in my FormSplash I wrote [partial example]
public FormSplash()
{
InitializeComponent();
this.Text = String.Format("About {0}", AssemblyTitle);
this.ApplicationTitle.Text = AssemblyProduct;
this.Version.Text = String.Format("Version {0}", AssemblyVersion);
this.Copyright.Text = AssemblyCopyright;
}
static public void ShowSplashScreen()
{
if (ms_frmSplash != null)
return;
ms_oThread = new Thread(new ThreadStart(FormSplash.ShowForm));
ms_oThread.IsBackground = true;
ms_oThread.SetApartmentState(ApartmentState.STA);
ms_oThread.Start();
while (ms_frmSplash == null || ms_frmSplash.IsHandleCreated == false)
{
System.Threading.Thread.Sleep(TIMER_INTERVAL);<br />
}
}
static public void ShowForm()
{
ms_frmSplash = new FormSplash();
Application.Run(ms_frmSplash);<br />
}
static public void CloseForm()
{
if (ms_frmSplash != null && ms_frmSplash.IsDisposed == false)
{
ms_frmSplash.m_dblOpacityIncrement = -ms_frmSplash.m_dblOpacityDecrement;
}
ms_oThread = null;
ms_frmSplash = null;
}
And in my program.cs I wrote
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
FormSplash.ShowSplashScreen();
FormSplash.CloseForm();
Application.Run(new FormMain());
}
|
|
|
|
|
Why don't you set this.Cose(); as the last line of the ShowSplashScreen() method?
In Word you can only store 2 bytes. That is why I use Writer.
|
|
|
|
|
I got the can't do that because it was made on a different thread error. So I played around with it, but I think I need to scrape that idea and start again for the 4th time. It's on the back burner for now.
|
|
|
|
|
A few changes to your FormSplash should make it work.
add a delegate to your class to handle the form closing
delegate void CloseDelegate();
Add a method to handle the delegated form closing in a thread safe manner:
void DoClose()
{
if (this.InvokeRequired)
{
CloseDelegate d = new CloseDelegate(DoClose);
this.Invoke(d);
}
else
{
while (ms_frmSplash.Opacity > 0)
{
this.Opacity -= m_dblOpacityDecrement;
System.Threading.Thread.Sleep(TIMER_INTERVAL);
}
this.Close();
}
}
Change the CloseForm method to read:
static public void CloseForm()
{
if (ms_frmSplash != null && ms_frmSplash.IsDisposed == false)
{
ms_frmSplash.DoClose();
}
ms_oThread = null;
ms_frmSplash = null;
}
Note also I used the following values:
static int TIMER_INTERVAL = 1 * 1000;
double m_dblOpacityIncrement = .1;
double m_dblOpacityDecrement = .1;
[edit]
Updated to use proper cross-thread checking
[/edit]
modified 10-Apr-15 9:09am.
|
|
|
|
|
Thanks for bailing my rear out on this again Richard.
Works like a charm!, and the fade is really slow, but hey it works.
Why the 1 * 1000 on the timer interval?
I figured out it was a thread issue, but between this being my first 100% c# Windows Form App and learning more c#, it was a brain overload for me.
CloseDelegate DoClose
[FYI]
I bought a subscription to outsource.com, and scored my first job in 7 days. It was the only Microsoft Job that I had seen posted so I went for it. I had to learn c# anyways, and could use a library of code functions for later use.
So I figured what the heck and put a competitive price out for it and got the job. I should be done by today.
Interesting, the customer is a VB6 programmer, and wanted to test the concept of using one DAL for a Win App, MVC 5, and a WPF project as a single source of data using Entity Framework. So I thought I was going to do a MVC 5 Job, but turned out to be a C# win app. Pretty cool, the DAL gets compiled as a DLL, and can be used by all the program types.
Thanks Richard!
|
|
|
|
|
Happy to help, Jim.
The 1 * 1000 (1 second) on the timer interval was just an arbitrary choice so I could see clearly what was happening. You can adjust it to your own requirements. Similarly the 0.1 (10%) on the m_dblOpacityDecrement is arbitrary. Just have a play with the numbers until you get the effect you want.
|
|
|
|
|
okeedokey on that.
I'll may be back here shortly so stay tuned.
Now I have to sort on Entity Framework, in which I've never used before.
|
|
|
|
|
This is my first c# Windows Form App that I'm working on here.
It worked fine, then I started modifying it, and I get this error in program.cs
I moved the form files into new folders to stay organized.
So I created a new project and double checked the project properties, and the main form code plus program.cs code and there identical. I don't get it.
History, c# is new to me, I code in VB.
Application.Run(new FormMain());
|
|
|
|
|
Sounds like your FormMain class doesn't have a parameterless constructor. You should have something like:
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
}
...
}
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|