简体   繁体   中英

c# Generic on variable declaration, is this possible?

I have the following problem:

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

Is that possible somehow?

If you want to make the type of a field or property of MyClass generic based on some type parameter U , you have to declare that as a type parameter of 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 ...
}

However, that doesn't apply to methods. This is perfectly fine:

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

It looks like you want MyClass<T> to contain a reference to MyOtherClass<T, U> where both T s match but any U is accepted. If this is what you're trying to do, the existing answers probably don't help because a method with a generic U parameter still requires the user to specify U .

Classes with type parameters (especially multiple ones) should inherit / implement something less generic to support situations like this. For example:

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

Now, MyClass<T> can declare a variable as IOtherThing<T> , which can be assigned to any MyOtherClass<T, U> .

To directly answer the question as it is titled, you can't do that because variable is a field of type MyOtherClass<T, U> , which means MyOtherClass defines type parameters T and U - as you have it!

The T of MyClass<T> is not the same T as that of MyOtherClass<T, U> , because the declaration of generic type constraints belongs to the generic type itself, not to the types that use it - and that's good!

If it were possible, a type such as this:

public class SomeRepository<TEntity>
    where TEntity : IEntity { /* ... */}

Could possibly be used like this:

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

Interfaces, classes and methods can be generic (ie are able to define type constraints); fields and properties can't, but they can be of a generic type.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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