Access类属性作为泛型类型传递

时间:2011-06-28 06:50:16

标签: c# class generics generic-type-argument

我有两个类,它们被传递给Serialization方法,我想在Serialization方法中访问这些类的两个属性。问题是Serialization方法参数作为泛型类型传递,在这种情况下我不知道如何访问传递类的属性。以下示例。

    public class MyClass1 
    {

            public string MyProperty1 { get; set; }

            //These properties are shared in both classes
            public bool Result { get; set; }
            public string EngineErrorMessage { get; set; }

    }
    public class MyClass2 
    {

            public string MyProperty2 { get; set; }

            //These properties are shared in both classes
            public bool Result { get; set; }
            public string EngineErrorMessage { get; set; }

    }


//The method is used to serialize classes above, classes are passed as generic types
    public void Serialization<T>(ref T engine)
            {
                try
                {
                 //Do some work with passed class
                 }
                catch (Exception e)
                {

                   //If Exception occurs I would like to write values to passed class properties, how to do that?
                   Result = false;
                   EngineErrorMessage = e.Message;
                }
    }

完整方法代码

     public void Submit<T>(ref T engine)
        {
            try
            {

                var workingDir = Path.Combine(Settings.FileStoragePath, Helpers.GetRandomInt(9).ToString());



                Directory.CreateDirectory(workingDir);
                var inputFile = Path.Combine(workingDir, Settings.InFileName);
                var outputFile = Path.Combine(workingDir, Settings.OutFileName);
                var deleteFile = Path.Combine(workingDir, Settings.DelFileName);

                try
                {



                    using (var stream = new FileStream(inputFile, FileMode.Create, FileAccess.Write, FileShare.None))
                    {
                        Serializer.Serialize(stream, engine);
                    }


                    CheckStatus(outputFile);


                    using (var stream = new FileStream(outputFile, FileMode.Open, FileAccess.Read, FileShare.None))
                    {
                        engine = Serializer.Deserialize<T>(stream);                        
                    }


                }
                finally
                {
                    File.Create(deleteFile).Dispose();
                }
            }
            catch (Exception e)
            {
                //ToDo: Not implemented yet.
/*               Result = false;
               ErrorMessage = e.Message;*/
            }
        }

3 个答案:

答案 0 :(得分:3)

声明包含属性ResultEngineErrorMessage的接口。现在您有两个选择:

  1. 为序列化类型参数添加约束,以便只能序列化从上述接口派生的类型,或
  2. 在catch块中尝试将engine转换为上述接口。如果演员成功,请写下属性值,否则什么都不做。
  3. 样品:

    public interface ISerializationErrorWriter
    {
        bool Result { set; get; }
        string EngineErrorMessage { set; get; }
    }
    
    public class MyClass1 : ISerializationErrorWriter
    {
        public string MyProperty1 { get; set; }
    
        public bool Result { get; set; }
        public string EngineErrorMessage { get; set; }
    }
    
    public class MyClass2 : ISerializationErrorWriter
    {
        public string MyProperty2 { get; set; }
    
        public bool Result { get; set; }
        public string EngineErrorMessage { get; set; }
    }
    
    // Option 1:
    public void Serialization_1<T>(ref T engine) where T : ISerializationErrorWriter
    {
        try
        {
            //Do some work with passed class
        }
        catch (Exception e)
        {
            engine.Result = false;
            engine.EngineErrorMessage = e.Message;
        }
    }
    
    // Option 2:
    public void Serialization_2<T>(ref T engine)
    {
        try
        {
            //Do some work with passed class
        }
        catch (Exception e)
        {
            var serializationErrorWriter = engine as ISerializationErrorWriter;
            if(serializationErrorWriter != null)
            {
                serializationErrorWriter.Result = false;
                serializationErrorWriter.EngineErrorMessage = e.Message;
            }
        }
    }
    

答案 1 :(得分:2)

您必须通过typeof(T)(或engine.GetType())在某个时刻使用反射。如果这是一个频繁的代码路径,您可能希望缓存每种类型的某种策略以避免开销。或者更好:使用预先构建的序列化API来优化这种类型的场景(即大多数场景)。

如果您的意思是ResultEngineErrorMessage,则有2个选项:

  1. 将这两个属性放在接口上,从t 2类型实现该接口,并将where T : ISomeInterface约束添加到Serialization<T>
  2. 使用dynamic将鸭子类型添加到属性

答案 2 :(得分:-1)

如果你只有两个类来处理,我认为下面的序列化代码可以为你提供服务

//The method is used to serialize classes above, classes are passed as generic types
                public void Serialization<T>(ref T engine)
                {
                    try
                    {
                        Type genericType = typeof(T);

                        if (typeof(MyClass1).Equals(genericType))
                        {
                            MyClass1 engineClass1 = engine as MyClass1;
                            //DO something for class 1
                        }
                        else if (typeof(MyClass2).Equals(genericType))
                        {
                            MyClass2 engineClass2 = engine as MyClass2;
                            //DO something for class 2
                        }

                    }
                    catch (Exception e)
                    {
                        //If Exception occurs I would like to write values to passed class properties, how to do that?
                        Result = false;
                        EngineErrorMessage = e.Message;
                    }
                }