簡體   English   中英

C#如何強制泛型參數為type

[英]C# how to force generic argument to be type

我有通用的方法。 我想要通用方法來限制一種類型。 問題是派生類型不被允許 - 我不想要這個。 示例代碼:

public static T Generate<T>(T input)
    where T : Operation // ALLOWS BinaryOperation - NOT WANT THIS
{
    //...
}

怎么做我要求的?

問題是派生類型是不允許的

沒有在運行時檢查它就無法強制執行此約束。 這樣做將違反Liskov替換原則 ,該原則規定任何類型都應允許您無限制地傳遞派生類型。

如果必須強制執行此操作,則它僅適用於運行時檢查,例如:

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...
    }
}

請注意,在這種情況下,實際上沒有理由將其設為通用,因為相同的代碼可以用作:

public static Operation Generate(Operation input)
{ // ...

如果類型不是結構或密封類,則不可能強制方法只接受一個特定類型,如Operation

讓我在一個例子中展示這一點,為什么這無論如何都不會起作用:

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(); }

正如您所看到的,即使存在限制,也很容易傳遞BitOperation

除了上面提到的其他解決方案之外,只有一個解決方案(結構,密封): 運行時檢查。 你可以為自己寫一個小幫手方法。

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
}

小注意

如果你想加速幫助,你可以使用一個泛型類RuntimeHelper<T>和一個類型為T的靜態只讀類型變量。

當你這樣做時,你不能再使用擴展方法,所以調用將如下所示:

RuntimeHelper<Operation>.CheckType(op);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM