MGG*_*GGD 0 c# unity-game-engine
我有以下设置:
public class Child<T>: BaseClass
{
public T Value;
}
public class IntChild: Child<int> { }
public class BoolChild: Child<bool> { }
public class FloatChild: Child<float> { }
public class MyProgram
{
public BaseClass Source;
public void SetValue(object val)
{
// I want to do something like the following
// ((Child) Source).Value = (val.GetType()) val;
// Instead, I have to do it like this
string temp = val.ToString();
switch (Source.GetType())
{
case "IntChild":
((IntChild) Source).Value = int.Parse(val.ToString());
break;
case "BoolChild":
((BoolChild) Source).Value = bool.Parse(val.ToString());
break;
case "FloatChild":
((FloatChild) Source).Value = float.Parse(val.ToString());
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我无法修改BaseClass(我只能覆盖ToString()).
如何用更简单的代码替换开关?我想做类似以下的事情
((Child) Source).Value = (val.GetType()) val;
Run Code Online (Sandbox Code Playgroud)
而不是开关.这甚至可能吗?
你应该使用访客模式:
public abstract class BaseClassWithVisitor : BaseClass {
void AcceptVisitor(BaseClassVisitor visitor);
}
Run Code Online (Sandbox Code Playgroud)
这意味着Child<T>
变得抽象.
使所有Child<T>
子类实现BaseClassWithVisitor.AcceptVisitor()
方法,因此它们不是抽象的:
public class IntChild : Child<int> {
...
/// This method should be implemented in all Child<T> descendant classes
public override void AcceptVisitor(BaseClassVisitor visitor) { visitor.Visit(this); }
...
}
Run Code Online (Sandbox Code Playgroud)
然后定义BaseClassVisitor
接口:
public interface BaseClassVisitor {
void Visit(IntChild intChild);
void Visit(...); // all the other possible types
...
}
Run Code Online (Sandbox Code Playgroud)
然后最终创建一个BaseClassVisitor
将执行您想要的操作的实现:
public class SetValueVisitor : BaseClassVisitor {
void Visit(IntChild intChild) { intChild.Value = 1; }
void Visit(BoolChild boolChild) { boolChild.Value = false; }
...
}
Run Code Online (Sandbox Code Playgroud)
这是一个让事情更清晰的完整示例:
using System;
using System.Globalization;
namespace Visitor
{
class BaseClass
{
}
abstract class BaseClassWithVisitor : BaseClass
{
public abstract void AcceptVisitor(Visitor visitor);
}
abstract class Child<T> : BaseClassWithVisitor
{
public T Value;
}
class IntChild : Child<int>
{
public override void AcceptVisitor(Visitor visitor)
{
visitor.Visit(this);
}
}
class FloatChild : Child<float>
{
public override void AcceptVisitor(Visitor visitor)
{
visitor.Visit(this);
}
}
class StringChild : Child<string>
{
public override void AcceptVisitor(Visitor visitor)
{
visitor.Visit(this);
}
}
class Visitor
{
public object Value;
public void Visit(IntChild intChild)
{
intChild.Value = int.Parse(Value.ToString());
}
public void Visit(FloatChild floatChild)
{
floatChild.Value = float.Parse(Value.ToString(), CultureInfo.InvariantCulture);
}
public void Visit(StringChild stringChild)
{
stringChild.Value = Value.ToString();
}
}
class Program
{
static void Main(string[] args)
{
var visitor = new Visitor { Value = "12345" };
var intChild = new IntChild();
intChild.AcceptVisitor(visitor);
visitor = new Visitor { Value = "1.2345" };
var floatChild = new FloatChild();
floatChild.AcceptVisitor(visitor);
visitor = new Visitor { Value = "Hello World" };
var stringChild = new StringChild();
stringChild.AcceptVisitor(visitor);
Console.WriteLine("intChild.Value = {0}", intChild.Value);
Console.WriteLine("floatChild.Value = {0}", floatChild.Value);
Console.WriteLine("stringChild.Value = {0}", stringChild.Value);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这将输出:
intChild.Value = 12345
floatChild.Value = 1,2345
stringChild.Value = Hello World
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
76 次 |
最近记录: |