C# C语言中泛型数字类型的探讨#

C# C语言中泛型数字类型的探讨#,c#,generics,C#,Generics,我想知道是否有一种方法,在C#中,基于一个基元类型创建一个类型,然后复制它以使用其他基元 我知道这不是很清楚,我真的不知道如何解释这一点(英语不是我的母语,很抱歉…),所以我将尝试使用伪代码来解释它 一个简单的例子: public struct Vector2d { public double X; public double Y; //Arithmetic methods: Length, normalize, rotate, operators overloads,

我想知道是否有一种方法,在C#中,基于一个基元类型创建一个类型,然后复制它以使用其他基元

我知道这不是很清楚,我真的不知道如何解释这一点(英语不是我的母语,很抱歉…),所以我将尝试使用伪代码来解释它

一个简单的例子:

public struct Vector2d {
    public double X;
    public double Y;

    //Arithmetic methods: Length, normalize, rotate, operators overloads, etc...
}
问题是我想要一个float和一个这种类型的int32版本

我实际上在做什么(有效的C代码):

它可以工作,但并不“性感”,如果使用AsXXX方法进行大量的演员阵容转换,将不可避免地对表演产生影响

理想情况下,我会在所有三种类型上都有算术方法,但要保持

理想的解决方案是什么(伪代码,不是有效的C#):

这样,我就不会有重复的代码,更易于维护

等待您的想法:)


PS:如果主持人对如何更好地编排我的问题有想法,请随意编辑:)

你可以这样做

public struct Vector2<T> where T : IConvertible
{
    private readonly double x;
    private readonly double y;

    public Vector2(T x, T y)
    {
        this.x = x.ToDouble(CultureInfo.CurrentCulture);
        this.y = y.ToDouble(CultureInfo.CurrentCulture);
    }

    public T X
    {
        get
        {
            return ConvertBack(this.x);
        }
    }

    public T Y
    {
        get
        {
            return ConvertBack(this.y);
        }
    }

    private static T ConvertBack(double d)
    {
        return (t)Convert.ChangeType(d, typeof(T), CultureInfo.CurrentCulture); 
    }
}
public struct Vector2其中T:IConvertible
{
私有只读双x;
私人只读双y;
公共向量2(TX,TY)
{
this.x=x.ToDouble(CultureInfo.CurrentCulture);
this.y=y.ToDouble(CultureInfo.CurrentCulture);
}
公共T X
{
得到
{
返回(this.x);
}
}
公共交通
{
得到
{
返回(this.y);
}
}
专用静态T转换器(双d)
{
return(t)Convert.ChangeType(d,typeof(t),CultureInfo.CurrentCulture);
}
}

但是,如果你不想要一般治疗。然后,您还可以使用几个专门的
矢量2
类型。

下面是@mike-z使用T4模板给出的一个非常好的方法:

模板(.tt文件):


没有通用性,因此不会影响性能,代码只编写一次…

我考虑了与Jodrell建议的相同的解决方案。 我只想补充一下:

private Vector2(double x, double y)
{
 this.x = x;
 this.y = y;
}

public Vector2<E> ToVector<E>() where E : IConvertible
{
 return  new Vector2<E>(x, y);
}
专用矢量2(双x,双y)
{
这个.x=x;
这个。y=y;
}
公共向量2 ToVector(),其中E:IConvertible
{
返回新矢量2(x,y);
}

我在想
Vector2,其中T:IConvertible
有很多方法只要搜索“[C#][generics]数字”就可以得到多个结果。但这将严重影响性能。考虑到你想要使用向量,性能是这里首先要考虑的。可能的复制我没有机会经常使用它们,但T4模板可以完成这项工作。为什么你需要int和float版本?也许有另一种方法可以解决你的问题。非常有趣的方法。性能对密集使用会有什么影响?@ingham转换会减慢速度。一般来说,泛型不会对性能造成影响。现在,这种方法唯一的一个小错误是,在处理.tt文件时,缺少Syntax高亮显示,但是由于每次保存.tt文件时,.cs都会自动生成,.cs,它有Syntax高亮显示…这与我的想法一致。我只想补充一点,如果您想要定制生成的代码,您可能需要查看分部类(或结构,这里)和分部方法。
//The TYPE defined constant should be used by Vector2Body instead of plain typed "double", "float", etc...

public struct Vector2d {
    #define TYPE double
    #import Vector2Body
}

public struct Vector2f {
    #define TYPE float
    #import Vector2Body
}

public struct Vector2i {
    #define TYPE int
    #import Vector2Body
}
public struct Vector2<T> where T : IConvertible
{
    private readonly double x;
    private readonly double y;

    public Vector2(T x, T y)
    {
        this.x = x.ToDouble(CultureInfo.CurrentCulture);
        this.y = y.ToDouble(CultureInfo.CurrentCulture);
    }

    public T X
    {
        get
        {
            return ConvertBack(this.x);
        }
    }

    public T Y
    {
        get
        {
            return ConvertBack(this.y);
        }
    }

    private static T ConvertBack(double d)
    {
        return (t)Convert.ChangeType(d, typeof(T), CultureInfo.CurrentCulture); 
    }
}
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".cs" #>
using System;

namespace My.Math {
<# Vector2Body("d", "double"); #>
<# Vector2Body("f", "float"); #>
<# Vector2Body("i", "int"); #>
}

<#+ private void Vector2Body(string suffix, string t) { #>

    public struct Vector2<#= suffix #> {
        public <#= t #> X;
        public <#= t #> Y;

        //Arithmetic for <#= t #>...
    }

<#+ } #>
using System;

namespace My.Math {

    public struct Vector2d {
        public double X;
        public double Y;

        //Arithmetic for double...
    }


    public struct Vector2f {
        public float X;
        public float Y;

        //Arithmetic for float...
    }


    public struct Vector2i {
        public int X;
        public int Y;

        //Arithmetic for int...
    }

}
private Vector2(double x, double y)
{
 this.x = x;
 this.y = y;
}

public Vector2<E> ToVector<E>() where E : IConvertible
{
 return  new Vector2<E>(x, y);
}