C#泛型接口专业化 [英] C# generic interface specialization
问题描述
我不知道如果是在任何可能的方式在C#中莫名其妙地专注通用接口的方法呢?我也发现了类似的问题,但没有完全一样。现在,我猜想,答案是不,你不能,但我想有它证实。
I wonder if it is in any way possible to specialize generic interface methods somehow in C#? I have found similar questions, but nothing exactly like this. Now I suspect that the answer is "No, you can't" but I would like to have it confirmed.
我已经是像下面这样。
public interface IStorage
{
void Store<T>(T data);
}
public class Storage : IStorage
{
public void Store<T>(T data)
{
Console.WriteLine("Generic");
}
public void Store(int data)
{
Console.WriteLine("Specific");
}
}
class Program
{
static void Main(string[] args)
{
IStorage i = new Storage();
i.Store("somestring"); // Prints Generic
i.Store(1); // Prints Generic
Storage s = (Storage)i;
s.Store("somestring"); // Prints Generic
s.Store(1); // Prints Specific
}
}
有没有什么办法让它使用Store的特殊版本通过接口调用时?如果没有的话,没有人知道确切的原因,C#把通用参数这样
Is there any way to make it use the specialized version of Store when called through the interface? And if not, does anyone know the exact reason why C# treats Generic arguments this way?
编辑:
中的问题可能如果不是被身边工作。因此C#无法解决模板参数在多个一步
The issue could be worked around if it wasn't so that C# cannot resolve template arguments in more than one step.
void Foo<T>(T t)
{
SubFoo(t);
}
void SubFoo<T>(T t)
{
Console.WriteLine("Generic");
}
void SubFoo(int t)
{
Console.WriteLine("Specific");
}
要foo的调用(1)在这里将打印一般为好,不应该编译器能够解决呢?抑或是JIT防止这种情况?
A call to Foo(1) here will print "Generic" as well, shouldn't the compiler be able to resolve this? Or does the JIT prevent this?
推荐答案
。类型传递的值
IStorage i = new Storage();
i.Store("somestring"); // Prints Generic
i.Store(1); // Prints Generic
这将始终调用通用的方法,因为只有一个过载商店
在的IStorage
和编译器不知道 I
实际上包含存储
对象。编译器如何知道关于存储
?
This will always call the "generic" method, because there is only one overload of Store
in IStorage
and the compiler doesn't know that i
actually contains a Storage
object. How can the compiler know about the other overload in Storage
?
Storage s = (Storage)i;
s.Store("somestring"); // Prints Generic
s.Store(1); // Prints Specific
下面,编译器知道取值
包含存储
对象(或一个从存储
导出),因为取值
声明的方式。因此,它看到两个重载。它选择了 INT
中值的特定超载,因为超载解决规则说更喜欢普通的重载特定的过载。
Here, the compiler knows that s
contains a Storage
object (or one deriving from Storage
), because s
is declared that way. So it sees two overloads. It chooses the specific overload for int
values, because overload resolution rules say to prefer specific overloads over generic overloads.
这是技术上是可行的,确定的typeof(T)
在运行时的一般方法和方法调用转发到特定的方法。但是,如果你仔细想想,这没有很大的意义。泛型方法意味着同样实现适用于不同的,不相关类型的参数。如果你想不同的实现对于不同类型的,你不应该使用泛型这一点。
It's technically possible to determine typeof(T)
in the generic method at run-time and forward the method call to a specific method. But if you think about it, this doesn't make a lot of sense. A generic method means that the same implementation works for arguments of different, unrelated types. If you want different implementations for different types, you shouldn't use generics for this.
void Foo<T>(T t)
{
SubFoo(t);
}
void SubFoo<T>(T t);
void SubFoo(int t);
泛型工作从C ++模板有点不同。 C#编译器编译美孚只有一次 - 到一个通用的方法。记住:通用方法对不同类型相同的实现。 C#编译器不知道在编译时如果T将是一个 INT
或字符串
或其他任何类型。所以唯一可能实现的Foo,对于任意t工作是调用SubFoo< T&取代。如果SubFoo重载之一,将取决于对T被调用,美孚的执行将不会对所有的T更多的是一样的。
Generics work quite a bit different from C++ templates. The C# compiler compiles Foo only once -- to a generic method. Remember: generic means same implementation for different types. The C# compiler does not know at compile-time if T is going to be an int
or a string
or any other type. So the only possible implementation of Foo that works for any T is to call SubFoo<T>. If one of the SubFoo overloads would be called depending on T, the implementation of Foo wouldn't be the same for all T any more.
这篇关于C#泛型接口专业化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!