不能直接铸造或作为操作者的通用类型到具体类型

时间:2012-08-29 18:25:41

标签: c# generics

请在代码中查看我的评论,如何获取具体的actiontype以及为什么直接转换为MyDto不起作用?

  public class Gen1Layer<TData, TAction> : GenBaseLayer<TData, TAction>
        {

            public Gen1Layer(IGenBaseLayer<TData, TAction> layer) : base(layer) { }

            public override Document<TData, TAction> ProcessDocument(Document<TData, TAction> document)
            {
                // Does not work!
                // MyDto dto = (MyDto) document.Data;

                // Does cast!
                MyDto dto1 = document.Data as MyDto;

                // Does not work!
                MyConsts.ActionType bla =  document.ActionType as MyConsts.ActionType;

                // Does not work!
                MyConsts.ActionType bla = (MyConsts.ActionType)document.ActionType;


            }
        }

Gen1Layer以这种方式调用:

IGenBaseLayer<MyDto,MyConsts.ActionType>  layer = new Gen1Layer<MyDto,MyConsts.ActionType>(null);
Document<MyDto,MyConsts.ActionType> doc = new Document<MyDto,MyConsts.ActionType>(new MyDto(),MyConsts.ActionType.Add,new Session());   
doc =  layer.ProcessDocument(doc);

public class Document<TData,TAction>
    {
        public Document(TData data, TAction actionType,Session session)
        {
            Data = data;
            ActionType = actionType;
            Session = session;
        }

        public TData Data { get; set; }
        public TAction ActionType { get; set; }
        public Session Session { get; set; }
    }

public class MyConsts
    {
        public enum ActionType
        { 
            Get,
            Add,
        }
    }

public interface IGenBaseLayer<TData, TAction>
    {
        Document<TData,TAction> ProcessDocument(Document<TData,TAction> document);
    }

public class GenBaseLayer<TData,TAction> : IGenBaseLayer<TData,TAction>
    {
        public GenBaseLayer(IGenBaseLayer<TData,TAction> layer)
        {
            NextLayer = layer;
        }

        public IGenBaseLayer<TData,TAction> NextLayer { get; set; }

        public virtual Document<TData,TAction> ProcessDocument(Document<TData, TAction> document)
        {
            Console.Write("Gen’s");
            return document;
        }
    }

我想要实现的是在覆盖ProcessDocument方法中具有通用基础层并且派生层是具体类型。我知道这会打破多态性,IGenBaseLayer永远不会调用派生层实例的ProcessDocument方法。但这就是我需要的。每个图层都可以包含具有不同封闭泛型类型的Document,如CustomerDto或SupplierDto以及相关的CustomerActionType或SupplierActionType。

2 个答案:

答案 0 :(得分:0)

MyConsts的ActionType属性是枚举类型,而Document的ActionType属性是TAction类型。 TAction看起来像引用类型,枚举更像是值类型。如果从该类型继承引用类型,则只能将引用类型转换为其他类型。您不能将值类型转换为引用类型。最好的办法是在Document类上添加一个getActionType()方法,处理任何TAction,并返回相应的枚举。在此之前,您应该使枚举可用于Document类(可能在MyConsts类之外定义它?)。

答案 1 :(得分:0)

虽然你在做什么似乎有点粗略

MyConsts.ActionType bla = (MyConsts.ActionType)Enum.
    ToObject(typeof(MyConsts.ActionType), System.Convert.ToInt32(document.ActionType));

将以牺牲类型安全为代价来实现您的目标。