方法重载类型C#
我想知道以下是否可能。创建一个接受匿名类型(string,int,decimal,customObject等)的类,然后重载基于类型执行不同操作的方法。例如方法重载类型C#
class TestClass<T>
{
public void GetName<string>()
{
//do work knowing that the type is a string
}
public string GetName<int>()
{
//do work knowing that the type is an int
}
public string GetName<int>(int addNumber)
{
//do work knowing that the type is an int (overloaded)
}
public string GetName<DateTime>()
{
//do work knowing that the type is a DateTime
}
public string GetName<customObject>()
{
//do work knowing that the type is a customObject type
}
}
所以,现在我可以调用GetName方法,因为我已经在类型过去了我初始化的对象,正确的方法是发现和执行。
TestClass foo = new TestClass<int>();
//executes the second method because that's the only one with a "int" type
foo.GetName();
这是可能的还是我只是在做梦?
你试图做的是可能是这样的:
class TestClass<T>
{
public string GetName<T>()
{
Type typeOfT = typeof(T);
if(typeOfT == typeof(string))
{
//do string stuff
}
}
}
虽然这是可能的,你是那种击败仿制药的目的。泛型的一点是当型不是的问题时,所以我不认为泛型在这种情况下是合适的。
会使用类扩展方法吗?
你基本上可以将方法添加到你想要的类,然后你可以用同样的方法调用它。
namespace ExtensionMethods
{
public static class MyExtensions
{
public static int GetName(this String str)
{
...
}
}
}
使用称为:
myString.GetName();
“专业化”,在C#是不可能的它是在C++的方式。在.NET泛型中,对于T的所有可能值,通用类或方法<T>必须相同。这允许运行时执行两种不同参考类型的优化,例如TestClass <字符串>和TestClass <列表<int> >,共享相同的机器语言代码。 (不同的值类型获得单独的机器代码,但你仍然无法专注。)
我发现它有时帮助创建一个通用的接口或基类是这样的:
abstract class Base<T> {
public abstract T GetName();
// any common code goes here that does not require specialization
}
而且在衍生做到专业化类别:
class IntVersion : Base<int> {
public override int GetName() { return 1; }
public int GetName(int addNumber) { ... }
}
class StringVersion : Base<string> {
public override string GetName() { return "foo"; }
}
class DateTimeVersion : Base<DateTime> {
public override DateTime GetName() { return DateTime.Now; }
}
不,这是不可能的。你想要做的是类似于C++中的模板专门化,这在C#中(可惜)是不可能的。
你需要
typeof(T)
到的if/else或开关来调用特定的实现。
但是,可以约束T的类型为一个类(基准值)或结构(值)或特定基类的子类,像这样:
public Foo<T> DoBar<T>() where T : FooBase;
C#不具有用于支撑这种调度。
只要<>内部不是方法签名的一部分,这也是做方法重载的不正确方法(Error'TestClass'已经定义了一个名为'GetName'的成员具有相同的参数类型)。
专业化在C#中是不可能的。在C#中最接近的东西是以下内容
public void Example() {
public static void Method<T>(T value) { ... }
public static void Method(int value){ ... }
public static void Method(string) { ... }
}
C#编译器将优先于通用方法的非泛型方法。这意味着使用int参数进行调用将绑定到int重载与通用重载之间。
Example.Method(42); // Method(int)
Example.Method(new Class1()) // Method<T>(T)
这会咬你,因为这种方法一般称为不适用。在这种情况下,无论类型如何,它都会绑定到泛型重载。
public void Gotcha<T>(T value) {
Example.Method(value);
}
Gotcha(42); // Still calls Example.Method<T>()
如果你需要在你的类中做类型特定的工作,那么你的类不是通用的。你应该为每个你想要处理的类型创建一个单独的类。如果某些功能确实具有通用的理由,那么可以将它放在通用的基类中。
一个例子:
abstract class TestClass<T>
{
public List<T> Items { get; set; }
// other generic (i.e. non type-specific) code
}
class IntTestClass : TestClass<int>
{
public string GetName()
{
// do work knowing that the type is an int
}
// other code specific to the int case
}
class StringTestClass : TestClass<string>
{
public string GetName()
{
// do work knowing that the type is a string
}
// other code specific to the string case
}
由于贝丽提到的,你可以,如果树,或者更可能的switch语句有做到这一点,但在某些时候你会希望你可以只写方法,让净弄明白,特别是如果你随着时间的推移增长超负荷库。
的解决方案有反映,虽然它是相当便宜的性能代价在.net:
using System.Reflection;
...
public string DoSomething(object val)
{
// Force the concrete type
var typeArgs = new Type[] { val.GetType() };
// Avoid hard-coding the overloaded method name
string methodName = new Func<string, string>(GetName).Method.Name;
// Use BindingFlags.NonPublic instead of Public, if protected or private
var bindingFlags = BindingFlags.Public | BindingFlags.Instance;
var method = this.GetType().GetMethod(
methodName, bindingFlags, null, typeArgs, null);
string s = (string)method.Invoke(this, new object[] { val });
return s;
}
你基本上只是告诉了思考框架去做到这一点switch语句你。
+1 Generics!=模板 – user7116 2009-10-22 17:11:56