将 System.Type 类保存到变量并使用变量引用(而不是实例化)类型
本文关键字:变量 类型 实例化 引用 Type System 保存 | 更新日期: 2023-09-27 18:35:48
我了解如何将类型类分配给变量:
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);
}
}
即使从它的字符串名称中获取System.Type
,也只能将其类型化为object
,并且不能调用在类FileSystemSecurity
上定义的成员。您可以使用泛型并传递<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
签入方法进行决定。若要使方法更加万无一失,可以将该方法设为私有并提供两个公共方法重载,例如:
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
)
);
}
现在,如果它作为方法重载的一部分编写一次,则不必传递庞大的访问规则。但我想说它仍然不值得做这一切,因为你失去了编译时间检查......还要避免使用它们的方式进行尝试捕获。