Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Windows Forms / Design Time / December 2004

Tip: Looking for answers? Try searching our database.

GetHashCode and variable names given by VS Designer

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
LF - 28 Nov 2004 03:47 GMT
Hi,

If I have a class that overrides Equals/GetHashCode and returns same
hashcode based on data members equality for 2 different instances of the
class, VS 2003 designer gives exact same name to the local variable
auto-generated inside the InitializeComponent method. This results in
unbuildable code.

In VS 2005 beta it works as expected. It reuses the same variable.

Is there any work around for VS2003?

Thank you
LF - 28 Nov 2004 17:20 GMT
If you pass false for new InstanceDescriptor(ci,new object[]{test.Data},
false), to specify that it's not complete type, then designer will create
local variables in InitializeComponent method with conflicting names.

Here is an example:

public class Component1 : Component
{
...
 TestCollection _test = new TestCollection();

 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
 [Editor(typeof(CollectionEditor), typeof(UITypeEditor))]
 public TestCollection Test
 {
  get { return _test; }
 }
}

public class TestCollection : CollectionBase
{
 public TestCollection()
 {
 }
 public Test this[ int index ]
 {
  get { return (Test)base.List[ index ]; }
 }

 public void Add( Test item )
 {
  base.List.Add( item );
 }
 public void Remove(int index)
 {
  base.List.Remove(index);
 }
 public void Remove(Test item)
 {
  base.List.Remove(item);
 }
 public void AddRange( Test[] items )
 {

 }
 public int IndexOf( Test item )
 {
  return base.List.IndexOf( item );
 }
 public bool Contains(Test item)
 {
  return base.List.Contains(item);
 }
 public void Insert( System.Int32 index , Test item)
 {
  base.List.Insert(index, item);
 }
}

[TypeConverter(typeof(TestTypeConverter))]
public class Test
{
 public Test()
 {
 }
 public Test(string data)
 {
  _data = data;
 }
 string _data = "";
 public string Data
 {
  get { return _data; }
  set { _data = value; }
 }
 public override bool Equals(object obj)
 {
  if(obj == null || !(obj is Test))
   return false;
  Test test = (Test)obj;
  return test._data == _data;
 }
 public override int GetHashCode()
 {
  return _data.GetHashCode();
 }
 public override string ToString()
 {
  return _data;
 }
}
internal sealed class TestTypeConverter: TypeConverter
{
 public override bool CanConvertTo(ITypeDescriptorContext context, Type
destinationType)
 {
  if(destinationType == typeof(InstanceDescriptor))
   return true;
  return base.CanConvertTo (context, destinationType);
 }
 public override object ConvertTo(ITypeDescriptorContext context,
CultureInfo culture, object value, Type destinationType)
 {
  if(value is Test)
  {
   if(destinationType == typeof(string))
   {
    return ((Test)value).Data;
   }
   else if(destinationType == typeof(InstanceDescriptor))
   {
    ConstructorInfo ci = typeof(Test).GetConstructor(new
Type[]{typeof(string)});
    Test test = (Test) value;
    return new InstanceDescriptor(ci,new object[]{test.Data}, false);
   }
  }
  return base.ConvertTo(context, culture, value, destinationType);
 }
}
"Jeffrey Tan[MSFT]" - 29 Nov 2004 09:27 GMT
Hi LF,

Thanks for your posting!!

After trying your code snippet I have reproduced out this issue.

I suspect that VS.net designer will store the CodeDOM references in
hashtable, so when generating the reference, it will query the object's
GetHashCode method. Because you apply the string.GetHashCode logic to the
Test.GetHashCode method, designer will generate the same reference names
for the Test items with the same string field.

I think this behavior is by design. I am not sure why you use
isComplete=false for InstanceDescriptor, your Test class has only one field
"Data", so when use set it in Test's constructor, all the information for
Test class is complete, isComplete=true for InstanceDescriptor is more
suitable for this senario. And using isComplete=false for
InstanceDescriptor will not have such problem in VS.net.

If you have any other concern on this issue, please feel free to tell me.
Thanks

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Signature

Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

LF - 05 Dec 2004 17:20 GMT
Example follows. Note the order of two AddRange methods:

public void AddRange( int[] items )

public void AddRange( Test[] items )

Change them around and everything is fine. For the above order of
declarations we'll get this from VS designer:
this.component11.Test.AddRange(new int[] { new TestApp.Test("val")});

And of course this will not build. I'm not sure anymore what the order of
declarations should be for VS 2003 designer to pick the right signature. I
guess whatever is returned last from Reflection.

public class Component1 : Component
{
public Component1(System.ComponentModel.IContainer container)
{
 container.Add(this);
}
public Component1(){}

TestCollection _test = new TestCollection();

[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[Editor(typeof(CollectionEditor), typeof(UITypeEditor))]
public TestCollection Test
{
 get { return _test; }
}
bool ShouldSerializeTest()
{
 return true;
}
}

public class TestCollection : CollectionBase
{
public TestCollection()
{
}
public Test this[ int index ]
{
 get { return (Test)base.List[ index ]; }
}

public void Add( Test item )
{
 base.List.Add( item );
}
public void Remove(int index)
{
 base.List.Remove(index);
}
public void Remove(Test item)
{
 base.List.Remove(item);
}
public void AddRange( int[] items )
{

}
public void AddRange( Test[] items )
{

}
public int IndexOf( Test item )
{
 return base.List.IndexOf( item );
}
public bool Contains(Test item)
{
 return base.List.Contains(item);
}
public void Insert( System.Int32 index , Test item)
{
 base.List.Insert(index, item);
}
}

[TypeConverter(typeof(TestTypeConverter))]
public class Test
{
public Test(){}
public Test(string val){}
}
internal sealed class TestTypeConverter: TypeConverter
{
public override bool CanConvertTo(ITypeDescriptorContext context, Type
destinationType)
{
 if(destinationType == typeof(InstanceDescriptor))
  return true;
 return base.CanConvertTo (context, destinationType);
}
public override object ConvertTo(ITypeDescriptorContext context,
CultureInfo culture, object value, Type destinationType)
{
 if(value is Test)
 {
  if(destinationType == typeof(string))
   return ((Test)value).ToString();
  else if(destinationType == typeof(InstanceDescriptor))
  {
   ConstructorInfo ci = typeof(Test).GetConstructor(new
Type[]{typeof(string)});
   Test test = (Test) value;
   return new InstanceDescriptor(ci,new object[]{"val"});
  }
 }
 return base.ConvertTo(context, culture, value, destinationType);
}
}

> Hi LF,
>
[quoted text clipped - 24 lines]
> Get Secure! - www.microsoft.com/security
> This posting is provided "as is" with no warranties and confers no rights.
"Jeffrey Tan[MSFT]" - 06 Dec 2004 02:26 GMT
Hi LF,

For this reply, I have replied to you in "Interesting VS 2003 designer
behavior" post. Please follow up me there. Thanks

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Signature

Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.