C#中的泛型是否可以在变量声明时使用?

4

我有以下问题:

public class MyClass<T> where T : class
{
    private MyOtherClass<T, U> variable where U : class;
    ... content ...
}
public class MyOtherClass<T, U> where T : class where U : class
{
    ... content ...
}

有什么办法可以实现这个吗?
3个回答

3

如果你想要让 MyClass 类的一个字段或属性的类型基于一些类型参数 U 变成泛型,你需要将其声明为 MyClass 的一个类型参数:

public class MyClass<T, U> 
    where T : class 
    where U : class
{
    private MyOtherClass<T, U> variable;
    ... content ...
}
public class MyOtherClass<T, U>
    where T : class 
    where U : class
{
    ... content ...
}

但是,这并不适用于方法。下面的代码是完全正确的:

public class MyClass<T> 
    where T : class 
{
    private MyOtherClass<T, U> Method<U>() where U : class
    {
        ... content ...
    }
}

1
直接回答标题中的问题是不可能的,因为variableMyOtherClass<T, U>类型的字段,这意味着MyOtherClass 定义了类型参数TU - 就像你写的一样!
MyClass<T>中的TMyOtherClass<T, U>中的T不同,因为泛型类型约束的声明属于泛型类型本身,而不属于使用它的类型 - 这是好的!
如果可能的话,会出现这样的类型:
public class SomeRepository<TEntity>
    where TEntity : IEntity { /* ... */}

可能会被用作如下所示:

public class SomeService
{
    private SomeRepository<TEntity> _someRepo where TEntity : INotAnEntity
}

接口、类和方法可以是泛型的(即能够定义类型约束);字段和属性不能,但它们可以是泛型类型。


1
看起来你希望MyClass<T>包含对MyOtherClass<T, U>的引用,其中两个T匹配但接受任何U。如果这是你想做的,现有的答案可能不会有所帮助,因为具有通用U参数的方法仍需要用户指定U
具有类型参数的类(特别是多个)应继承/实现一些更少通用的内容以支持此类情况。例如:
public interface IOtherThing<T> {
    T Value1 { get; }
    object Value2 { get; }
}

public class MyOtherClass<T, U> : IOtherThing<T> {
    public T Value1 { get { ... } }
    public U Value2 { get { ... } }
    object IOtherThing<T>.Value2 { get { return Value2; } }
}

现在,MyClass<T> 可以声明一个变量为 IOtherThing<T>,它可以被赋值给任何 MyOtherClass<T, U>

+1 没有想到问题会这样,如果这是楼主的意思,那么你猜得很好,答案也很好!通过继承MyOtherClassT 在两种类型中具有相同的含义(它们甚至需要具有相同的类型约束才能编译)。 - Mathieu Guindon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接