[英]C# how to force generic argument to be type
i have generic method. 我有通用的方法。 i want generic method to limit one type. 我想要通用方法来限制一种类型。 problem is derived type not to be allowed - i do not want this. 问题是派生类型不被允许 - 我不想要这个。 example codes: 示例代码:
public static T Generate<T>(T input)
where T : Operation // ALLOWS BinaryOperation - NOT WANT THIS
{
//...
}
how to do what I request? 怎么做我要求的?
problem is derived type not to be allowed 问题是派生类型是不允许的
There is no way to enforce this constraint, without checking it at runtime. 没有在运行时检查它就无法强制执行此约束。 Doing so would be a violation of the Liskov Substitution Principle , which states that any type should allow you to pass in a derived type without restriction. 这样做将违反Liskov替换原则 ,该原则规定任何类型都应允许您无限制地传递派生类型。
If you must enforce this, it will only work with a runtime check, like: 如果必须强制执行此操作,则它仅适用于运行时检查,例如:
public static T Generate<T>(T input)
where T : Operation // ALLOWS BinaryOperation - NOT WANT THIS
{
// Checks to see if it is "Operation" (and not derived type)
if (input.GetType() != typeof(Operation))
{
// Handle bad case here...
}
// Alternatively, if you only want to not allow "BinaryOperation", you can do:
if (input is BinaryOperation)
{
// Handle "bad" case of a BinaryOperation passed in here...
}
}
Note that, in this case, there's really no reason to make it generic, as the same code would work as: 请注意,在这种情况下,实际上没有理由将其设为通用,因为相同的代码可以用作:
public static Operation Generate(Operation input)
{ // ...
It's not possible to force a method to accept only one specific type like Operation
if the type is not a struct or a sealed class. 如果类型不是结构或密封类,则不可能强制方法只接受一个特定类型,如Operation
。
Let's me show this in a example why this won't work anyway: 让我在一个例子中展示这一点,为什么这无论如何都不会起作用:
public void Generate<T>(Operation op)
// We assume that there is the keyword "force" to allow only Operation classes
// to be passed
where T : force Operation
{ ... }
public void DoSomething()
{
Generate(new BitOperation()); // Will not build
// "GetOperation" retrieves a Operation class, but at this point you dont
// know if its "Operation" or not
Operation op = GetOperation();
Generate(op); // Will pass
}
public Operation GetOperation() { return new BitOperation(); }
As you can see it will be easy to pass a BitOperation
even when there is a restriction. 正如您所看到的,即使存在限制,也很容易传递BitOperation
。
There is only one solution beside the others mentioned above ( struct, sealed ): Runtime Check. 除了上面提到的其他解决方案之外,只有一个解决方案(结构,密封): 运行时检查。 You can write yourself a little helper method for this. 你可以为自己写一个小帮手方法。
public class RuntimeHelper
{
public static void CheckType<T>(this Object @this)
{
if (typeof(T) != @this.GetType())
throw new ....;
}
}
public void Generate(Operation op)
{
op.CheckType<Operation>(); // Throws an error when BitOperation is passed
}
If you want to speed up the helper you could use a generic class RuntimeHelper<T>
with a static readonly type variable which has the type of T. 如果你想加速帮助,你可以使用一个泛型类RuntimeHelper<T>
和一个类型为T的静态只读类型变量。
When you're doing this you cannot longer use extension methods so the call would look like this: 当你这样做时,你不能再使用扩展方法,所以调用将如下所示:
RuntimeHelper<Operation>.CheckType(op);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.