Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/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#_Inheritance_Polymorphism_Unity3d - Fatal编程技术网

C# 操作系统设计问题:与其相应程序关联的文件类型

C# 操作系统设计问题:与其相应程序关联的文件类型,c#,inheritance,polymorphism,unity3d,C#,Inheritance,Polymorphism,Unity3d,我正在Unity3D和C#中工作,以创建一个虚拟的游戏内操作系统(有点雄心勃勃) 请注意,这是一个纯粹的设计问题,您可以在不了解任何统一性的情况下回答 以下是我所拥有的: 摘要文件,包含子项: TextFile MediaFile ImageFile 此外,还有一个抽象的应用程序,其子项为: TextViewer MediaPlayer ImageViewer 显然,TextViewer应该打开TextFiles,MediaPlayer应该打开MediaFiles,ImageViewer应该打

我正在Unity3D和C#中工作,以创建一个虚拟的游戏内操作系统(有点雄心勃勃)

请注意,这是一个纯粹的设计问题,您可以在不了解任何统一性的情况下回答

以下是我所拥有的:

摘要
文件
,包含子项:

  • TextFile
  • MediaFile
  • ImageFile
  • 此外,还有一个抽象的
    应用程序
    ,其子项为:

  • TextViewer
  • MediaPlayer
  • ImageViewer
  • 显然,
    TextViewer
    应该打开
    TextFile
    s,
    MediaPlayer
    应该打开
    MediaFile
    s,
    ImageViewer
    应该打开
    ImageFile
    s

    现在,我想了一会儿,我应该把谁打开谁的信息放在哪里? 我应该让每个文件自己打开吗?通过在
    文件
    中创建一个摘要
    打开
    ,并在子文件中覆盖该摘要?-我认为这没有意义,因为一个文件并不真正知道如何打开它自己,只有应用程序知道如何打开一个文件。例如,对于pdf文件,如果您没有pdf阅读器(Adobe或其他),则无法打开pdf

    这意味着
    TextViewer
    应该有
    Open(TextFile text)
    方法,
    MediaPlayer
    应该有
    Open(MediaFile media)
    方法,
    ImageViewer
    应该有
    Open(ImageFile image)
    方法

    这可以通过在
    应用程序
    的声明中使用泛型来实现,例如:

    public abstract class Application<T> where T : FILE
    {
      public abstract void Open(T file);
    }
    
    好的,现在我可以让我的字典成为

    这对我来说就像一场噩梦

    通过使我的应用程序成为单例,我可以避免所有的麻烦,因此现在在每个文件中:

    public class TextFile : FILE
    {
       public override void Open()
       {
          TextViewer.Instance.Open(this);
       }
    }
    
    其余的文件也是如此。但我不想这么做,我不想放弃使用单身!如果我想让我的
    MediaPlayer
    TextViewer
    拥有多个实例,而不仅仅是一个实例,该怎么办

    我已经为此奋斗了很长时间了,我希望我能把我的问题说清楚。我只是想知道,将文件类型与正确的应用程序关联如何以正确的方式工作(例如在Windows中)-如何以优雅、稳健的方式实现我所追求的目标有没有一种设计模式可以用于此我所有的尝试,我想对了吗?我接近解决方案了吗


    非常感谢您提前提供的帮助。

    也许这对您来说是可行的,而不是在应用程序类中声明抽象方法 创建泛型可以创建一个接口并实现其开放方法,如下所示:

        public interface IFile<T>
        {
            void Open(T path);
        }
    
        public abstract class Application
        {
            //public abstract void Open();
        }
    
    
        public class TextViewer : Application, IFile<TextFile>
        {
            public void Open(TextFile path)
            {
                //open textfile....
            }
        }
    
        public class MediaPlayer : Application, IFile<MediaFile>
        {     
            public void Open(MediaFile path)
            {
                //open media file...
            }
        }
    
        public class ImageViewer : Application, IFile<ImageFile>
        {
            public void Open(ImageFile path)
            {
                //open imagefile....
            }
        }
    
    公共接口IFile
    {
    空旷(T径);
    }
    公共抽象类应用程序
    {
    //公开摘要空开();
    }
    公共类TextViewer:应用程序,IFile
    {
    公共无效打开(文本文件路径)
    {
    //打开文本文件。。。。
    }
    }
    公共类MediaPlayer:应用程序,IFile
    {     
    公共无效打开(媒体文件路径)
    {
    //打开媒体文件。。。
    }
    }
    公共类ImageViewer:应用程序,IFile
    {
    公共无效打开(图像文件路径)
    {
    //打开图像文件。。。。
    }
    }
    
    在设计中不花大量心思,也不知道统一性,也不知道文件是如何真正表示的情况下,我会采用基于接口的方法,而不是基于泛型的方法

    首先,我将定义一个接口来定义我的文件类,即IFile,并在我的每个文件中实现它

    public interface IFile
    {
    
    }
    
    public class MediaFile : IFile
    {
        ...
    }
    
    接下来,我将定义一个接口来定义我的应用程序类,即IAApplication,并在我的每个应用程序中实现它

    public interface IApplication
    {
        Type GetSupportedApplicationType();
        void OpenFile(IFile oFile);
    }
    
    
    public class MediaApplication : IApplication
    {
    
        #region IApplication Members
    
        public Type GetSupportedApplicationType()
        {
            return typeof(MediaFile);
        }
    
        public void OpenFile(IFile oFile)
        {
            // do the work
        }
    
        #endregion
    }
    
    因此,文件和应用程序之间的链接将是一个字典,其中包含文件的类类型作为键,应用程序的类类型作为值:

    <GetType(MediaFile), GetType(MediaPlayer)>
    

    @terrybozzio:我曾想过给unity3d贴标签,但后来我发现几乎没有什么与之相关的东西——这是一个纯粹的设计问题。这就是为什么我认为,操作系统更好。无论如何,你很可能想要这个:太棒了!然而,有一个问题:在你的
    媒体应用程序中,你打开了
    文件,这意味着我必须把它转换成
    媒体文件(知道它实现了
    文件,对吗?因为我需要
    MediaFile
    info…是的,每个OpenFile实现都需要转换为适当的类型,假设您确实需要知道执行操作的类型。如果可以的话,处理这个问题的最好方法是向IFile接口添加尽可能多的内容。这种方法还允许单个应用程序支持多种文件类型;OpenFile只需要修改以测试IFile的类型并相应地进行操作。好吧,我想这会起作用,但让我试试:D-但是你不认为如果每个应用程序在其
    Open
    方法中采用正确的文件类型会是最佳的吗我的意思是,如果有人进入并离开mediaPlayer.Open(
    并将
    IFile
    视为一个参数,这意味着实现
    IFile
    的任何东西都应该很好地适应……(这是事实,我的意思是我们将检查以确保获得正确的文件类型,但仍然,你知道……我希望你能感觉到我)-也许有办法解决这个问题?好吧,我想这不是什么大问题。我想我会继续讨论你的解决方案,看看有什么结论。如果你不介意的话,我可能会稍后再与你联系。不过,有一件事,你为什么要为文件和应用程序使用接口?为什么不使用抽象类?我正试图弄清楚什么时候应该使用,他们说,你需要我们当你有一个逻辑的时候,你可以创建一个类,当你有一个行为的时候,你可以创建一个接口!我为应用程序选择一个抽象类的原因是
        public interface IFile<T>
        {
            void Open(T path);
        }
    
        public abstract class Application
        {
            //public abstract void Open();
        }
    
    
        public class TextViewer : Application, IFile<TextFile>
        {
            public void Open(TextFile path)
            {
                //open textfile....
            }
        }
    
        public class MediaPlayer : Application, IFile<MediaFile>
        {     
            public void Open(MediaFile path)
            {
                //open media file...
            }
        }
    
        public class ImageViewer : Application, IFile<ImageFile>
        {
            public void Open(ImageFile path)
            {
                //open imagefile....
            }
        }
    
    public interface IFile
    {
    
    }
    
    public class MediaFile : IFile
    {
        ...
    }
    
    public interface IApplication
    {
        Type GetSupportedApplicationType();
        void OpenFile(IFile oFile);
    }
    
    
    public class MediaApplication : IApplication
    {
    
        #region IApplication Members
    
        public Type GetSupportedApplicationType()
        {
            return typeof(MediaFile);
        }
    
        public void OpenFile(IFile oFile)
        {
            // do the work
        }
    
        #endregion
    }
    
    <GetType(MediaFile), GetType(MediaPlayer)>
    
    public static class Mediator
    {
        static private Dictionary<Type, Type> dic = new Dictionary<Type, Type>();
    
        static Mediator()
        {
            RegisterApp(new MediaApplication());
        }
    
        static void RegisterApp(IApplication oApp)
        {
            dic.Add(oApp.GetSupportedApplicationType(), oApp.GetType());
        }
    
        static public void Open(IFile file)
        {
            Type appType = dic[file.GetType()];
            if (appType == null)
            {
                Console.WriteLine("No application was assigned to open up " + file);
                return;
            }
    
            IApplication app = (IApplication)System.Activator.CreateInstance(appType);
            app.OpenFile(file);
        }
    }