0

假设我有一个来自第 3 方的课程,它是一个数据模型。它可能有 100 个属性(一些具有公共设置器和获取器,其他具有公共获取器但私有设置器)。我们将这个类称为 ContosoEmployeeModel

我想用一个接口(INavigationItem,它具有 Name 和 DBID 属性)来装饰这个类,以允许它在我的应用程序中使用(它是一个 PowerShell 提供程序,但现在这并不重要)。但是,它还需要可用作 ContosoEmployeeModel。

我最初的实现是这样的:

public class ContosoEmployeeModel
{
    // Note this class is not under my control. I'm supplied
    // an instance of it that I have to work with.

    public DateTime EmployeeDateOfBirth { get; set; }
    // and 99 other properties.
}

public class FacadedEmployeeModel : ContosoEmployeeModel, INavigationItem
{
    private ContosoEmployeeModel model;
    public FacadedEmployeeModel(ContosoEmployeeModel model)
    {
        this.model = model;
    }

    // INavigationItem properties
    string INavigationItem.Name { get; set;}

    int INavigationItem.DBID { get; set;}

    // ContosoEmployeeModel properties
    public DateTime EmployeeDateOfBirth
    {
        get { return this.model.EmployeeDateOfBirth; }
        set { this.model.EmployeeDateOfBirth = value; }
    }
    // And now write 99 more properties that look like this :-(
}

但是,很明显,这将涉及编写大量样板代码来公开所有属性,如果可以的话,我宁愿避免这种情况。我可以在部分类中 T4 代码生成此代码,如果没有更好的想法,我会这样做,但我想在这里问是否有人使用一些超级奇特 C# 魔法有更好的想法

请注意 - 我用来获取 ContosoEmployeeModel 的 API 只能返回 ContosoEmployeeModel - 我无法将其扩展为返回 FacededEmployeeModel,因此包装模型是我能想到的唯一解决方案 - 我很高兴得到纠正: )

4

2 回答 2

1

Resharper 允许创建“委托成员”,它将包含对象的接口复制到包含对象上,并将方法调用/属性访问通过隧道传递到包含对象。

http://www.jetbrains.com/resharper/webhelp/Code_Generation__Delegating_Members.html

完成此操作后,您可以在代理类上提取接口。

于 2013-07-02T10:16:44.677 回答
1

另一种可能适合您的方法是使用 AutoMapper 将基类映射到您的外观这里是示例代码:

class Program
    {
        static void Main(string[] args)
        {
            var model = new Model { Count = 123, Date = DateTime.Now, Name = "Some name" };

            Mapper.CreateMap<Model, FacadeForModel>();
            var mappedObject = AutoMapper.Mapper.Map<FacadeForModel>(model);

            Console.WriteLine(mappedObject);

            Console.ReadLine();
        }

        class Model
        {
            public string Name { get; set; }

            public DateTime Date { get; set; }

            public int Count { get; set; }
        }

        interface INavigationItem
        {
            int Id { get; set; }

            string OtherProp { get; set; }
        }

        class FacadeForModel : Model, INavigationItem
        {
            public int Id { get; set; }

            public string OtherProp { get; set; }
        }
    }
于 2013-07-02T10:01:31.513 回答