c# - 重构函数以使其更通用

标签 c# refactoring

我多次复制/粘贴了以下代码。更改的值是字符串文字(“TabStates”更改为“ContentStates”等)和字典的值(RadTabSetting -> ContentSetting)。

public static SerializableDictionary<string, RadTabSetting> GetTabStates()
{
    SerializableDictionary<string, RadTabSetting> _tabStates = new SerializableDictionary<string, RadTabSetting>();

    if (!object.Equals(DashboardSessionRepository.Instance.GetSession("TabStates"), null))
    {
        _tabStates = DashboardSessionRepository.Instance.GetSession("TabStates") as SerializableDictionary<string, RadTabSetting>;
    }
    else
    {
        XmlSerializer serializer = new XmlSerializer(_tabStates.GetType());

        string data = DashoardDatabaseRepository.Instance.GetWebLayoutData("TabStates");

        if ( !string.IsNullOrEmpty(data) )
        {
            byte[] dataAsArray = Convert.FromBase64String(data);
            MemoryStream stream = new MemoryStream(dataAsArray);
            _tabStates = serializer.Deserialize(stream) as SerializableDictionary<string, RadTabSetting>;
            }
            DashboardSessionRepository.Instance.SetSession("TabStates", _tabStates);
        }

        return _tabStates;
    }

    public static void SetTabStates(SerializableDictionary<string, RadTabSetting> tabStates)
    {
        DashboardSessionRepository.Instance.SetSession("TabStates", tabStates);
        DashboardDatabaseRepository.Instance.SaveToDatabase("TabStates", tabStates);
    }

我不是在寻找答案,只是好奇我应该阅读哪些内容来学习如何重写它。我确定它很简单,只是不确定它叫什么。它只是函数模板吗?

    public static T GetStates<T>() where T: new()
    {
        T _states = new T();//(T)Activator.CreateInstance(typeof(T));

        string stateName = StateDictionary.GetStateName(typeof(T));

        if (!object.Equals(DashboardSessionRepository.Instance.GetSession(stateName), null))
        {
            _states = (T)DashboardSessionRepository.Instance.GetSession(stateName);

            //Work-Around
            System.IO.MemoryStream memoryStream = new System.IO.MemoryStream();
            System.Xml.Serialization.XmlSerializer xmlSerializer = new System.Xml.Serialization.XmlSerializer(_states.GetType());
            xmlSerializer.Serialize(memoryStream, _states);
            string data = System.Convert.ToBase64String(memoryStream.ToArray());
            string otherData = DashboardDatabaseRepository.Instance.GetWebLayoutData(stateName);

            if (!string.IsNullOrEmpty(data))
            {
                XmlSerializer serializer = new XmlSerializer(_states.GetType());
                byte[] dataAsArray = Convert.FromBase64String(data);
                MemoryStream stream = new MemoryStream(dataAsArray);

                _states = (T)serializer.Deserialize(stream);
            }
            //Work-Around
        }
        else
        {
            XmlSerializer serializer = new XmlSerializer(_states.GetType());

            string data = DashboardDatabaseRepository.Instance.GetWebLayoutData(stateName);

            if (!string.IsNullOrEmpty(data))
            {
                byte[] dataAsArray = Convert.FromBase64String(data);
                MemoryStream stream = new MemoryStream(dataAsArray);
                _states = (T)serializer.Deserialize(stream);
            }
            DashboardSessionRepository.Instance.SetSession(stateName, _states);
        }

        return _states;
    }

    public static void SetStates<T>(T states) where T: new()
    {
        string stateName = StateDictionary.GetStateName(typeof(T));

        DashboardSessionRepository.Instance.SetSession(stateName, states);
        DashboardDatabaseRepository.Instance.SaveToDatabase(stateName);
    }

static class StateDictionary
{   
    //TODO: Might (should?) be able to redo this polymorphically.
    static IDictionary<Type, string> _stateDictionary = new Dictionary<Type, string>
    {
        {typeof(SerializableDictionary<string, RadTabSetting>), "TabStates"},
        {typeof(SerializableDictionary<string, RadDockContentSetting>), "ContentStates"},
        {typeof(SerializableDictionary<string, RadPaneSetting>), "PaneStates"},
        {typeof(SerializableDictionary<string, RadDockSetting>), "DockStates"},
        {typeof(SerializableDictionary<string, RadDockZoneSetting>), "DockZoneStates"},
        {typeof(SerializableDictionary<string, RadSplitterSetting>), "SplitterStates"},
        {typeof(SerializableDictionary<string, RadSplitBarSetting>), "SplitBarStates"},
        {typeof(KnownGlobalSettings), "GlobalSettings"},
    };

    public static string GetStateName(Type type)
    {
        string stateName = string.Empty;

        if (_stateDictionary.ContainsKey(type))
        {
            stateName = _stateDictionary[type];
        }

        return stateName;
    }
}

最佳答案

Martin Fowler's book是重构的标准来源。

但对于您的特定示例,只需创建一个新方法,该方法接收表示示例中发生变化的参数。因此,您需要一个字符串参数作为您的“TabStates”或“ContentStates”值,另一个代表您字典中 Key ContentSetting 的值。

这有意义吗?我是否完全理解您的问题?

编辑

根据您的评论,您希望使用泛型。像这样的事情应该让你继续:

public static Dictionary<string, T> GetTabStates<T>()

请注意,除非添加一些通用约束,否则您将无法对类型 T 做很多事情。

如果你想创建一个新的 T 实例,那么你需要

public static Dictionary<string, T> GetTabStates<T>() where T : new() {

如果你想访问 T 实例的实际属性,那么希望 T 的所有可能值都将实现某种接口(interface),在这种情况下你会说:

public interface IFoo {
    int Id { get; set; }
}

public static Dictionary<string, T> GetTabStates<T>() where T : new(), IFoo {
   T Tval = new T();
   Tval.Id = 1;
   //etc       

关于c# - 重构函数以使其更通用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6269103/

相关文章:

c# - 从自定义控件绑定(bind)到 ObservableCollection

c# - 在调用 Read() 之前尝试访问字段无效,但我先调用了 Read()

java - 如何在 Java 中以更好的方式编写这些循环?

javascript - Coffeescript jQuery - 如何重构这个(菜鸟)方法?

java - 如何避免 java7 if 语句或使代码更具可读性

java - 重构方法头参数顺序

c# - 更改事件选项卡(导航菜单)的 CSS

c# - NUnit 在运行 session 期间以编程方式获取结果

c# - 如何使用 ICU 扩展为 SQLIte 编写不区分大小写的 C# LIKE 语句?

spring - 如何在 Spring Boot 服务应用程序中的 REST 服务调用之间按原样传递请求参数?