考虑以下示例:
public class Foo
{
private string _text;
[BsonElement("text"), BsonRequired]
public string Text
{
get { return _text; }
set
{
_text = value;
Bar(_text);
}
}
private void Bar(string text)
{
//Only relevant when Text is set by the user of the class,
//not during deserialization
}
}
当类的用户为属性分配新值并且在MongoDB C#驱动程序的对象反序列化期间,调用Text
属性的setter以及随后的方法Bar
。我需要的是确保仅在用户设置Bar
属性时调用Text
,而不是在反序列化期间调用。{/ p>
我认为两种解决方案并不适合我:
第一种是将BsonElement
属性移动到支持字段。但是,据我所知,BsonElement
属性在MongoDB C#驱动程序的查询构建中使用,因此我将无法在查询中使用Text
属性。
第二个解决方案是将Text
setter设为私有,并添加一个方法,通过该方法,类的用户将设置Text
属性,并且Bar
方法将在其中调用。但是,Text
setter在现有解决方案中经常使用,我有点不愿意在所有文件中更改70多个调用。此外,代码的可读性会降低。
在保留属性的BsonElement
属性的同时,是否有更简洁的方法来分离反序列化和用户提示的属性更改?
答案 0 :(得分:1)
为什么不为用户创建单独的属性,为同一个私有变量创建DB,如下所示
public class Foo
{
private string _text;
[BsonElement("text"), BsonRequired]
public string TextDB
{
get { return _text; }
set
{
_text = value;
}
}
[BsonIgnore]
public string Text
{
get { return _text; }
set
{
_text = value;
Bar(_text);
}
}
private void Bar(string text)
{
//Only relevant when Text is set by the user of the class,
//not during deserialization
}
}
答案 1 :(得分:0)
你可以使用一个小技巧实现一种属性监听器。
用法是:
// Working with some foo here...
var foo = new Foo();
foo.Text = "Won't fire anything";
using (var propertyListener = new FooPropertiesListener(foo))
{
foo.Text = "Something will fire you listener";
}
// Some more work with foo here...
foo.Text = "Won't fire anything";
它背后的实现,如:
<强> FooPropertiesListener 强>
public class FooPropertiesListener : IDisposable
{
private readonly Foo Foo;
public FooPropertiesListener(Foo foo)
{
this.Foo = foo;
this.Foo.PropertiesListener = this;
}
public void Bar(string text)
{
//Only relevant when Text is set by the user of the class,
//not during deserialization
}
public void Dispose()
{
Foo.PropertiesListener = null;
}
}
<强>富强>
public class Foo
{
internal FooPropertiesListener PropertiesListener;
private string _text;
[BsonElement("text"), BsonRequired]
public string Text
{
get { return _text; }
set
{
_text = value;
if (PropertiesListener != null)
{
PropertiesListener.Bar(_text);
}
}
}
}
答案 2 :(得分:0)
我知道这个问题已经过时了,但我仍然希望像其他人那样帮助其他人绊倒这个问题。
它基本上归结为一些非常简单的事情:序列化和反序列化不仅限于公共字段和属性!
下一个例子将涵盖原始问题,而不必发明可疑的二级属性:
public class Foo
{
[BsonElement("Text"), BsonRequired]
private string _text;
[BsonIgnore]
public string Text
{
get { return _text; }
set
{
_text = value;
Bar(_text);
}
}
private void Bar(string text)
{
//Only relevant when Text is set by the user of the class,
//not during deserialization
}
}
只需将您的BsonElement
课程放在支持字段上,然后告诉BsonIgnore
该属性。
你可以在getter和setter中做任何你喜欢的事情,而不必担心现在在私有字段级别发生的反序列化。
希望这有助于某人!