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」のいずれかを上記のコードに一般的に渡す方法を見つけようとしてきたので、すべての重複はありません。

Type を変数に保存できることに遭遇しました。しかし、私が見た Activator を扱った例のほとんどは、オブジェクトのインスタンスの作成に関係していました。

ご覧のとおり、これはインスタンスを作成していません。これが、「FileSecurity/DirectorySecurity fSecurity/dSecurity 部分を一般化する方法」と考えていた理由です。

ご協力いただきありがとうございます。

解決策 : nawfal によって提供された回答に基づいて、Main メソッドのコードと共に FileInfo と DirectoryInfo の両方で機能するようになった更新されたクラスを次に示します。注: 例外をまだ実装していないため、例外のスローに関するセクションをコメントアウトしました。

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>が、それでも、単純に醜い文字列を使用して一連のリフレクション呼び出しを続行する必要があります。

dynamicキーワードを使用して DLR に依存することができます。コンパイル時のエラーチェックの利点はありませんが、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、メソッドをチェックインして決定することができます。メソッドをより簡単にするために、メソッドをプライベートにして、次のような 2 つのパブリック メソッドのオーバーロードを提供できます。

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 に答える