首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在C#中进行模板专门化

如何在C#中进行模板专门化
EN

Stack Overflow用户
提问于 2009-03-02 01:23:05
回答 5查看 71.1K关注 0票数 91

您将如何在C#中进行专业化?

我会提出一个问题。你有一个模板类型,你不知道它是什么。但是你知道如果它是从XYZ派生的,你想调用.alternativeFunc()。一种很好的方法是调用一个专门的函数或类,让normalCall返回.normalFunc(),同时在任何派生类型的XYZ上进行其他专门化,以调用.alternativeFunc()。在C#中如何做到这一点?

EN

回答 5

Stack Overflow用户

发布于 2009-03-02 01:45:29

假设您谈论的是模板专门化,因为它可以使用C++模板来完成-这样的功能在C#中并不真正可用。这是因为C#泛型在编译期间不会被处理,而更多的是运行时的一个特性。

但是,您可以使用C# 3.0扩展方法来实现类似的效果。下面的示例展示了如何仅为MyClass<int>类型添加扩展方法,这就像模板专门化一样。但是请注意,您不能使用它来隐藏该方法的默认实现,因为C#编译器总是首选标准方法而不是扩展方法:

代码语言:javascript
复制
class MyClass<T> {
  public int Foo { get { return 10; } }
}
static class MyClassSpecialization {
  public static int Bar(this MyClass<int> cls) {
    return cls.Foo + 20;
  }
}

现在你可以这样写了:

代码语言:javascript
复制
var cls = new MyClass<int>();
cls.Bar();

如果您希望在没有提供专门化的情况下使用该方法的默认情况,那么我相信编写一个通用的Bar扩展方法应该可以做到这一点:

代码语言:javascript
复制
  public static int Bar<T>(this MyClass<T> cls) {
    return cls.Foo + 42;
  }
票数 65
EN

Stack Overflow用户

发布于 2015-04-01 05:53:49

我也在寻找一种模式来模拟模板专门化。有一些方法在某些情况下可能会起作用。然而,这个案例呢?

代码语言:javascript
复制
static void Add<T>(T value1, T value2)
{
    //add the 2 numeric values
}

可以使用语句选择操作,例如if (typeof(T) == typeof(int))。但有一种更好的方法来模拟真实的模板专门化,只需一个虚拟函数调用的开销:

代码语言:javascript
复制
public interface IMath<T>
{
    T Add(T value1, T value2);
}

public class Math<T> : IMath<T>
{
    public static readonly IMath<T> P = Math.P as IMath<T> ?? new Math<T>();

    //default implementation
    T IMath<T>.Add(T value1, T value2)
    {
        throw new NotSupportedException();    
    }
}

class Math : IMath<int>, IMath<double>
{
    public static Math P = new Math();

    //specialized for int
    int IMath<int>.Add(int value1, int value2)
    {
        return value1 + value2;
    }

    //specialized for double
    double IMath<double>.Add(double value1, double value2)
    {
        return value1 + value2;
    }
}

现在,我们可以编写代码,而不必事先知道类型:

代码语言:javascript
复制
static T Add<T>(T value1, T value2)
{
    return Math<T>.P.Add(value1, value2);
}

private static void Main(string[] args)
{
    var result1 = Add(1, 2);
    var result2 = Add(1.5, 2.5);

    return;
}

如果不仅应该为实现的类型调用专门化,而且还应该为派生类型调用专门化,则可以对接口使用In参数。但是,在这种情况下,方法的返回类型不能再是泛型类型T

票数 16
EN

Stack Overflow用户

发布于 2018-03-02 23:56:47

我认为有一种方法可以通过.NET 4+使用动态解析来实现:

代码语言:javascript
复制
static class Converter<T>
{
    public static string Convert(T data)
    {
        return Convert((dynamic)data);
    }

    private static string Convert(Int16 data) => $"Int16 {data}";
    private static string Convert(UInt16 data) => $"UInt16 {data}";
    private static string Convert(Int32 data) => $"Int32 {data}";
    private static string Convert(UInt32 data) => $"UInt32 {data}";
}

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(Converter<Int16>.Convert(-1));
        Console.WriteLine(Converter<UInt16>.Convert(1));
        Console.WriteLine(Converter<Int32>.Convert(-1));
        Console.WriteLine(Converter<UInt32>.Convert(1));
    }
}

输出:

代码语言:javascript
复制
Int16 -1
UInt16 1
Int32 -1
UInt32 1

这表明为不同的类型调用了不同的实现。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/600978

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档