重构函数以使其更通用
我多次复制/粘贴以下代码。更改的值是字符串文字(“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;
}
}
I have the following code copy/pasted multiple times. The values that change are the string literals ("TabStates" changes to "ContentStates" etc..) and the value of the dictionary (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);
}
I'm not looking for an answer, just curious what I should read about to learn how to rewrite this. I'm sure it's simple enough, just not sure what it's called. Is it just function templating?
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;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Martin Fowler 的书是重构的标准来源。
但对于您的具体示例,只需创建一个新方法,该方法接受表示示例中发生变化的参数。因此,您需要一个字符串参数来表示“TabStates”或“ContentStates”值,另一个表示字典中关键内容设置的值。
这有道理吗?我完全理解你的问题吗?
编辑
根据您的评论,您想使用泛型。像这样的事情应该可以让您继续下去:
请注意,除非您添加一些通用约束,否则您将无法对类型 T 做太多事情。
如果您想创建 T 的新实例,那么您需要
如果您想访问 T 实例上的实际属性,那么希望 T 的所有可能值都将实现某种接口,在这种情况下您会说:
Martin Fowler's book is the standard source for refactoring.
But for your specific example, just create a new method that takes in parameters representing the things that change in your example. So you'll want a string parameter for your "TabStates" or "ContentStates" value, and another representing your Value for Key ContentSetting in your dictionary.
Does that make sense? Am I understanding your question fully?
EDIT
Based on your comment, you want to use generics. Something like this should get you going:
Just note that you won't be able to do much with your type T unless you add some generic constraints.
If you want to create a new instance of T, then you would need
And if you want to access actual properties on an instance of T, then hopefully all possible values for T will implement some sort of interface, in which case you would say: