为了解释我的问题,这里有一个例子
namespace CheckAbstarct
{
class Program
{
static void Main(string[] args)
{
myAbstarctClass mac1 = ObjectFactory.ObjectCreator("aaa");
myAbstarctClass mac2 = ObjectFactory.ObjectCreator("bbb");
mac1.changeMyString();
mac2.changeMyString();
string myString = (string)mac2.returnMyObject();
DateTime myObject = (DateTime) mac1.returnMyObject();
object obj1 = mac1.returnMyObject();
object obj2 = mac2.returnMyObject();
myMethod(obj1); //---> This is not compiling
myMethod(obj2); //---> This is not compiling
myMethod(myString); //---> works fine
myMethod(myObject); //---> works fine
Console.ReadKey();
}
public static void myMethod(DateTime dt)
{
}
public static void myMethod(string st)
{
}
}
abstract class myAbstarctClass
{
protected string mMyString;
public myAbstarctClass()
{
mMyString = "myAbstarctClass ";
}
public abstract void changeMyString();
public abstract object returnMyObject();
}
class MyNewAbstractClass1 : myAbstarctClass
{
DateTime mObject;
public MyNewAbstractClass1(string myString)
{
mMyString = myString;
mObject = new DateTime().Date;
}
public override void changeMyString()
{
mMyString += " MyNewAbstractClass1";
Console.WriteLine(mMyString);
}
public override object returnMyObject()
{
return mObject;
}
}
class MyNewAbstractClass2 : myAbstarctClass
{
string mString;
public MyNewAbstractClass2(string myString)
{
mMyString = myString;
mString = mMyString;
}
public override void changeMyString()
{
mMyString += " MyNewAbstractClass2";
Console.WriteLine(mMyString);
}
public override object returnMyObject()
{
return mString;
}
}
static class ObjectFactory
{
public static myAbstarctClass ObjectCreator(string myString)
{
switch (myString)
{
case "aaa":
return new MyNewAbstractClass1(myString);
case "bbb":
return new MyNewAbstractClass2(myString);
default:
return null;
}
}
}
}
我的问题是在Main()中我不知道returnMyObject()方法返回什么类型,所以我无法将它发送给MyMethod。有没有办法摆放对象??
答案 0 :(得分:5)
因为在您的returnMyObject()
设计中,您回到了最常见的object
引用,您必须在运行时找到它们:
if (obj1 is string)
myMethod((string)obj1); //--->cast it
else if (obj1 is DateTime)
myMethod((DateTime) obj1);
答案 1 :(得分:4)
您可以在运行时检查对象的类型:
public static void myMethod(Object o) { if (o is DateTime) myMethod((DateTime)o); else if (o is string) myMethod((string)o); }
虽然在您的情况下,您也可以将myAbstarctClass
实例传递给myMethod
,然后在那里拨打returnMyObject()
。
答案 2 :(得分:1)
您可以使用C#4.0中的动态功能或更改设计以使用某种双重调度技术
dynamic obj1 = mac1.returnMyObject();
dynamic obj2 = mac2.returnMyObject();
答案 3 :(得分:1)
使用多态机制,因此您无需知道对象的类型。
使myMethod
成为myAbstarctClass
的抽象方法,并在MyNewAbstractClass1
和MyNewAbstractClass2
中提供实施。
修改myAbstractClass1.returnMyObject()
以返回myAbstarctClass
(不是object
)。
然后可以编写Main
中的测试代码:
...
myAbstarctClass obj1 = mac1.returnMyObject();
myAbstarctClass obj2 = mac2.returnMyObject();
obj1.myMethod(); // calls MyNewAbstractClass1.myMethod()
// no if statement required!
obj2.myMethod(); // calls MyNewAbstractClass2.myMethod()
// no if statement required!
Console.ReadKey();
编辑:这可以进一步简化,因为不再需要returnMyObject()
方法 - 它们只返回您已有的对象。测试代码现在只是:
mac1.myMethod();
mac2.myMethod();
// etc...
Console.ReadKey();
答案 4 :(得分:0)
不,您必须创建具有所有可能性的开关,或类似Dictionary<Type, Delegate>
或者你可以创建myMethod(object obj)
它被称为多次发送(http://en.wikipedia.org/wiki/Multiple_dispatch),并且有一些库可以做到这一点
答案 5 :(得分:0)
由于您似乎将您的类用作类型的容器(例如。DateTime
,string
),因此Generics可能是比继承更好的选择:
namespace CheckAbstract
{
class Program
{
static void Main(string[] args)
{
myTemplateClass<DateTime> mac1 = new myTemplateClass<DateTime>(new DateTime().Date);
myTemplateClass<string> mac2 = new myTemplateClass<string>("cat dog");
mac1.changeMyString();
mac2.changeMyString();
string myString = (string)mac2.returnMyObject();
DateTime myObject = (DateTime) mac1.returnMyObject();
myMethod<string>(myString);
myMethod<DateTime>(myObject);
Console.ReadKey();
}
public static void myMethod<T>(T obj)
{
}
}
class myTemplateClass<T>
{
T mObject;
string mMyString;
public myTemplateClass(T init)
{
mMyString = init.ToString();
mObject = init;
}
public void changeMyString()
{
mMyString += " " + mObject.ToString();
Console.WriteLine(mMyString);
}
public T returnMyObject()
{
return mObject;
}
}
}