Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Generic Copy Constructor

I have an interface, and two classes that implements the interface. The classes have generic types. I would like to clone from an instance of one class to the other.

interface IFoo
{
    // stuff
}

class Foo<T> : IFoo
{
    // foo stuff
    // ifoo implementation
}

class Bar<T> : IFoo
{
    // bar stuff
    // ifoo implementation
}

I have a Foo and would like a Bar. Bar has a copy constructor taking a parameter of IFoo. I created an extension method to implement the clone:

public static Bar<T> Clone<T>(this IFoo foo) 
{
    return new Bar<T>(foo);
}

Calling the method requires the type:

someFoo.Clone<T> ...

Is there a way to omit declaring the type when calling the method by modifying the extension method, or any other way, to allow the the instance to just be passed in without caring about its underlying type?

Update Here is how this is being used to better illustrate the situation.

In a method I iterate a collection and return an enumeration of IFoo. In the method I look at an attribute of the source collection and determine the type of the Foo.

IFoo foo = null;

string type = element.Attribute("Type").Value;
switch (type)
{
    case "int":
        foo = new Foo<int>();
        break;

    case "string":
        foo = new Foo<string>();
        break;

    // etc
}
// other stuff

yield return foo;

The calling method has a List. Later I select individual items from this list for use, at which point I would like a Bar instead of a Foo. When selecting from the list the instances are of type IFoo, as in they only see the extension methods for "this IFoo foo". I do not want to cast the IFoo to a Foo, that would require re-declaring the type of T. I would just like to have Foo tell Bar what it is. Is this possible?

like image 319
blu Avatar asked Nov 05 '22 22:11

blu


1 Answers

So you have everything ok but you want to be able to use the syntax

someFoo.Clone()

instead of

someFoo.Clone<int>()

you want the int to be implied rather than having to put it ther explicitly?

The reason you can't do that in your code example is that IFoo doesn't reference the generic type T that you need in order to create Bar<T>.

I would suggest that you really need another interface: IFoo<T>

If you had that, and your extension method looks like this:

public static Bar<T> Clone<T>(this IFoo<T> foo) 
{
    return new Bar<T>(foo);
}

Then you will have no problem using

IFoo<int> someFoo = new Foo<int>();
Bar<int> someBar = someFoo.Clone();

Hope that helps

like image 113
Jero Avatar answered Nov 12 '22 10:11

Jero