【问题标题】:Arbitrary number of type parameters in C# [duplicate]C#中任意数量的类型参数[重复]
【发布时间】:2011-03-17 18:16:27
【问题描述】:

我需要将一个类型列表传递给一个方法,但我想确保(在编译时)它们都继承自 BaseType。 另外,我不知道要传递多少个类型。

所以我认为这是一个糟糕的方法:

public void DoSomething(params Type[] types)

所以我到现在为止所做的事情是这样的:

private void DoSomething(params Type[] types)

public void DoSomething<T1>() 
    where T1 : BaseType
{ 
    DoSomething(typeof(T1)); 
}

public void DoSomething<T1, T2>() 
    where T1 : BaseType
    where T2 : BaseType
{ 
    DoSomething(typeof(T1), typeof(T2)); 
}


public void DoSomething<T1, T2, T3>() 
    where T1 : BaseType
    where T2 : BaseType
    where T3 : BaseType{...}

// and so on...

你明白了。 所以问题是:你能把这个做得更漂亮一点吗? 因为这不支持任意数量的类型。 在我的场景中,八种或更多类型并不少见。

我想将它用于this 类型的“魔法”,但调用者没有对容器的引用。

【问题讨论】:

    标签: c# generics


    【解决方案1】:

    没有办法在 C#(或 CIL 中)表示这样的约束,因此您要么必须努力编写所有这些重载,要么放弃编译时安全性并在运行时检查-时间。

    如果可能,另一种选择是编写一个可以使用示例的重载。这是否有用取决于领域,真的。

    public void DoSomething(params BaseClass[] examples)
    {
        //null-checks here
    
       Type[] types = examples.Select(e => e.GetType())
                              .ToArray();
       //...    
    }
    

    用法(假设BaseClassMammal):

    // Compiles fine.
    DoSomething(new Goat(), new Tiger(), new Lion());
    
    // Won't compile.
    DoSomething(new Fish(), new Tiger(), new Lion()); 
    

    以下是运行时检查的示例:

    public void DoSomething(Type[] types)
    {
        //null-checks here
    
        // Or perhaps you want IsSubclassOf...
       if(types.Any(t => !typeof(BaseClass).IsAssignableFrom(t))
            throw new ArgumentException(...);           
    }
    

    【讨论】:

      【解决方案2】:

      不,泛型类型是由命名空间、类名和类型参数的数量定义的(即,您不能在同一个命名空间中拥有具有相同类型参数数量的同名类,即使如果对它们的约束不同)。

      如果可以让单个类具有未定义数量的类型参数,那么框架将利用 Action 和 Func 类来利用这一点,但它没有。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-05-26
        • 1970-01-01
        • 2023-04-03
        • 1970-01-01
        • 2016-05-13
        • 1970-01-01
        • 2011-01-07
        相关资源
        最近更新 更多