C#泛型接口专业化 [英] C# generic interface specialization

查看:204
本文介绍了C#泛型接口专业化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道如果是在任何可能的方式在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆