C# 类型的方法重载
我想知道以下是否可能。创建一个接受匿名类型(string、int、decimal、customObject 等)的类,然后具有根据类型执行不同操作的重载方法。示例
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();
这是可能的还是我只是在做梦?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
您尝试做的事情是可能的,如下所示:
虽然这是可能的,但您有点违背了泛型的目的。泛型的要点是当类型不重要时,所以我认为泛型在这种情况下不合适。
What you're trying to do is possible like this:
While this is possible, you're kind of defeating the purpose of generics. The point of generics is when the type doesn't matter, so I don't think generics is appropriate in this case.
“专业化”在 C# 中不可能像在 C++ 中那样。在 .NET 泛型中, 的泛型类或方法可以被定义为泛型。对于 T 的所有可能值必须相同。这允许运行时对两种不同的引用类型(例如 TestClass)进行优化。和 TestClass
> 共享相同的机器语言代码。 (不同的值类型获得单独的机器代码,但您仍然无法专门化。)
我发现有时有助于创建像这样的通用接口或基类:
并在派生类中进行专门化:
"Specialization" is not possible in C# the way it is in C++. In .NET generics, a generic class or method of <T> must be the same for all possible values of T. This allows the runtime to do an optimization that two different reference types, say TestClass<string> and TestClass<List<int>>, share the same machine language code. (different value types get separate machine code, but you still can't specialize.)
I find it sometimes helps to create a generic interface or base class like this:
And do specialization in derived classes:
C# 中不可能进行专业化。 C# 中最接近的内容如下:
C# 编译器会优先选择非泛型方法而不是泛型方法。这意味着使用 int 参数调用将绑定到 int 重载而不是通用重载。
但这会让您感到困扰,因为当一般调用该方法时,这并不适用。在这种情况下,无论类型如何,它都会绑定到泛型重载。
Specialization is not possible in C#. The closest thing in C# is the following
The C# compiler will prefer a non-generic method over a generic method. This means that calling with an int paramater will bind to the int overload vs. the generic one.
This will bite you though because this does not apply when the method is called generically. In that case it will bind to the generic overload no matter the type.
不,这是不可能的。您尝试做的事情类似于 C++ 中的模板专业化,(遗憾的是)这在 C# 中是不可能的。
您需要 if/else 或 switch on
来调用专门的实现。
但是,您可以将 T 的类型限制为类(引用值)或结构(值)或某个基类的子类,如下所示:
No, this is not possible. What you are trying to do is similar to template specialization in C++, which is (sadly) not possible in C#.
You need to if/else or switch on
to invoke specialized implementations.
However, you can constraint the type of T to be either a class (reference Value) or struct (value) or subclass of a certain baseclass like so:
c# 不支持此类调度。
这也不是进行方法重载的正确方法(Error'TestClass' 已经定义了一个名为 'GetName' 且具有相同参数类型的成员),只要 <> 内的所有内容都正确。不是方法签名的一部分。
c# doesn't have support for such dispatching.
and this is not right way for doing method overloading also (Error'TestClass' already defines a member called 'GetName' with the same parameter types) as long as all inside <> is not a part of method signature.
使用类扩展方法对您有用吗?
您本质上可以向所需的类添加方法,然后可以以相同的方式调用它。
调用使用:
Would using class extension methods work for you?
You can essentially add methods to the classes you want, and then you can call it the same way.
called using:
如果您需要在类中执行特定于类型的工作,那么您的类就不是通用的。您可能应该为要处理的每种类型创建一个单独的类。如果某些功能确实有适当的理由成为通用的,则可以将其放入公共基类中。
一个例子:
If you need to do type-specific work in your class, then your class is not generic. You should probably make a seperate class for each type you want to handle. If there is some functionality that does have a proper reason for being generic, you can put it in an common base class.
An example:
正如 BFree 提到的,您可以使用 if 树或更可能是 switch 语句来做到这一点,但在某些时候您会希望只编写方法并让 .Net 来解决它,特别是如果您随着时间的推移增加重载库的话。
解决方案是反射,尽管它在 .Net 中的性能相当便宜:
您基本上只是告诉反射框架为您执行该 switch 语句。
As BFree mentioned you can do this with an if tree, or more likely a switch statement, but at some point you'll wish you could just write methods and let .Net figure it out, especially if you grow the library of overloads over time.
The solution there is reflection, although it is pretty cheap performance-wise in .Net:
You're basically just telling the Reflection framework to go do that switch statement for you.