[英]C#: Internal and public interfaces, auto-implemented properties, but with structs…
我知道有一种模式涉及部分类,以实现一个具有可设置程序集属性的类,但该类从外部是只读的,例如
// This is just the non-working example to get the idea of what I want it to do across
public interface IMyReadable
{
int Property1 { get; }
string Property2 { get; }
}
internal interface IMyEditable : IMyReadable
{
int Property1 { get; set; }
string Property2 { get; set;}
}
public class Implementation : IMyEditable
{
public int Property1 { get; internal set; }
public string Property2 { get; internal set;}
}
因为您无法在界面中定义“内部集”。 可以为诸如https://stackoverflow.com/a/42082500/6155053之类的类实现
…但是如果我想对结构执行此操作怎么办?
我知道,结构通常应该是完全只读的,但是最好有多个不同的结构实现来实现接口,然后能够首先对其进行实例化,然后再从程序集内部按属性初始化它们,例如在工厂类,而不必为每个不同的实现(通过其c'tor或其他东西)写出接口的每个属性的设置。
那会让我做类似的事情
// non-sense, but explanatory code snippet
[…]
var structs = new HashSet<IMyEditable>();
structs.Add(new MyEditableImplementation1());
structs.Add(new MyEditableImplementation2());
structs.Add(new MyEditableImplementation3());
int i = 0;
foreach(IMyEditable s in structs)
{
s.Property1 = ++i;
s.Property2 = i.ToString();
}
// ...and still be able to set custom properties only some of the implementations
// have afterwards, etc., and when you then return, for example do:
return structs.Cast<IMyReadable>();
随着接口实现数量的增加,将省去编写很多用于初始化的样板。
但是,由于结构始终是密封的,并且不能从“基本结构”继承……我将如何做到这一点,而又不会失去自动实现属性的优势(如果我要使用具有共享私有字段的代理属性来实现的话)在每个结构中-再次,这意味着很多样板代码,仅在另一个地方)。
这可能吗? 如果是这样,怎么办?
编辑:添加了第二个示例以解释所需的用法
这个怎么样?
IReader.cs(ClassLibrary1)
namespace ClassLibrary1
{
public interface IReader
{
int Property1 { get; }
string Property2 { get; }
}
}
IWriter.cs(ClassLibrary1)
namespace ClassLibrary1
{
internal interface IWriter : IReader
{
new int Property1 { get; set; }
new string Property2 { get; set; }
}
}
SomeObject.cs(ClassLibrary1)
namespace ClassLibrary1
{
internal class SomeObject : IWriter
{
public int Property1 { get; set; }
public string Property2 { get; set; }
}
}
Worker.cs(ClassLibrary1)
namespace ClassLibrary1
{
using System.Collections.Generic;
using System.Linq;
public static class Worker
{
// NOTE: Thanks to internal on the IWriter, you can't return IWriter here.
public static IEnumerable<IReader> DoSomething()
{
var structs = new HashSet<IWriter>();
structs.Add(new SomeObject());
structs.Add(new SomeObject());
structs.Add(new SomeObject());
int i = 0;
foreach (IWriter s in structs)
{
s.Property1 = ++i;
s.Property2 = i.ToString();
}
return structs.Cast<IReader>();
}
}
}
Program.cs(ConsoleApplication3)
namespace ConsoleApplication3
{
using System.Collections.Generic;
using System.Linq;
using ClassLibrary1;
public class Program
{
private static void Main(string[] args)
{
// NOTE: You can't cast the structs to IWriter here.
var structs = Worker.DoSomething();
// This will not compile:
// (structs.FirstOrDefault() as IWriter).Property1 = 10
}
}
}
注意:
IWriter
是internal
,这意味着您不能在ClassLibrary1之外传递/使用它。 完美,只有您的“内部人员”可以处理它,而对于外部世界,您只能公开IReader
,这就是我们所做的。 IWriter
。 哪个好 有趣的是,“立即窗口”使我可以将结构IWriter
为IWriter
,但是我认为它使用了反射,并且在编译时不允许这样做,所以您很好!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.