[英]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.