Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从抽象类将枚举作为参数传递_C#_Enums - Fatal编程技术网

C# 从抽象类将枚举作为参数传递

C# 从抽象类将枚举作为参数传递,c#,enums,C#,Enums,我有一个抽象基类,TestFactory,它看起来像: public abstract class TestFactory { //static method that can create concrete factories public static TestFactory CreateTestFactory(FactoryType factoryType) { TestFactory factory

我有一个抽象基类,
TestFactory
,它看起来像:

    public abstract class TestFactory
    {
        //static method that can create concrete factories
        public static TestFactory CreateTestFactory(FactoryType factoryType)
        {
            TestFactory factory = null;
            switch (factoryType)
            {
                case FactoryType.Blood:
                    factory = new BloodTestFactory();
                    break;
                case FactoryType.Urine:
                    factory = new UrineTestFactory();
                    break;
                default:
                    break;
            }
            return factory;
        }
        //BloodTestFactory and UrineTestFactory are concrete types 
        //that will need to create their own tests
        //this enum parameter needs to 'switch' between
        //BloodTestType and UrineTestType
        public abstract LabTest CreateTest(Enum e);
    }
    public enum FactoryType
    {
        Blood,Urine
    }
        public override LabTest CreateTest(Enum e)
        {
            BloodTest bt = null;
            if(!e.GetType.Equals(typeof(BloodTestType)))
            {
               // throw type exception of your choice
            }
        }
所以这个类创建了一个具体的工厂,比如:

    public class BloodTestFactory :TestFactory
    {

        //both BloodTestFactory and UrineTestFactory will create a LabTest object
        //I would like to have a BloodTestType and UrineTestType enum, what do I need 
        //to do to pass a generic Enum as a parameter and then switch on BloodTestType

        public override LabTest CreateTest(Enum e)
        {
            BloodTest bt = null;
            //switch (e)
            //{
            //    default:
            //        break;
            //}
            //creation logic here
        }
    }
    public enum BloodTestType
    {
        H1AC,Glucose
    }
        public override LabTest CreateTest(Enum e)
        {
            BloodTest bt = null;
            if(!e.GetType.Equals(typeof(BloodTestType)))
            {
               // throw type exception of your choice
            }
        }

BloodTest
本身是一个抽象类,它将基于枚举值返回一个具体的
BloodTest
对象。为了清楚起见,我想要一个
BloodTestType
UrineTestType
(未显示)枚举。由于
CreateTest
方法是抽象的,当我想创建
BloodTest
s时,如何确保我能通过
BloodTestType
,当我想创建UrineTest时通过
UrineTestType
枚举?

只需在重写方法中测试类型安全性即可:

        public override LabTest CreateTest(Enum e)
        {
            BloodTest bt = null;
            if(!e.GetType.Equals(typeof(BloodTestType)))
            {
               // throw type exception of your choice
            }
        }
我不确定这是否是满足此需求的最佳方法,我将把设计模式讨论留给评论/其他答案

        public override LabTest CreateTest(Enum e)
        {
            BloodTest bt = null;
            if(!e.GetType.Equals(typeof(BloodTestType)))
            {
               // throw type exception of your choice
            }
        }
我不一定要这样做,但是,为了使您的代码正常工作,我会在
TestFactory
上为
enum
引入一个类级通用参数

        public override LabTest CreateTest(Enum e)
        {
            BloodTest bt = null;
            if(!e.GetType.Equals(typeof(BloodTestType)))
            {
               // throw type exception of your choice
            }
        }
public abstract class TestFactory<TTestType>
{
    public abstract LabTest CreateTest(TTestType testType);
}

就我个人而言,我可能会将这两个工厂分解成没有基的独立类,或者考虑使用接口。在“常用”方法中处理特定参数是很困难的。

只需在基类中添加参数检查:

        public override LabTest CreateTest(Enum e)
        {
            BloodTest bt = null;
            if(!e.GetType.Equals(typeof(BloodTestType)))
            {
               // throw type exception of your choice
            }
        }
public abstract class TestFactory
{
    //static method that can create concrete factories
    public static TestFactory CreateTestFactory(FactoryType factoryType)
    {
        if (!Enum.IsDefined(typeof(FactoryType), factoryType)
        {
             throw InvalidEnumArgumentException(...);
        }

        TestFactory factory = null;
        switch (factoryType)
        {
            case FactoryType.Blood:
                factory = new BloodTestFactory();
                break;
            case FactoryType.Urine:
                factory = new UrineTestFactory();
                break;
            default:
                break;
        }
        return factory;
    }       
    //...
}

有一种很好的方法可以做到这一点,它会产生如下代码:

        public override LabTest CreateTest(Enum e)
        {
            BloodTest bt = null;
            if(!e.GetType.Equals(typeof(BloodTestType)))
            {
               // throw type exception of your choice
            }
        }
var client = new LabTestClient();
client.Run<BloodTestFactory,BloodTestType>(BloodTestType.H1AC);
client.Run<BloodTestFactory,BloodTestType>(BloodTestType.Glucose);
// outputs
//   BloodTest: H1AC
//   BloodTest: Glucose

你能不能在
CreateTest
方法中把你的泛型
Enum e
转换成具体的
BloodTestType
。我只是好奇是否有更“优雅”的方式来做这件事。我知道枚举不做继承,但我想可能有办法解决这个问题。你可能不知道,但实际上,最后一个可能需要的枚举可能相当大。我越看这个问题,就越觉得你的架构是错误的。您试图在枚举上进行切换,以确定要执行哪种测试,但像工厂方法/抽象工厂这样的模式的全部要点是从代码中删除这种分支逻辑。因此,您将得到类
GlucoseBloodLabTest
H1ACBloodLabTest
SomeUrineLabTest
等。所有这些都是从基类
LabTest
继承的。如果你想知道如何改变你的代码以另一种方式完成它,请发到这里,我将为你准备一个单独的答案。@Jamiec我相信我没有很好地解释它,但在我的设计中,我也有了
血液测试
。因此,抽象工厂创建工厂,而血液测试工厂可以创建几种抽象血液测试类型中的任意一种。不过,我确实同意,我的设计似乎并不理想。@Jamiec我一直处于知识搜索模式,我非常感谢任何知识会议:)这种工作,除了
CreateTestFactory
方法现在也需要采用泛型,否定使用
FactoryType
@Jamiec是的,该方法需要返回一个
TestFactory
,就像您所说的,这会使方法变得毫无意义。@wootscootinboogie真的不确定。我现在会回顾一下基类的必要性。您希望由基类公开的方法必须采用派生类特定的参数,这在我看来是不必要的。@AdamHouldsworth我倾向于同意您的看法。:)@Jamiec我总是发现很难找到一种处理逻辑相关实体的通用方法,但碰巧需要特定于实体的方法参数(如本例所示)。你对它的方法有什么想法?老实说,这有点超出我的工资等级!:)非常感谢有机会学习。您能解释一下
where-TFactory:LabTestFactory,new()
部分吗?
where-TFactory:LabTestFactory,new()
-a指示泛型类型必须继承
LabTestFactory
,并且必须具有无参数构造函数(允许类型本身的行为类似于工厂-请参见方法中的
new-TFactory()