我实现自定义方法的属性是否有 shorthand?
Is there a shorthand for properties where I implement a custom method?
public class ServerState
{
public static Action stateChanged;
private string currentMap;
public string CurrentMap
{
get { return currentMap; }
set
{
currentMap = value;
stateChanged?.Invoke();
}
}
}
我有一个 class 包含许多变量,每个变量都需要自己的 属性 以便我可以调用一个动作。也就是说,我打算把上面的代码重复几十次,感觉应该有更好的方法。
上面的代码有shorthand吗?
这里有一些想法:
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace ConsoleApp1
{
public class ServerState
{
public static Action stateChanged;
private Dictionary<string, object> _values = new Dictionary<string, object>();
private void Set(object value, [CallerMemberName] string propertyName = null)
{
_values[propertyName] = value;
stateChanged?.Invoke();
}
private T Get<T>([CallerMemberName] string propertyName = null)
{
if (_values.TryGetValue(propertyName, out var v)) return (T)v;
throw new KeyNotFoundException(propertyName);
}
public string CurrentMap
{
get => Get<string>();
set => Set(value);
}
// You can make them in one line if you want
public string CurrentMap2 { get => Get<string>(); set => Set(value); }
}
public class ServerState2
{
public static Action stateChanged;
private string currentMap;
private void Set<T>(ref T property, T value)
{
property = value;
stateChanged?.Invoke();
}
public string CurrentMap
{
get => currentMap;
set => Set(ref currentMap, value);
}
}
}
如果您想使用多个事件,或者跟踪值是否实际发生变化,您可以扩展这一想法:
public class ServerState
{
public static Action currentMapChanged;
public static Action currentMap2Changed;
private Dictionary<string, object> _values = new Dictionary<string, object>();
private void Set(object value, Action onChange, [CallerMemberName] string propertyName = null)
{
var previousValue = _values[propertyName];
// Check if value has changed
if (value != previousValue)
{
_values[propertyName] = value;
onChange?.Invoke();
}
}
private T Get<T>([CallerMemberName] string propertyName = null)
{
if (_values.TryGetValue(propertyName, out var v)) return (T)v;
throw new KeyNotFoundException(propertyName);
}
public string CurrentMap
{
get => Get<string>();
// Call `currentMapChanged` if value differs
set => Set(value, currentMapChanged);
}
// You can make them in one line if you want
// Call `currentMap2Changed` if value differs
public string CurrentMap2 { get => Get<string>(); set => Set(value, currentMap2Changed); }
}
此外,您应该考虑使用 event
关键字来阻止其他 类 触发此事件。还要注意静态事件,它们在静态上下文中持有对侦听委托的引用,需要小心避免内存泄漏。
public class ServerState
{
public static Action stateChanged;
private string currentMap;
public string CurrentMap
{
get { return currentMap; }
set
{
currentMap = value;
stateChanged?.Invoke();
}
}
}
我有一个 class 包含许多变量,每个变量都需要自己的 属性 以便我可以调用一个动作。也就是说,我打算把上面的代码重复几十次,感觉应该有更好的方法。
上面的代码有shorthand吗?
这里有一些想法:
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace ConsoleApp1
{
public class ServerState
{
public static Action stateChanged;
private Dictionary<string, object> _values = new Dictionary<string, object>();
private void Set(object value, [CallerMemberName] string propertyName = null)
{
_values[propertyName] = value;
stateChanged?.Invoke();
}
private T Get<T>([CallerMemberName] string propertyName = null)
{
if (_values.TryGetValue(propertyName, out var v)) return (T)v;
throw new KeyNotFoundException(propertyName);
}
public string CurrentMap
{
get => Get<string>();
set => Set(value);
}
// You can make them in one line if you want
public string CurrentMap2 { get => Get<string>(); set => Set(value); }
}
public class ServerState2
{
public static Action stateChanged;
private string currentMap;
private void Set<T>(ref T property, T value)
{
property = value;
stateChanged?.Invoke();
}
public string CurrentMap
{
get => currentMap;
set => Set(ref currentMap, value);
}
}
}
如果您想使用多个事件,或者跟踪值是否实际发生变化,您可以扩展这一想法:
public class ServerState
{
public static Action currentMapChanged;
public static Action currentMap2Changed;
private Dictionary<string, object> _values = new Dictionary<string, object>();
private void Set(object value, Action onChange, [CallerMemberName] string propertyName = null)
{
var previousValue = _values[propertyName];
// Check if value has changed
if (value != previousValue)
{
_values[propertyName] = value;
onChange?.Invoke();
}
}
private T Get<T>([CallerMemberName] string propertyName = null)
{
if (_values.TryGetValue(propertyName, out var v)) return (T)v;
throw new KeyNotFoundException(propertyName);
}
public string CurrentMap
{
get => Get<string>();
// Call `currentMapChanged` if value differs
set => Set(value, currentMapChanged);
}
// You can make them in one line if you want
// Call `currentMap2Changed` if value differs
public string CurrentMap2 { get => Get<string>(); set => Set(value, currentMap2Changed); }
}
此外,您应该考虑使用 event
关键字来阻止其他 类 触发此事件。还要注意静态事件,它们在静态上下文中持有对侦听委托的引用,需要小心避免内存泄漏。