C# 如何简化泛型方法中的条件?
我有一个通用方法C# 如何简化泛型方法中的条件?,c#,generics,C#,Generics,我有一个通用方法public void DoAThing(T inputData) 在方法中,我需要根据T的实际类型采取具体措施: if (typeof(T) == int) { // Handle integer input. } else if (typeof(T) == string) { // Do something else. } else { // Default action. } 当我为更多类型提出操作时,如何防止if/else语句变得任意大?替换为switch语
public void DoAThing(T inputData)
在方法中,我需要根据T的实际类型采取具体措施:
if (typeof(T) == int)
{
// Handle integer input.
}
else if (typeof(T) == string)
{
// Do something else.
}
else
{
// Default action.
}
当我为更多类型提出操作时,如何防止if/else语句变得任意大?替换为switch
语句在语法上看起来更好,但有相同的潜在问题:我必须添加越来越多的案例
直觉上,我知道转换必须在某个时候完成,我只是在寻找一种更优雅的方式
编辑:我得到的答案并不完全是我想要的,但这可能是因为我走错了路。我意识到我原来的问题是错的,这可能是问题的一部分
我使用的方法实际上是:
public T void ReturnAThing(字符串名称)
因此,我之所以启用T,是因为该方法需要进行一些不同的处理以获得返回值。在这种情况下,什么更有效:对每个预期类型使用带有if/else的泛型方法,或者对每个有效的返回类型使用一系列方法(ReturnAString
,returnanit
,等等)?也许(强调也许)您想要的是这样的。(最终,这个长答案的底部解释了为什么你不应该这样做。但这是一个很好的实验。)
当泛型类不“关心”特定类型是什么时,泛型是有意义的,比如List
。它将保存T
的实例,而不管T
是什么。或者您可以对其设置一个约束,如:
public class MyFooHandler<TFoo> where TFoo:Foo
公共类myfoodhandler,其中TFoo:Foo
这确保泛型类型为Foo
或继承自Foo
。但是在这种情况下,这些方法应该只“注意”它是一个Foo
。如果您发现自己在检查它,看看它是什么类型的Foo
,那么再次说明,出了问题
如果您有一个类可能在int
上操作,或者可能在字符串上操作,那么一个好问题是,既然它可能在做两件完全不同的事情,为什么它需要一个类或一个方法?也许应该有两门课。也许应该有一个类具有多个方法。也许您只需要一个string
方法,在调用该方法之前,您的int应该转换为string
有时我们会被这些问题所吸引,因为我们试图找到一种方法让一个类做很多不同的事情。当我们在实验泛型时,这种情况经常发生。但答案往往是,如果我们在做两件不同的事情,我们应该有两门课
即使在上面的示例中,有两个类继承自doesmething
,我们也可以问,让这些类继承自一个基类有什么好处?很多时候,这根本没有任何好处,只是在以后制造麻烦。最好从编写单独的类开始,每个类都做一件小事或几个密切相关的小事。你应该做的事
public void DoAThing(int inputData)
public void DoAThing(string inputData)
通过使用单个泛型方法,您允许调用方期望从中得到任何类型的返回值,但是您能在方法中处理它吗
此示例显示,您可以轻松打破能够处理任何返回类型的方法契约:
@SuppressWarnings("unchecked")
public <T> T returnAThing(String input){
if (input.equals("a") ) return (T) new Integer(1);
else if (input.equals("b") ) return (T)"ABC";
else return null;
}
@Test
public void test(){
Integer result1 = returnAThing("a"); //ok result is 1
Integer result2 = returnAThing("b"); //fails
}
@SuppressWarnings(“未选中”)
公共T返回(字符串输入){
if(input.equals(“a”))返回(T)个新整数(1);
否则如果(输入等于(“b”)返回(T)“ABC”;
否则返回null;
}
@试验
公开无效测试(){
整数result1=returnAThing(“a”);//确定结果为1
整数result2=returnAThing(“b”);//失败
}
我想你只有两个选择:
1) 让您的方法获取类实例,这样您就可以知道调用者希望从您那里得到什么样的返回类型。F
@SuppressWarnings("unchecked")
public <T> T returnAThing(Class<T> type, String input){
if ( input.equals("a") && type.equals(Integer.class) ) return (T) new Integer(1);
else if (input.equals("b") && type.equals(String.class) ) return (T)"ABC";
else return null;
}
@Test
public void test(){
Integer result = returnAThing(Integer.class, "a"); //ok result is 1
result = returnAThing(Integer.class, "b"); //ok result is null
}
@SuppressWarnings(“未选中”)
公共T返回(类类型,字符串输入){
if(input.equals(“a”)&&type.equals(Integer.class))返回(T)个新整数(1);
else if(input.equals(“b”)&type.equals(String.class))返回(T)“ABC”;
否则返回null;
}
@试验
公开无效测试(){
整数结果=returnAThing(Integer.class,“a”);//确定结果为1
result=returnAThing(Integer.class,“b”);//确定结果为空
}
2) 每个返回类型都有单独的方法
哪种方法更适合你?视情况而定。如果你处理的是少数几种不同的返回类型,那么就使用单独的方法。直觉上,我理解必须在某个时候进行切换
不,事实上,如果你在切换类型,你就犯了很大的错误。如果要为三种不同类型的参数执行三种不同的操作,则参数有三种不同的重载,并且没有开关。通用方法应该是通用的;你的方法实际上不是泛型的。
public void DoAThing(int inputData)
public void DoAThing(string inputData)
@SuppressWarnings("unchecked")
public <T> T returnAThing(String input){
if (input.equals("a") ) return (T) new Integer(1);
else if (input.equals("b") ) return (T)"ABC";
else return null;
}
@Test
public void test(){
Integer result1 = returnAThing("a"); //ok result is 1
Integer result2 = returnAThing("b"); //fails
}
@SuppressWarnings("unchecked")
public <T> T returnAThing(Class<T> type, String input){
if ( input.equals("a") && type.equals(Integer.class) ) return (T) new Integer(1);
else if (input.equals("b") && type.equals(String.class) ) return (T)"ABC";
else return null;
}
@Test
public void test(){
Integer result = returnAThing(Integer.class, "a"); //ok result is 1
result = returnAThing(Integer.class, "b"); //ok result is null
}