huMpty duMpty
huMpty duMpty

Reputation: 14460

Allow only types inherited from a Class

I have class A and B (just sample)

   public class A
    {
        public long Id { get; set; }
        public string Name { get; set; }
    }


    public class B : A
    {            
        public B(long id,string name)
        {

        }
    }

And want to do

 var b = new B(100, "myName");
 Save(b);

I have a save method that I want to allow only types inherited from A Class and also have uses the constructor that accept two parameters

// I know this will work if my Class B has public B() {}, 
//but not sure how to restrict to have only the once which accept constructor with two parameters           
 private void Save<T>(T target) where T : A, new ()
 {
       //do something
 }

Upvotes: 0

Views: 1504

Answers (2)

Me.Name
Me.Name

Reputation: 12544

Generic constraints do not support constructors with parameters. Mostly a factory or creation function is used ( e.g. Is there a generic constructor with parameter constraint in C#? ), but since the object is created beforehand and you only want to filter which objects are allowed, a safer method is to implement an (empty) interface and use that as constraint:

   public class A
    {
        public long Id { get; set; }
        public string Name { get; set; }
    }


    public class B : A, IAmB
    {            
        public B(long id,string name)
        {

        }
    }

    public interface IAmB{}

That way the constraint would be:

private void Save<T>(T target) where T : A, IAmB
 {

 }

Upvotes: 2

Mark Brackett
Mark Brackett

Reputation: 85645

There's nothing in the C# type system that will enforce that constraint. You could use the reflection APIs to verify at runtime.

Another alternative would be to specify a factory:

interface IFactory<T> where T : A {
   T Construct(object param1, object param2)
}

class BFactory : IFactory<B> {
   public B Construct(object param1, object param2) {
       return new B(param1, param2);
   }
}

void Save<T>(T target, IFactory<T> tFactory) where T : A {
   T newT = tFactory.Construct(a, b);
}

Upvotes: 2

Related Questions