C# 泛型类-C的字段约束#
我想在C#中创建一个库,它可以处理Point对象,但在C#中有很多框架都有很多Point的实现:Point、Vector2f(unity)、Vector2f(monogame)、Vector3f。。。我希望我的图书馆能和他们一起工作 唯一的约束是对象具有属性X和Y,并且X和Y必须实现IComparable接口。问题是我找不到一种不使用反射的方法(我认为这不是最好的方法) 我不希望所有类点都继承自我的接口,但我希望它们有两个字段/成员X和Y 有办法吗?像C# 泛型类-C的字段约束#,c#,unity3d,monogame,C#,Unity3d,Monogame,我想在C#中创建一个库,它可以处理Point对象,但在C#中有很多框架都有很多Point的实现:Point、Vector2f(unity)、Vector2f(monogame)、Vector3f。。。我希望我的图书馆能和他们一起工作 唯一的约束是对象具有属性X和Y,并且X和Y必须实现IComparable接口。问题是我找不到一种不使用反射的方法(我认为这不是最好的方法) 我不希望所有类点都继承自我的接口,但我希望它们有两个字段/成员X和Y 有办法吗?像 class MyAlgo<T>
class MyAlgo<T> : where T has X and Y properties {}
类MyAlgo:其中T具有X和Y属性{}
您不能在编译时检查它,因为如果您不希望所有类都继承一个公共接口或创建大量适配器,C#无法满足您的需要
在运行时,反射是实现这一点的唯一方法。反思并不总是那么糟糕,它只取决于你如何实现事情。事实上,反思的第一个问题是表现
如果您在每次调用中都使用它,它可能会带来很大的开销。但是,如果您在静态构造函数中检查它,那么该检查将只应用一次,并且在正常执行时不会产生任何开销
class MyAlgo<T>
{
static private Func<T, int> X;
static private Func<T, int> Y;
static MyAlgo()
{
//check here!
var type = typeof(T);
var x = type.GetProperty("X");
if (x == null) { throw new NotSupportedException($"missing X property in { type }"); }
var y = type.GetProperty("Y");
if (y == null) { throw new NotSupportedException($"missing Y property in { type }"); }
// you can store delegate to retreive X & Y in static fields.
MyAlgo<T>.X = Delegate.CreateDelegate(typeof(Func<T, int>), x.GetGetMethod());
MyAlgo<T>.Y = Delegate.CreateDelegate(typeof(Func<T, int>), y.GetGetMethod());
}
}
类MyAlgo
{
静态私有函数X;
静态私有函数;
静态MyAlgo()
{
//检查这里!
var类型=类型(T);
var x=type.GetProperty(“x”);
如果(x==null){throw new NotSupportedException($“在{type}中缺少x属性”);}
var y=type.GetProperty(“y”);
如果(y==null){抛出新的NotSupportedException($“在{type}中缺少y属性”);}
//您可以在静态字段中存储要检索X&Y的委托。
MyAlgo.X=Delegate.CreateDelegate(typeof(Func),X.getMethod());
MyAlgo.Y=Delegate.CreateDelegate(typeof(Func),Y.getMethod());
}
}
您不能在编译时检查它,因为如果您不希望所有类都继承一个公共接口或创建大量适配器,C#无法满足您的需要
在运行时,反射是实现这一点的唯一方法。反思并不总是那么糟糕,它只取决于你如何实现事情。事实上,反思的第一个问题是表现
如果您在每次调用中都使用它,它可能会带来很大的开销。但是,如果您在静态构造函数中检查它,那么该检查将只应用一次,并且在正常执行时不会产生任何开销
class MyAlgo<T>
{
static private Func<T, int> X;
static private Func<T, int> Y;
static MyAlgo()
{
//check here!
var type = typeof(T);
var x = type.GetProperty("X");
if (x == null) { throw new NotSupportedException($"missing X property in { type }"); }
var y = type.GetProperty("Y");
if (y == null) { throw new NotSupportedException($"missing Y property in { type }"); }
// you can store delegate to retreive X & Y in static fields.
MyAlgo<T>.X = Delegate.CreateDelegate(typeof(Func<T, int>), x.GetGetMethod());
MyAlgo<T>.Y = Delegate.CreateDelegate(typeof(Func<T, int>), y.GetGetMethod());
}
}
类MyAlgo
{
静态私有函数X;
静态私有函数;
静态MyAlgo()
{
//检查这里!
var类型=类型(T);
var x=type.GetProperty(“x”);
如果(x==null){throw new NotSupportedException($“在{type}中缺少x属性”);}
var y=type.GetProperty(“y”);
如果(y==null){抛出新的NotSupportedException($“在{type}中缺少y属性”);}
//您可以在静态字段中存储要检索X&Y的委托。
MyAlgo.X=Delegate.CreateDelegate(typeof(Func),X.getMethod());
MyAlgo.Y=Delegate.CreateDelegate(typeof(Func),Y.getMethod());
}
}
你在这里所说的叫做。(如果它看起来像只鸭子,嘎嘎叫起来像只鸭子,那它一定是只鸭子,对吧?)
C#不完全支持传统意义上的duck类型。大多数强类型编译语言没有此功能(afaik)。然而,正如您在维基百科上看到的,您可能可以使用动态
如前所述,反射实际上是唯一的方法,我对它的理解是
dynamic
实际上只是在引擎盖下使用反射。如果性能是一个问题(在本例中可能是这样),您应该尝试几种不同的方法和度量。A似乎表明它相当复杂,但至少值得一试。这里所说的是“名称”。(如果它看起来像只鸭子,嘎嘎叫起来像只鸭子,那它一定是只鸭子,对吧?)
C#不完全支持传统意义上的duck类型。大多数强类型编译语言没有此功能(afaik)。然而,正如您在维基百科上看到的,您可能可以使用动态
如前所述,反射实际上是唯一的方法,我对它的理解是
dynamic
实际上只是在引擎盖下使用反射。如果性能是一个问题(在本例中可能是这样),您应该尝试几种不同的方法和度量。A似乎表明它相当复杂,但至少值得一试。为什么不希望它们继承接口?怎么了?你可以在地狱脸上声明你的财产,这会让你的生活更美好simpler@FCin-他不能让他们从他的界面继承。。。这些是来自不同领域的现有类frameworks@GiladGreen哦,我误解了他的问题。@FCin-不用担心:)无论如何,这是一个很好的想法,它们中的大多数都是struct
而不是class
,理由很充分,所以请记住为什么不希望它们继承接口?怎么了?你可以在地狱脸上声明你的财产,这会让你的生活更美好simpler@FCin-他不能让他们从他的界面继承。。。这些是来自不同领域的现有类frameworks@GiladGreen哦,我误解了他的问题。@FCin-不用担心:)不管怎样,这都是一个很好的想法,他们中的大多数人都是struct
而不是class
,理由很充分,所以记住这是一个很好的解决办法,可以避免在C#中没有特征(如生锈)。在编写既适用于我自己的数据类型又适用于第三方数据类型的算法时,我也不得不做过几次同样的事情。这是一个很好的解决办法,可以避免在C#中出现特性(如Rust)。在编写同时适用于我自己的数据类型和第三方数据类型的算法时,我也不得不这样做过几次。