首页 > 解决方案 > c# where for generic type constraint class may not be

问题描述

我想排除一些在泛型类中使用的类型。我知道如何进行约束以确保泛型类型是某种(接口)类型。但我似乎无法弄清楚如何排除(多种)类型。

例如:我想要一个通用类来排除 int 和 uints(但不排除 DateTime 例如,所以不是所有的 Primitives 都可以排除)。

我不能做这样的事情:

public class SomeWhereTest2<T> where T : !System.Int32 
{ 
}

有人可以帮助我一次排除多种类型吗?


我做了一个像字典一样的特殊类,也是一个带有索引的 FiFo 集合,其中 0 是最近的值,1 是前一个值,等等。(public class FiFoDictionary<K, V>: IDictionary<K, V>用作OrderedDictionary内部字典。)

但是由于索引是通过 an 给出的int,所以当字典的键是 an 时会出现问题int。因为那样你会得到链接到键的值,而不是索引。或者有什么方法可以强制使用索引而不是键OrderedDictionary

标签: c#genericsconstraints

解决方案


鉴于评论中的解释,为什么你认为你需要这个:不,你不需要int从泛型类型中排除。

当在泛型类中使用类中的重载方法(仅参数类型不同的方法)时,已经决定调用哪个方法,而泛型类独立于具体类型进行编译,然后稍后使用上。

例子:

class Test<T>
{
    public void Trigger(T test)
    {
        // Will always call Internal(object) and never call Internal(int) even when T is int.
        Internal(test);
    }

    private void Internal(int test)
    {
        MessageBox.Show("Triggered int");
    }

    private void Internal(object test)
    {
        MessageBox.Show("Triggered object");
    }
}

private void buttonTest_Click(object sender, EventArgs e)
{
    Test<int> test = new Test<int>();
    test.Trigger(42);
}

输出是

“触发对象”

即使在Tis时int,也永远不会调用采用 an 的重载Internal方法,int因为Trigger调用Internal期望 an 的方法的决定object已经针对整个泛型类做出,而与使用的具体类型无关。


当您在OrderedDictionary内部使用时也是如此。myOrderedDictionary[x]泛型类型将x始终使用通过键访问条目的索引属性,而不是按顺序访问它们的索引属性,因为此决定是基于泛型类型的已知约束做出的,与稍后使用的具体类型无关。

class TestDictionary<TKey, TValue> 
{
    OrderedDictionary orderedDictionary = new OrderedDictionary();

    public void Add(TKey key, TValue value)
    {
        orderedDictionary.Add(key, value);
    }

    public TValue GetByIndex(int index)
    {
        return (TValue)orderedDictionary[index];
    }

    public TValue GetByKey(TKey key)
    {
        return (TValue)orderedDictionary[key];
    }
}

private void buttonTest_Click(object sender, EventArgs e)
{
    TestDictionary<int, string> test = new TestDictionary<int, string>();

    test.Add(42, "Test");

    MessageBox.Show(test.GetByIndex(0)); // Correct output "Test"
    MessageBox.Show(test.GetByKey(42)); // Correct output "Test"
}

推荐阅读