C# 将DataContractSerializer的事件标记为不可序列化

C# 将DataContractSerializer的事件标记为不可序列化,c#,events,datacontractserializer,C#,Events,Datacontractserializer,我在实施RelayCommand时遇到以下事件: public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } 现在我使用的是DataContractSerializer。我知道在使用DataContractSerializer时,所有事件都必须标记

我在实施RelayCommand时遇到以下事件:

public event EventHandler CanExecuteChanged
{
  add { CommandManager.RequerySuggested += value; }
  remove { CommandManager.RequerySuggested -= value; }
}
现在我使用的是
DataContractSerializer
。我知道在使用
DataContractSerializer
时,所有事件都必须标记为
[字段:非序列化]
。但在本例中,这不起作用,因为我的
CanExecuteChanged
事件只是一个没有私有字段的属性

如何将此属性标记为
不可序列化

编辑:

以下是整个RelayCommand课程:

[DataContract]
public class RelayCommand : ICommand
{

  [field:NonSerialized]
  readonly Action<object> _execute;

  [field:NonSerialized]
  readonly Predicate<object> _canExecute;

  public RelayCommand(Action<object> execute)
    : this(execute, null)
  {
  }

  public RelayCommand(Action<object> execute, Predicate<object> canExecute)
  {
    if (execute == null)
      throw new ArgumentNullException("execute");

    _execute = execute;
    _canExecute = canExecute;
  }

  [DebuggerStepThrough]
  public bool CanExecute(object parameters)
  {
    return _canExecute == null ? true : _canExecute(parameters);
  }

  public event EventHandler CanExecuteChanged
  {
    add { CommandManager.RequerySuggested += value; }
    remove { CommandManager.RequerySuggested -= value; }
  }

  public void Execute(object parameters)
  {
    _execute(parameters);
  }
}
[DataContract]
公共类中继命令:ICommand
{
[字段:非序列化]
只读操作_执行;
[字段:非序列化]
只读谓词_canExecute;
公共中继命令(操作执行)
:此(执行,空)
{
}
公共RelayCommand(操作执行,谓词canExecute)
{
if(execute==null)
抛出新的ArgumentNullException(“执行”);
_执行=执行;
_canExecute=canExecute;
}
[调试步骤至]
公共布尔CanExecute(对象参数)
{
return _canExecute==null?true:_canExecute(参数);
}
公共事件事件处理程序CanExecuteChanged
{
添加{CommandManager.RequerySuggested+=value;}
删除{CommandManager.RequerySuggested-=value;}
}
公共void执行(对象参数)
{
_执行(参数);
}
}
当我尝试执行
DataContractSerializer
时,出现以下错误:

键入“MyNamespace.RelayCommand”,数据协定名称为“RelayCommand”:http://schemas.datacontract.org/2004/07/MyNamespace”他说。将任何静态未知的类型添加到已知类型列表中-例如,使用KnownTypeAttribute属性或将它们添加到传递给DataContractSerializer的已知类型列表中


这就是我从以下位置更新示例的方式:


它毫无例外地工作。

正如您所说,它不是一个字段,因此它永远不会被序列化。你为什么认为会这样?我记得,
DataContractSerializer
只会序列化标记为
DataMember
的字段/属性。我想我遇到了与此线程相同的情况:当我尝试使用
DataContractSerializer
进行序列化时,会收到相同的错误消息,因此我尝试了此处给出的解决方案,但这对我不起作用。我刚刚使用了中的示例,但我用您的
CanExecuteChanged
事件替换了
PropertyChanged
事件。它工作正常,请检查您是否没有其他事件。
DataContractSerializer
具有重载构造函数,其中包含第二个参数
knownTypes
您应该传递给它,例如
new[]{typeof(RelayCommand)}
[Serializable]
public abstract class BaseClass
{
    public string Name { get; set; }

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }
}

public class DerivedClass : BaseClass
{
    public int Age { get; set; }
}


class Program
{
    static void Main(string[] args)
    {
        var derivedClass = new DerivedClass { Name = "Test", Age = 10 };
        derivedClass.CanExecuteChanged += (sender, eventArgs) => Console.WriteLine("hello");

        var serializer = new DataContractSerializer(typeof(DerivedClass));
        using (var stream = new FileStream("d:\\test.txt", FileMode.Create, FileAccess.ReadWrite))
        {
            serializer.WriteObject(stream, derivedClass);
        }
    }
}