gpt4 book ai didi

c# - 类扩展 - 最佳实践/最佳解决方案

转载 作者:行者123 更新时间:2023-11-30 22:44:00 24 4
gpt4 key购买 nike

首先要注意的是 - 我知道委托(delegate)和修饰符模式!

其次 - 我使用的是 C# .NET 4.0,所以如果您能想出一个专门针对它的解决方案,那很好。但是,如果解决方案适用于任何 OOP 语言和平台,那就太好了。

问题来了...

我有一个部分类(让它命名为 Class1 ),我无法修改它。因此,我可以扩展它或/和继承它。这个类为我提供了一个完美的数据模型,我唯一需要做的就是向它的属性添加一些属性(用于验证、在 MVC 中定义标签文本值等——现在,我不需要像“你可以做你能做的”这样的回答需要没有属性',这不是我的问题)。

使用另一个类作为数据模型不是问题,所以我可以创建 Class2 : Class1并使用 Class2作为一个模型。需要属性的属性将定义为 public new <type> <propertyname> .这将限制我只重写需要属性的属性,而其他所有属性保持不变。

较小的问题是我没有为属性重新定义 getter 和 setter,因为它们只包含 return base.<propertyname>。和 base.<propertyname> = value ,如果有很多这样的属性,这意味着很多“愚蠢”的编码。有没有办法避免这种情况?

更大的问题是我必须参数化我的 Class2Class1实例并制作类似class2.<propertyname> = class1.<propertyname>的东西对于我拥有的每一个属性——太多的“愚蠢”编码。我可以使用反射来避免它 - 在 Class1 中找到所有具有公共(public) getter 和 setter 的属性并调用prop.SetValue(child, prop.GetValue(parent, null), null);在循环。这为简单的情况提供了一个通用函数,这很好,因为我主要有简单的模型——许多属性具有公共(public) getter 和 setter,没有主体和其他逻辑。但我想要更通用的解决方案,而且我不喜欢反射(reflection)。有什么想法吗?

这里是创建 Class2 的扩展方法的完整代码基于Class1

    public static Child ToExtendedChild<Parent, Child>(this Parent parent)
where Child : Parent, new()
{
Child child = new Child();

var props = typeof(Parent).GetProperties().Where(p => p.GetAccessors().Count() >= 2);

foreach (var prop in props)
{
prop.SetValue(child, prop.GetValue(parent, null), null);
}

return child;
}

(顺便说一句,这种方法可能无法理想地实现我的解决方案,所以任何更正也将不胜感激)

提前致谢!

最佳答案

较小的问题 似乎不是什么大问题。也许我误解了这个问题,但假设您只是派生一个子类,那么应该没有理由重新定义属性或它们关联的 getter/setter。

更大的问题可能会使用更简单的方法来解决。对大量对象初始化使用反射似乎有点昂贵。如果您处理的类主要是一个大包或属性,也许您应该好像在任何给定情况下都需要访问所有 这些属性一样。您提到 MVC 和验证,整个模型是否在您进行验证的 Controller 方法中使用?如果没有,为什么不考虑使用只公开该方法中需要的那些部分的 View 模型?

你的反射初始化器很有趣,但如果你要做很多这样的事情,那么你可能会考虑花点时间在 Automapper 上。 .否则,可以考虑从通用解决方案转移到只解决手头问题的东西,即将属性从一个对象的实例映射到另一个派生对象的实例。也许您可以在父类中创建一个复制构造函数并在您的派生类中使用它?

public class Foo {
public string PropOne { get; set; }
public string PropTwo { get; set; }

public Foo(string propOne, string propTwo) {
PropOne = propOne;
PropTwo = propTwo;
}

public Foo(Foo foo) {
PropOne = foo.PropOne;
PropTwo = foo.PropTwo;
}
}

public class Pho : Foo {
// if you have additional properties then handle them here
// and let the base class take care of the rest.
public string PropThree { get; set; }
public Pho(string propOne, string propTwo, string propThree)
: base(propOne, propTwo) {
PropThree = propThree;
}
public Pho(Pho pho) : base(pho) {
PropThree = pho.PropThree;
}
// otherwise you can just rely on a copy constructor
// to handle the initialization.
public Pho(Foo foo) : base(foo) {}
}

关于c# - 类扩展 - 最佳实践/最佳解决方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3646568/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com