我写了一个TextBox来检查其文本的有效性。检查文本的方法由呼叫者提供为System.Func<string, bool>
。简化代码如下所示:
public class ValidTextBox : System.Windows.Forms.TextBox
{
public System.Func<string, bool> IsValid { get; set; }
}
我成功地使用了几件事,但后来我尝试提供非静态方法。代码编译得很好,但每当我尝试将它从工具箱拖到窗体中时,Visual Studio的设计器都会抛出一个冗长的异常(见下文)。
public class SpecialTextBox : ValidTextBox
{
public SpecialTextBox()
{
base.IsValid = s => true; // works
base.IsValid = StaticReturnTrue; // works
base.IsValid = s => StaticReturnTrue(s); // works
base.IsValid = this.ReturnTrue; // doesn't work
base.IsValid = s => this.ReturnTrue(s); // doesn't work
}
private static bool StaticReturnTrue(string s)
{
return true;
}
private bool ReturnTrue(string s)
{
return true;
}
}
我无法复制并粘贴MessageBox的文本,请原谅错别字。语言是德语:
Fehler beim Erstellen der Komponente SpecialTextBox。 Die Fehlermeldung: System.Runtime.Serialization.SerializationException:Der Typ&#34; GuiTest.SpecialTextBox&#34;在Assembly&#34; GuiTest,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null&#34; ist nicht als serialisierbar gekennzeichnet bei System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type)
bei System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type,StreamingContent content)
bei System.Runtime.Serialization.FormatterServices.Binary.WriteObjectInfo.InitMemberInfo()
bei System.Runtime.Serialization.FormatterServices.Binary.WriteObjectInfo.InitSerialze([...]) bei System.Runtime.Serialization.FormatterServices.Binary.ObjectWriter.Write([...])
如果我将SpecialTextBox
标记为[System.Serializable]
,则设计师会抱怨ValidTextBox
未标记为可序列化。如果我将ValidTextBox
标记为[System.Serializable]
,设计师会抱怨System.Windows.Forms.TextBox
未标记为可序列化,我无法更改。
为什么设计师会例外?
如何在运行时提供非静态方法?
答案 0 :(得分:3)
它尝试序列化属性值,因为它具有非null值。这无法达到目的,C#编译器为实现lambda(委托的目标对象的类型)而生成的隐藏类是不可序列化的。当需要捕获状态时,这是一个问题,例如正确调用ReturnTrue()方法所需的 this 引用。
修复很简单,您不需要序列化,因为您始终在运行时初始化它。所以使用属性来阻止它:
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public System.Func<string, bool> IsValid { get; set; }