简体   繁体   中英

C# Constructor with argument on generic type combine with interface

Ok, here we go ! I try to do a thing I never try before and... C# bit me.

The thing is my program need to translate some input objects to an output objects, with many in for one out at the time. And the out need the in for instantiate.

I'm not sure I'm very clear at this point... So an example to illustrate this will be better :

public class Class1
{
    public interface ITranslatable { }

    public interface ITranslatable<T> { }

    public class OriginClass : ITranslatable { }

    public class TargetClass : ITranslatable<OriginClass>
    {
        public TargetClass(OriginClass origin)
        {
            // Instantiate some properties from arg
        }
    }

    public class Test
    {
        public Y Execute<X, Y>(X origin, Y target)
            where X : ITranslatable
            where Y : ITranslatable<X>, new()
        {
            target = new Y(origin); // <= How can I make this
            // Some stuff
            return target;
        }
    }

    public TargetClass Function(OriginClass origin, TargetClass target)
    {
        var test = new Test();
        return test.Execute(origin, target);
    }
}

You declared new() constraint which mean that you expect class to have empy parameterless constuctor.

Does below code fits you needs?

 public class Class1
{
    public interface ITranslatable { }

    public interface ITranslatable<T>
    {
        T Origin { get; set; }
    }

    public class OriginClass : ITranslatable
    {

    }

    public class TargetClass : ITranslatable<OriginClass>
    {
        private OriginClass _origin;

        public OriginClass Origin
        {
            get => _origin;
            set
            {
                //Do some stuff
                _origin = value;
            }
        }

        public TargetClass()
        {

        }

    }

    public class Test
    {
        public Y Execute<X, Y>(X origin, Y target)
            where X : ITranslatable
            where Y : ITranslatable<X>, new()
        {
            var result = new Y {Origin = origin};

            // Some stuff
            return target;
        }
    }

    public TargetClass Function(OriginClass origin, TargetClass target)
    {
        var test = new Test();
        return test.Execute(origin, target);
    }
}

After a few tries, I found the solution : use an abstract class.

Solution:

public class Class1
{
    public interface ITranslatable { }

    public interface ITranslatableOut
    {
        ITranslatable Origin { set; }
    }

    public class OriginClass : ITranslatable
    {
        public string Custom { get; set; }
    }

    public abstract class TargetBase : ITranslatableOut
    {
        public ITranslatable Origin { set { Initialize(value); } }

        protected abstract void Initialize(ITranslatable input);
    }

    public class TargetClass : TargetBase
    {
        protected override void Initialize(ITranslatable input)
        {
            // Initialize some properties
        }
    }

    public class Test
    {
        public Y Execute<X, Y>(X origin, Y target)
            where X : ITranslatable
            where Y : ITranslatableOut, new()
        {
            target = new Y { Origin = origin }; // It works !
            // Some stuff
            return target;
        }
    }

    public TargetClass Function(OriginClass origin, TargetClass target)
    {
        var test = new Test();
        return test.Execute(origin, target);
    }
}

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