简体   繁体   English

C#泛型类:如何限制成员函数与特定类型一起使用?

[英]c# generic class: how can I restrict a member function to be used with specific types?

I have a generic class CGeometryCalibration2D<T> which can be used with numeric types like int , double , float , and my custom type CLocation . 我有一个通用类CGeometryCalibration2D<T> ,它可以与intdoublefloat和我的自定义类型CLocation这样的数字类型一起使用。
(less important) question 1: how can I restrict T to one of these types? (不太重要)问题1:如何将T限制为这些类型之一?

Inside this class, there is a function 在此类中,有一个函数

double InterpolateReverse (T i_Value);

which should be used only with CLocation as T . 仅应在CLocationT

I don't know any way to apply such a restriction. 我不知道有什么办法可以应用这种限制。
I already tried extension methods, which would do exactly this restriction 我已经尝试过扩展方法,它可以完全满足此限制

double InterpolateReverse (this CGeometricCalibration2D<CLocation>, CLocation i_Value);

but they don't allow access to private members. 但他们不允许访问私人成员。 I could work around this limitation by using Reflection, but that's not the nicest way. 我可以通过使用反射来解决此限制,但这不是最好的方法。

What can I do here? 我在这里可以做什么?
Should I maybe find a completely different approach? 我是否应该找到一种完全不同的方法?

The only remaining idea I have is overloading the generic class by concrete implmentations and adding the function there, like 我唯一剩下的想法是通过具体的实现重载泛型类并在其中添加函数,例如

CGeometricCalibration2D_CLocation : CGeometricCalibration2D<CLocation>
{
  double InterpolateReverse (CLocation i_Value);
}

but then I need to have an object of the concrete type CGeometricCalibration2D_CLocation in order to execute InterpolateReverse () 但是然后我需要有一个具体类型为CGeometricCalibration2D_CLocation的对象才能执行InterpolateReverse ()

I have a generic class CGeometryCalibration2D<T> which can be used with numeric types like int, double, float, and my custom type CLocation. 我有一个通用类CGeometryCalibration2D<T> ,可以与int,double,float和我的自定义类型CLocation这样的数字类型一起使用。

That doesn't sound like a generic type. 这听起来不像泛型。

how can I restrict T to one of these types. 如何将T限制为这些类型之一。

You can't, there is no constraint that encompasses those types. 您不能,没有包含这些类型的约束。

Inside this class there is a function (...) that should only be used with CLocation as T . 在此类内部,有一个函数(...)仅应与CLocation用作T

Easy, don't make the method generic because it isn't. 容易,不要使方法通用,因为不是。 Simply write a single overlord with a CLocation argument. 只需编写一个带有CLocation参数的霸主。

Remember, generic means generic . 请记住,泛型表示泛型 A generic class or method should be able to work with an infinite set of generic type parameters. 泛型类或方法应该能够使用无限组泛型类型参数。 When the valid types are limited chances are that you are doing something wrong. 如果有效类型有限,则可能是您做错了什么。

You can achieve it by defining additional type parameter on that method, and add type constraint. 您可以通过在该方法上定义其他类型参数并添加类型约束来实现。 In order to achieve this, you'll need to create ICLocation interface 为此,您需要创建ICLocation接口

public class CGeometryCalibration2D<T> where T: struct
{
    public double InterpolateReverse<V>(V i_Value) where V: struct, ICLocation
    {
        return default(double);
    }
}

public interface ICLocation { }

public struct CLocation : ICLocation { }

Example of usage: 用法示例:

var geoInt = new CGeometryCalibration2D<int>();
geoInt.InterpolateReverse(12); //Compile time error
var loc = new CLocation();
geoInt.InterpolateReverse(loc);

You cannot put a value type constraint on generic parameters, as documented here . 您不能对通用参数施加值类型约束,如此处所述

What you could do is create overloads of your function instead of using generics, eg 您可以做的是创建函数的重载而不是使用泛型,例如

double InterpolateReverse (int i_Value);
double InterpolateReverse (double i_Value);
double InterpolateReverse (float i_Value);

For the first question, you cannot use multiple types for one generic parameter. 对于第一个问题,不能对一个通用参数使用多种类型。 Think about it. 想一想。 How will the compiler decide the compile-time type of the parameter in that case? 在这种情况下,编译器将如何确定参数的编译时类型? You should use overloaded methods for each of the types that you want to support and simply remove that generic parameter. 您应该对要支持的每种类型使用重载方法,并只需删除该通用参数即可。

This should solve your second problem as well. 这也应该解决您的第二个问题。

Thank you all for your answers and comments! 谢谢大家的回答和评论!
After thinking about them, I decided to mix generics with inheritance, which hopefully is the cleanest solution to my problem. 考虑了它们之后,我决定将泛型与继承混合在一起,希望这是解决我的问题的最干净的方法。
The abstract generic base class contains all that stuff that applies to all usable types of T, but it isn't instantiable. 抽象的通用基类包含所有适用于T的所有可用类型的东西,但它不可实例化。 The concrete implementations ensure that only those T are usable that make sense to be used. 具体的实现方式确保只有那些有意义的T才可以使用。

public abstract class CGeometryCalibration2D<T> : CGeometryCalibration<T>
{
  ctor()
  public override void Clear ()
  public bool Add (double i_dPosition, CGeometryCalibration1D<T> i_oGeoCalib1D)
  public bool Remove (double i_dPosition)
  public override void CopyTo (ref CGeometryCalibration<T> io_oGeoCalib)
  public override T Interpolate (CLocation i_locPosition, bool i_bExtrapolate = false)
  public T Interpolate (double i_dPosition, double i_dPositionGC1D, bool i_bExtrapolate = false)
  public override CResulT Load (CXmlDocReader i_xmldocreader)
  public override CResulT Save (CXmlDocWriter i_xmldocwriter)
}

public class CGeometryCalibration2D_Double : CGeometryCalibration2D<double>
{
  ctor()
}

public class CGeometryCalibration2D_CLocation : CGeometryCalibration2D<CLocation>
{
  ctor()
  public double InterpolateReverse (CLocation i_locValue, out CLocation o_ValueInterpolated, bool i_bExtrapolate = false)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 限制泛型子类方法在c#中可以接受的类型 - Restrict types a generic subclass method can accept in c# 如何将 C# 中的通用 function 重写为 OOP 以避免切换类型? - How can I rewrite generic function in C# into OOP to avoid switching on types? 从 C# 泛型类型继承到非泛型类型时,如何减少冗长? - How can I decrease verbosity when inheriting from C# generic types to non-generic types? C#如何在泛型类中访问泛型类型的成员? - C# How to access member of generic type in a generic class? 我可以扩展一个泛型类,对可以使用的类型进行限制吗? - Can I extend a generic class putting a restriction on the types that can be used? 通用类参数用作对成员通用类型的限制 - Generic class parameters used as restrictions on member generic types 如何在 C# 通用 class 中找到要在通用 function 中使用的基础类型? - How to find the underlying type in a C# generic class to be used in a generic function? CodeGo.net&gt;如何更改泛型特定类 - c# - How to change the generic specific class C#是否可以将Generic Abstract类的单个参数限制为两个不同的用户定义类型? - C# Is it possible to restrict a Generic Abstract class single parameter to two different user defined types? 在 C# 中,我可以根据所使用的类型 (T) 使用泛型的特定实现吗 - In C# can I use a specific implementation of a generic based on the type (T) used
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM