Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using c# generics in a nested class

Consider the following class structure:

public class Foo<T>
{
    public virtual void DoSomething()
    {
    }

    public class Bar<U> where U : Foo<T>, new()
    {
        public void Test()
        {
            var blah = new U();
            blah.DoSomething();
        }
    }
}

public class Baz
{
}

public class FooBaz : Foo<Baz>
{
    public override void DoSomething()
    {
    }
}

When I go to use the nested class, I have something like the following:

var x = new FooBaz.Bar<FooBaz>();

It seems redundant to have to specify it twice. How would I create my class structure such that I can do this instead:

var x = new FooBaz.Bar();

Shouldn't there be some way on the where clause of the nested class to say that U is always the parent? How?


Update: Added methods for DoSomething() above to address some of the comments. It's important that when I call DoSomething, it addresses the overridden version. If I just use Foo instead of U, then the base implementation is called instead.

like image 341
Matt Johnson-Pint Avatar asked Oct 28 '11 17:10

Matt Johnson-Pint


People also ask

What does %d do in C?

In C programming language, %d and %i are format specifiers as where %d specifies the type of variable as decimal and %i specifies the type as integer. In usage terms, there is no difference in printf() function output while printing a number using %d or %i but using scanf the difference occurs.

What does %C do in C?

Show activity on this post. %d is used to print decimal(integer) number ,while %c is used to print character . If you try to print a character with %d format the computer will print the ASCII code of the character.

Is C useful now?

C is worth learning in 2022 because it is easy to grasp. It gives you basic knowledge about the inner workings of computer systems and the core concepts that drive programming.


2 Answers

If class Bar does not need to be generic, why do you make it one?

This would work:

public class Foo<T, U> where U : Foo<T, U>
{     
    public class Bar
    {
        private T t;
        private U u;
    }
}

public class Baz
{
}

public class FooBaz : Foo<Baz, FooBaz>
{
}

And then

var bar = new FooBaz.Bar();

Of course all of this is totally abstract, so it might or might not apply to a practical example. What exactly are you trying to achieve here?

like image 164
Jon Avatar answered Sep 27 '22 23:09

Jon


No, you can't merge that.

Inside Foo you have T and U, 2 different types and the compiler cannot make up a type for U, only constrain it.

like image 36
Henk Holterman Avatar answered Sep 27 '22 22:09

Henk Holterman