简体   繁体   English

c# 其中对于泛型类型约束 class 可能不是

[英]c# where for generic type constraint class may NOT be

I would like to exclude some types for being used in a generic class. I know how to make constrains in order to make sure a generic type is some kind of (interface) type.我想排除一些在通用 class 中使用的类型。我知道如何进行约束以确保通用类型是某种(接口)类型。 But I can't seem to figure out how to exclude (multiple) types.但我似乎无法弄清楚如何排除(多种)类型。

For instance: I want a generic class to exclude ints and uints (but don't exclude DateTime for instance, so not all Primitives may be excluded).例如:我想要一个通用的 class 来排除 ints 和 uints(但是不排除 DateTime,例如,所以不是所有的 Primitives 都可以被排除)。

I can't do something like this:我不能做这样的事情:

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

Can someone help me out how to exclude multiple types at once?有人可以帮我解决如何一次排除多种类型吗?


I made a special class that acts like a dictionary and is also a FiFo collection with an index, where 0 is the most recent value, 1 the previous etc. ( public class FiFoDictionary<K, V>: IDictionary<K, V> , which uses OrderedDictionary as the internal dict.)我制作了一个特殊的 class ,它就像一本字典,也是一个带有索引的 FiFo 集合,其中 0 是最近的值,1 是前一个值等。( public class FiFoDictionary<K, V>: IDictionary<K, V> ,它使用OrderedDictionary作为内部字典。)

But since the index is given via an int , this gives issues when the key of the dictionary is an int .但是由于索引是通过int给出的,因此当字典的键是int时会出现问题。 Because then you get the value linked to the key, instead of the index.因为那样你会得到链接到键的值,而不是索引。 Or is there any way to force the use of the index instead of the key for an OrderedDictionary ?或者有什么方法可以强制使用索引而不是OrderedDictionary的键?

Given the explanation in the comment, why you think you need this: No, you don't need to exclude int from the generic type.鉴于评论中的解释,为什么你认为你需要这个:不,你不需要从通用类型中排除int

When overloaded methods in a class (methods that differ by type of their parameters only) are used in a generic class, then the decision which of the methods is called is already made while the Generic class is compiled independently of the concrete type then used later on.当 class 中的重载方法(仅参数类型不同的方法)在泛型 class 中使用时,已经决定调用哪个方法,而泛型 class 独立于具体类型进行编译,然后稍后使用在。

Example:例子:

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

The output is output 是

"Triggered object" “触发对象”

Even when T is int , the overloaded Internal method that takes an int is never called because the decision that Trigger calls the Internal method that expects an object is already made for the whole generic class independently of the concrete type used.即使Tint ,采用int的重载Internal方法也永远不会被调用,因为Trigger调用期望objectInternal方法的决定已经针对整个泛型 class 做出,与所使用的具体类型无关。


The same is true when you use an OrderedDictionary internally.在内部使用OrderedDictionary时也是如此。 myOrderedDictionary[x] where x is a generic type will always use the index property that accesses entries by key and not the one that accesses them by order because this decision is made based on the known constraints of the generic type independently of the concrete type used later on. myOrderedDictionary[x] where x is a generic type will always use the index property that accesses by key 而不是按顺序访问它们的属性,因为这一决定是基于通用类型的已知约束而独立于所使用的具体类型稍后的。

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

There is no such thing in C# however you can scope the generic type in a way that may help you to achieve that. C# 中没有这样的东西,但是您可以 scope 通用类型以一种可以帮助您实现它的方式。 This is just a sample and I don't consider this as a solution to your problem这只是一个示例,我不认为这是解决您问题的方法

class MyGeneric<T> where T : new() { } // T must be a class with default constructor
class MyGeneric<T> where T : System.IComparable<T> { }// T must implement IComparable interface 
class MyGeneric<T> where T : System.IComparable<T>, new () { }

its no posible to do, The.= and == operators can't be used because there's no guarantee that the concrete type argument will support these operators.它不可能做到,不能使用 The.= 和 == 运算符,因为不能保证具体类型参数将支持这些运算符。 here you can read more about 在这里你可以阅读更多关于

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM