(打扰一下,我的英语很差) 我在c#中有三个类,它们都有一个方法“SaveObject”, 在GUI我想调用这些方法,所以我写这段代码:
private void save(object sender, EventArgs e)
{
switch(sender.GetType().Name.Tostring())
{
case "ClassOne" :
ClassOne obj1 = sender as ClassOne;
obj1.SaveObject();
break;
case "ClassTwo" :
ClassTwo obj2 = sender as ClassTwo;
obj2.SaveObject();
break;
case "ClassThree" :
ClassThree obj3 = sender as ClassThree;
obj3.SaveObject();
break;
}
}
有没有办法比上面更好地编写这段代码;
答案 0 :(得分:4)
让所有三个类都实现一个接口:ISaveable
或其他东西。向该接口添加一个方法:SaveObject
,并在三个类中的每个类中实现该方法(您实际已经拥有)。
然后你可以用以下代码替换上面的内容:
private void save(object sender, EventArgs e)
{
ISaveable saveable = (ISaveable)sender;
saveable.SaveObject();
}
答案 1 :(得分:1)
您应该让这三个类使用方法interface
继承我的IMyInterface
(SaveObject
),然后将sender
转换为IMyInterface
并从那里开始致电SaveObject()
。
我将补充说C#有is
运算符。
if (sender is ClassOne)
但是你不能使用开关。
啊,Name
已经是string
,因此您不需要ToString
答案 2 :(得分:1)
如果您无法创建界面(可能是因为您无法控制类)并且正在使用C#4,则可以使用新的动态功能:
((dynamic)sender).SaveObject();
如果您无法创建界面而无法使用dynamic
,则必须使用反射。
答案 3 :(得分:1)
是的,有!
这里有两种选择。
SaveObject()
的逻辑对于所有三个类都相同在第一种情况下,您创建所谓的抽象类,其他类“继承”它。这意味着SaveObject
方法只创建一次,您不必在所有三个类中编写它。
public abstract class ClassBase
{
public void SaveObject()
{
// save logic goes here
}
}
public class ClassOne : ClassBase
{
// other methods and properties; do the same for ClassTwo and ClassThree
}
现在您可以在事件处理程序中执行此操作:
if (sender is ClassBase)
{
((ClassBase) sender).SaveObject();
}
在第二种情况下,所有三个类的逻辑都不同,你创建一个“接口”,其他类将“实现”它。这意味着他们每个人都必须声明自己的SaveObject()
方法。
public interface IClass
{
void SaveObject(); // use the signature only here -- no logic; you cannot use access modifiers like "public"
}
public class ClassOne : IClass
{
// other stuff
public void SaveObject()
{
// save logic for this class
}
}
public class ClassTwo : IClass
{
// other stuff
public void SaveObject()
{
// different save logic for this class
}
}
现在你可以创建这样的方法:
public void PerformSave(IClass myClass)
{
myClass.SaveObject();
}
...无论您是否传递ClassOne
,ClassTwo
或ClassThree
的实例,它都会有效。
但是,在您的情况下,您只有object
类型的参数。你可以这样做:
private void save(object sender, EventArgs e)
{
if(sender is IClass)
{
((IClass) sender).SaveObject();
}
}
答案 4 :(得分:0)
我建议您使用'SaveObject()'方法实现一个接口,并为每个类继承此接口。然后你可以执行演员表并调用方法。
public interface ISaveObject
{
void SaveObject();
}
public class ClassOne : ISaveObject
{
public void SaveObject()
{
//...
}
}
答案 5 :(得分:0)
最好使用方法SaveObject()为所有3个类公开公共接口,然后将发送方转换为该接口并调用方法。
或者您可以查看策略/命令模式。
答案 6 :(得分:0)
不确定。代码的问题是,如果通过进行任何重构来重命名类,它将会中断。我会把它写成:
private void save(object sender, EventArgs e)
{
if (sender is ClassOne)
{
((ClassOne)sender).SaveObject();
}
else if (sender is ClassTwo)
{
((ClassTwo)sender).SaveObject();
}
else if (sender is ClassThree)
{
((ClassThree)sender).SaveObject();
}
else
{
throw new Exception("Unknown type");
}
}
虽然界面可能是更好的解决方案。为什么不在一个名为SaveObject
的成员的所有类上添加一个接口,只是将它放到接口上?
public class ClassOne : IPersistable
{
}
public class ClassTwo : IPersistable
{
}
//etc...
public interface IPersistable
{
void SaveObject();
}
然后:
var persistable = (IPersistable)sender;
persistable.SaveObject();