1

我了解如何将类型类分配给变量:

Type type = ("System.Security.AccessControl.FileSecurity").GetType();

然后我如何使用这个变量作为已经实例化对象的引用?

如果我尝试以下操作:

type instance = new SomeOtherType();

我收到以下错误代码:

找不到类型或命名空间名称“type”(您是否缺少 using 指令或程序集引用?)

例子:

FileSecurity fSecurity = fInfo.GetAccessControl();

我希望能够做到:

Type sometype = ("System.Security.AccessControl.FileSecurity").GetType();
sometype mynewtype = fInfo.GetAccessControl(); 

编辑: 为了更好地解释为什么我什至首先尝试这样做,请查看以下代码:

public static class FileFolderPermissions
{
    public static void SetFileFolderPermissions()
    {
        try
        {
            DirectoryInfo dInfo = new DirectoryInfo(@"D:\SomeFolder");
            DirectorySecurity dSecurity = dInfo.GetAccessControl();

            FileInfo fInfo = new FileInfo(@"D:\Test.txt");
            FileSecurity fSecurity = fInfo.GetAccessControl();

            dSecurity.AddAccessRule(new FileSystemAccessRule("TestAccount",
                    FileSystemRights.FullControl, InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit,
                    PropagationFlags.NoPropagateInherit, AccessControlType.Allow));
            dInfo.SetAccessControl(dSecurity);

            fSecurity.AddAccessRule(new FileSystemAccessRule("TestAccount",
                    FileSystemRights.FullControl, AccessControlType.Allow));
            fInfo.SetAccessControl(fSecurity);

        }
        catch
        {
            Console.WriteLine("Error.");
        }
    }
}

我要做的是创建一种通用方法来设置对象是文件还是目录的 ACL。如您所见,上面的代码中有很多代码重复。所以我一直试图弄清楚如何将“DirectoryInfo”或“FileInfo”一般地传递​​给上面的代码,所以我没有所有的重复。

我曾经遇到能够将类型保存到变量中。但是我看到的大多数与 Activator 打交道的示例都涉及创建对象的实例。

如您所见,这不是创建实例。所以这就是为什么我想知道“如何概括 FileSecurity/DirectorySecurity fSecurity/dSecurity 部分”?

谢谢你的帮助。

解决方案:根据 nawfal 提供的答案,这里是更新的类,它现在适用于 FileInfo 和 DirectoryInfo 以及 Main 方法中的代码。注意:我注释掉了处理抛出异常的部分,因为我还没有实现异常。

public static class DynFileFolderPermissions
{
    public static void SetFileFolderPermissions(dynamic info, FileSystemAccessRule FileAccessRule)
    {
        // if (!(info is System.IO.FileInfo) || !(info is System.IO.DirectoryInfo))
        //    throw new System.InvalidOperationException("Incorrect Type.");

        try
        {

            var security = info.GetAccessControl();

            security.AddAccessRule(FileAccessRule);
            info.SetAccessControl(security);
        }
        catch
        {
            Console.WriteLine("Error.");
        }
    }
}

// Main
class Program
{
    static void Main(string[] args)
    {
        // Grants FullControl to user "TestUser" on file D:\Test.txt
        var fileInfo = new FileInfo(@"D:\Test.txt");
        var FileAccessRule = new FileSystemAccessRule("TestUser", FileSystemRights.FullControl, AccessControlType.Allow);
        DynFileFolderPermissions.SetFileFolderPermissions(fileInfo, FileAccessRule);

        // Grants FullControl to user "TestUser" on directory D:\Test
        var directoryInfo = new DirectoryInfo(@"D:\Test");
        var DirectoryAccessRule = new FileSystemAccessRule("TestUser", FileSystemRights.FullControl,
                    InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit,
                    PropagationFlags.None, AccessControlType.Allow);
        DynFileFolderPermissions.SetFileFolderPermissions(directoryInfo, DirectoryAccessRule);
    }
}
4

1 回答 1

0

即使您System.Type从它的字符串名称中获取,您也只能将其键入为object,并且您不能调用在FileSystemSecurity类上定义的成员。您可以使用泛型并传递 a<T>但您仍然必须使用非常难看的字符串进行一堆反射调用。

您可以使用关键字来使用依赖 DLR dynamic,更不用说麻烦了。虽然它没有提供编译时错误检查的好处,dynamic但使它更干净。至少你可以看到你的代码。

public static void SetFileFolderPermissions(dynamic info)
{
    if (!(info is FileInfo) || !(info is DirectoryInfo))
        throw new explosion;

    try
    {
        var security = info.GetAccessControl();
        security.AddAccessRule(new FileSystemAccessRule(...));
        info.SetAccessControl(security);
    }
    catch
    {
        Console.WriteLine("Error.");
    }
}

您可以传递一个FileInfo对象或DirectoryInfo对象。如果FileSystemAccessRule两者都不同,那么您可以将其作为参数传递,或者if-else检查方法来决定。为了使您的方法更加安全,您可以将方法设为私有并提供两个公共方法重载,例如:

public static void SetFilePermissions(string path)
{
    SetFileFolderPermissions
    (
        new FileInfo(path), 
        new FileSystemAccessRule
        (
            "TestAccount", 
            FileSystemRights.FullControl, 
            AccessControlType.Allow
        )
    );
}

//so that now nobody from outside can pass any dumb object to it
static void SetFileFolderPermissions(dynamic info, FileSystemAccessRule rule)
{
    try
    {
        var security = info.GetAccessControl();
        security.AddAccessRule(rule);
        info.SetAccessControl(security);
    }
    catch
    {
        Console.WriteLine("Error.");
    }
}

public static void SetFolderPermissions(string path)
{
    SetFileFolderPermissions
    (
        new DirectoryInfo(path), 
        new FileSystemAccessRule
        (
            "TestAccount",
             FileSystemRights.FullControl,
             InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit,
             PropagationFlags.NoPropagateInherit,
             AccessControlType.Allow
        )
    );
}

现在,如果将其作为方法重载的一部分编写一次,您就不必绕过庞大的访问规则。但我会说它仍然不值得做这一切,因为你失去了编译时间检查......还要避免他们使用的 try-catch。

于 2013-10-18T17:13:27.283 回答