以下方法无法编译.Visual Studio警告"可能无法在匿名方法中使用out参数".该WithReaderLock(Proc action)方法需要一个delegate void Proc().
public Boolean TryGetValue(TKey key, out TValue value)
{
Boolean got = false;
WithReaderLock(delegate
{
got = dictionary.TryGetValue(key, out value);
});
return got;
}
Run Code Online (Sandbox Code Playgroud)
获得这种行为的最佳方法是什么?(请不要提供有关线程安全词典的建议,这个问题一般是为了解决out参数问题).
我想开始使用泛型和匿名方法,主要是为了了解这是什么以及为什么我想要使用它们.
有了Delphi 2009,我经常读到泛型和匿名方法没有完全实现或有缺陷,这在Delphi 2010中得到了修复.
我想避免不得不怀疑这是我的错,还是Delphi 2009中的一个错误,每次有些东西不能按照我的预期运行.
我的问题是:
在Delphi 2009中使用泛型和匿名方法时,我会遇到什么问题?
我应该避免什么?
例如,我有一个包含在类中的属性
public class Greeter {
private Hashtable _data;
public string HelloPhrase { get; set; }
public Greeter(data) {
_data = data;
}
}
Run Code Online (Sandbox Code Playgroud)
我想要做的是向HelloPhrase属性添加一个属性,就像这样
[MyCustomAttribute("Hello_Phrase")]
public string SayHello { get; set; }
Run Code Online (Sandbox Code Playgroud)
这样在构造函数中我可以反映已经定义了MyCustomAttribute的类(Greeter)中的Properties,并将属性的Get/Set方法设置为匿名方法/委托.
public Greeter(data) {
_data = data;
ConfigureProperties();
}
Run Code Online (Sandbox Code Playgroud)
我已经设法从类中获取PropertyInfo,但这只暴露了GetSetMethod(http://msdn.microsoft.com/en-us/library/system.reflection.propertyinfo.getsetmethod.aspx)和相应的GetGetMethod.
我已经在这里和网上阅读了一些问题,但找不到不使用某种Aspects库的答案.
任何人都可以提供指向在运行时设置Get/Set方法的指针吗?理想情况下,像一个代表
x =>_data[keyDefinedByAttribute];
Run Code Online (Sandbox Code Playgroud) 我创建了以下示例代码:
class Program {
static void Main(string[] args) {
var x = new ActionTestClass();
x.ActionTest();
var y = x.Act.Target;
}
}
public class ActionTestClass {
public Action Act;
public void ActionTest() {
this.Act = new Action(this.ActionMethod);
}
private void ActionMethod() {
MessageBox.Show("This is a test.");
}
}
Run Code Online (Sandbox Code Playgroud)
当我以这种方式执行此操作时,y将是ActionTestClass类型的对象(为x创建).现在,当我改变线
this.Act = new Action(this.ActionMethod);
Run Code Online (Sandbox Code Playgroud)
至
this.Act = new Action(() => MessageBox.Show("This is a test."));
Run Code Online (Sandbox Code Playgroud)
y(行动目标)将为空.有没有办法,我可以在使用匿名操作的方式上获取Target(在示例中为ActionTestClass对象)?
假设我有一个IMyInterface<T>简单描述一个函数的接口:
public interface IMyInterface<T>
{
T MyFunction(T item);
}
Run Code Online (Sandbox Code Playgroud)
我可以用这个替换它Func<T, T>,但是出于语义原因我想要接口.我可以在该接口之间定义隐式转换,Func<T,T>以便我可以将匿名委托或lambda作为参数传递给接受此接口作为参数的函数,就像我曾经使用过一样Func<T,T>吗?
为了演示,使用上面声明的接口我想要一个这样的函数:
public T TestFunction<T>(IMyInterface myInterface, T value)
{
return myInterface.MyFunction(value);
}
Run Code Online (Sandbox Code Playgroud)
我可以像这样打电话:
TestFunction<string>( x => return x + " world", "hello");
Run Code Online (Sandbox Code Playgroud)
结果将是"你好世界".
是否可以从字符串中创建c#中的匿名方法?
例如,如果我有一个字符串"x + y * z",才有可能把它变成某种方法/λ对象,我可以任意拨打x,y,z参数?
我有一些linq to sql方法,当它执行查询时,它返回一些匿名类型.
我想将该匿名类型返回到我的服务层,以便对其进行一些逻辑和操作.
我不知道如何归还它.
我以为我能做到这一点
public List<T> thisIsAtest()
{
return query;
}
Run Code Online (Sandbox Code Playgroud)
但是我得到了这个错误
Error 1 The type or namespace name 'T' could not be found (are you missing a using directive or an assembly reference?)
Run Code Online (Sandbox Code Playgroud)
所以不确定我错过了什么组件,或者甚至是不是这样.
谢谢
编辑
好吧,我的第一个问题已经解决,但现在我遇到了一个新问题,我不确定如何修复,因为我对匿名类型不太了解.
我收到这个错误
无法将类型'System.Collections.Generic.List'隐式转换为'System.Collections.Generic.List
这是查询
DbContext.Table.Where(u => u.Table.UserId == userId && u.OutOFF != 0)
.GroupBy(u => new { u.Table.Prefix })
.Select(group => new { prefix = group.Key,
Marks = group.Sum(item => (item.Mark * item.Weight) / item.OutOFF) })
.ToList();
Run Code Online (Sandbox Code Playgroud)
编辑2
public class ReturnValue …Run Code Online (Sandbox Code Playgroud) 以下代码(仅用于演示问题)构建并在Delphi 2010中工作.在Delphi 2009中,编译器失败并显示"E2035实际参数不足".
program Project50;
{$APPTYPE CONSOLE}
uses
SysUtils;
type
TMyProc = reference to procedure(param: integer);
var
a: TProc;
b: TMyProc;
begin
b := procedure (param: integer)
begin
end;
a := TProc(b); // <-- [DCC Error] Project50.dpr(19): E2035 Not enough actual parameters
end.
Run Code Online (Sandbox Code Playgroud)
我发现只有一个非常难看的黑客来解决这个问题(a:TProc绝对b).有没有人知道这个编译器缺陷的更好的解决方法?
[TProc字段实际上隐藏在可以存储各种'可执行'代码的记录中 - TProcedure,TMethod和TProc.Casting用于将特定的匿名proc存储到此字段中.]
我想做的事:
我在genric列表中有一些对象.我想以匿名方法捕获每个对象,并将此方法作为单独的OTL任务执行.
这是一个简化的例子:
program Project51;
{$APPTYPE CONSOLE}
uses
SysUtils, Generics.Collections, OtlTaskControl, OtlTask;
type
TProc = reference to procedure;
type
TMyObject = class(TObject)
public
ID: Integer;
constructor Create(AID: Integer);
end;
constructor TMyObject.Create(AID: Integer);
begin
ID := AID;
end;
var
Objects: TList<TMyObject>;
LObject: TMyObject;
MyProc: TProc;
begin
Objects := TList<TMyObject>.Create;
Objects.Add(TMyObject.Create(1));
Objects.Add(TMyObject.Create(2));
Objects.Add(TMyObject.Create(3));
for LObject in Objects do
begin
//This seems to work
MyProc := procedure
begin
Writeln(Format('[SameThread] Object ID: %d',[LObject.ID]));
end;
MyProc;
//This doesn't work, sometimes it returns 4 lines in …Run Code Online (Sandbox Code Playgroud) delphi closures anonymous-methods delphi-2009 omnithreadlibrary
如果我有这个匿名方法,我应该声明x变量为final.
private void testMethod (ListField<BeanModel> listField){
final ListLoader<BeanModel> loader = new PagedListLoader<BeanModel>();
listField.addListener(Events.Attach, new Listener<ListViewEvent<BeanModel>>() {
@Override
public void handleEvent(ListViewEvent<BeanModel> be) {
loader.load();
}
});
}
Run Code Online (Sandbox Code Playgroud)
但是,如果loader是一个类字段,则没有必要将其声明为final:
public class testClass{
private ListLoader<BeanModel> loader = new PagedListLoader<BeanModel>();
private void testMethod (ListField<BeanModel> listField){
listField.addListener(Events.Attach, new Listener<ListViewEvent<BeanModel>>() {
@Override
public void handleEvent(ListViewEvent<BeanModel> be) {
loader.load();
}
});
//Could I modify loader's reference here, before the method executes?
//loader = null;
}
}
Run Code Online (Sandbox Code Playgroud)
有没有人知道为什么他们保证局部变量在被访问时不会改变但是没有为类字段做?
c# ×6
delphi ×3
delphi-2009 ×3
.net ×2
generics ×2
.net-4.0 ×1
aspects ×1
attributes ×1
closures ×1
delegates ×1
implicit ×1
java ×1
lambda ×1
properties ×1
reflection ×1