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

标签 c# oop reflection properties attributes

首先要注意的是 - 我知道委托(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 的属性,没有主体和其他逻辑。但我想要更通用的解决方案,而且我不喜欢反射。有什么想法吗?

这里是创建 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/

相关文章:

c# - wpf 应用程序中的异步/等待方法

c# - 将按位运算从 C# 移植到 C

C# Newtonsoft JSON 库在不同计算机上为同一数据集输出不同的错误 JSON 键

python - 如何在 Python 中枚举对象的属性?

javascript - 是否有与引擎无关的 Reflect.parse?

c# - 如何以编程方式重建现有程序集?

c# - 为什么我会收到 403?

PHP 扩展现有类以进行表插入/更新

swift - 在 Swift 中将可变结构转换为不可变结构

oop - OO 编程中的子类型化和继承有什么区别?