[英]Is it possible to “extend” the property “class”?
我是C#的新手(上周開始),所以對我很冷靜;)。 我想知道我是否能以某種方式編寫自定義屬性,讓我解釋一下:
我有一些部分類,我通過添加屬性完成,但所有getter和setter的模式是相同的,所以我想分解這個:
public partial class Travel
{
public String TravelName
{
get
{
return LocaleHelper.GetRessource(Ressource1);
}
set
{
if (this.Ressource1 == null)
Ressource1 = new Ressource() { DefaultValue = value };
else
Ressource1.DefaultValue = value;
}
}
public String TravelDescription
{
get
{
return LocaleHelper.GetRessource(Ressource2);
}
set
{
if (this.Ressource2 == null)
Ressource2 = new Ressource() { DefaultValue = value };
else
Ressource2.DefaultValue = value;
}
}
}
正如您所看到的,唯一改變的是Ressource1 / Ressource2。 我的目標是能夠寫出如下內容:
public partial class Travel
{
public LocalizedString TravelName(Ressource1);
public LocalizedString TravelDescription(Ressource2);
}
有人有想法讓這個或其他想法讓我的代碼更干凈嗎? 謝謝,
紀堯姆
在C#或.NET本身內沒有設施可以做到這一點,但是如果你正在做很多這樣的事情,那么通過postharp調查面向方面的編程可能是值得的。 基本上它允許您定義一個屬性,該屬性導致在編譯時注入額外的代碼。 您輸入的代碼如下:
public partial class Travel
{
[LocalizedProperty(source = "Ressource1")
public string TravelName { get; set; }
[LocalizedProperty(source = "Ressource2")
public string TravelDescription{ get; set; }
}
在編譯時,PostSharp將使用您在新LocalizedPropertyAttribute類中定義的模板替換該屬性。
你不能讓它很簡明扼要你的描述,但可以降低的setter方法的復雜性和冗余。
private void SetRessource(ref Ressource res, string value)
{
if(res == null) res = new Ressource();
res.DefaultValue = value;
}
public String TravelName
{
get { return LocaleHelper.GetRessource(Ressource1); }
set { SetRessource(ref this.Ressource1, value); }
}
public String TravelDescription
{
get { return LocaleHelper.GetRessource(Ressource2); }
set { SetRessource(ref this.Ressource2, value); }
}
我不確切地知道你想要實現什么,但你可能會讓事情變得太復雜。 這不夠嗎?
public class Travel
{
/// <summary>
/// Creates a new instance of <see cref="Travel"/>.
/// </summary>
public Travel()
{
this.TravelName = Resources.DefaultTravelName;
this.TravelDescription = Resources.DefaultTravelDescription;
}
public string TravelName { get; set; }
public string TravelDescription { get; set; }
}
其中Resources是本地化資源的生成類(來自resx文件)。 我有一種感覺,你正在嘗試構建自己的本地化框架,因為你還不知道.NET 已經有了基礎設施 。
不,沒有這樣的方式。 它可能在PHP中,但不在C#中。
在這種情況下,您應該改變您的方法遠離屬性。
UPD:可能你可以為每個屬性使用這樣的東西(除了它明顯的弱點):
public class Prop
{
Resource _res;
public Prop(Resource res)
{
this._res = res;
}
public string Value
{
get
{
return LocaleHelper.GetRessource(_res);
}
set
{
if(_res == null)
// This is a weak point as it's now
// as it wont work
else
_res.DefaultValue = value;
}
}
您可以實現單個索引屬性,根據您的偏好為您提供以下兩種語法選擇之一。 代碼基本上是一個接受特定命名資源並返回正確內容的函數。
Travel t = new Travel();
string x = t["Name"];
or
string x = t[Travel.Name];
通過將getter和setter邏輯封裝在基類中,然后從您創建的任何新屬性中調用這些方法(簡單地充當這些方法的瘦包裝器),您可以使您的生活更輕松。 這是一個例子:
public class Travel : LocalizedRessourceSubscriber
{
private Ressource<string> Ressource1 = null;
private Ressource<string> Ressource2 = null;
public String TravelName {
get { return GetRessource<string>(Ressource2); }
set { SetRessource<string>(Ressource1, value); }
}
public String TravelDescription {
get { return GetRessource<string>(Ressource2); }
set { SetRessource<string>(Ressource2, value); }
}
}
public class LocalizedRessourceSubscriber
{
protected T GetRessource<T>(Ressource<T> Source)
{
return LocaleHelper.GetRessource<T>(Source);
}
protected void SetRessource<T>(Ressource<T> Source, T Value)
{
(Source ??
(Source = new Ressource<T>())
).DefaultValue = Value;
}
}
...這樣,您的屬性中的邏輯很少,並且您重復的代碼更少。 這假設以下類(我嘲笑為通用化):
public static class LocaleHelper
{
public static T GetRessource<T>(Ressource<T> Source)
{
return default(T);
}
}
public class Ressource<T>
{
public T DefaultValue { get; set; }
}
這沒有意義。 使用propertys就像你現在擁有它們一樣,你可以簡單地寫:
Travel t = new Travel();
string tvlName = t.TravelName;
string desc = t.TravelDescription;
如果您更改為您想要的方式,則還必須指定參數
Travel t = new Travel();
LocalizedString tvlName = t.TravelName([someresopurcedesignator]);
LocalizedString desc = t.TravelDescription([someresopurcedesignator]);
你所能做的就是做一個“propertyBag”模擬器
public class Travel
{
private LocalizedString props = new LocalizedString();
public LocalizedString Propertys
{
get { return props; }
set { props = value; }
}
}
public class LocalizedString // this is property Bag emulator
{
public string this[string resourceName]
{
get{ return LocaleHelper.GetRessource(resourceName); }
set{ LocaleHelper.GetRessource(resourceName) = value; }
}
}
您可以這樣訪問:
Travel t = new Travel();
t.Propertys[NameResource1] = "Bob Smith";
t.Propertys[DescriptionResource2] = "Fun trip to discover the orient";
string tvlName = t.Propertys[NameResource1];
string desc = t.Propertys[DescriptionResource2];
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.