我想加载一个程序集(它的名称存储在一个字符串中),使用反射来检查它是否有一个名为"CustomType MyMethod(byte [] a,int b)"的方法并调用它或者抛出异常.我想我应该做这样的事情,但如果有人可以就如何做到这一点提出相同的建议,我将不胜感激:
Assembly asm = Assembly.Load("myAssembly"); /* 1. does it matter if write myAssembly or myAssembly.dll? */
Type t = asm.GetType("myAssembly.ClassName");
// specify parameters
byte[] a = GetParamA();
int b = GetParamB();
object[] params = new object[2];
params[0] = a;
params[1] = b;
/* 2. invoke method MyMethod() which returns object "CustomType" - how do I check if it exists? */
/* 3. what's the meaning of 4th parameter (t in this case); MSDN says this is …
Run Code Online (Sandbox Code Playgroud) 当使用二进制流(即byte[]
数组)时,使用BinaryReader
或BinaryWriter
似乎是简化从流中读取/写入原始数据类型的主要观点,使用诸如ReadBoolean()
考虑编码的方法.这是整个故事吗?如果直接使用a Stream
而不使用BinaryReader/BinaryWriter
?是否存在固有的优势或劣势?大多数方法,例如Read()
,在两个类中似乎都是相同的,我的猜测是它们在下面工作相同.
考虑一个以两种不同方式处理二进制文件的简单示例(编辑:我意识到这种方式是无效的,可以使用缓冲区,它只是一个示例):
// Using FileStream directly
using (FileStream stream = new FileStream("file.dat", FileMode.Open))
{
// Read bytes from stream and interpret them as ints
int value = 0;
while ((value = stream.ReadByte()) != -1)
{
Console.WriteLine(value);
}
}
// Using BinaryReader
using (BinaryReader reader = new BinaryReader(FileStream fs = new FileStream("file.dat", FileMode.Open)))
{
// Read bytes and interpret them as ints
byte value = 0;
while …
Run Code Online (Sandbox Code Playgroud) 我正在使用方法重载Assembly A
:
public static int GetPersonId(EntityDataContext context, string name)
{
var id = from ... in context... where ... select ...;
return id.First();
}
public static int GetPersonId(SqlConnection connection, string name)
{
using (var context = new EntityDataContext(connection, false))
{
return GetPersonId(context, name);
}
}
Run Code Online (Sandbox Code Playgroud)
当我尝试从第二次重载调用时Assembly B
,VS会产生以下编译时错误:
"System.Data.Entity.DbContext"类型在未引用的程序集中定义.您必须添加对程序集'EntityFramework,Version = 6.0.0.0,Culture = neutral,PublicKeyToken = ...'的引用.
Assembly B
参考Assembly A
.实体框架仅在引用Assembly A
是Assembly B
不使用它.来自的呼叫Assembly B
如下:
using (SqlConnection connection = new SqlConnection(connectionString))
{ …
Run Code Online (Sandbox Code Playgroud) 假设一个简单的示例,其中方法检索集合(例如包含一些配置字符串的列表)并尝试以某种方式检查它:
void Init()
{
XmlDocument config = new XmlDocument();
config.Load(someXml);
var list = config.SelectNodes("/root/strings/key"); // Normally, list should not be null or empty
if (list == null || list.Count == 0)
throw new SomeExceptionType(message); // What kind of exception to throw?
// Iterate list and process/examine its elements
foreach (var e in list) ...
}
Run Code Online (Sandbox Code Playgroud)
在此特定实例中,如果未检索到任何内容,则该方法无法正常继续.我不确定在这种情况下抛出什么异常类型.据我所知,我的选择是:
手动抛出任何东西,让它NullReferenceException
自动抛出(不处理空列表情况),
抛出自定义异常类型(可能不是一个好主意,因为我不期望调用者会尝试对异常做任何事情,即他不会寻找一个特殊的异常类型来处理),
在一个子类中,我有一个私有std::mutex m
字段,我在基类纯虚方法的实现中使用它以线程安全的方式返回一个值(该值可以由另一个线程更新):
int SubClass::get() const // implements 'virtual int get() = 0 const' of the base class
{
std::lock_guard<std::mutex> lck(m);
return value;
}
Run Code Online (Sandbox Code Playgroud)
编译器通过产生错误告诉我这违反了const正确性:
错误:将'const std :: mutex'绑定到类型'std :: lock_guard :: mutex_type&{aka std :: mutex&}'的引用将丢弃限定符
有没有办法使这种兼容并std::lock_guard
以const正确的方式使用?只需改变它就不会const std::lock_guard
改变任何东西 我真的不明白哪个部分有问题,然后我再次对C++很新...
我正在设计一个Visual Studio项目,它将使用各种类型的潜在大量(最多约300个)脚本文件.这些文件不会与其他项目共享,即它们是项目专有的.是否有任何好的论据反对将所有这些文件包含为嵌入式资源(通过设置其构建操作),然后使用Assembly.GetManifestResourceStream()
它们在运行时检索它们?或者这是否是对嵌入资源的滥用,应该使用将这些资源作为文件保存的文件系统目录?
使用嵌入式资源的好处似乎是:
反对这种方法的论据通常是:
还有其他考虑因素吗?更一般地说,是否有一个原因是项目资源 - 不管它们是什么 - 不应该作为嵌入资源包括在内,除了在修改时需要的程序集重新编译?
我有一个共享的网络文件夹\\some.domain.net\Shared
,其中包含多个共享子文件夹,具有不同用户的不同权限.我希望从同一个Windows帐户打开多个子文件夹的连接,但是使用不同的凭据 - 这是否可以在不必先断开与同一共享的其他连接的情况下进行?
确切地说:在C#方法中,我尝试使用WNetUseConnection()
(p/invoke)以下列方式连接到特定的子文件夹:
ConnectToSharedFolder("\\some.domain.net\Shared\Subfolder1", user, password); // calls WNetUseConnection() internally
Run Code Online (Sandbox Code Playgroud)
只要在调用连接到子文件夹时没有与根文件夹(即\\some.domain.net\Shared
)或其他共享子文件夹(或通常是任何文件夹\\some.domain.net
)建立连接,这就可以正常工作.即,在连接到子文件夹之前,请考虑返回:WNetUseConnection()
net use
Status Local Remote
------------------------------------------------
OK \\some.domain.net\Shared
Run Code Online (Sandbox Code Playgroud)
现在我想连接到共享子文件夹\\some.domain.net\Shared\Subfolder1
,如本文顶部所示.这将导致Windows错误1219:
Multiple connections to a server or shared resource by the same user, using more than one user name, are not allowed. Disconnect all previous connections to the server or shared resource and try again.
Run Code Online (Sandbox Code Playgroud)
因此,尽管提供了不同的访问凭据,但Windows(Server 2008 R2)似乎并未认识到\\some.domain.net\Shared
和之间存在\\some.domain.net\Shared\Subfolder1
差异.但是,尝试在使用错误1219的情况下取消连接
WNetCancelConnection2(@"\\some.domain.net\Shared\Subfolder1", …
Run Code Online (Sandbox Code Playgroud) 从.NET 4开始,Lazy<T>
可以用来懒惰地初始化对象.直观地,懒惰初始化也可以在公共属性的getter中执行,以向调用者提供相同的功能.我想知道是否Lazy<T>
提供了后者的任何固有优势,因此应该优先考虑?
就个人而言,我觉得Lazy<>
可以迅速降低代码的可读性,但也许我刚看到它被误用了.从好的方面来说,它确保了线程的安全性,但是有很多.NET同步结构 - 也许我错了 - 让它很容易在getter中实现相同的功能.
选择最佳方法时需要注意哪些注意事项?
我可能在这里遗漏了一些非常简单的东西,但是使用反射从包含资源的同一程序集中检索嵌入资源而不是简单地通过.resx文件检索它有什么好处?我看到了很多但是没有得到它 - Assembly.GetExecutingAssembly().GetManifestResourceStream(resource)
与resx文件相比,是否有理由使用Resources.resource
?甚至微软也这样做:如何嵌入和访问资源.
我的意思是:假设我有一个MyAssembly
包含嵌入式资源的程序集Config.xml
.程序集MyClass
实现了一个以字符串形式返回所述资源的方法:
public string GetConfigXML() // returns the content of Config.xml as a string
Run Code Online (Sandbox Code Playgroud)
通常,我看到这样实现,使用反射来检索资源:
public string GetConfigXML()
{
Stream xmlStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("MyAssembly.Config.xml");
string xml = GetStringFromStream(xmlStream);
return xml;
}
Run Code Online (Sandbox Code Playgroud)
为什么GetManifestResourceStream()
在可以的时候使用:
Resource.resx
向MyAssembly
项目添加资源文件();Config.xml
到资源的'文件';Config.xml
以更简单的方式获取内容:string xml = Resource.Config;
我不知道Visual Studio如何在内部处理.resx文件,但我怀疑它只是将资源复制到.resx文件中(在这种情况下,您最终会得到重复的资源).我假设它也没有在内部使用反射,所以为什么不在这样的情况下简单地使用.resx文件,这对我来说似乎更加性能友好?
当使用代码首先从数据库方法从现有数据库创建新的实体数据模型时,可以直接指定要包含在模型中的表.可以在Visual Studio向导中选择子集(或所有)表:
在这个例子中,Category
和Product
类都将与所创建的沿DbContext
派生上下文类.如果我以后想要在同一个模型中添加其他表,是否有一种简单的方法来添加它们,即无需自己手动创建类?
例如,最初,我的DbContext
课程将包含:
public virtual DbSet<Category> Categories { get; set; }
public virtual DbSet<Product> Products { get; set; }
Run Code Online (Sandbox Code Playgroud)
现在假设我还想要包含Employee
表,以便将DbContext
类更新为:
public virtual DbSet<Category> Categories { get; set; }
public virtual DbSet<Product> Products { get; set; }
public virtual DbSet<Employee> Employees { get; set; }
Run Code Online (Sandbox Code Playgroud)
VS上下文菜单似乎没有提供此选项,但也许我错过了一些东西.有没有办法恢复向导,以便我可以选择其他表?
一个解决方案是有一个单独的空项目,您只需创建一个新模型,然后复制/粘贴新类,但我很好奇是否有更快的方法.
c# ×8
.net ×6
reflection ×2
c++ ×1
constants ×1
invokemember ×1
overloading ×1
stream ×1
winapi ×1
windows ×1