C# 替换子类类型的开关语句
有一种方法可接受2个参数:C# 替换子类类型的开关语句,c#,.net,switch-statement,mapping,C#,.net,Switch Statement,Mapping,有一种方法可接受2个参数: int selectedClass; int selectedFunction; 接下来,有两个switch语句。首先,它使用枚举确定子类类型: ParentClass p; switch(selectedClass){ case (int)ClassTypes.A: p = new classA(); break; case (int)ClassTypes.B: p = new classB();
int selectedClass;
int selectedFunction;
接下来,有两个switch语句。首先,它使用枚举确定子类类型:
ParentClass p;
switch(selectedClass){
case (int)ClassTypes.A:
p = new classA();
break;
case (int)ClassTypes.B:
p = new classB();
break;
case (int)ClassTypes.C:
p = new classC();
break;
}
而且它会持续50多条语句。此外,还有另一个switch语句确定函数:
string result;
switch(selectedFunction){
case (int)FunctionTypes.Func1:
result = p.function1();
break;
case (int)FunctionTypes.Func2:
result = p.function2();
break;
case (int)FunctionTypes.Func3:
result = p.function3();
break;
}
我确实使用了搜索,有很多改进第二个switch语句的例子,但第一个没有。第一个问题是:在没有switch语句的情况下,如何确定子类和函数
第二:在js中,我会这样做:
functionsArray[selectedClass][selectedFunction]();
是否可以在c#中实现类似的映射
更新#1:
我已将第一个开关更换为以下代码:
public static Dictionary<ClassTypes, Type> typeDict = new Dictionary<ClassTypes, Type>()
{
{ ClassTypes.A , typeof(classA) },
{ ClassTypes.B , typeof(classB) },
{ ClassTypes.C , typeof(classC) }
};
ParentClass p = (ParentClass)Activator.CreateInstance(typeDict[selectedClass]);
publicstaticdictionary typeDict=newdictionary()
{
{ClassTypes.A,typeof(classA)},
{ClassTypes.B,typeof(classB)},
{ClassTypes.C,typeof(classC)}
};
ParentClass p=(ParentClass)Activator.CreateInstance(typeDict[selectedClass]);
我对原始代码做了一些更改,我将输入参数更改为字符串,假设您可以直接将名称作为输入。然后使用第一个方法实例化,然后使用第二个方法调用。如果您想继续使用枚举,我添加了一个重载
string selectedClass;
string selectedFunction;
public object GetClassInstanceFromName(string name)
{
object type = Type.GetType($"{this.GetType().Namespace}.{name}";
return Activator.CreateInstance((Type)type);
}
public string InVokefunctionByName(object instance,string methName)
{
return instance.GetType().GetMethod(methName).Invoke(instance, null) as string;
}
//Overload if you want to continue to use your enum
public object GetClassInstanceFromName(ClassTypes name)
{
return
Activator.CreateInstance(Assembly.GetExecutingAssembly().FullName,
"class" +name.ToString());
}
private void Test()
{
object a = GetClassInstanceFromName(selectedClass);
Console.WriteLine(InVokefunctionByName(a, selectedFunction));
Console.ReadKey();
}
另外,建议您选择更好的设计。我对您的原始代码做了一些更改,我将输入参数更改为字符串,假设您可以直接将名称作为输入。然后使用第一个方法实例化,然后使用第二个方法调用。如果您想继续使用枚举,我添加了一个重载
string selectedClass;
string selectedFunction;
public object GetClassInstanceFromName(string name)
{
object type = Type.GetType($"{this.GetType().Namespace}.{name}";
return Activator.CreateInstance((Type)type);
}
public string InVokefunctionByName(object instance,string methName)
{
return instance.GetType().GetMethod(methName).Invoke(instance, null) as string;
}
//Overload if you want to continue to use your enum
public object GetClassInstanceFromName(ClassTypes name)
{
return
Activator.CreateInstance(Assembly.GetExecutingAssembly().FullName,
"class" +name.ToString());
}
private void Test()
{
object a = GetClassInstanceFromName(selectedClass);
Console.WriteLine(InVokefunctionByName(a, selectedFunction));
Console.ReadKey();
}
另外,建议您选择更好的设计。我不能说我理解导致您选择这种奇怪设计的逻辑,但我可以想出至少两种方法来改进它,前提是您调用的所有函数都在基类中实现(当然,在需要时在派生类中重写) 这两种解决方案仅在所有类都提供无参数构造函数和无参数函数的情况下相关,并且执行函数不需要进一步初始化: 第一个解决方案要求您更改方法签名,并强制调用方法知道类的类型,因此您可能无法实现它,但所涉及的代码要少得多
ExecuteMethod<TClass>(Func<TClass, string> func) where T: BaseClass, new()
(
return func(new T());
)
请注意,代码是直接在这里编写的,没有经过测试,因此我可能遗漏了一两件事,但这是总体思路。我不能说我理解导致您选择这种奇怪设计的逻辑,但我可以想出至少两种改进方法,提供您正在调用的所有函数都在基类中实现(当然,在需要时在派生类中重写) 这两种解决方案仅在所有类都提供无参数构造函数和无参数函数的情况下相关,并且执行函数不需要进一步初始化: 第一个解决方案要求您更改方法签名,并强制调用方法知道类的类型,因此您可能无法实现它,但所涉及的代码要少得多
ExecuteMethod<TClass>(Func<TClass, string> func) where T: BaseClass, new()
(
return func(new T());
)
请注意,代码是直接在这里编写的,没有经过测试,因此我可能遗漏了一两件事,但这是一般的想法。创建一个所有类都实现的公共基类/-接口,然后简单地调用
myInstance.TheSingleFunction()
?如您所见,已经有一个具有虚拟函数的基类,我确实从父类调用函数,如p.function3()
。另外,在那个项目中,创建接口并不是靠设计来完成的。但是,基类中没有三个方法,而是只有一个方法供所有yopur派生类实现。这样你就不必打开方法,而只需要打开类型。可能字典样式的方式更好-在使用中,然后是开关,开关在少数情况下是好的,否则可读性就差了。性能类似-开关变为基于哈希的搜索如果传入类型而不是int并使用Activator.CreateInstance(),第一个开关可以很容易地解决;创建一个所有类都实现的公共基类/-接口,然后简单地调用myInstance.TheSingleFunction()
?正如您所见,已经有一个基类具有虚拟函数,我确实从父类调用函数,如p.function3()
。另外,在那个项目中,创建接口并不是靠设计来完成的。但是,基类中没有三个方法,而是只有一个方法供所有yopur派生类实现。这样你就不必打开方法,而只需要打开类型。可能字典样式的方式更好-在使用中,然后是开关,开关在少数情况下是好的,否则可读性就差了。性能类似-开关变为基于哈希的搜索如果传入类型而不是int并使用Activator.CreateInstance(),第一个开关可以很容易地解决;很乐意帮忙:-)很乐意帮忙:-)
string DoSomething(int classType, int function)
{
var instance = constructors[classType].Invoke();
return methods[function].Invoke(instance);
}