Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 泛型或多个类_C#_Generics - Fatal编程技术网

C# 泛型或多个类

C# 泛型或多个类,c#,generics,C#,Generics,现在我们有两个结构来表示二维点 public struct Point2D { public double X { get; set; } public double Y { get; set; } } public struct Point2DF { public float X { get; set; } public float Y { get; set; } } 现在我们需要制作另一个结构来表示整数的2d点 public struct Point2DI

现在我们有两个结构来表示二维点

public struct Point2D
{
    public double X { get; set; }
    public double Y { get; set; }
}

public struct Point2DF
{
    public float X { get; set; }
    public float Y { get; set; }
}
现在我们需要制作另一个结构来表示整数的2d点

public struct Point2DI
{
    public int X { get; set; }
    public int Y { get; set; }
}
我的问题是我应该在这里使用泛型吗?如果我使用泛型,我将有一个结构而不是三个

public struct Point<T>
{
    public T X { get; set; }
    public T Y { get; set; }
}
公共结构点
{
公共tx{get;set;}
公共T{get;set;}
}

但使用者可以将T设置为字符串或某个类/结构。我该怎么办?有什么方法可以强制T为double/int/float吗?

您不能为数字类型创建约束,最接近的方法是:

public struct Point<T> where T:struct, IComparable

我认为最好使用泛型,因为如果您不需要多个类、继承或任何其他花哨的东西(这也可以工作,但在我看来它不会那么干净),那么泛型会更干净

不幸的是,数字类型没有约束,因此我提出了以下内容:

public class Point<T>
    where T : struct, IComparable, IFormattable, IConvertible, IComparable<T>, IEquatable<T>
{

    protected readonly Type[] AllowedTypes = 
        {
            typeof(decimal), typeof(double), typeof(short), typeof(int), typeof(long),
            typeof(sbyte), typeof(float), typeof(ushort), typeof(uint), typeof(ulong)
        };

    public Point()
    {   
        if (!this.AllowedTypes.Contains(typeof(T)))
        {
            throw new NotSupportedException(typeof(T).ToString());
        }           
    }

    public T X { get; set; }

    public T Y { get; set; }

    // UPDATE: arithmetic operations require dynamic proxy-Properties or
    // variables since T is not explicitly numeric... :(
    public T CalculateXMinusY()
    {
        dynamic x = this.X;
        dynamic y = this.Y;

        return x - y;
    }
}
公共类点
其中T:struct,i可比较,i可附加,i可转换,i可比较,i可计算
{
受保护的只读类型[]AllowedTypes=
{
typeof(十进制)、typeof(双精度)、typeof(短)、typeof(int)、typeof(长),
类型化(sbyte)、类型化(float)、类型化(ushort)、类型化(uint)、类型化(ulong)
};
公共点()
{   
如果(!this.AllowedTypes.Contains(typeof(T)))
{
抛出新的NotSupportedException(typeof(T).ToString();
}           
}
公共tx{get;set;}
公共T{get;set;}
//更新:算术运算需要动态代理属性或
//变量,因为T不是显式数字…:(
公共T计算最小值()
{
动态x=这个.x;
动态y=这个.y;
返回x-y;
}
}
它为您提供了最大的智能感知支持,同时建议主要有效的输入,但如果使用不当,仍然会失败。所有这些都只使用一个干净、可读且可维护的类


唯一有点难看的是,巨大的泛型类型约束,但这是C#中所有数字类型的共同点,因此最好这样做。

泛型在这里对您没有任何帮助。您最好创建多个类型。正如在另一个问题中解释的,您不能对数字类型进行约束遗憾的是,这是不可能的。你要么接受它(可能添加运行时类型检查),要么坚持使用单独的类型。C没有
数值
类(就像Java那样),所以,唉,泛型没有帮助。我想我们将无法对此执行算术运算。我也将无法获得T的扩展方法(我们已经编写了一些)。我想我的问题没有答案。这是真的,因为我所有的计算都发生在类内,所以我分配了所需的值(<代码> x 和<代码> y>代码>在您的情况下),到<代码>动态< /COD>变量,这使我能够对它执行算术运算。也许这有帮助。我将以一个例子更新我的答案。更新我的答案。如果这是经常需要的,你应该考虑做一个被保护的属性,这样做“转换”。.但是用这种方法做数学是可能的(尽管这不是最明显的事情)
public class Point<T>
    where T : struct, IComparable, IFormattable, IConvertible, IComparable<T>, IEquatable<T>
{

    protected readonly Type[] AllowedTypes = 
        {
            typeof(decimal), typeof(double), typeof(short), typeof(int), typeof(long),
            typeof(sbyte), typeof(float), typeof(ushort), typeof(uint), typeof(ulong)
        };

    public Point()
    {   
        if (!this.AllowedTypes.Contains(typeof(T)))
        {
            throw new NotSupportedException(typeof(T).ToString());
        }           
    }

    public T X { get; set; }

    public T Y { get; set; }

    // UPDATE: arithmetic operations require dynamic proxy-Properties or
    // variables since T is not explicitly numeric... :(
    public T CalculateXMinusY()
    {
        dynamic x = this.X;
        dynamic y = this.Y;

        return x - y;
    }
}