C# 将两个非常相似的类重构为一个
这是第一节课:C# 将两个非常相似的类重构为一个,c#,refactoring,C#,Refactoring,这是第一节课: public class TextBoxInt : TextBox { public int min; public int max; public Value<int> value; public virtual void Update(object sender, EventArgs e) { int newValue; if (int.TryParse(Text, out newVal
public class TextBoxInt : TextBox
{
public int min;
public int max;
public Value<int> value;
public virtual void Update(object sender, EventArgs e)
{
int newValue;
if (int.TryParse(Text, out newValue))
{
if (newValue < min || newValue > max)
{
//do thing A
}
value.Set(newValue);
Text = value.Get().ToString();
}
else
{
Text = value.Get().ToString();
Focus();
}
}
public TextBoxInt(Value<int> value, int min, int max)
{
this.value = value;
this.min = min;
this.max = max;
Text = value.Get().ToString();
LostFocus += new EventHandler(update);
}
}
公共类TextBoxInt:TextBox
{
公共int min;
公共整数最大值;
公共价值;
公共虚拟无效更新(对象发送方,事件参数e)
{
int新值;
if(int.TryParse(Text,out newValue))
{
如果(新值<最小值| |新值>最大值)
{
//做事
}
value.Set(newValue);
Text=value.Get().ToString();
}
其他的
{
Text=value.Get().ToString();
焦点();
}
}
公共文本框int(值、最小值、最大值)
{
这个值=值;
this.min=min;
this.max=max;
Text=value.Get().ToString();
LostFocus+=新事件处理程序(更新);
}
}
这是第二节课:
public class TextBoxFloat : TextBox
{
public float min;
public float max;
public Value<float> value;
public virtual void Update(object sender, EventArgs e)
{
float newValue;
if (float.TryParse(Text, out newValue))
{
if (newValue < min || newValue > max)
{
//do thing A
}
value.Set(newValue);
Text = value.Get().ToString();
}
else
{
Text = value.Get().ToString();
Focus();
}
}
public TextBoxFloat(Value<float> value, float min, float max)
{
this.value = value;
this.min = min;
this.max = max;
Text = value.Get().ToString();
LostFocus += new EventHandler(update);
}
}
公共类TextBoxFloat:TextBox
{
公众持股;
公共浮动最大值;
公共价值;
公共虚拟无效更新(对象发送方,事件参数e)
{
浮动新值;
if(float.TryParse(Text,out newValue))
{
如果(新值<最小值| |新值>最大值)
{
//做事
}
value.Set(newValue);
Text=value.Get().ToString();
}
其他的
{
Text=value.Get().ToString();
焦点();
}
}
public TextBoxFloat(值、浮点最小值、浮点最大值)
{
这个值=值;
this.min=min;
this.max=max;
Text=value.Get().ToString();
LostFocus+=新事件处理程序(更新);
}
}
此外,这是值类:
public class Value<T>
{
private T value;
private List<IValueListener<T>> listeners = new List<IValueListener<T>>();
public Value(T value)
{
this.value = value;
}
public T Get()
{
return value;
}
public void Set(T value)
{
this.value = value;
foreach (IValueListener<T> listener in listeners)
{
listener.ValueUpdated(this);
}
}
public void AddListener(IValueListener<T> listener)
{
listeners.Add(listener);
}
public void RemoveListener(IValueListener<T> listener)
{
listeners.Remove(listener);
}
}
公共类值
{
私人T值;
私有列表侦听器=新列表();
公共价值(T值)
{
这个值=值;
}
公共部门得不到
{
返回值;
}
公共作废集(T值)
{
这个值=值;
foreach(侦听器中的IValueListener侦听器)
{
listener.ValueUpdated(this);
}
}
公共void AddListener(IValueListener listener)
{
添加(侦听器);
}
公共void RemovelListener(IValueListener侦听器)
{
删除(侦听器);
}
}
如您所见,前两个类基本上是同一个类。唯一的区别是类型。第一个是int
,另一个是float
。如果我能将这两个类合并到一个类中,我似乎会得到更好的代码
我可以将min
和max
设置为浮动,如果是int类,则在需要时将它们转换为int
。当类型为int时,我只需确保传递“整”浮点
有没有办法不用复制Update()
方法(如果int做codeForInt,否则如果float做sameCodeButForFloat
)就可以做到这一点
而且,即使我复制了代码,我也会遇到value.Set(newValue)的问题代码>-在一种情况下,newValue
将是int
,在另一种情况下它将是float
,我也不能转换为t
还有,有没有办法限制泛型类型?指定它只能是int或float
我应该把它们作为两个类,还是有办法将它们统一起来?您可以创建一个泛型类,而不是创建单独的类
public class BoundedTextBox<T> : TextBox where T : IComparable<T> ...
让一个抽象的TextBox
类继承TextBox
类,其中TextBox
有一个新的抽象字符串GetValue()
方法,怎么样?您将使用TextBoxFloat
类实现GetValue()
,该类将执行float
特定逻辑,类似地,TextBoxInt
类也将执行该逻辑。您的文本框将类似
public abstract class TextBox<T> : TextBox
{
public T min;
public T max;
public Value<T> value;
public virtual void Update(object sender, EventArgs e)
{
Text = GetValue();
Focus();
}
public TextBoxFloat(Value<T> value, T min, T max)
{
this.value = value;
this.min = min;
this.max = max;
Text = value.Get().ToString();
LostFocus += new EventHandler(update);
}
public abstract string GetValue();
}
公共抽象类TextBox:TextBox
{
公共卫生部;
公共T最大值;
公共价值;
公共虚拟无效更新(对象发送方,事件参数e)
{
Text=GetValue();
焦点();
}
公共TextBoxFloat(值、最小值、最大值)
{
这个值=值;
this.min=min;
this.max=max;
Text=value.Get().ToString();
LostFocus+=新事件处理程序(更新);
}
公共抽象字符串GetValue();
}
正如@flkes所说,泛型类是实现这一点的方法。你可以尝试以下方法:(你可以找到一个很好的例子)
公共抽象类TextBoxBase
{
公共抽象对象GetMin();
公共抽象对象GetMax();
公共抽象对象GetValue();
}
公共抽象类TextBox:TextBoxBase
{
公共T min{get;set;}
公共T max{get;set;}
公共T值{get;set;}
公共虚拟void SetTextBox(T mn、T mx、T val)
{
min=mn;
max=mx;
值=val;
}
公共重写对象GetMin(){return min;}
公共重写对象GetMax(){return max;}
公共重写对象GetValue(){return value;}
}
公共类TextBoxInt:TextBox
{
公共覆盖void SetTextBox(int mn、int mx、int val)
{
min=mn;
max=mx;
值=val;
}
}
公共类TextBoxFloat:TextBox
{
公共覆盖void SetTextBox(浮点mn、浮点mx、浮点val)
{
min=mn;
max=mx;
值=val;
}
}
您可能会在不知道存在的问题上取得更大的成功。这仍然给我留下了int.TryParse(Text,out newValue)
的问题。如果我使用一个大的If并分别处理int和float,我a)使用的代码是我想要的两倍b)我无法使用value.set(newValue),因为newValue将是int或float,而不是泛型类型。
public abstract class TextBox<T> : TextBox
{
public T min;
public T max;
public Value<T> value;
public virtual void Update(object sender, EventArgs e)
{
Text = GetValue();
Focus();
}
public TextBoxFloat(Value<T> value, T min, T max)
{
this.value = value;
this.min = min;
this.max = max;
Text = value.Get().ToString();
LostFocus += new EventHandler(update);
}
public abstract string GetValue();
}
public abstract class TextBoxBase
{
public abstract object GetMin();
public abstract object GetMax();
public abstract object GetValue();
}
public abstract class TextBox<T> : TextBoxBase
{
public T min { get; set; }
public T max { get; set; }
public T value { get; set; }
public virtual void SetTextBox(T mn, T mx, T val)
{
min = mn;
max = mx;
value = val;
}
public override object GetMin() { return min; }
public override object GetMax() { return max; }
public override object GetValue() { return value; }
}
public class TextBoxInt : TextBox<int>
{
public override void SetTextBox(int mn, int mx, int val)
{
min = mn;
max = mx;
value = val;
}
}
public class TextBoxFloat : TextBox<float>
{
public override void SetTextBox(float mn, float mx, float val)
{
min = mn;
max = mx;
value = val;
}
}