简体   繁体   中英

Cast generic class object to non-generic

I have 2 classes:

public class GenericClass<T>
{
   public T Item {get;set;}
}
public class StringClass
{
  public string Item {get;set;}
}

now i have a GenericClass object and i need to cast it to StringClass object:

var genericObj = new GenericClass<string>();
var stringObj = (StringClass)genericObj; // <---

How to cast / convert from generic class to specific one?

You can't cast one type to the other because the types are unrelated.

You could, however, define a conversion operator :

public class StringClass
{
    public string Item { get; set; }
    
    public static explicit operator StringClass(GenericClass<string> generic)
        => new StringClass { Item = generic.Item };
}

Which would allow this syntax:

var genericObj = new GenericClass<string>();
var stringObj = (StringClass)genericObj;

You can't. You would need common inherited type or implement an interface.

With inheritance:

public class GenericClass<T>
{
   public T Item {get;set;}
}
public class StringClass : GenericClass<string>
{
}

if your really need it, you can do this way for examle

var stringObj = new  StringClass(genericObj);

public class StringClass
{
    public string Item { get; set; }
    
    public StringClass(GenericClass<string> genericClass)
    {
        Item=genericClass.Item;
    }
 
   public StringClass(){}
}   

or this is more flexible

public interface IGenericClass<T>
{
    public T Item { get; set; }
}
public class GenericClass<T>:IGenericClass<T>
{
    public T Item { get; set; }
}
public class StringClass
{
    public string Item { get; set; }
    
    public StringClass(IGenericClass<string> genericClass)
    {
        Item=genericClass.Item;
    }
   
    public StringClass(){}
}

Finally i solved using ICloneable,

Here i have a base class named GenericClass , a generic class named GenericClassT , and a class named StringClass .

Inheritance is:

GenericClass <- GenericClassT <- StringClass

Using ICloneable implementation on GenericClass and GenericClassT, adding a CreateObject and CopyTo methods i reach the final goal:

var genericObj = new GenericClass<string>();
var stringObj = (StringClass)genericObj.Clone<StringClass>();

class definitions:

public class GenericClass: ICloneable
{
    public string Id {get;set;}

    protected virtual ApiRequestResult CreateObject()
    {
        return new GenericClass();
    }
    protected virtual void CopyTo(GenericClass obj)
    {
        obj.Id = Id;
    }
    public virtual object Clone()
    {
        var obj = CreateObject();

        CopyTo(obj);

        return obj;
    }
    public virtual object Clone<T>() where T: GenericClass
    {
        var obj = (GenericClass)Activator.CreateInstance(typeof(T));

        CopyTo(obj);

        return obj;
    }
}

public class GenericClass<T>: GenericClass
{
    public T Data {get; set;}

    protected override GenericClass CreateObject()
    {
        return new GenericClass<T>();
    }
    protected override void CopyTo(GenericClass obj)
    {
        base.CopyTo(obj);
        ((GenericClass<T>)obj).Data = Data;
    }
}

public class StringClass: GenericClass<string>
{
    
}

Using this answer :

var genericObj = new GenericClass<string>();
var stringObj = (StringClass)Convert.ChangeType(genericObj, typeof(StringClass));

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