将Type变量限制为特定的类或子类

时间:2018-11-02 19:41:53

标签: c# types factory

我正在C#中工作,并且想在类中存储一个类型,但是我希望该类型是某个类或它的子类。

这可能是代码的样子:

android:id

我要解决的问题(以防万一有人有更好的主意):我正在创建一种工厂,该工厂将实例化一些指定类型的对象。因此,在创建该工厂时,将使用应实例化的类型来创建它。但是,此工厂具有特定的用途,因此它仅应实例化特定类(或该类的子类)的对象。

4 个答案:

答案 0 :(得分:3)

您是否正在问类似这样的事情?

class C<T> where T: SomeBaseClass
{
}

答案 1 :(得分:0)

如果需要在运行时进行检查,则可以在逻辑中使用Type的{​​{1}}。例如

IsAssignableFrom

有关更详细的示例,请在此处查看我的代码:https://stackoverflow.com/a/53121973/361842

答案 2 :(得分:0)

给出以下类别:

public abstract class ABaseType
{
    public abstract void PrintSomethingToConsole();
}

public class ASubType : ABaseType
{
    public override void PrintSomethingToConsole()
    {
        System.Console.WriteLine("Something");
    }
}

public class AnotherSubType : ABaseType
{
    public override void PrintSomethingToConsole()
    {
        System.Console.WriteLine("Something else");
    }
}

(快速说明:如果要创建实例,则AnotherSubType和ASubType类不能是抽象的。)

您的工厂可以这样重构:

public class Factory 
{
    private readonly List<ABaseType> _instances;

    public Factory()
    {
        _instances = new List<ABaseType>();
    }

    public void Register<T>()  where T : ABaseType, new()
    {
        // creates a new instance of the object
        // As an alternative, save the type and create a new instance in DoTheThing()
        var instance = new T();
        _instances.Add(instance);
    }

    public void DoTheThing()
    {
        _instances.ForEach(x => x.PrintSomethingToConsole());
    }
}

使用代码:

var factory = new Factory();
factory.Register<AnotherSubType>();
factory.Register<ASubType>();

factory.DoTheThing();

输出:

  

还有其他事情

     

某事

答案 3 :(得分:-1)

我了解您的要求如下:

  1. 您想要一个可以包含其他类型的类(仅限于BaseType的子类),并且是类型安全的。
  2. 此类的不同实例必须能够存储在相同类型的变量中。

您可以使用协方差和类型约束来做到这一点。

声明协变接口:

public interface IMyFactory<out T>
{
    T Resolve();
}

在您的课堂上实现它:

public class MyFactory<T> : IMyFactory<T> where T :BaseType, new()
{
    public readonly Type typeToInstantiate;

    public MyFactory()
    {
        typeToInstantiate = typeof(T);
    }

    public T Resolve()
    {
        return new T();
    }
}

并命名为:

public class Program
{
    public static void Main()
    {
        IMyFactory<BaseType> factory;
        {
            factory = new MyFactory<BaseType>();
            var instance = factory.Resolve();
            Console.WriteLine(instance.GetType().FullName);
        }
        {
            factory = new MyFactory<DerivedType>() as IMyFactory<BaseType>;
            var instance = factory.Resolve();
            Console.WriteLine(instance.GetType().FullName);
        }

    }
}

请注意,这里只声明了一个变量,但是它可以包含两种类型的工厂,每个工厂在运行时都将解析为正确的类型,如输出所示。

输出:

Example.BaseType
Example.DerivedType

这是上面的link to a DotNetFiddle