C# 为类和运算符分配默认属性 =
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/433523/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C# Assigning default property for class and operator =
提问by Steve
Problem 1:
问题1:
I have a simple winforms app and I want to DataBind my Person.Name property to a textbox. Name is of type StringField. I originally defined the Name property as String. The data binding works great on value types such as String. I would like the StringField.Value property to be the default property of StringField. I want to see the value of StringField.Value in the textBox rather than the text "FieldApp.StringField".
我有一个简单的 winforms 应用程序,我想将我的 Person.Name 属性数据绑定到一个文本框。名称的类型为 StringField。我最初将 Name 属性定义为 String。数据绑定对字符串等值类型非常有效。我希望 StringField.Value 属性成为 StringField 的默认属性。我想在文本框中看到 StringField.Value 的值,而不是文本“FieldApp.StringField”。
Problem 2:
问题2:
I would like to be able to assign a string to a StringField using operator =. This assignment would result in the StringField.Value member being set.
我希望能够使用运算符 = 将字符串分配给 StringField。此分配将导致设置 StringField.Value 成员。
Can this be accomplished?
这能实现吗?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace FieldApp
{
public class StringField
{
public string Value { get; set; }
}
public class Person
{
//private String _Name;
//public String Name
//{
// get { return _Name; }
// set { _Name = value; }
//}
//public Person(string name)
//{
// Name = name;
//}
private StringField _Name;
public StringField Name
{
get { return _Name; }
set { _Name = value; }
}
public Person(string name)
{
Name = new StringField();
Name.Value = name;
}
}
public partial class FieldAppForm : Form
{
Person person = new Person("steve");
public FieldAppForm()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//our form contains a button1 and textBox1
//this compiles
person.Name.Value = "steve";
//this does not. Is there anyway to accomplish this?
person.Name = "steve";
//steve appears in the textbox
textBox1.DataBindings.Add("Text", person, "Name.Value");
//FieldApp.StringField appears in the textbox
textBox1.DataBindings.Add("Text", person, "Name");
}
}
}
采纳答案by ?yvind Skaar
You could create an implicit operator overload. Then you can create StringField
from strings like this:
您可以创建一个隐式运算符重载。然后你可以StringField
从这样的字符串创建:
StringField field = "value of new object";
string value=(string)field;
Know that this creates a new StringField
object. I wouldn't necessarily advice you to do this.
知道这会创建一个新StringField
对象。我不一定建议你这样做。
[System.Diagnostics.DebuggerDisplay("{Value}")]
public class StringField
{
public string Value { get; set; }
public static implicit operator StringField(string s)
{
return new StringField { Value = s };
}
public static explicit operator string(StringField f)
{
return f.Value;
}
public override string ToString()
{
return Value;
}
}
回答by Rune Grimstad
You can hade the StringField by mapping the Name property to the Name.Value field internally in your class.
您可以通过将 Name 属性映射到类内部的 Name.Value 字段来生成 StringField。
so you can define the Name property like this:
所以你可以像这样定义 Name 属性:
string Name
{
get { return _name.Value; }
set { _name.Value = value; }
}
Here _name is your StringField variable.
这里 _name 是您的 StringField 变量。
回答by Rowland Shaw
The assignment operator cannot be overridden in C#. You could however have a property to do the type conversion for you and expose that one the class
在 C# 中不能覆盖赋值运算符。但是,您可以拥有一个属性来为您进行类型转换并将该属性公开给类
回答by Marc Gravell
Re data-binding, for somebinding targets (PropertyGrid
, DataGridView
, etc), you can do this with a TypeConverter
(see below). Unfortunately, this doesn't seem to work with TextBox
, so I think your best option is to simply add a shim property (as already suggested):
重新数据绑定,对于某些绑定目标(PropertyGrid
、DataGridView
等),您可以使用 a TypeConverter
(见下文)执行此操作。不幸的是,这似乎不适用于TextBox
,所以我认为您最好的选择是简单地添加一个 shim 属性(如已经建议的那样):
string NameString
{
get { return Name.Value; }
set { Name.Value = value; } // or new blah...
}
(and bind to NameString
)
(并绑定到NameString
)
In the past, I have used custom PropertyDescriptor
implementations to side-step this, but it isn't worth it justfor this.
过去,我使用自定义PropertyDescriptor
实现来回避这个问题,但仅仅为了这个是不值得的。
Anyway, a TypeConverter
example (works with PropertyGrid
and DataGridView
):
无论如何,一个TypeConverter
例子(适用于PropertyGrid
和DataGridView
):
[TypeConverter(typeof(StringFieldConverter))]
public class StringField
{
public StringField() : this("") { }
public StringField(string value) { Value = value; }
public string Value { get; private set; }
}
class StringFieldConverter : TypeConverter
{
public override bool CanConvertFrom(
ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string)
|| base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(
ITypeDescriptorContext context,
System.Globalization.CultureInfo culture,
object value)
{
string s = value as string;
if (s != null) return new StringField(s);
return base.ConvertFrom(context, culture, value);
}
public override bool CanConvertTo(
ITypeDescriptorContext context, Type destinationType)
{
return destinationType == typeof(string)
|| base.CanConvertTo(context, destinationType);
}
public override object ConvertTo(
ITypeDescriptorContext context,
System.Globalization.CultureInfo culture,
object value, Type destinationType)
{
if (destinationType == typeof(string) && value != null
&& value is StringField)
{
return ((StringField)value).Value;
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
回答by Hans Passant
You can implement assignment by providing a conversion operator. Given the nature of your class, you should also override the Object methods:
您可以通过提供转换运算符来实现赋值。鉴于您的类的性质,您还应该覆盖 Object 方法:
public class StringField {
public string Value { get; set; }
public static implicit operator StringField(string value) {
StringField sf = new StringField();
sf.Value = value;
return sf;
}
public override string ToString() {
return Value;
}
public override bool Equals(object obj) {
if (obj == null || !(obj is StringField)) return false;
return 0 == string.Compare(Value, (obj as StringField).Value);
}
public override int GetHashCode() {
return Value.GetHashCode();
}
}