我想知道在C#中是否有一种方法可以获得基于基本类型的类型,并将其复制以使用其他基元.
我知道它不是很清楚,我真的不知道如何解释这个(英语不是我的母语,对不起......),所以我会尝试用伪代码来解释它.
一个简单的例子:
public struct Vector2d {
public double X;
public double Y;
//Arithmetic methods: Length, normalize, rotate, operators overloads, etc...
}
Run Code Online (Sandbox Code Playgroud)
问题是我想要一个float和这种类型的int32版本.
我在做什么(有效的C#代码):
//This type contains all useful methods
public struct Vector2d {
public float X;
public float Y;
public Vector2f AsFloat() {
return new Vector2f((float)X, (float)Y);
}
public Vector2f AsInteger() {
return new Vector2i((int)X, (int)Y);
}
//Arithmetic methods
}
//These types are only here to be casted from/to, all the arithmetics methods are on the double-based type
public struct Vector2f {
public float X;
public float Y;
public Vector2f AsDouble() {
return new Vector2d(X, Y);
}
public Vector2f AsInteger() {
return new Vector2i((int)X, (int)Y);
}
}
public struct Vector2i {
public int X;
public int Y;
public Vector2f AsFloat() {
return new Vector2f(X, Y);
}
public Vector2f AsDouble() {
return new Vector2d(X, Y);
}
}
Run Code Online (Sandbox Code Playgroud)
它有效,但不是"性感",如果使用AsXXX方法进行大量演员表演,将不可避免地对演出产生影响.
理想情况下,我会在所有三种类型上都使用算术方法,但维持......会很痛苦...
什么是理想的解决方案(伪代码,无效的C#):
public struct Vector2<T> where T : numeric {
public T X;
public T Y;
public T Length {
return (T)Math.Sqrt(X * X + Y * Y);
}
//Other arithmetic methods
}
Run Code Online (Sandbox Code Playgroud)
我知道目前在C#中这是不可能的,但这是真正的问题:
你对如何妥善有效地处理这个有任何想法吗?
我一直在想的(伪代码,无效的C#):
//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
}
Run Code Online (Sandbox Code Playgroud)
这样,我就不会有重复的代码,更容易维护
等待你的想法:)
PS:如果版主有关于如何更好地格式化我的问题的想法,请随时编辑它:)
这是@ mike-z使用T4模板给出的非常好的方法:
模板(.tt文件):
<#@ 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 #>...
}
<#+ } #>
Run Code Online (Sandbox Code Playgroud)
并自动生成代码:
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...
}
}
Run Code Online (Sandbox Code Playgroud)
没有通用,所以没有性能影响,代码写一次......