是否可以“系結”同一物件的兩個不同實體的屬性?
例如;
class bar{
public int MyInt {get;set;}
public var foo {get;set;}
}
------------------------------------------
class MainProgram{
bar Bar1 = new bar();
bar Bar2 = new bar();
bar Bar3 = new bar();
//some logic here to decide which objects properties needs to get binded (in our case it could be Bar1 and Bar2)
}
我希望當我更改 bar1.MyInt 或 bar2.myInt 時,另一個也被修改為相同的值。問題是只需要系結 MyInt 屬性。所以 bar.foo 應該為每個實體保持不同。
我的意思是它可以通過一些回圈等來完成,但應用程式中有許多相同物件的實體。速度很重要,所以有什么方法可以做到這一點,就像在 c 中使用參考/指標一樣。
uj5u.com熱心網友回復:
您可以使用 來做到這一點INotifyPropertyChanged,但這需要大量的樣板代碼。
第 1 步:創建一個基本實作INotifyPropertyChanged:
internal abstract class Notifier:INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
第 2 步:繼承資料物件中的實作并NotifyPropertyChanged在屬性更新時呼叫:
class bar:Notifier
{
private int _myInt;
public int MyInt
{
get=>_myInt;
set
{
_myInt = value;
NotifyPropertyChanged();
}
}
private string _foo;
public string foo
{
get=>_foo;
set
{
_foo = value;
NotifyPropertyChanged();
}
}
}
PropertyChanged第 3 步(可選,但可以節省一些作業):撰寫一個擴展方法,讓您(更容易)為實作的物件呼叫事件回呼INotifyPropertyChanged:
internal static class Extensions
{
public static void BindProperty(this INotifyPropertyChanged viewModel, string propertyName, Action changeAction)
{
viewModel.PropertyChanged = (p, e) =>
{
if (e.PropertyName == propertyName) changeAction();
};
}
}
第 4 步:定義兩個實體之間的系結行為bar:
在酒吧類:
public void Bind(bar twin)
{
//whenever twin.MyInt changes, update our value as well
twin.BindProperty(nameof(MyInt), () =>
{
_myInt = twin.MyInt;
});
//whenever twin.Foo changes, update our value as well
twin.BindProperty(nameof(foo), () =>
{
_foo = twin.foo;
});
}
在您的主程式中,將兩個實體相互系結:
public static void Main()
{
bar Bar1 = new bar();
bar Bar2 = new bar();
Bar1.Bind(Bar2);//property changes on Bar2 now update Bar1
Bar2.Bind(Bar1);//property changes on Bar1 now update Bar2
}
注意:這種方法有其局限性。最大的是屬性更改事件不會“鏈接”,這意味著如果我將 3rd bar, Bar3,系結到Bar2(但不是Bar1)并且我在 上更新屬性Bar1,Bar 3將不會更新其匹配屬性。為了將所有三個配對,您必須將每個鏈接bar到其他兩個bar。當然,也有解決方法:
是bar您需要相互系結的s 的一小部分嗎?您可以通過編程方式創建所有連接:
這依賴于NotifyPropertyChanged樣板代碼
public static void BindMany(params bar[] bars) => BindMany(bars);
public static void BindMany(IEnumerable<bar> bars)
{
foreach (var bar1 in bars)
{
foreach (var bar2 in bars)
{
if (bar1 != bar2) bar1.Bind(bar2);
}
}
}
用法:
public static void Main()
{
bar Bar1 = new bar();
bar Bar2 = new bar();
bar Bar3 = new bar();
bar Bar4 = new bar();
bar Bar5 = new bar();
BindMany(bar1, bar2, bar3);//bars 1-3 now always share the same property values
BindMany(bar4, bar5);//bars 4-5 now always share the same property values, but the values can be different from bars 1-3
}
順便說一句,我已經編程了大約 10 年,專業 3 年,我從來沒有遇到過需要這樣做的情況。很有可能您的問題可以在不系結物件組中的屬性的情況下得到解決。你的用例是什么?
uj5u.com熱心網友回復:
它看起來像代碼氣味。我不知道你為什么希望它表現得那樣,但我會重新考慮這種類設計。
如果您仍然希望所有實體共享相同的值并且不想使用靜態屬性,則將其包裝MyInt在 ref 型別中并將該 ref 型別用作類中的屬性bar。
class Wrapper
{
public int MyInt {get;set;}
}
class bar
{
public Wrapper MyWrapper {get;set;}
public var foo {get;set;}
}
class MainProgram
{
Wrapper shared = new Wrapper();
shared.MyInt = 10;
bar Bar1 = new bar();
Bar1.MyWrapper = shared;
bar Bar2 = new bar();
Bar2.MyWrapper = shared;
bar Bar3 = new bar();
Bar3.MyWrapper = shared;
shared.MyInt = 20; // Affects all three objects
}
uj5u.com熱心網友回復:
沒有內置機制來“系結”兩個物件的屬性,但有不同的方法可以做到這一點,具體取決于您的用例:
- 創建屬性(或它后面的欄位),
static以便所有實體共享它。 INotifyPropertyChanged當屬性更改時添加一個事件(或使用)(并將代碼添加到設定器以觸發事件)并讓第二個實體訂閱該事件。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/420885.html
標籤:
上一篇:在.NET中決議XML檔案
