C#专门用于泛型类

Nos*_*ion 5 c# generics template-specialization

是否可以在C#中进行以下专业化?我可以用C++做到这一点,但不了解如何在C#中实现相同的结果.

class GenericPrinter<T>
{
    public void Print()
    {
        Console.WriteLine("Unspecialized method");
    }
}

class GenericPrinter<int>
{
    public void Print()
    {
         Console.WriteLine("Specialized with int");
    }
}
Run Code Online (Sandbox Code Playgroud)

添加:

建议的GenericPrinterInt解决方案的问题是我需要明确地创建它.new GenericPrinter<int>仍然会打印Unspecialized method.

我想要的是使用来自另一个泛型类的GenericPrinter,而knoledge是T等于int或其他东西.

rom*_*aga 8

我想你可以在C#中获得的距离越近:

class GenericPrinter<T>
{
    public virtual void Print()
    {
        Console.WriteLine("Unspecialized method");
    }
}

class IntPrinter : GenericPrinter<int>
{
    public override void Print()
    {
         Console.WriteLine("Specialized with int");
    }
}
Run Code Online (Sandbox Code Playgroud)

否则,答案是,你不能专攻C#.

正如Lyubomyr Shaydariv在评论中所说:

C++模板不是.NET泛型.你不能.


从你的编辑我想你会有一些类型检查.

例如,您可以使用字典来完成此操作.

class GenericPrinter<T>
{
    private Dictionary<Type, Action> _actions
        = new Dictionary<Type, Action>()
    {
        { typeof(int), PrintInt }
    };

    public virtual void Print()
    {
        foreach (var pair in _actions)
            if (pair.First == typeof(T))
            {
                pair.Second();
                return ;
            }
        Console.WriteLine("Unspecialized method");
    }

    public virtual void PrintInt()
    {
        Console.WriteLine("Specialized with int");
    }
}
Run Code Online (Sandbox Code Playgroud)

就像你可以看到的那样,你必须为你想要处理的每种类型创建一个方法.当您尝试将T操作为int时,您可能还会遇到一些问题.因为,T实在是通用的(它没有任何约束),则更有可能充当object在你的代码(不是在运行时),你将不得不投它就像(int)(object)yourTVariable在你的方法,你确信这里T是一个int.

但对于这一部分,我想我的一些同行,会得到比我更好的答案给你.


如果它只是显示您正在使用的类型:

public virtual void Print()
{
    Console.WriteLine($"Specialized with {typeof(T).Name}");
}
Run Code Online (Sandbox Code Playgroud)

但是你不会再有非特殊化的消息了(如果你想一想,你就不能在没有指定类型的情况下实例化GenericPrinter.那么有一个方法显示"unspecialized"是没有意义的,你将永远拥有指定的类型)

无论如何,答案仍然是相同的,你不能专门在C#中使用泛型.

  • Voteup的速度.你快了1分钟.;) (2认同)

Dmi*_*try 5

在C#中是不可能的。
您可以改用继承:

class GenericPrinter<T>
{
    public virtual void Print()
    {
        Console.WriteLine("Unspecialized method");
    }
}

class GenericPrinterInt : GenericPrinter<int>
{
    public override void Print()
    {
        Console.WriteLine("Specialized with int");
    }
}
Run Code Online (Sandbox Code Playgroud)

根据更新后的问题,我只能建议您采用以下方法。您可以创建一个静态工厂方法,在其中可以检查的类型,T并在类型符合条件的情况下实例化适当的专用类:

class GenericPrinter<T>
{
    public static GenericPrinter<T> Create()
    {
        if (typeof(int).IsAssignableFrom(typeof(T)))
            return (GenericPrinter<T>)(object)new GenericPrinterInt();

        if (typeof(double).IsAssignableFrom(typeof(T)))
            return (GenericPrinter<T>)(object)new GenericPrinterDouble();

        // Other types to check ...

        return new GenericPrinter<T>();
    }

    public virtual void Print()
    {
        Console.WriteLine("Unspecialized method");
    }
}

class GenericPrinterInt : GenericPrinter<int>
{
    public override void Print()
    {
        Console.WriteLine("Specialized with int");
    }
}

class GenericPrinterDouble : GenericPrinter<double>
{
    public override void Print()
    {
        Console.WriteLine("Specialized with double");
    }
}
Run Code Online (Sandbox Code Playgroud)

其他一些通用类:

class SomeGenericClass<T>
{
    public readonly GenericPrinter<T> Printer = GenericPrinter<T>.Create();
}
Run Code Online (Sandbox Code Playgroud)

用法样本:

var intClass = new SomeGenericClass<int>();
intClass.Printer.Print();
// Output: Specialized with int

var doubleClass = new SomeGenericClass<double>();
doubleClass.Printer.Print();
// Output: Specialized with double

var stringClass = new SomeGenericClass<string>();
stringClass.Printer.Print();
// Output: Unspecialized method
Run Code Online (Sandbox Code Playgroud)

  • 我们之间只有一分钟的时间,我们得到的答案完全相同x) (2认同)